summaryrefslogtreecommitdiff
path: root/sc/source/ui/Accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/Accessibility')
-rw-r--r--sc/source/ui/Accessibility/AccessibilityHints.cxx112
-rw-r--r--sc/source/ui/Accessibility/AccessibleCell.cxx459
-rw-r--r--sc/source/ui/Accessibility/AccessibleCellBase.cxx345
-rw-r--r--sc/source/ui/Accessibility/AccessibleContextBase.cxx628
-rw-r--r--sc/source/ui/Accessibility/AccessibleCsvControl.cxx1680
-rw-r--r--sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx739
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocument.cxx2120
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocumentBase.cxx51
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx1942
-rw-r--r--sc/source/ui/Accessibility/AccessibleEditObject.cxx358
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenu.cxx398
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx205
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx127
-rw-r--r--sc/source/ui/Accessibility/AccessibleGlobal.cxx95
-rw-r--r--sc/source/ui/Accessibility/AccessiblePageHeader.cxx441
-rw-r--r--sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx330
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewCell.cxx316
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx443
-rw-r--r--sc/source/ui/Accessibility/AccessiblePreviewTable.cxx769
-rw-r--r--sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx999
-rw-r--r--sc/source/ui/Accessibility/AccessibleTableBase.cxx495
-rw-r--r--sc/source/ui/Accessibility/AccessibleText.cxx1911
-rw-r--r--sc/source/ui/Accessibility/DrawModelBroadcaster.cxx92
-rw-r--r--sc/source/ui/Accessibility/makefile.mk94
24 files changed, 15149 insertions, 0 deletions
diff --git a/sc/source/ui/Accessibility/AccessibilityHints.cxx b/sc/source/ui/Accessibility/AccessibilityHints.cxx
new file mode 100644
index 000000000000..6c276b806e88
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibilityHints.cxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "AccessibilityHints.hxx"
+
+using namespace ::com::sun::star;
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccWinFocusLostHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccWinFocusLostHint - the current window lost its focus (to another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccWinFocusLostHint::ScAccWinFocusLostHint(
+ const uno::Reference< uno::XInterface >& xOld )
+ :
+ xOldAccessible(xOld)
+{
+}
+
+ScAccWinFocusLostHint::~ScAccWinFocusLostHint()
+{
+}
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccWinFocusGotHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccWinFocusGotHint - the window got the focus (from another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccWinFocusGotHint::ScAccWinFocusGotHint(
+ const uno::Reference< uno::XInterface >& xNew )
+ :
+ xNewAccessible(xNew)
+{
+}
+
+ScAccWinFocusGotHint::~ScAccWinFocusGotHint()
+{
+}
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccGridWinFocusLostHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccGridWinFocusLostHint - the current grid window lost its focus (to another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccGridWinFocusLostHint::ScAccGridWinFocusLostHint(ScSplitPos eOld,
+ const uno::Reference< uno::XInterface >& xOld )
+ :
+ ScAccWinFocusLostHint(xOld),
+ eOldGridWin(eOld)
+{
+}
+
+ScAccGridWinFocusLostHint::~ScAccGridWinFocusLostHint()
+{
+}
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(ScAccGridWinFocusGotHint, SfxHint);
+
+// -----------------------------------------------------------------------
+// ScAccGridWinFocusGotHint - the grid window got the focus (from another application, view or document)
+// -----------------------------------------------------------------------
+
+ScAccGridWinFocusGotHint::ScAccGridWinFocusGotHint(ScSplitPos eNew,
+ const uno::Reference< uno::XInterface >& xNew )
+ :
+ ScAccWinFocusGotHint(xNew),
+ eNewGridWin(eNew)
+{
+}
+
+ScAccGridWinFocusGotHint::~ScAccGridWinFocusGotHint()
+{
+}
diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx
new file mode 100644
index 000000000000..434ea2dea40c
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCell.cxx
@@ -0,0 +1,459 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleCell.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include "AccessibleText.hxx"
+#include "AccessibleDocument.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "miscuno.hxx"
+#include "unoguard.hxx"
+#include "editsrc.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <editeng/brshitem.hxx>
+#include <comphelper/sequence.hxx>
+#include <float.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleCell::ScAccessibleCell(
+ const uno::Reference<XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScAddress& rCellAddress,
+ sal_Int32 nIndex,
+ ScSplitPos eSplitPos,
+ ScAccessibleDocument* pAccDoc)
+ :
+ ScAccessibleCellBase(rxParent, GetDocument(pViewShell), rCellAddress, nIndex),
+ ::accessibility::AccessibleStaticTextBase(CreateEditSource(pViewShell, rCellAddress, eSplitPos)),
+ mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ meSplitPos(eSplitPos)
+{
+ if (pViewShell)
+ pViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessibleCell::~ScAccessibleCell()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleCell::Init()
+{
+ ScAccessibleCellBase::Init();
+
+ SetEventSource(this);
+}
+
+void SAL_CALL ScAccessibleCell::disposing()
+{
+ ScUnoGuard aGuard;
+ // #100593# dispose in AccessibleStaticTextBase
+ Dispose();
+
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ mpAccDoc = NULL;
+
+ ScAccessibleCellBase::disposing();
+}
+
+ //===== XInterface =====================================================
+
+IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase )
+
+ //===== XTypeProvider ===================================================
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase )
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleCell::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ return AccessibleStaticTextBase::getAccessibleAtPoint(rPoint);
+}
+
+void SAL_CALL ScAccessibleCell::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is() && mpViewShell)
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ {
+ xAccessibleComponent->grabFocus();
+ mpViewShell->SetCursor(maCellAddress.Col(), maCellAddress.Row());
+ }
+ }
+}
+
+Rectangle ScAccessibleCell::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessibleCell::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ long nSizeX, nSizeY;
+ mpViewShell->GetViewData()->GetMergeSizePixel(
+ maCellAddress.Col(), maCellAddress.Row(), nSizeX, nSizeY);
+ aCellRect.SetSize(Size(nSizeX, nSizeY));
+ aCellRect.SetPos(mpViewShell->GetViewData()->GetScrPos(maCellAddress.Col(), maCellAddress.Row(), meSplitPos, TRUE));
+
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ Rectangle aRect(pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()));
+ aRect.Move(-aRect.Left(), -aRect.Top());
+ aCellRect = aRect.Intersection(aCellRect);
+ }
+
+ /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
+ boundaries. This leads to wrong results in cases where the cell
+ text is rotated, because rotation is not taken into account when
+ calculating the visible part of the text. In these cases we will
+ simply expand the cell size to the width of the unrotated text. */
+ if (mpDoc)
+ {
+ const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >(
+ mpDoc->GetAttr( maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_ROTATE_VALUE ) );
+ if( pItem && (pItem->GetValue() != 0) )
+ {
+ Rectangle aParaRect = GetParagraphBoundingBox();
+ if( !aParaRect.IsEmpty() && (aCellRect.GetWidth() < aParaRect.GetWidth()) )
+ aCellRect.SetSize( Size( aParaRect.GetWidth(), aCellRect.GetHeight() ) );
+ }
+ }
+ }
+ if (aCellRect.IsEmpty())
+ aCellRect.SetPos(Point(-1, -1));
+ return aCellRect;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleCell::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ return AccessibleStaticTextBase::getAccessibleChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ return AccessibleStaticTextBase::getAccessibleChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleCell::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ if (IsEditable(xParentStates))
+ {
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::RESIZABLE);
+ }
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ if (IsOpaque(xParentStates))
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::SELECTABLE);
+ if (IsSelected())
+ pStateSet->AddState(AccessibleStateType::SELECTED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleCell::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if (mpAccDoc)
+ pRelationSet = mpAccDoc->GetRelationSet(&maCellAddress);
+ if (!pRelationSet)
+ pRelationSet = new utl::AccessibleRelationSetHelper();
+ FillDependends(pRelationSet);
+ FillPrecedents(pRelationSet);
+ return pRelationSet;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleCell::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCell"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleCell::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessibleCell"));
+
+ return aSequence;
+}
+
+ //==== internal =========================================================
+
+sal_Bool ScAccessibleCell::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleCell::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ sal_Bool bEditable(sal_True);
+ if (rxParentStates.is() && !rxParentStates->contains(AccessibleStateType::EDITABLE) &&
+ mpDoc)
+ {
+ // here I have to test whether the protection of the table should influence this cell.
+ const ScProtectionAttr* pItem = (const ScProtectionAttr*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(),
+ maCellAddress.Tab(), ATTR_PROTECTION);
+ if (pItem)
+ bEditable = !pItem->GetProtection();
+ }
+ return bEditable;
+}
+
+sal_Bool ScAccessibleCell::IsOpaque(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // test whether there is a background color
+ sal_Bool bOpaque(sal_True);
+ if (mpDoc)
+ {
+ const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(),
+ maCellAddress.Tab(), ATTR_BACKGROUND);
+ if (pItem)
+ bOpaque = pItem->GetColor() != COL_TRANSPARENT;
+ }
+ return bOpaque;
+}
+
+sal_Bool ScAccessibleCell::IsSelected()
+{
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsCellMarked(maCellAddress.Col(), maCellAddress.Row());
+ }
+ return bResult;
+}
+
+ScDocument* ScAccessibleCell::GetDocument(ScTabViewShell* pViewShell)
+{
+ ScDocument* pDoc = NULL;
+ if (pViewShell && pViewShell->GetViewData())
+ pDoc = pViewShell->GetViewData()->GetDocument();
+ return pDoc;
+}
+
+::std::auto_ptr< SvxEditSource > ScAccessibleCell::CreateEditSource(ScTabViewShell* pViewShell, ScAddress aCell, ScSplitPos eSplitPos)
+{
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData
+ ( new ScAccessibleCellTextData( pViewShell, aCell, eSplitPos, this ) );
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleCellTextData));
+
+ return pEditSource;
+}
+
+void ScAccessibleCell::FillDependends(utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ if (mpDoc)
+ {
+ ScCellIterator aCellIter( mpDoc, 0,0, maCellAddress.Tab(), MAXCOL,MAXROW, maCellAddress.Tab() );
+ ScBaseCell* pCell = aCellIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ sal_Bool bFound(sal_False);
+ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+ ScRange aRef;
+ while ( !bFound && aIter.GetNextRef( aRef ) )
+ {
+ if (aRef.In(maCellAddress))
+ bFound = sal_True;
+ }
+ if (bFound)
+ AddRelation(ScAddress(aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab()), AccessibleRelationType::CONTROLLER_FOR, pRelationSet);
+ }
+ pCell = aCellIter.GetNext();
+ }
+ }
+}
+
+void ScAccessibleCell::FillPrecedents(utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ if (mpDoc)
+ {
+ ScBaseCell* pBaseCell = mpDoc->GetCell(maCellAddress);
+ if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_FORMULA))
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pBaseCell;
+
+ ScDetectiveRefIter aIter( pFCell );
+ ScRange aRef;
+ while ( aIter.GetNextRef( aRef ) )
+ {
+ AddRelation( aRef, AccessibleRelationType::CONTROLLED_BY, pRelationSet);
+ }
+ }
+ }
+}
+
+void ScAccessibleCell::AddRelation(const ScAddress& rCell,
+ const sal_uInt16 aRelationType,
+ utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ AddRelation(ScRange(rCell, rCell), aRelationType, pRelationSet);
+}
+
+void ScAccessibleCell::AddRelation(const ScRange& rRange,
+ const sal_uInt16 aRelationType,
+ utl::AccessibleRelationSetHelper* pRelationSet)
+{
+ uno::Reference < XAccessibleTable > xTable ( getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY );
+ if (xTable.is())
+ {
+ sal_uInt32 nCount(static_cast<sal_uInt32>(rRange.aEnd.Col() -
+ rRange.aStart.Col() + 1) * (rRange.aEnd.Row() -
+ rRange.aStart.Row() + 1));
+ uno::Sequence < uno::Reference < uno::XInterface > > aTargetSet( nCount );
+ uno::Reference < uno::XInterface >* pTargetSet = aTargetSet.getArray();
+ if (pTargetSet)
+ {
+ sal_uInt32 nPos(0);
+ for (sal_uInt32 nRow = rRange.aStart.Row(); nRow <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Row()); ++nRow)
+ {
+ for (sal_uInt32 nCol = rRange.aStart.Col(); nCol <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Col()); ++nCol)
+ {
+ pTargetSet[nPos] = xTable->getAccessibleCellAt(nRow, nCol);
+ ++nPos;
+ }
+ }
+ DBG_ASSERT(nCount == nPos, "something wents wrong");
+ }
+ AccessibleRelation aRelation;
+ aRelation.RelationType = aRelationType;
+ aRelation.TargetSet = aTargetSet;
+ pRelationSet->AddRelation(aRelation);
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx
new file mode 100644
index 000000000000..cc93d0a93350
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleCellBase.hxx"
+#include "attrib.hxx"
+#include "scitems.hxx"
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "docfunc.hxx"
+#include "cell.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+#include "unonames.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <tools/debug.hxx>
+#include <editeng/brshitem.hxx>
+#include <rtl/uuid.h>
+#include <comphelper/sequence.hxx>
+#include <sfx2/objsh.hxx>
+
+#include <float.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleCellBase::ScAccessibleCellBase(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScAddress& rCellAddress,
+ sal_Int32 nIndex)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
+ maCellAddress(rCellAddress),
+ mpDoc(pDoc),
+ mnIndex(nIndex)
+{
+}
+
+ScAccessibleCellBase::~ScAccessibleCellBase()
+{
+}
+
+ //===== XAccessibleComponent ============================================
+
+sal_Bool SAL_CALL ScAccessibleCellBase::isVisible( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ // test whether the cell is hidden (column/row - hidden/filtered)
+ sal_Bool bVisible(sal_True);
+ if (mpDoc)
+ {
+ bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab());
+ bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab());
+ bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab());
+ bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab());
+
+ if (bColHidden || bColFiltered || bRowHidden || bRowFiltered)
+ bVisible = sal_False;
+ }
+ return bVisible;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDoc)
+ {
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if ( pObjSh )
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
+ uno::Reference<sheet::XSpreadsheet> xTable;
+ if (aTable>>=xTable)
+ {
+ uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
+ if (xCell.is())
+ {
+ uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
+ if (xCellProps.is())
+ {
+ uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR)));
+ aAny >>= nColor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+
+ if (mpDoc)
+ {
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if ( pObjSh )
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
+ uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
+ uno::Reference<sheet::XSpreadsheet> xTable;
+ if (aTable>>=xTable)
+ {
+ uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
+ if (xCell.is())
+ {
+ uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
+ if (xCellProps.is())
+ {
+ uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK)));
+ aAny >>= nColor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return nColor;
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleCellBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleCellBase::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32
+ ScAccessibleCellBase::getAccessibleIndexInParent(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return mnIndex;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleCellBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR));
+
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleCellBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName( ScResId(STR_ACC_CELL_NAME) );
+ String sAddress;
+ // Document not needed, because only the cell address, but not the tablename is needed
+ // always us OOO notation
+ maCellAddress.Format( sAddress, SCA_VALID, NULL );
+ sName.SearchAndReplaceAscii("%1", sAddress);
+ /* #i65103# ZoomText merges cell address and contents, e.g. if value 2 is
+ contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2".
+ Simple solution: Append a space character to the cell address. */
+ sName.Append( ' ' );
+ return rtl::OUString(sName);
+}
+
+ //===== XAccessibleValue ================================================
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getCurrentValue( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Any aAny;
+ if (mpDoc)
+ aAny <<= mpDoc->GetValue(maCellAddress);
+
+ return aAny;
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ double fValue = 0;
+ sal_Bool bResult(sal_False);
+ if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell())
+ {
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ if (IsEditable(xParentStates))
+ {
+ ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell();
+ ScDocFunc aFunc(*pDocShell);
+ bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), TRUE );
+ }
+ }
+ return bResult;
+}
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getMaximumValue( )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny;
+ aAny <<= DBL_MAX;
+
+ return aAny;
+}
+
+uno::Any SAL_CALL
+ ScAccessibleCellBase::getMinimumValue( )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny;
+ aAny <<= -DBL_MAX;
+
+ return aAny;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase"));
+}
+
+ //===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleCellBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+sal_Bool ScAccessibleCellBase::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ sal_Bool bEditable(sal_False);
+ if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE))
+ bEditable = sal_True;
+ return bEditable;
+}
diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
new file mode 100644
index 000000000000..0f1fcfa337a5
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
@@ -0,0 +1,628 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleContextBase.hxx"
+#include "unoguard.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <toolkit/helper/convert.hxx>
+#include <svl/smplhint.hxx>
+#include <comphelper/sequence.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <vcl/unohelp.hxx>
+#include <tools/color.hxx>
+#include <comphelper/accessibleeventnotifier.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+DBG_NAME(ScAccessibleContextBase)
+
+ScAccessibleContextBase::ScAccessibleContextBase(
+ const uno::Reference<XAccessible>& rxParent,
+ const sal_Int16 aRole)
+ :
+ ScAccessibleContextBaseWeakImpl(m_aMutex),
+ mxParent(rxParent),
+ mnClientId(0),
+ maRole(aRole)
+{
+ DBG_CTOR(ScAccessibleContextBase, NULL);
+}
+
+
+ScAccessibleContextBase::~ScAccessibleContextBase(void)
+{
+ DBG_DTOR(ScAccessibleContextBase, NULL);
+
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleContextBase::Init()
+{
+ // hold reference to make sure that the destructor is not called
+ uno::Reference< XAccessibleContext > xOwnContext(this);
+
+ if (mxParent.is())
+ {
+ uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(this);
+ }
+ msName = createAccessibleName();
+ msDescription = createAccessibleDescription();
+}
+
+void SAL_CALL ScAccessibleContextBase::disposing()
+{
+ ScUnoGuard aGuard;
+// CommitDefunc(); not necessary and should not be send, because it cost a lot of time
+
+ // hold reference to make sure that the destructor is not called
+ uno::Reference< XAccessibleContext > xOwnContext(this);
+
+ if ( mnClientId )
+ {
+ sal_Int32 nTemClientId(mnClientId);
+ mnClientId = 0;
+ comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nTemClientId, *this );
+ }
+
+ if (mxParent.is())
+ {
+ uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->removeEventListener(this);
+ mxParent = NULL;
+ }
+
+ ScAccessibleContextBaseWeakImpl::disposing();
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleContextBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleContextBaseWeakImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBaseImplEvent::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleContextBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBaseWeakImpl::acquire();
+}
+
+void SAL_CALL ScAccessibleContextBase::release()
+ throw ()
+{
+ ScAccessibleContextBaseWeakImpl::release();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessibleContextBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ if (rRef.GetId() == SFX_HINT_DYING)
+ {
+ // it seems the Broadcaster is dying, since the view is dying
+ dispose();
+ }
+ }
+}
+
+//===== XAccessible =========================================================
+
+uno::Reference< XAccessibleContext> SAL_CALL
+ ScAccessibleContextBase::getAccessibleContext(void)
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//===== XAccessibleComponent ================================================
+
+sal_Bool SAL_CALL ScAccessibleContextBase::containsPoint(const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return Rectangle (Point(), GetBoundingBox().GetSize()).IsInside(VCLPoint(rPoint));
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleContextBase::getAccessibleAtPoint(
+ const awt::Point& /* rPoint */ )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return uno::Reference<XAccessible>();
+}
+
+awt::Rectangle SAL_CALL ScAccessibleContextBase::getBounds( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTRectangle(GetBoundingBox());
+}
+
+awt::Point SAL_CALL ScAccessibleContextBase::getLocation( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTPoint(GetBoundingBox().TopLeft());
+}
+
+awt::Point SAL_CALL ScAccessibleContextBase::getLocationOnScreen( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTPoint(GetBoundingBoxOnScreen().TopLeft());
+}
+
+awt::Size SAL_CALL ScAccessibleContextBase::getSize( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return AWTSize(GetBoundingBox().GetSize());
+}
+
+sal_Bool SAL_CALL ScAccessibleContextBase::isShowing( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Bool bShowing(sal_False);
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleComponent> xParentComponent (mxParent->getAccessibleContext(), uno::UNO_QUERY);
+ if (xParentComponent.is())
+ {
+ Rectangle aParentBounds(VCLRectangle(xParentComponent->getBounds()));
+ Rectangle aBounds(VCLRectangle(getBounds()));
+ bShowing = aBounds.IsOver(aParentBounds);
+ }
+ }
+ return bShowing;
+}
+
+sal_Bool SAL_CALL ScAccessibleContextBase::isVisible( )
+ throw (uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleContextBase::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+}
+
+sal_Int32 SAL_CALL ScAccessibleContextBase::getForeground( )
+ throw (uno::RuntimeException)
+{
+ return COL_BLACK;
+}
+
+sal_Int32 SAL_CALL ScAccessibleContextBase::getBackground( )
+ throw (uno::RuntimeException)
+{
+ return COL_WHITE;
+}
+
+//===== XAccessibleContext ==================================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleContextBase::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return 0;
+}
+
+uno::Reference<XAccessible> SAL_CALL
+ ScAccessibleContextBase::getAccessibleChild(sal_Int32 /* nIndex */)
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return uno::Reference<XAccessible>();
+}
+
+uno::Reference<XAccessible> SAL_CALL
+ ScAccessibleContextBase::getAccessibleParent(void)
+ throw (uno::RuntimeException)
+{
+ return mxParent;
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleContextBase::getAccessibleIndexInParent(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ // Use a simple but slow solution for now. Optimize later.
+ // Return -1 to indicate that this object's parent does not know about the
+ // object.
+ sal_Int32 nIndex(-1);
+
+ // Iterate over all the parent's children and search for this object.
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ {
+ sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
+ for (sal_Int32 i=0; i<nChildCount; ++i)
+ {
+ uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i));
+ if (xChild.is())
+ {
+ if (xChild.get() == this)
+ nIndex = i;
+ }
+ }
+ }
+ }
+
+ return nIndex;
+}
+
+sal_Int16 SAL_CALL
+ ScAccessibleContextBase::getAccessibleRole(void)
+ throw (uno::RuntimeException)
+{
+ return maRole;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::getAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!msDescription.getLength())
+ {
+ OUString sDescription(createAccessibleDescription());
+// DBG_ASSERT(sDescription.getLength(), "We should give always a descripition.");
+
+ if (msDescription != sDescription)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= msDescription;
+ aEvent.NewValue <<= sDescription;
+
+ msDescription = sDescription;
+
+ CommitChange(aEvent);
+ }
+ }
+ return msDescription;
+}
+
+OUString SAL_CALL
+ ScAccessibleContextBase::getAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!msName.getLength())
+ {
+ OUString sName(createAccessibleName());
+ DBG_ASSERT(sName.getLength(), "We should give always a name.");
+
+ if (msName != sName)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::NAME_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= msName;
+ aEvent.NewValue <<= sName;
+
+ msName = sName;
+
+ CommitChange(aEvent);
+ }
+ }
+ return msName;
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleContextBase::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ return new utl::AccessibleRelationSetHelper();
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleContextBase::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ return uno::Reference<XAccessibleStateSet>();
+}
+
+lang::Locale SAL_CALL
+ ScAccessibleContextBase::getLocale(void)
+ throw (IllegalAccessibleComponentStateException,
+ uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ return xParentContext->getLocale ();
+ }
+
+ // No locale and no parent. Therefore throw exception to indicate this
+ // cluelessness.
+ throw IllegalAccessibleComponentStateException ();
+}
+
+ //===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL
+ ScAccessibleContextBase::addEventListener(
+ const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!IsDefunc())
+ {
+ if (!mnClientId)
+ mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
+ comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
+ }
+ }
+}
+
+void SAL_CALL
+ ScAccessibleContextBase::removeEventListener(
+ const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+ ScUnoGuard aGuard;
+ if (!IsDefunc() && mnClientId)
+ {
+ sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
+ if ( !nListenerCount )
+ {
+ // no listeners anymore
+ // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
+ // and at least to us not firing any events anymore, in case somebody calls
+ // NotifyAccessibleEvent, again
+ comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
+ mnClientId = 0;
+ }
+ }
+ }
+}
+
+ //===== XAccessibleEventListener ========================================
+
+void SAL_CALL ScAccessibleContextBase::disposing(
+ const lang::EventObject& rSource )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ if (rSource.Source == mxParent)
+ dispose();
+}
+
+void SAL_CALL ScAccessibleContextBase::notifyEvent(
+ const AccessibleEventObject& /* aEvent */ )
+ throw (uno::RuntimeException)
+{
+}
+
+//===== XServiceInfo ========================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleContextBase"));
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleContextBase::supportsService(const OUString& sServiceName)
+ throw (uno::RuntimeException)
+{
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ sal_Int32 nLength(aSupportedServices.getLength());
+ const OUString* pServiceNames = aSupportedServices.getConstArray();
+ for (int i=0; i<nLength; ++i, ++pServiceNames)
+ if (sServiceName == *pServiceNames)
+ return sal_True;
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleContextBase::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence<OUString> aServiceNames(2);
+ OUString* pServiceNames = aServiceNames.getArray();
+ if (pServiceNames)
+ {
+ pServiceNames[0] = OUString(RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.Accessible"));
+ pServiceNames[1] = OUString(RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext"));
+ }
+
+ return aServiceNames;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleContextBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleContextBaseWeakImpl::getTypes(), ScAccessibleContextBaseImplEvent::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleContextBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ============================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleContextBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return rtl::OUString();
+}
+
+void ScAccessibleContextBase::CommitChange(const AccessibleEventObject& rEvent) const
+{
+ if (mnClientId)
+ comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
+}
+
+void ScAccessibleContextBase::ChangeName()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::NAME_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.OldValue <<= msName;
+
+ msName = rtl::OUString(); // reset the name so it will be hold again
+ getAccessibleName(); // create the new name
+
+ aEvent.NewValue <<= msName;
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleContextBase::CommitFocusGained() const
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.NewValue <<= AccessibleStateType::FOCUSED;
+
+ CommitChange(aEvent);
+
+ ::vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
+}
+
+void ScAccessibleContextBase::CommitFocusLost() const
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
+ aEvent.OldValue <<= AccessibleStateType::FOCUSED;
+
+ CommitChange(aEvent);
+
+ vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
+}
+
+Rectangle ScAccessibleContextBase::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return Rectangle();
+}
+
+Rectangle ScAccessibleContextBase::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented");
+ return Rectangle();
+}
+
+void ScAccessibleContextBase::IsObjectValid() const
+ throw (lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ throw lang::DisposedException();
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleCsvControl.cxx b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx
new file mode 100644
index 000000000000..e99bd1971e4c
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx
@@ -0,0 +1,1680 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// ============================================================================
+#include "AccessibleCsvControl.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <tools/debug.hxx>
+#include <rtl/uuid.h>
+#include <toolkit/helper/convert.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <comphelper/sequence.hxx>
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/langitem.hxx>
+#include "csvcontrol.hxx"
+#include "csvruler.hxx"
+#include "csvgrid.hxx"
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include <svtools/colorcfg.hxx>
+// ause
+#include "editutil.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::utl::AccessibleRelationSetHelper;
+using ::utl::AccessibleStateSetHelper;
+using ::accessibility::AccessibleStaticTextBase;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::lang::DisposedException;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::beans::PropertyValue;
+using namespace ::com::sun::star::accessibility;
+
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 nRulerRole = AccessibleRole::TEXT;
+const sal_uInt16 nGridRole = AccessibleRole::TABLE;
+const sal_uInt16 nCellRole = AccessibleRole::TEXT;
+
+#define CREATE_OUSTRING( name ) OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
+
+#define RULER_IMPL_NAME "ScAccessibleCsvRuler"
+#define GRID_IMPL_NAME "ScAccessibleCsvGrid"
+#define CELL_IMPL_NAME "ScAccessibleCsvCell"
+
+const sal_Unicode cRulerDot = '.';
+const sal_Unicode cRulerLine = '|';
+
+const sal_Int32 CSV_LINE_HEADER = CSV_POS_INVALID;
+const sal_uInt32 CSV_COLUMN_HEADER = CSV_COLUMN_INVALID;
+
+
+// CSV base control ===========================================================
+
+DBG_NAME( ScAccessibleCsvControl )
+
+ScAccessibleCsvControl::ScAccessibleCsvControl(
+ const Reference< XAccessible >& rxParent,
+ ScCsvControl& rControl,
+ sal_uInt16 nRole ) :
+ ScAccessibleContextBase( rxParent, nRole ),
+ mpControl( &rControl )
+{
+ DBG_CTOR( ScAccessibleCsvControl, NULL );
+}
+
+ScAccessibleCsvControl::~ScAccessibleCsvControl()
+{
+ DBG_DTOR( ScAccessibleCsvControl, NULL );
+ implDispose();
+}
+
+void SAL_CALL ScAccessibleCsvControl::disposing()
+{
+ ScUnoGuard aGuard;
+ mpControl = NULL;
+ ScAccessibleContextBase::disposing();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvControl::getAccessibleAtPoint( const AwtPoint& /* rPoint */ )
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvControl::isVisible() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().IsVisible();
+}
+
+void SAL_CALL ScAccessibleCsvControl::grabFocus() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ implGetControl().GrabFocus();
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvControl::SendFocusEvent( bool bFocused )
+{
+ if( bFocused )
+ CommitFocusGained();
+ else
+ CommitFocusLost();
+}
+
+void ScAccessibleCsvControl::SendCaretEvent()
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendCaretEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendVisibleEvent()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvControl::SendSelectionEvent()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvControl::SendTableUpdateEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */, bool /* bAllRows */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendTableUpdateEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendInsertColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendInsertColumnEvent - Illegal call" );
+}
+
+void ScAccessibleCsvControl::SendRemoveColumnEvent( sal_uInt32 /* nFirstColumn */, sal_uInt32 /* nLastColumn */ )
+{
+ DBG_ERRORFILE( "ScAccessibleCsvControl::SendRemoveColumnEvent - Illegal call" );
+}
+
+
+// helpers --------------------------------------------------------------------
+
+Rectangle ScAccessibleCsvControl::GetBoundingBoxOnScreen() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().GetWindowExtentsRelative( NULL );
+}
+
+Rectangle ScAccessibleCsvControl::GetBoundingBox() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetControl().GetWindowExtentsRelative( implGetControl().GetAccessibleParentWindow() );
+}
+
+void ScAccessibleCsvControl::getUuid( Sequence< sal_Int8 >& rSeq )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ if( !rSeq.hasElements() )
+ {
+ rSeq.realloc( 16 );
+ rtl_createUuid( reinterpret_cast< sal_uInt8* >( rSeq.getArray() ), NULL, sal_True );
+ }
+}
+
+void ScAccessibleCsvControl::ensureAlive() const throw( DisposedException )
+{
+ if( !implIsAlive() )
+ throw DisposedException();
+}
+
+ScCsvControl& ScAccessibleCsvControl::implGetControl() const
+{
+ DBG_ASSERT( mpControl, "ScAccessibleCsvControl::implGetControl - missing control" );
+ return *mpControl;
+}
+
+Reference< XAccessible > ScAccessibleCsvControl::implGetChildByRole(
+ const Reference< XAccessible >& rxParentObj, sal_uInt16 nRole ) throw( RuntimeException )
+{
+ Reference< XAccessible > xAccObj;
+ if( rxParentObj.is() )
+ {
+ Reference< XAccessibleContext > xParentCtxt = rxParentObj->getAccessibleContext();
+ if( xParentCtxt.is() )
+ {
+ sal_Int32 nCount = xParentCtxt->getAccessibleChildCount();
+ sal_Int32 nIndex = 0;
+ while( !xAccObj.is() && (nIndex < nCount) )
+ {
+ Reference< XAccessible > xCurrObj = xParentCtxt->getAccessibleChild( nIndex );
+ if( xCurrObj.is() )
+ {
+ Reference< XAccessibleContext > xCurrCtxt = xCurrObj->getAccessibleContext();
+ if( xCurrCtxt.is() && (xCurrCtxt->getAccessibleRole() == nRole) )
+ xAccObj = xCurrObj;
+ }
+ ++nIndex;
+ }
+ }
+ }
+ return xAccObj;
+}
+
+AccessibleStateSetHelper* ScAccessibleCsvControl::implCreateStateSet()
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = new AccessibleStateSetHelper();
+ if( implIsAlive() )
+ {
+ const ScCsvControl& rCtrl = implGetControl();
+ pStateSet->AddState( AccessibleStateType::OPAQUE );
+ if( rCtrl.IsEnabled() )
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ if( isShowing() )
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ if( isVisible() )
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ }
+ else
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ return pStateSet;
+}
+
+void ScAccessibleCsvControl::implDispose()
+{
+ if( implIsAlive() )
+ {
+ // prevent multiple call of dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+Point ScAccessibleCsvControl::implGetAbsPos( const Point& rPos ) const
+{
+ return rPos + implGetControl().GetWindowExtentsRelative( NULL ).TopLeft();
+}
+
+
+// Ruler ======================================================================
+
+/** Converts a ruler cursor position to API text index. */
+sal_Int32 lcl_GetApiPos( sal_Int32 nRulerPos )
+{
+ sal_Int32 nApiPos = nRulerPos;
+ sal_Int32 nStart = (nRulerPos - 1) / 10;
+ sal_Int32 nExp = 1;
+ while( nStart >= nExp )
+ {
+ nApiPos += nStart - nExp + 1;
+ nExp *= 10;
+ }
+ return ::std::max( nApiPos, static_cast<sal_Int32>(0) );
+}
+
+/** Converts an API text index to a ruler cursor position. */
+sal_Int32 lcl_GetRulerPos( sal_Int32 nApiPos )
+{
+ sal_Int32 nDiv = 10;
+ sal_Int32 nExp = 10;
+ sal_Int32 nRulerPos = 0;
+ sal_Int32 nApiBase = 0;
+ sal_Int32 nApiLimit = 10;
+ while( nApiPos >= nApiLimit )
+ {
+ ++nDiv;
+ nRulerPos = nExp;
+ nExp *= 10;
+ nApiBase = nApiLimit;
+ nApiLimit = lcl_GetApiPos( nExp );
+ }
+ sal_Int32 nRelPos = nApiPos - nApiBase;
+ return nRulerPos + nRelPos / nDiv * 10 + ::std::max( nRelPos % nDiv - nDiv + 10L, 0L );
+}
+
+/** Expands the sequence's size and returns the base index of the new inserted elements. */
+inline sal_Int32 lcl_ExpandSequence( Sequence< PropertyValue >& rSeq, sal_Int32 nExp )
+{
+ DBG_ASSERT( nExp > 0, "lcl_ExpandSequence - invalid value" );
+ rSeq.realloc( rSeq.getLength() + nExp );
+ return rSeq.getLength() - nExp;
+}
+
+/** Fills the property value rVal with the specified name and value from the item. */
+inline void lcl_FillProperty( PropertyValue& rVal, const OUString& rPropName, const SfxPoolItem& rItem, sal_uInt8 nMID )
+{
+ rVal.Name = rPropName;
+ rItem.QueryValue( rVal.Value, nMID );
+}
+
+/** Fills the sequence with all font attributes of rFont. */
+void lcl_FillFontAttributes( Sequence< PropertyValue >& rSeq, const Font& rFont )
+{
+ SvxFontItem aFontItem( rFont.GetFamily(), rFont.GetName(), rFont.GetStyleName(), rFont.GetPitch(), rFont.GetCharSet(), ATTR_FONT );
+ SvxFontHeightItem aHeightItem( rFont.GetSize().Height(), 100, ATTR_FONT_HEIGHT );
+ SvxLanguageItem aLangItem( rFont.GetLanguage(), ATTR_FONT_LANGUAGE );
+
+ sal_Int32 nIndex = lcl_ExpandSequence( rSeq, 7 );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontName" ), aFontItem, MID_FONT_FAMILY_NAME );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontFamily" ), aFontItem, MID_FONT_FAMILY );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontStyleName" ), aFontItem, MID_FONT_STYLE_NAME );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontCharSet" ), aFontItem, MID_FONT_PITCH );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharFontPitch" ), aFontItem, MID_FONT_CHAR_SET );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharHeight" ), aHeightItem, MID_FONTHEIGHT );
+ lcl_FillProperty( rSeq[ nIndex++ ], CREATE_OUSTRING( "CharLocale" ), aLangItem, MID_LANG_LOCALE );
+}
+
+
+
+// ----------------------------------------------------------------------------
+
+DBG_NAME( ScAccessibleCsvRuler )
+
+ScAccessibleCsvRuler::ScAccessibleCsvRuler( ScCsvRuler& rRuler ) :
+ ScAccessibleCsvControl( rRuler.GetAccessibleParentWindow()->GetAccessible(), rRuler, nRulerRole )
+{
+ DBG_CTOR( ScAccessibleCsvRuler, NULL );
+ constructStringBuffer();
+}
+
+ScAccessibleCsvRuler::~ScAccessibleCsvRuler()
+{
+ DBG_DTOR( ScAccessibleCsvRuler, NULL );
+ implDispose();
+}
+
+// XAccessibleComponent -----------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getForeground( )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRuler().GetSettings().GetStyleSettings().GetLabelTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getBackground( )
+ throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRuler().GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+}
+
+// XAccessibleContext ---------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getAccessibleChildCount() throw( RuntimeException )
+{
+ ensureAlive();
+ return 0;
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvRuler::getAccessibleChild( sal_Int32 /* nIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ throw IndexOutOfBoundsException();
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
+ Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nGridRole );
+ if( xAccObj.is() )
+ {
+ Sequence< Reference< XInterface > > aSeq( 1 );
+ aSeq[ 0 ] = xAccObj;
+ pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLER_FOR, aSeq ) );
+ }
+ return pRelationSet;
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvRuler::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
+ if( implGetRuler().HasFocus() )
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ }
+ return pStateSet;
+}
+
+
+// XAccessibleText ------------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCaretPosition() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return lcl_GetApiPos( implGetRuler().GetRulerCursorPos() );
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::setCaretPosition( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ ScCsvRuler& rRuler = implGetRuler();
+ sal_Int32 nOldCursor = rRuler.GetRulerCursorPos();
+ rRuler.Execute( CSVCMD_MOVERULERCURSOR, lcl_GetRulerPos( nIndex ) );
+ return rRuler.GetRulerCursorPos() != nOldCursor;
+}
+
+sal_Unicode SAL_CALL ScAccessibleCsvRuler::getCharacter( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ return maBuffer.charAt( nIndex );
+}
+
+Sequence< PropertyValue > SAL_CALL ScAccessibleCsvRuler::getCharacterAttributes( sal_Int32 nIndex,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& /* aRequestedAttributes */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+ Sequence< PropertyValue > aSeq;
+ lcl_FillFontAttributes( aSeq, implGetRuler().GetFont() );
+//! TODO split attribute: waiting for #102221#
+// if( implHasSplit( nIndex ) )
+// {
+// sal_Int32 nIndex = lcl_ExpandSequence( aSeq, 1 );
+// aSeq[ nIndex ].Name = CREATE_OUSTRING( "..." );
+// aSeq[ nIndex ].Value <<= ...;
+// }
+ return aSeq;
+}
+
+ScAccessibleCsvRuler::AwtRectangle SAL_CALL ScAccessibleCsvRuler::getCharacterBounds( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+ ScCsvRuler& rRuler = implGetRuler();
+ Point aPos( rRuler.GetX( lcl_GetRulerPos( nIndex ) ) - rRuler.GetCharWidth() / 2, 0 );
+ AwtRectangle aRect( aPos.X(), aPos.Y(), rRuler.GetCharWidth(), rRuler.GetSizePixel().Height() );
+ // #107054# do not return rectangle out of window
+ sal_Int32 nWidth = rRuler.GetOutputSizePixel().Width();
+ if( aRect.X >= nWidth )
+ throw IndexOutOfBoundsException();
+ if( aRect.X + aRect.Width > nWidth )
+ aRect.Width = nWidth - aRect.X;
+ return aRect;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getCharacterCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetTextLength();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getIndexAtPoint( const AwtPoint& rPoint )
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ScCsvRuler& rRuler = implGetRuler();
+ // #107054# use object's coordinate system, convert to API position
+ return lcl_GetApiPos( ::std::min( ::std::max( rRuler.GetPosFromX( rPoint.X ), static_cast<sal_Int32>(0) ), rRuler.GetPosCount() ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getSelectedText() throw( RuntimeException )
+{
+ ensureAlive();
+ return OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionStart() throw( RuntimeException )
+{
+ ensureAlive();
+ return -1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvRuler::getSelectionEnd() throw( RuntimeException )
+{
+ ensureAlive();
+ return -1;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::setSelection( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getText() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return OUString( maBuffer.getStr(), implGetTextLength() );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidRange( nStartIndex, nEndIndex );
+ return OUString( maBuffer.getStr() + nStartIndex, nEndIndex - nStartIndex );
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ if( (nIndex == implGetTextLength()) && (nTextType != AccessibleTextType::LINE) )
+ return aResult;
+
+ ensureValidIndex( nIndex );
+
+ OUStringBuffer aResultText; // will be assigned to aResult.SegmentText below
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ {
+ aResult.SegmentStart = nIndex;
+ aResultText.append( maBuffer.charAt( nIndex ) );
+ }
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ aResult.SegmentStart = nIndex;
+ if( nRulerPos % 10 )
+ aResultText.append( maBuffer.charAt( nIndex ) );
+ else
+ aResultText.append( nRulerPos ); // string representation of sal_Int32!!!
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ aResult.SegmentStart = 0;
+ aResultText.append( maBuffer.getStr(), implGetTextLength() );
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
+ sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
+ aResult.SegmentStart = nFirstIndex;
+ aResultText.append( maBuffer.getStr() + nFirstIndex, nLastIndex - nFirstIndex + 1 );
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+
+ aResult.SegmentText = aResultText.makeStringAndClear();
+ aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
+ return aResult;
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ if( nIndex > 0 )
+ aResult = getTextAtIndex( nIndex - 1, nTextType );
+ // else empty
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ if( nRulerPos > 0 )
+ aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos - 1 ), nTextType );
+ // else empty
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ // empty
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nFirstIndex = implGetFirstEqualFormatted( nIndex );
+ if( nFirstIndex > 0 )
+ aResult = getTextAtIndex( nFirstIndex - 1, nTextType );
+ // else empty
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+ return aResult;
+}
+
+TextSegment SAL_CALL ScAccessibleCsvRuler::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
+ throw( IndexOutOfBoundsException, IllegalArgumentException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndexWithEnd( nIndex );
+
+ TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nIndex );
+ sal_Int32 nLastValid = implGetTextLength();
+
+ switch( nTextType )
+ {
+ // single character
+ case AccessibleTextType::CHARACTER:
+ if( nIndex < nLastValid )
+ aResult = getTextAtIndex( nIndex + 1, nTextType );
+ // else empty
+ break;
+
+ // entire number or single dot/line
+ case AccessibleTextType::WORD:
+ case AccessibleTextType::GLYPH:
+ if( nRulerPos < implGetRuler().GetPosCount() )
+ aResult = getTextAtIndex( lcl_GetApiPos( nRulerPos + 1 ), nTextType );
+ // else empty
+ break;
+
+ // entire text
+ case AccessibleTextType::SENTENCE:
+ case AccessibleTextType::PARAGRAPH:
+ case AccessibleTextType::LINE:
+ // empty
+ break;
+
+ // equal-formatted text
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ sal_Int32 nLastIndex = implGetLastEqualFormatted( nIndex );
+ if( nLastIndex < nLastValid )
+ aResult = getTextAtIndex( nLastIndex + 1, nTextType );
+ // else empty
+ }
+ break;
+
+ default:
+ throw RuntimeException();
+ }
+ return aResult;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvRuler::copyText( sal_Int32 /* nStartIndex */, sal_Int32 /* nEndIndex */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+
+// XInterface -----------------------------------------------------------------
+
+Any SAL_CALL ScAccessibleCsvRuler::queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( RuntimeException )
+{
+ Any aAny( ScAccessibleCsvRulerImpl::queryInterface( rType ) );
+ return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
+}
+
+void SAL_CALL ScAccessibleCsvRuler::acquire() throw ()
+{
+ ScAccessibleCsvControl::acquire();
+}
+
+void SAL_CALL ScAccessibleCsvRuler::release() throw ()
+{
+ ScAccessibleCsvControl::release();
+}
+
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvRuler::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( RULER_IMPL_NAME );
+}
+
+
+// XTypeProvider --------------------------------------------------------------
+
+Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvRuler::getTypes() throw( RuntimeException )
+{
+ Sequence< ::com::sun::star::uno::Type > aSeq( 1 );
+ aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleText >* >( NULL ) );
+ return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
+}
+
+Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvRuler::getImplementationId() throw( RuntimeException )
+{
+ static Sequence< sal_Int8 > aSeq;
+ getUuid( aSeq );
+ return aSeq;
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvRuler::SendCaretEvent()
+{
+ sal_Int32 nPos = implGetRuler().GetRulerCursorPos();
+ if( nPos != CSV_POS_INVALID )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CARET_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= nPos;
+ CommitChange( aEvent );
+ }
+}
+
+
+// helpers --------------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleName() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVRULER_NAME ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvRuler::createAccessibleDescription() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVRULER_DESCR ) );
+}
+
+void ScAccessibleCsvRuler::ensureValidIndex( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex >= implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvRuler::ensureValidIndexWithEnd( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex > implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvRuler::ensureValidRange( sal_Int32& rnStartIndex, sal_Int32& rnEndIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( rnStartIndex > rnEndIndex )
+ ::std::swap( rnStartIndex, rnEndIndex );
+ if( (rnStartIndex < 0) || (rnEndIndex > implGetTextLength()) )
+ throw IndexOutOfBoundsException();
+}
+
+ScCsvRuler& ScAccessibleCsvRuler::implGetRuler() const
+{
+ return static_cast< ScCsvRuler& >( implGetControl() );
+}
+
+void ScAccessibleCsvRuler::constructStringBuffer() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ // extend existing string buffer to new ruler size
+ sal_Int32 nRulerCount = implGetRuler().GetPosCount();
+ sal_Int32 nRulerPos = lcl_GetRulerPos( maBuffer.getLength() );
+ for( ; nRulerPos <= nRulerCount; ++nRulerPos ) // include last position
+ {
+ switch( nRulerPos % 10 )
+ {
+ case 0: maBuffer.append( nRulerPos ); break;
+ case 5: maBuffer.append( cRulerLine ); break;
+ default: maBuffer.append( cRulerDot );
+ }
+ }
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetTextLength() const
+{
+ return lcl_GetApiPos( implGetRuler().GetPosCount() + 1 );
+}
+
+bool ScAccessibleCsvRuler::implHasSplit( sal_Int32 nApiPos )
+{
+ sal_Int32 nRulerPos = lcl_GetRulerPos( nApiPos );
+ return implGetRuler().HasSplit( nRulerPos ) && (nApiPos == lcl_GetApiPos( nRulerPos ));
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetFirstEqualFormatted( sal_Int32 nApiPos )
+{
+ bool bSplit = implHasSplit( nApiPos );
+ while( (nApiPos > 0) && (implHasSplit( nApiPos - 1 ) == bSplit) )
+ --nApiPos;
+ return nApiPos;
+}
+
+sal_Int32 ScAccessibleCsvRuler::implGetLastEqualFormatted( sal_Int32 nApiPos )
+{
+ bool bSplit = implHasSplit( nApiPos );
+ sal_Int32 nLength = implGetTextLength();
+ while( (nApiPos < nLength - 1) && (implHasSplit( nApiPos + 1 ) == bSplit) )
+ ++nApiPos;
+ return nApiPos;
+}
+
+
+// Grid =======================================================================
+
+/** Converts a grid columnm index to an API column index. */
+inline sal_Int32 lcl_GetApiColumn( sal_uInt32 nGridColumn )
+{
+ return (nGridColumn != CSV_COLUMN_HEADER) ? static_cast< sal_Int32 >( nGridColumn + 1 ) : 0;
+}
+
+/** Converts an API columnm index to a ScCsvGrid column index. */
+inline sal_uInt32 lcl_GetGridColumn( sal_Int32 nApiColumn )
+{
+ return (nApiColumn > 0) ? static_cast< sal_uInt32 >( nApiColumn - 1 ) : CSV_COLUMN_HEADER;
+}
+
+
+// ----------------------------------------------------------------------------
+
+DBG_NAME( ScAccessibleCsvGrid )
+
+ScAccessibleCsvGrid::ScAccessibleCsvGrid( ScCsvGrid& rGrid ) :
+ ScAccessibleCsvControl( rGrid.GetAccessibleParentWindow()->GetAccessible(), rGrid, nGridRole )
+{
+ DBG_CTOR( ScAccessibleCsvGrid, NULL );
+}
+
+ScAccessibleCsvGrid::~ScAccessibleCsvGrid()
+{
+ DBG_DTOR( ScAccessibleCsvGrid, NULL );
+ implDispose();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint )
+ throw( RuntimeException )
+{
+ Reference< XAccessible > xRet;
+ if( containsPoint( rPoint ) )
+ {
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ const ScCsvGrid& rGrid = implGetGrid();
+ // #102679#; use <= instead of <, because the offset is the size and not the point
+ sal_Int32 nColumn = ((rGrid.GetFirstX() <= rPoint.X) && (rPoint.X <= rGrid.GetLastX())) ?
+ lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0;
+ sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ?
+ (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0;
+ xRet = implCreateCellObj( nRow, nColumn );
+ }
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getForeground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getBackground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+// XAccessibleContext ---------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetCellCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nIndex );
+ return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) );
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ AccessibleRelationSetHelper* pRelationSet = new AccessibleRelationSetHelper();
+ Reference< XAccessible > xAccObj = implGetChildByRole( getAccessibleParent(), nRulerRole );
+ if( xAccObj.is() )
+ {
+ Sequence< Reference< XInterface > > aSeq( 1 );
+ aSeq[ 0 ] = xAccObj;
+ pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::CONTROLLED_BY, aSeq ) );
+ }
+ return pRelationSet;
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ pStateSet->AddState( AccessibleStateType::MULTI_SELECTABLE );
+ pStateSet->AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ if( implGetGrid().HasFocus() )
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ }
+ else
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ return pStateSet;
+}
+
+
+// XAccessibleTable -----------------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRowCount();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetColumnCount();
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleRowDescription( sal_Int32 nRow )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, 0 );
+ return implGetCellText( nRow, 0 );
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( 0, nColumn );
+ return implGetCellText( 0, nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return 1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return 1;
+}
+
+Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleRowHeaders()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Reference< XAccessibleTable > SAL_CALL ScAccessibleCsvGrid::getAccessibleColumnHeaders()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleRows()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return Sequence< sal_Int32 >();
+}
+
+Sequence< sal_Int32 > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleColumns()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+
+ ScCsvGrid& rGrid = implGetGrid();
+ Sequence< sal_Int32 > aSeq( implGetColumnCount() );
+
+ sal_Int32 nSeqIx = 0;
+ sal_uInt32 nColIx = rGrid.GetFirstSelected();
+ for( ; nColIx != CSV_COLUMN_INVALID; ++nSeqIx, nColIx = rGrid.GetNextSelected( nColIx ) )
+ aSeq[ nSeqIx ] = lcl_GetApiColumn( nColIx );
+
+ aSeq.realloc( nSeqIx );
+ return aSeq;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleRowSelected( sal_Int32 /* nRow */ )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ensureAlive();
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nColumn );
+ return implIsColumnSelected( nColumn );
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return implCreateCellObj( nRow, nColumn );
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleSummary()
+ throw( RuntimeException )
+{
+ ensureAlive();
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ return isAccessibleColumnSelected( nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidPosition( nRow, nColumn );
+ return implGetIndex( nRow, nColumn );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleRow( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ return implGetRow( nChildIndex );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ return implGetColumn( nChildIndex );
+}
+
+
+// XAccessibleSelection -------------------------------------------------------
+
+void SAL_CALL ScAccessibleCsvGrid::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ sal_Int32 nColumn = implGetColumn( nChildIndex );
+ if( nChildIndex == 0 )
+ implGetGrid().SelectAll();
+ else
+ implSelectColumn( nColumn, true );
+}
+
+sal_Bool SAL_CALL ScAccessibleCsvGrid::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ensureValidIndex( nChildIndex );
+ sal_Int32 nColumn = implGetColumn( nChildIndex );
+ return implIsColumnSelected( nColumn );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::clearAccessibleSelection() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ implGetGrid().SelectAll( false );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::selectAllAccessibleChildren() throw( RuntimeException )
+{
+ selectAccessibleChild( 0 );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChildCount() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetRowCount() * implGetSelColumnCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ sal_Int32 nColumns = implGetSelColumnCount();
+ if( nColumns == 0 )
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nRow = nSelectedChildIndex / nColumns;
+ sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
+ return getAccessibleCellAt( nRow, nColumn );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ sal_Int32 nColumns = implGetSelColumnCount();
+ if( nColumns == 0 )
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nColumn = implGetSelColumn( nSelectedChildIndex % nColumns );
+ ensureValidPosition( nSelectedChildIndex / nColumns, nColumn );
+ if( nColumn > 0 )
+ implSelectColumn( nColumn, false );
+}
+
+
+// XInterface -----------------------------------------------------------------
+
+Any SAL_CALL ScAccessibleCsvGrid::queryInterface( const ::com::sun::star::uno::Type& rType )
+ throw( RuntimeException )
+{
+ Any aAny( ScAccessibleCsvGridImpl::queryInterface( rType ) );
+ return aAny.hasValue() ? aAny : ScAccessibleCsvControl::queryInterface( rType );
+}
+
+void SAL_CALL ScAccessibleCsvGrid::acquire() throw ()
+{
+ ScAccessibleCsvControl::acquire();
+}
+
+void SAL_CALL ScAccessibleCsvGrid::release() throw ()
+{
+ ScAccessibleCsvControl::release();
+}
+
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvGrid::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( GRID_IMPL_NAME );
+}
+
+
+// XTypeProvider --------------------------------------------------------------
+
+Sequence< ::com::sun::star::uno::Type > SAL_CALL ScAccessibleCsvGrid::getTypes() throw( RuntimeException )
+{
+ Sequence< ::com::sun::star::uno::Type > aSeq( 2 );
+ aSeq[ 0 ] = getCppuType( static_cast< const Reference< XAccessibleTable >* >( NULL ) );
+ aSeq[ 1 ] = getCppuType( static_cast< const Reference< XAccessibleSelection >* >( NULL ) );
+ return ::comphelper::concatSequences( ScAccessibleCsvControl::getTypes(), aSeq );
+}
+
+Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( RuntimeException )
+{
+ static Sequence< sal_Int8 > aSeq;
+ getUuid( aSeq );
+ return aSeq;
+}
+
+
+// events ---------------------------------------------------------------------
+
+void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused )
+{
+ ScAccessibleCsvControl::SendFocusEvent( bFocused );
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ (bFocused ? aEvent.NewValue : aEvent.OldValue) <<=
+ getAccessibleCellAt( 0, lcl_GetApiColumn( implGetGrid().GetFocusColumn() ) );
+ CommitChange( aEvent );
+}
+
+void ScAccessibleCsvGrid::SendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::UPDATE, 0, bAllRows ? implGetRowCount() - 1 : 0,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+void ScAccessibleCsvGrid::SendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::INSERT, 0, implGetRowCount() - 1,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+void ScAccessibleCsvGrid::SendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
+{
+ if( nFirstColumn <= nLastColumn )
+ {
+ AccessibleTableModelChange aModelChange(
+ AccessibleTableModelChangeType::DELETE, 0, implGetRowCount() - 1,
+ lcl_GetApiColumn( nFirstColumn ), lcl_GetApiColumn( nLastColumn ) );
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = Reference< XAccessible >( this );
+ aEvent.NewValue <<= aModelChange;
+ CommitChange( aEvent );
+ }
+}
+
+
+// helpers --------------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleName() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVGRID_NAME ) );
+}
+
+OUString SAL_CALL ScAccessibleCsvGrid::createAccessibleDescription() throw( RuntimeException )
+{
+ return String( ScResId( STR_ACC_CSVGRID_DESCR ) );
+}
+
+void ScAccessibleCsvGrid::ensureValidIndex( sal_Int32 nIndex ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nIndex < 0) || (nIndex >= implGetCellCount()) )
+ throw IndexOutOfBoundsException();
+}
+
+void ScAccessibleCsvGrid::ensureValidPosition( sal_Int32 nRow, sal_Int32 nColumn ) const
+ throw( IndexOutOfBoundsException )
+{
+ if( (nRow < 0) || (nRow >= implGetRowCount()) || (nColumn < 0) || (nColumn >= implGetColumnCount()) )
+ throw IndexOutOfBoundsException();
+}
+
+ScCsvGrid& ScAccessibleCsvGrid::implGetGrid() const
+{
+ return static_cast< ScCsvGrid& >( implGetControl() );
+}
+
+bool ScAccessibleCsvGrid::implIsColumnSelected( sal_Int32 nColumn ) const
+{
+ return (nColumn > 0) && implGetGrid().IsSelected( lcl_GetGridColumn( nColumn ) );
+}
+
+void ScAccessibleCsvGrid::implSelectColumn( sal_Int32 nColumn, bool bSelect )
+{
+ if( nColumn > 0 )
+ implGetGrid().Select( lcl_GetGridColumn( nColumn ), bSelect );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetRowCount() const
+{
+ return static_cast< sal_Int32 >( implGetGrid().GetLastVisLine() - implGetGrid().GetFirstVisLine() + 2 );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetColumnCount() const
+{
+ return static_cast< sal_Int32 >( implGetGrid().GetColumnCount() + 1 );
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetSelColumnCount() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nCount = 0;
+ for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
+ ++nCount;
+ return nCount;
+}
+
+sal_Int32 ScAccessibleCsvGrid::implGetSelColumn( sal_Int32 nSelColumn ) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nColumn = 0;
+ for( sal_uInt32 nColIx = rGrid.GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = rGrid.GetNextSelected( nColIx ) )
+ {
+ if( nColumn == nSelColumn )
+ return static_cast< sal_Int32 >( nColIx + 1 );
+ ++nColumn;
+ }
+ return 0;
+}
+
+String ScAccessibleCsvGrid::implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ sal_Int32 nLine = nRow + rGrid.GetFirstVisLine() - 1;
+ String aCellStr;
+ if( (nColumn > 0) && (nRow > 0) )
+ aCellStr = rGrid.GetCellText( lcl_GetGridColumn( nColumn ), nLine );
+ else if( nRow > 0 )
+ aCellStr = String::CreateFromInt32( nLine + 1L );
+ else if( nColumn > 0 )
+ aCellStr = rGrid.GetColumnTypeName( lcl_GetGridColumn( nColumn ) );
+ return aCellStr;
+}
+
+
+ScAccessibleCsvControl* ScAccessibleCsvGrid::implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const
+{
+ return new ScAccessibleCsvCell( implGetGrid(), implGetCellText( nRow, nColumn ), nRow, nColumn );
+}
+
+
+// ============================================================================
+
+DBG_NAME( ScAccessibleCsvCell )
+
+ScAccessibleCsvCell::ScAccessibleCsvCell(
+ ScCsvGrid& rGrid,
+ const String& rCellText,
+ sal_Int32 nRow, sal_Int32 nColumn ) :
+ ScAccessibleCsvControl( rGrid.GetAccessible(), rGrid, nCellRole ),
+ AccessibleStaticTextBase( SvxEditSourcePtr( NULL ) ),
+ maCellText( rCellText ),
+ mnLine( nRow ? (nRow + rGrid.GetFirstVisLine() - 1) : CSV_LINE_HEADER ),
+ mnColumn( lcl_GetGridColumn( nColumn ) ),
+ mnIndex( nRow * (rGrid.GetColumnCount() + 1) + nColumn )
+{
+ DBG_CTOR( ScAccessibleCsvCell, NULL );
+ SetEditSource( implCreateEditSource() );
+}
+
+ScAccessibleCsvCell::~ScAccessibleCsvCell()
+{
+ DBG_DTOR( ScAccessibleCsvCell, NULL );
+}
+
+void SAL_CALL ScAccessibleCsvCell::disposing()
+{
+ ScUnoGuard aGuard;
+ SetEditSource( SvxEditSourcePtr( NULL ) );
+ ScAccessibleCsvControl::disposing();
+}
+
+
+// XAccessibleComponent -------------------------------------------------------
+
+void SAL_CALL ScAccessibleCsvCell::grabFocus() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ ScCsvGrid& rGrid = implGetGrid();
+ rGrid.Execute( CSVCMD_MOVEGRIDCURSOR, rGrid.GetColumnPos( mnColumn ) );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getForeground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetGrid().GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getBackground( )
+throw (RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+// XAccessibleContext -----------------------------------------------------
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleChildCount() throw( RuntimeException )
+{
+ return AccessibleStaticTextBase::getAccessibleChildCount();
+}
+
+Reference< XAccessible > SAL_CALL ScAccessibleCsvCell::getAccessibleChild( sal_Int32 nIndex )
+ throw( IndexOutOfBoundsException, RuntimeException )
+{
+ return AccessibleStaticTextBase::getAccessibleChild( nIndex );
+}
+
+sal_Int32 SAL_CALL ScAccessibleCsvCell::getAccessibleIndexInParent() throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return mnIndex;
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvCell::getAccessibleRelationSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return new AccessibleRelationSetHelper();
+}
+
+Reference< XAccessibleStateSet > SAL_CALL ScAccessibleCsvCell::getAccessibleStateSet()
+ throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ AccessibleStateSetHelper* pStateSet = implCreateStateSet();
+ if( implIsAlive() )
+ {
+ const ScCsvGrid& rGrid = implGetGrid();
+ pStateSet->AddState( AccessibleStateType::SINGLE_LINE );
+ if( mnColumn != CSV_COLUMN_HEADER )
+ pStateSet->AddState( AccessibleStateType::SELECTABLE );
+ if( rGrid.HasFocus() && (rGrid.GetFocusColumn() == mnColumn) && (mnLine == CSV_LINE_HEADER) )
+ pStateSet->AddState( AccessibleStateType::ACTIVE );
+ if( rGrid.IsSelected( mnColumn ) )
+ pStateSet->AddState( AccessibleStateType::SELECTED );
+ }
+ return pStateSet;
+}
+
+// XInterface -----------------------------------------------------------------
+
+IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
+
+// XTypeProvider --------------------------------------------------------------
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCsvCell, ScAccessibleCsvControl, AccessibleStaticTextBase )
+
+// XServiceInfo ---------------------------------------------------------------
+
+OUString SAL_CALL ScAccessibleCsvCell::getImplementationName() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( CELL_IMPL_NAME );
+}
+
+// helpers --------------------------------------------------------------------
+
+Rectangle ScAccessibleCsvCell::GetBoundingBoxOnScreen() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ Rectangle aRect( implGetBoundingBox() );
+ aRect.SetPos( implGetAbsPos( aRect.TopLeft() ) );
+ return aRect;
+}
+
+Rectangle ScAccessibleCsvCell::GetBoundingBox() const throw( RuntimeException )
+{
+ ScUnoGuard aGuard;
+ ensureAlive();
+ return implGetBoundingBox();
+}
+
+OUString SAL_CALL ScAccessibleCsvCell::createAccessibleName() throw( RuntimeException )
+{
+ return maCellText;
+}
+
+OUString SAL_CALL ScAccessibleCsvCell::createAccessibleDescription() throw( RuntimeException )
+{
+ return OUString();
+}
+
+ScCsvGrid& ScAccessibleCsvCell::implGetGrid() const
+{
+ return static_cast< ScCsvGrid& >( implGetControl() );
+}
+
+Point ScAccessibleCsvCell::implGetRealPos() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return Point(
+ (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrX() : rGrid.GetColumnX( mnColumn ),
+ (mnLine == CSV_LINE_HEADER) ? 0 : rGrid.GetY( mnLine ) );
+}
+
+sal_uInt32 ScAccessibleCsvCell::implCalcPixelWidth(sal_uInt32 nChars) const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return rGrid.GetCharWidth() * nChars;
+}
+
+Size ScAccessibleCsvCell::implGetRealSize() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ return Size(
+ (mnColumn == CSV_COLUMN_HEADER) ? rGrid.GetHdrWidth() : implCalcPixelWidth( rGrid.GetColumnWidth( mnColumn ) ),
+ (mnLine == CSV_LINE_HEADER) ? rGrid.GetHdrHeight() : rGrid.GetLineHeight() );
+}
+
+Rectangle ScAccessibleCsvCell::implGetBoundingBox() const
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ Rectangle aClipRect( Point( 0, 0 ), rGrid.GetSizePixel() );
+ if( mnColumn != CSV_COLUMN_HEADER )
+ {
+ aClipRect.Left() = rGrid.GetFirstX();
+ aClipRect.Right() = rGrid.GetLastX();
+ }
+ if( mnLine != CSV_LINE_HEADER )
+ aClipRect.Top() = rGrid.GetHdrHeight();
+
+ Rectangle aRect( implGetRealPos(), implGetRealSize() );
+ aRect.Intersection( aClipRect );
+ if( (aRect.GetWidth() <= 0) || (aRect.GetHeight() <= 0) )
+ aRect.SetSize( Size( -1, -1 ) );
+ return aRect;
+}
+
+::std::auto_ptr< SvxEditSource > ScAccessibleCsvCell::implCreateEditSource()
+{
+ ScCsvGrid& rGrid = implGetGrid();
+ Rectangle aBoundRect( implGetBoundingBox() );
+ aBoundRect -= implGetRealPos();
+
+ ::std::auto_ptr< ScAccessibleTextData > pCsvTextData( new ScAccessibleCsvTextData(
+ &rGrid, rGrid.GetEditEngine(), maCellText, aBoundRect, implGetRealSize() ) );
+
+ ::std::auto_ptr< SvxEditSource > pEditSource( new ScAccessibilityEditSource( pCsvTextData ) );
+ return pEditSource;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx
new file mode 100644
index 000000000000..1848c7bfefc0
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx
@@ -0,0 +1,739 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "AccessibleDataPilotControl.hxx"
+#include "unoguard.hxx"
+#include "fieldwnd.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <rtl/uuid.h>
+#include <tools/gen.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+class ScAccessibleDataPilotButton
+ : public ScAccessibleContextBase
+{
+public:
+ //===== internal ========================================================
+ ScAccessibleDataPilotButton(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow,
+ sal_Int32 nIndex);
+
+ virtual void Init();
+
+ using ScAccessibleContextBase::disposing;
+ virtual void SAL_CALL disposing();
+
+ void SetIndex(sal_Int32 nIndex) { mnIndex = nIndex; }
+ void NameChanged();
+ void SetFocused();
+ void ResetFocused();
+protected:
+ virtual ~ScAccessibleDataPilotButton(void);
+public:
+ ///===== XAccessibleComponent ============================================
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVisible( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the specified child or NULL if index is invalid.
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ /// Return this objects index among the parents children.
+ virtual sal_Int32 SAL_CALL
+ getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the set of current states.
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XServiceInfo ====================================================
+
+ /** Returns an identifier for the implementation of this object.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== XTypeProvider ===================================================
+
+ /** Returns a implementation id.
+ */
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ /// Return this object's description.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current name.
+ virtual ::rtl::OUString SAL_CALL
+ createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the desktop.
+ virtual Rectangle GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// Return the object's current bounding box relative to the parent object.
+ virtual Rectangle GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ScDPFieldWindow* mpDPFieldWindow;
+ sal_Int32 mnIndex;
+};
+
+ //===== internal ========================================================
+ScAccessibleDataPilotControl::ScAccessibleDataPilotControl(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::GROUP_BOX),
+ mpDPFieldWindow(pDPFieldWindow)
+{
+ if (mpDPFieldWindow)
+ maChildren.resize(mpDPFieldWindow->GetFieldCount());
+}
+
+ScAccessibleDataPilotControl::~ScAccessibleDataPilotControl(void)
+{
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleDataPilotControl::Init()
+{
+}
+
+void SAL_CALL ScAccessibleDataPilotControl::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDPFieldWindow = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleDataPilotControl::AddField(sal_Int32 nNewIndex)
+{
+ sal_Bool bAdded(sal_False);
+ if (static_cast<sal_uInt32>(nNewIndex) == maChildren.size())
+ {
+ maChildren.push_back(AccessibleWeak());
+ bAdded = sal_True;
+ }
+ else if (static_cast<sal_uInt32>(nNewIndex) < maChildren.size())
+ {
+ ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nNewIndex;
+ maChildren.insert(aItr, AccessibleWeak());
+
+ ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
+ aItr = maChildren.begin() + nNewIndex + 1;
+ uno::Reference< XAccessible > xTempAcc;
+ sal_Int32 nIndex = nNewIndex + 1;
+ while (aItr != aEndItr)
+ {
+ xTempAcc = aItr->xWeakAcc;
+ if (xTempAcc.is() && aItr->pAcc)
+ aItr->pAcc->SetIndex(nIndex);
+ ++nIndex;
+ ++aItr;
+ }
+ bAdded = sal_True;
+ }
+ else
+ {
+ DBG_ERRORFILE("did not recognize a child count change");
+ }
+
+ if (bAdded)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= getAccessibleChild(nNewIndex);
+
+ CommitChange(aEvent); // new child - event
+ }
+}
+
+void ScAccessibleDataPilotControl::RemoveField(sal_Int32 nOldIndex)
+{
+ sal_Bool bRemoved(sal_False);
+ uno::Reference< XAccessible > xTempAcc;
+ ScAccessibleDataPilotButton* pField = NULL;
+ if (static_cast<sal_uInt32>(nOldIndex) < maChildren.size())
+ {
+ xTempAcc = getAccessibleChild(nOldIndex);
+ pField = maChildren[nOldIndex].pAcc;
+
+ ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nOldIndex;
+ aItr = maChildren.erase(aItr);
+
+ ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
+ uno::Reference< XAccessible > xItrAcc;
+ while (aItr != aEndItr)
+ {
+ xItrAcc = aItr->xWeakAcc;
+ if (xItrAcc.is() && aItr->pAcc)
+ aItr->pAcc->SetIndex(nOldIndex);
+ ++nOldIndex;
+ ++aItr;
+ }
+ bRemoved = sal_True;
+ }
+ else
+ {
+ DBG_ERRORFILE("did not recognize a child count change");
+ }
+
+ if (bRemoved)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= xTempAcc;
+
+ CommitChange(aEvent); // gone child - event
+
+ if (pField)
+ pField->dispose();
+ }
+}
+
+void ScAccessibleDataPilotControl::FieldFocusChange(sal_Int32 nOldIndex, sal_Int32 nNewIndex)
+{
+ DBG_ASSERT(static_cast<sal_uInt32>(nOldIndex) < maChildren.size() &&
+ static_cast<sal_uInt32>(nNewIndex) < maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nOldIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nOldIndex].pAcc)
+ maChildren[nOldIndex].pAcc->ResetFocused();
+
+ xTempAcc = maChildren[nNewIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nNewIndex].pAcc)
+ maChildren[nNewIndex].pAcc->SetFocused();
+}
+
+void ScAccessibleDataPilotControl::FieldNameChange(sal_Int32 nIndex)
+{
+ DBG_ASSERT(static_cast<sal_uInt32>(nIndex) < maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->ChangeName();
+}
+
+void ScAccessibleDataPilotControl::GotFocus()
+{
+ if (mpDPFieldWindow)
+ {
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ sal_Int32 nIndex(mpDPFieldWindow->GetSelectedField());
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->SetFocused();
+ }
+}
+
+void ScAccessibleDataPilotControl::LostFocus()
+{
+ if (mpDPFieldWindow)
+ {
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ sal_Int32 nIndex(mpDPFieldWindow->GetSelectedField());
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (xTempAcc.is() && maChildren[nIndex].pAcc)
+ maChildren[nIndex].pAcc->ResetFocused();
+ }
+}
+
+ ///===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotControl::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAcc;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ {
+ Point aAbsPoint(VCLPoint(rPoint));
+ Point aControlEdge(GetBoundingBoxOnScreen().TopLeft());
+ Point aRelPoint(aAbsPoint - aControlEdge);
+ size_t nChildIndex(0);
+ if (mpDPFieldWindow->GetFieldIndex(aRelPoint, nChildIndex))
+ xAcc = getAccessibleChild(static_cast< long >( nChildIndex ));
+ }
+ }
+ return xAcc;
+}
+
+sal_Bool SAL_CALL ScAccessibleDataPilotControl::isVisible( )
+ throw (uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleDataPilotControl::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ mpDPFieldWindow->GrabFocus();
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getForeground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getBackground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ if (mpDPFieldWindow->GetType() == TYPE_SELECT)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+ }
+ else
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ }
+ }
+ return nColor;
+}
+
+ ///===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetFieldCount();
+ else
+ return 0;
+}
+
+uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotControl::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAcc;
+ if (mpDPFieldWindow)
+ {
+ if (nIndex < 0 || static_cast< size_t >( nIndex ) >= mpDPFieldWindow->GetFieldCount())
+ throw lang::IndexOutOfBoundsException();
+
+ DBG_ASSERT(static_cast<sal_uInt32>(mpDPFieldWindow->GetFieldCount()) == maChildren.size(), "did not recognize a child count change");
+
+ uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
+ if (!xTempAcc.is())
+ {
+ maChildren[nIndex].pAcc = new ScAccessibleDataPilotButton(this, mpDPFieldWindow, nIndex);
+ xTempAcc = maChildren[nIndex].pAcc;
+ maChildren[nIndex].xWeakAcc = xTempAcc;
+ }
+
+ xAcc = xTempAcc;
+ }
+ return xAcc;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotControl::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+
+ return pStateSet;
+}
+
+ ///===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotControl"));
+}
+
+ ///===== XTypeProvider ===================================================
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotControl::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+ //===== internal ========================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetDescription();
+
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetName();
+
+ return rtl::OUString();
+}
+
+Rectangle ScAccessibleDataPilotControl::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetWindowExtentsRelative(NULL);
+ else
+ return Rectangle();
+}
+
+Rectangle ScAccessibleDataPilotControl::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetWindowExtentsRelative(mpDPFieldWindow->GetAccessibleParentWindow());
+ else
+ return Rectangle();
+}
+
+
+//===============================================================================
+
+ScAccessibleDataPilotButton::ScAccessibleDataPilotButton(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldWindow* pDPFieldWindow,
+ sal_Int32 nIndex)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::PUSH_BUTTON),
+ mpDPFieldWindow(pDPFieldWindow),
+ mnIndex(nIndex)
+{
+}
+
+ScAccessibleDataPilotButton::~ScAccessibleDataPilotButton(void)
+{
+ if (!IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void ScAccessibleDataPilotButton::Init()
+{
+}
+
+void SAL_CALL ScAccessibleDataPilotButton::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDPFieldWindow = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleDataPilotButton::SetFocused()
+{
+ CommitFocusGained();
+}
+
+void ScAccessibleDataPilotButton::ResetFocused()
+{
+ CommitFocusLost();
+}
+
+ ///===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotButton::getAccessibleAtPoint(
+ const ::com::sun::star::awt::Point& /* rPoint */ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessibleDataPilotButton::isVisible( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL ScAccessibleDataPilotButton::grabFocus( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ {
+ mpDPFieldWindow->GrabFocusWithSel(getAccessibleIndexInParent());
+ }
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getForeground( )
+throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
+ }
+ return nColor;
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getBackground( )
+throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nColor(0);
+ if (mpDPFieldWindow)
+ {
+ nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
+ }
+ return nColor;
+}
+
+ ///===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleChildCount(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return 0;
+}
+
+uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotButton::getAccessibleChild(sal_Int32 /* nIndex */)
+ throw (::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::lang::IndexOutOfBoundsException)
+{
+ throw lang::IndexOutOfBoundsException();
+}
+
+sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleIndexInParent(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return mnIndex;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotButton::getAccessibleStateSet(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::FOCUSABLE);
+ if (mpDPFieldWindow && (sal::static_int_cast<sal_Int32>(mpDPFieldWindow->GetSelectedField()) == mnIndex))
+ pStateSet->AddState(AccessibleStateType::FOCUSED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+
+ return pStateSet;
+}
+
+ ///===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::getImplementationName(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotButton"));
+}
+
+ ///===== XTypeProvider ===================================================
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotButton::getImplementationId(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleDescription(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleName(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpDPFieldWindow)
+ return mpDPFieldWindow->GetFieldText(getAccessibleIndexInParent());
+
+ return rtl::OUString();
+}
+
+Rectangle ScAccessibleDataPilotButton::GetBoundingBoxOnScreen(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect(GetBoundingBox());
+
+ if (mpDPFieldWindow)
+ {
+ Point aParentPos(mpDPFieldWindow->GetWindowExtentsRelative(NULL).TopLeft());
+ aRect.Move(aParentPos.getX(), aParentPos.getY());
+ }
+
+ return aRect;
+}
+
+Rectangle ScAccessibleDataPilotButton::GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ if (mpDPFieldWindow)
+ return Rectangle (mpDPFieldWindow->GetFieldPosition(const_cast<ScAccessibleDataPilotButton*> (this)->getAccessibleIndexInParent()), mpDPFieldWindow->GetFieldSize());
+ else
+ return Rectangle();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx
new file mode 100644
index 000000000000..4c65632fb45e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx
@@ -0,0 +1,2120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleDocument.hxx"
+#include "AccessibleSpreadsheet.hxx"
+#include "tabvwsh.hxx"
+#include "AccessibilityHints.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "unoguard.hxx"
+#include "shapeuno.hxx"
+#include "DrawModelBroadcaster.hxx"
+#include "drawview.hxx"
+#include "gridwin.hxx"
+#include "AccessibleEditObject.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLERELATIONTYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#endif
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/ShapeTypeHandler.hxx>
+#include <svx/AccessibleShape.hxx>
+#include <svx/AccessibleShapeTreeInfo.hxx>
+#include <svx/AccessibleShapeInfo.hxx>
+#include <comphelper/sequence.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/unoshcol.hxx>
+#include <svx/unoshape.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <list>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::std::for_each;
+
+ //===== internal ========================================================
+
+struct ScAccessibleShapeData
+{
+ ScAccessibleShapeData() : pAccShape(NULL), pRelationCell(NULL), bSelected(sal_False), bSelectable(sal_True) {}
+ ~ScAccessibleShapeData();
+ mutable ::accessibility::AccessibleShape* pAccShape;
+ mutable ScAddress* pRelationCell; // if it is NULL this shape is anchored on the table
+// SdrObject* pShape;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
+ mutable sal_Bool bSelected;
+ sal_Bool bSelectable;
+};
+
+ScAccessibleShapeData::~ScAccessibleShapeData()
+{
+ if (pAccShape)
+ {
+ pAccShape->dispose();
+ pAccShape->release();
+ }
+}
+
+struct ScShapeDataLess
+{
+ rtl::OUString msLayerId;
+ rtl::OUString msZOrder;
+ ScShapeDataLess()
+ : msLayerId(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )),
+ msZOrder(RTL_CONSTASCII_USTRINGPARAM( "ZOrder" ))
+ {
+ }
+ void ConvertLayerId(sal_Int16& rLayerID) const // changes the number of the LayerId so it the accessibility order
+ {
+ switch (rLayerID)
+ {
+ case SC_LAYER_FRONT:
+ rLayerID = 1;
+ break;
+ case SC_LAYER_BACK:
+ rLayerID = 0;
+ break;
+ case SC_LAYER_INTERN:
+ rLayerID = 2;
+ break;
+ case SC_LAYER_CONTROLS:
+ rLayerID = 3;
+ break;
+ }
+ }
+ sal_Bool LessThanSheet(const ScAccessibleShapeData* pData) const
+ {
+ sal_Bool bResult(sal_False);
+ uno::Reference< beans::XPropertySet> xProps(pData->xShape, uno::UNO_QUERY);
+ if (xProps.is())
+ {
+ uno::Any aPropAny = xProps->getPropertyValue(msLayerId);
+ sal_Int16 nLayerID = 0;
+ if( (aPropAny >>= nLayerID) )
+ {
+ if (nLayerID == SC_LAYER_BACK)
+ bResult = sal_True;
+ }
+ }
+ return bResult;
+ }
+ sal_Bool operator()(const ScAccessibleShapeData* pData1, const ScAccessibleShapeData* pData2) const
+ {
+ sal_Bool bResult(sal_False);
+ if (pData1 && pData2)
+ {
+ uno::Reference< beans::XPropertySet> xProps1(pData1->xShape, uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySet> xProps2(pData2->xShape, uno::UNO_QUERY);
+ if (xProps1.is() && xProps2.is())
+ {
+ uno::Any aPropAny1 = xProps1->getPropertyValue(msLayerId);
+ uno::Any aPropAny2 = xProps2->getPropertyValue(msLayerId);
+ sal_Int16 nLayerID1(0);
+ sal_Int16 nLayerID2(0);
+ if( (aPropAny1 >>= nLayerID1) && (aPropAny2 >>= nLayerID2) )
+ {
+ if (nLayerID1 == nLayerID2)
+ {
+ uno::Any aAny1 = xProps1->getPropertyValue(msZOrder);
+ sal_Int32 nZOrder1 = 0;
+ uno::Any aAny2 = xProps2->getPropertyValue(msZOrder);
+ sal_Int32 nZOrder2 = 0;
+ if ( (aAny1 >>= nZOrder1) && (aAny2 >>= nZOrder2) )
+ bResult = (nZOrder1 < nZOrder2);
+ }
+ else
+ {
+ ConvertLayerId(nLayerID1);
+ ConvertLayerId(nLayerID2);
+ bResult = (nLayerID1 < nLayerID2);
+ }
+ }
+ }
+ }
+ else if (pData1 && !pData2)
+ bResult = LessThanSheet(pData1);
+ else if (!pData1 && pData2)
+ bResult = !LessThanSheet(pData2);
+ else
+ bResult = sal_False;
+ return bResult;
+ }
+};
+
+struct DeselectShape
+{
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData)
+ {
+ pAccShapeData->bSelected = sal_False;
+ if (pAccShapeData->pAccShape)
+ pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ }
+ }
+};
+
+struct SelectShape
+{
+ uno::Reference < drawing::XShapes > xShapes;
+ SelectShape(uno::Reference<drawing::XShapes>& xTemp) : xShapes(xTemp) {}
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData && pAccShapeData->bSelectable)
+ {
+ pAccShapeData->bSelected = sal_True;
+ if (pAccShapeData->pAccShape)
+ pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED);
+ if (xShapes.is())
+ xShapes->add(pAccShapeData->xShape);
+ }
+ }
+};
+
+struct Destroy
+{
+ void operator() (ScAccessibleShapeData* pData)
+ {
+ if (pData)
+ DELETEZ(pData);
+ }
+};
+
+class ScChildrenShapes : public SfxListener,
+ public ::accessibility::IAccessibleParent
+{
+public:
+ ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
+ ~ScChildrenShapes();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== IAccessibleParent ===============================================
+
+ virtual sal_Bool ReplaceChild (
+ ::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex,
+ const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
+ ) throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== Internal ========================================================
+ void SetDrawBroadcaster();
+
+ sal_Int32 GetCount() const;
+ uno::Reference< XAccessible > Get(const ScAccessibleShapeData* pData) const;
+ uno::Reference< XAccessible > Get(sal_Int32 nIndex) const;
+ uno::Reference< XAccessible > GetAt(const awt::Point& rPoint) const;
+
+ // gets the index of the shape starting on 0 (without the index of the table)
+ // returns the selected shape
+ sal_Bool IsSelected(sal_Int32 nIndex,
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape) const;
+
+ sal_Bool SelectionChanged();
+
+ void Select(sal_Int32 nIndex);
+ void DeselectAll(); // deselect also the table
+ void SelectAll();
+ sal_Int32 GetSelectedCount() const;
+ uno::Reference< XAccessible > GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const;
+ void Deselect(sal_Int32 nChildIndex);
+
+ SdrPage* GetDrawPage() const;
+
+ utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;
+
+ void VisAreaChanged() const;
+private:
+ typedef std::vector<ScAccessibleShapeData*> SortedShapes;
+
+ mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order
+
+ mutable ::accessibility::AccessibleShapeTreeInfo maShapeTreeInfo;
+ mutable com::sun::star::uno::Reference<com::sun::star::view::XSelectionSupplier> xSelectionSupplier;
+ mutable sal_uInt32 mnSdrObjCount;
+ mutable sal_uInt32 mnShapesSelected;
+ ScTabViewShell* mpViewShell;
+ ScAccessibleDocument* mpAccessibleDocument;
+ ScSplitPos meSplitPos;
+
+ void FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const;
+ sal_Bool FindSelectedShapesChanges(const com::sun::star::uno::Reference<com::sun::star::drawing::XShapes>& xShapes, sal_Bool bCommitChange) const;
+ void FillSelectionSupplier() const;
+
+ ScAddress* GetAnchor(const uno::Reference<drawing::XShape>& xShape) const;
+ uno::Reference<XAccessibleRelationSet> GetRelationSet(const ScAccessibleShapeData* pData) const;
+ void CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const;
+ void SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const;
+ void AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const;
+ void RemoveShape(const uno::Reference<drawing::XShape>& xShape) const;
+
+ sal_Bool FindShape(const uno::Reference<drawing::XShape>& xShape, SortedShapes::iterator& rItr) const;
+
+ sal_Int8 Compare(const ScAccessibleShapeData* pData1,
+ const ScAccessibleShapeData* pData2) const;
+};
+
+ScChildrenShapes::ScChildrenShapes(ScAccessibleDocument* pAccessibleDocument, ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
+ :
+ mnShapesSelected(0),
+ mpViewShell(pViewShell),
+ mpAccessibleDocument(pAccessibleDocument),
+ meSplitPos(eSplitPos)
+{
+ FillSelectionSupplier();
+ maZOrderedShapes.push_back(NULL); // 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();
+
+ uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xShapes.is())
+ FindSelectedShapesChanges(xShapes, sal_False);
+ }
+ if (pViewShell)
+ {
+ SfxBroadcaster* pDrawBC = pViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ {
+ StartListening(*pDrawBC);
+
+ maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(pViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
+ maShapeTreeInfo.SetSdrView(pViewShell->GetViewData()->GetScDrawView());
+ maShapeTreeInfo.SetController(NULL);
+ maShapeTreeInfo.SetWindow(pViewShell->GetWindowByPos(meSplitPos));
+ maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
+ }
+ }
+}
+
+ScChildrenShapes::~ScChildrenShapes()
+{
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), Destroy());
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ }
+}
+
+void ScChildrenShapes::SetDrawBroadcaster()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetViewData()->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ {
+ StartListening(*pDrawBC, TRUE);
+
+ maShapeTreeInfo.SetModelBroadcaster( new ScDrawModelBroadcaster(mpViewShell->GetViewData()->GetDocument()->GetDrawLayer()) );
+ maShapeTreeInfo.SetSdrView(mpViewShell->GetViewData()->GetScDrawView());
+ maShapeTreeInfo.SetController(NULL);
+ maShapeTreeInfo.SetWindow(mpViewShell->GetWindowByPos(meSplitPos));
+ maShapeTreeInfo.SetViewForwarder(mpAccessibleDocument);
+ }
+ }
+}
+
+void ScChildrenShapes::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SdrHint ) )
+ {
+ const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if (pSdrHint)
+ {
+ SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
+ if (pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->GetPage() == GetDrawPage()) &&
+ (pObj->GetPage() == pObj->GetObjList()) ) //#108480# only do something if the object lies direct on the page
+ {
+ switch (pSdrHint->GetKind())
+ {
+ case HINT_OBJCHG : // Objekt geaendert
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ ScShapeDataLess aLess;
+ std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), aLess); // sort, because the z index or layer could be changed
+ CheckWhetherAnchorChanged(xShape);
+ }
+ }
+ break;
+ case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ AddShape(xShape, sal_True);
+ }
+ break;
+ case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ RemoveShape(xShape);
+ }
+ break;
+ default :
+ {
+ // other events are not interesting
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex, const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo)
+ throw (uno::RuntimeException)
+{
+ // create the new child
+ ::accessibility::AccessibleShape* pReplacement = ::accessibility::ShapeTypeHandler::Instance().CreateAccessibleObject (
+ ::accessibility::AccessibleShapeInfo ( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex ),
+ _rShapeTreeInfo
+ );
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pReplacement ); // keep this alive (do this before calling Init!)
+ if ( pReplacement )
+ pReplacement->Init();
+
+ sal_Bool bResult(sal_False);
+ if (pCurrentChild && pReplacement)
+ {
+ DBG_ASSERT(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted");
+ SortedShapes::iterator aItr;
+ FindShape(pCurrentChild->GetXShape(), aItr);
+ if (aItr != maZOrderedShapes.end() && (*aItr))
+ {
+ if ((*aItr)->pAccShape)
+ {
+ DBG_ASSERT((*aItr)->pAccShape == pCurrentChild, "wrong child found");
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.OldValue <<= uno::makeAny(uno::Reference<XAccessible>(pCurrentChild));
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
+
+ pCurrentChild->dispose();
+ }
+ (*aItr)->pAccShape = pReplacement;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.NewValue <<= uno::makeAny(uno::Reference<XAccessible>(pReplacement));
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is new - event
+ bResult = sal_True;
+ }
+ }
+ return bResult;
+}
+
+sal_Int32 ScChildrenShapes::GetCount() const
+{
+ SdrPage* pDrawPage = GetDrawPage();
+ if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
+ {
+ mnSdrObjCount = pDrawPage->GetObjCount();
+ maZOrderedShapes.reserve(mnSdrObjCount + 1); // the table is always in
+ for (sal_uInt32 i = 0; i < mnSdrObjCount; ++i)
+ {
+ SdrObject* pObj = pDrawPage->GetObj(i);
+ if (pObj/* && (pObj->GetLayer() != SC_LAYER_INTERN)*/)
+ {
+ uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ AddShape(xShape, sal_False); //inserts in the correct order
+ }
+ }
+ }
+ return maZOrderedShapes.size();
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
+{
+ if (!pData)
+ return NULL;
+
+ if (!pData->pAccShape)
+ {
+ ::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)
+ {
+ pData->pAccShape->acquire();
+ 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;
+ }
+
+uno::Reference< XAccessible > ScChildrenShapes::Get(sal_Int32 nIndex) const
+{
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (static_cast<sal_uInt32>(nIndex) >= maZOrderedShapes.size())
+ return NULL;
+
+ return Get(maZOrderedShapes[nIndex]);
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ if(mpViewShell)
+ {
+ sal_Int32 i(maZOrderedShapes.size() - 1);
+ sal_Bool bFound(sal_False);
+ while (!bFound && i >= 0)
+ {
+ ScAccessibleShapeData* pShape = maZOrderedShapes[i];
+ if (pShape)
+ {
+ if (!pShape->pAccShape)
+ Get(pShape);
+
+ if (pShape->pAccShape)
+ {
+ Point aPoint(VCLPoint(rPoint));
+ aPoint -= VCLRectangle(pShape->pAccShape->getBounds()).TopLeft();
+ if (pShape->pAccShape->containsPoint(AWTPoint(aPoint)))
+ {
+ xAccessible = pShape->pAccShape;
+ bFound = sal_True;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("I should have an accessible shape now!");
+ }
+ }
+ else
+ bFound = sal_True; // this is the sheet and it lies before the rest of the shapes which are background shapes
+
+ --i;
+ }
+ }
+ return xAccessible;
+}
+
+sal_Bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
+ uno::Reference<drawing::XShape>& rShape) const
+{
+ sal_Bool bResult (sal_False);
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ if (!maZOrderedShapes[nIndex])
+ return sal_False;
+
+ bResult = maZOrderedShapes[nIndex]->bSelected;
+ rShape = maZOrderedShapes[nIndex]->xShape;
+
+#ifdef DBG_UTIL // test whether it is truly selected by a slower method
+ uno::Reference< drawing::XShape > xReturnShape;
+ sal_Bool bDebugResult(sal_False);
+ uno::Reference<container::XIndexAccess> xIndexAccess;
+ xSelectionSupplier->getSelection() >>= xIndexAccess;
+
+ if (xIndexAccess.is())
+ {
+ sal_Int32 nCount(xIndexAccess->getCount());
+ if (nCount)
+ {
+ uno::Reference< drawing::XShape > xShape;
+ uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
+ sal_Int32 i(0);
+ while (!bDebugResult && (i < nCount))
+ {
+ xIndexAccess->getByIndex(i) >>= xShape;
+ if (xShape.is() && (xIndexShape.get() == xShape.get()))
+ {
+ bDebugResult = sal_True;
+ xReturnShape = xShape;
+ }
+ else
+ ++i;
+ }
+ }
+ }
+ DBG_ASSERT((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result");
+#endif
+
+ return bResult;
+}
+
+sal_Bool ScChildrenShapes::SelectionChanged()
+{
+ sal_Bool bResult(sal_False);
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+
+ bResult = FindSelectedShapesChanges(xShapes, sal_True);
+
+ return bResult;
+}
+
+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();
+
+ if (!maZOrderedShapes[nIndex])
+ return;
+
+ uno::Reference<drawing::XShape> xShape;
+ if (!IsSelected(nIndex, xShape) && maZOrderedShapes[nIndex]->bSelectable)
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xSelectionSupplier->getSelection() >>= xShapes;
+
+ if (!xShapes.is())
+ xShapes = new SvxShapeCollection();
+
+ xShapes->add(maZOrderedShapes[nIndex]->xShape);
+
+ try
+ {
+ xSelectionSupplier->select(uno::makeAny(xShapes));
+ maZOrderedShapes[nIndex]->bSelected = sal_True;
+ if (maZOrderedShapes[nIndex]->pAccShape)
+ maZOrderedShapes[nIndex]->pAccShape->SetState(AccessibleStateType::SELECTED);
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ }
+ }
+}
+
+void ScChildrenShapes::DeselectAll()
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ sal_Bool bSomethingSelected(sal_True);
+ try
+ {
+ xSelectionSupplier->select(uno::Any()); //deselects all
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ DBG_ERRORFILE("nothing selected before");
+ bSomethingSelected = sal_False;
+ }
+
+ if (bSomethingSelected)
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), DeselectShape());
+}
+
+void ScChildrenShapes::SelectAll()
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with filtered shapes (no internal shapes)
+
+ if (maZOrderedShapes.size() > 1)
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xShapes = new SvxShapeCollection();
+
+ try
+ {
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), SelectShape(xShapes));
+ xSelectionSupplier->select(uno::makeAny(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<container::XIndexAccess> xIndexAccess;
+ xSelectionSupplier->getSelection() >>= xIndexAccess;
+
+ if (xIndexAccess.is())
+ {
+ sal_uInt32 nCount(xIndexAccess->getCount());
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<drawing::XShape> xShape;
+ xIndexAccess->getByIndex(i) >>= xShape;
+ if (xShape.is())
+ rShapes.push_back(xShape);
+ }
+ }
+}
+
+sal_Int32 ScChildrenShapes::GetSelectedCount() const
+{
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ std::vector < uno::Reference < drawing::XShape > > aShapes;
+ FillShapes(aShapes);
+
+ return aShapes.size();
+}
+
+uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedChildIndex, sal_Bool bTabSelected) const
+{
+ uno::Reference< XAccessible > xAccessible;
+
+ if (maZOrderedShapes.size() <= 1)
+ GetCount(); // fill list with shapes
+
+ if (!bTabSelected)
+ {
+ std::vector < uno::Reference < drawing::XShape > > aShapes;
+ FillShapes(aShapes);
+
+ SortedShapes::iterator aItr;
+ if (FindShape(aShapes[nSelectedChildIndex], aItr))
+ xAccessible = Get(aItr - maZOrderedShapes.begin());
+ }
+ else
+ {
+ SortedShapes::iterator aItr = maZOrderedShapes.begin();
+ SortedShapes::iterator aEndItr = maZOrderedShapes.end();
+ sal_Bool bFound(sal_False);
+ while(!bFound && aItr != aEndItr)
+ {
+ if (*aItr)
+ {
+ if ((*aItr)->bSelected)
+ {
+ if (nSelectedChildIndex == 0)
+ bFound = sal_True;
+ else
+ --nSelectedChildIndex;
+ }
+ }
+ else
+ {
+ if (nSelectedChildIndex == 0)
+ bFound = sal_True;
+ else
+ --nSelectedChildIndex;
+ }
+ if (!bFound)
+ ++aItr;
+ }
+ if (bFound && *aItr)
+ xAccessible = (*aItr)->pAccShape;
+ }
+
+ return xAccessible;
+}
+
+void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
+{
+ uno::Reference<drawing::XShape> xShape;
+ if (IsSelected(nChildIndex, xShape)) // returns false if it is the sheet
+ {
+ if (xShape.is())
+ {
+ uno::Reference<drawing::XShapes> xShapes;
+ xSelectionSupplier->getSelection() >>= xShapes;
+ if (xShapes.is())
+ xShapes->remove(xShape);
+
+ try
+ {
+ xSelectionSupplier->select(uno::makeAny(xShapes));
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ DBG_ERRORFILE("something not selectable");
+ }
+
+ maZOrderedShapes[nChildIndex]->bSelected = sal_False;
+ if (maZOrderedShapes[nChildIndex]->pAccShape)
+ maZOrderedShapes[nChildIndex]->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ }
+ }
+}
+
+
+SdrPage* ScChildrenShapes::GetDrawPage() const
+{
+ SCTAB nTab(mpAccessibleDocument->getVisibleTable());
+ SdrPage* pDrawPage = NULL;
+ if (mpViewShell)
+ {
+ ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
+ }
+ }
+ return pDrawPage;
+}
+
+struct SetRelation
+{
+ const ScChildrenShapes* mpChildrenShapes;
+ mutable utl::AccessibleRelationSetHelper* mpRelationSet;
+ const ScAddress* mpAddress;
+ SetRelation(const ScChildrenShapes* pChildrenShapes, const ScAddress* pAddress)
+ :
+ mpChildrenShapes(pChildrenShapes),
+ mpRelationSet(NULL),
+ mpAddress(pAddress)
+ {
+ }
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData &&
+ ((!pAccShapeData->pRelationCell && !mpAddress) ||
+ (pAccShapeData->pRelationCell && mpAddress && (*(pAccShapeData->pRelationCell) == *mpAddress))))
+ {
+ if (!mpRelationSet)
+ mpRelationSet = new utl::AccessibleRelationSetHelper();
+
+ AccessibleRelation aRelation;
+ aRelation.TargetSet.realloc(1);
+ aRelation.TargetSet[0] = mpChildrenShapes->Get(pAccShapeData);
+ aRelation.RelationType = AccessibleRelationType::CONTROLLER_FOR;
+
+ mpRelationSet->AddRelation(aRelation);
+ }
+ }
+};
+
+utl::AccessibleRelationSetHelper* ScChildrenShapes::GetRelationSet(const ScAddress* pAddress) const
+{
+ SetRelation aSetRelation(this, pAddress);
+ ::std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aSetRelation);
+ return aSetRelation.mpRelationSet;
+}
+
+sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawing::XShapes>& xShapes, sal_Bool /* bCommitChange */) const
+{
+ sal_Bool bResult(sal_False);
+ SortedShapes aShapesList;
+ uno::Reference<container::XIndexAccess> xIndexAcc(xShapes, uno::UNO_QUERY);
+ if (xIndexAcc.is())
+ {
+ mnShapesSelected = xIndexAcc->getCount();
+ for (sal_uInt32 i = 0; i < mnShapesSelected; ++i)
+ {
+ uno::Reference< drawing::XShape > xShape;
+ xIndexAcc->getByIndex(i) >>= xShape;
+ if (xShape.is())
+ {
+ ScAccessibleShapeData* pShapeData = new ScAccessibleShapeData();
+ pShapeData->xShape = xShape;
+ aShapesList.push_back(pShapeData);
+ }
+ }
+ }
+ else
+ mnShapesSelected = 0;
+ ScShapeDataLess aLess;
+ std::sort(aShapesList.begin(), aShapesList.end(), aLess);
+
+ SortedShapes::iterator aXShapesItr(aShapesList.begin());
+ SortedShapes::const_iterator aXShapesEndItr(aShapesList.end());
+ SortedShapes::iterator aDataItr(maZOrderedShapes.begin());
+ SortedShapes::const_iterator aDataEndItr(maZOrderedShapes.end());
+ SortedShapes::const_iterator aFocusedItr = aDataEndItr;
+ while((aDataItr != aDataEndItr))
+ {
+ if (*aDataItr) // is it realy a shape or only the sheet
+ {
+ sal_Int8 nComp(0);
+ if (aXShapesItr == aXShapesEndItr)
+ nComp = -1; // simulate that the Shape is lower, so the selction state will be removed
+ else
+ nComp = Compare(*aDataItr, *aXShapesItr);
+ if (nComp == 0)
+ {
+ if (!(*aDataItr)->bSelected)
+ {
+ (*aDataItr)->bSelected = sal_True;
+ if ((*aDataItr)->pAccShape)
+ {
+ (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED);
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
+ bResult = sal_True;
+ }
+ aFocusedItr = aDataItr;
+ }
+ ++aDataItr;
+ ++aXShapesItr;
+ }
+ else if (nComp < 0)
+ {
+ if ((*aDataItr)->bSelected)
+ {
+ (*aDataItr)->bSelected = sal_False;
+ if ((*aDataItr)->pAccShape)
+ {
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED);
+ (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED);
+ bResult = sal_True;
+ }
+ }
+ ++aDataItr;
+ }
+ else
+ {
+ DBG_ERRORFILE("here is a selected shape which is not in the childlist");
+ ++aXShapesItr;
+ --mnShapesSelected;
+ }
+ }
+ else
+ ++aDataItr;
+ }
+ if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1))
+ (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED);
+
+ std::for_each(aShapesList.begin(), aShapesList.end(), Destroy());
+
+ return bResult;
+}
+
+void ScChildrenShapes::FillSelectionSupplier() const
+{
+ if (!xSelectionSupplier.is() && mpViewShell)
+ {
+ SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame();
+ if (pViewFrame)
+ {
+ xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ {
+ if (mpAccessibleDocument)
+ xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument);
+ uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xShapes.is())
+ mnShapesSelected = xShapes->getCount();
+ }
+ }
+ }
+}
+
+ScAddress* ScChildrenShapes::GetAnchor(const uno::Reference<drawing::XShape>& xShape) const
+{
+ ScAddress* pAddress = NULL;
+ if (mpViewShell)
+ {
+ SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
+ uno::Reference<beans::XPropertySet> xShapeProp(xShape, uno::UNO_QUERY);
+ if (pShapeImp && xShapeProp.is())
+ {
+ SdrObject *pSdrObj = pShapeImp->GetSdrObject();
+ if (pSdrObj)
+ {
+ if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL)
+ {
+ ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
+ if (pDoc)
+ {
+ rtl::OUString sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape"));
+ awt::Point aPoint(xShape->getPosition());
+ awt::Size aSize(xShape->getSize());
+ rtl::OUString sType(xShape->getShapeType());
+ Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height);
+ if ( sType.equals(sCaptionShape) )
+ {
+ awt::Point aRelativeCaptionPoint;
+ rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
+ xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint;
+ Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y);
+ Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y);
+ aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint;
+ aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint));
+ }
+ ScRange aRange = pDoc->GetRange(mpAccessibleDocument->getVisibleTable(), aRectangle);
+ pAddress = new ScAddress(aRange.aStart);
+ }
+ }
+// else
+// do nothing, because it is always a NULL Pointer
+ }
+ }
+ }
+
+ return pAddress;
+}
+
+uno::Reference<XAccessibleRelationSet> ScChildrenShapes::GetRelationSet(const ScAccessibleShapeData* pData) const
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper();
+
+ if(pData && pRelationSet && mpAccessibleDocument)
+ {
+ uno::Reference<XAccessible> xAccessible = mpAccessibleDocument->GetAccessibleSpreadsheet(); // should be the current table
+ if (pData->pRelationCell && xAccessible.is())
+ {
+ uno::Reference<XAccessibleTable> xAccTable (xAccessible->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccTable.is())
+ xAccessible = xAccTable->getAccessibleCellAt(pData->pRelationCell->Row(), pData->pRelationCell->Col());
+ }
+ AccessibleRelation aRelation;
+ aRelation.TargetSet.realloc(1);
+ aRelation.TargetSet[0] = xAccessible;
+ aRelation.RelationType = AccessibleRelationType::CONTROLLED_BY;
+ pRelationSet->AddRelation(aRelation);
+ }
+
+ return pRelationSet;
+}
+
+void ScChildrenShapes::CheckWhetherAnchorChanged(const uno::Reference<drawing::XShape>& xShape) const
+{
+ SortedShapes::iterator aItr;
+ if (FindShape(xShape, aItr))
+ SetAnchor(xShape, *aItr);
+}
+
+void ScChildrenShapes::SetAnchor(const uno::Reference<drawing::XShape>& xShape, ScAccessibleShapeData* pData) const
+{
+ if (pData)
+ {
+ ScAddress* pAddress = GetAnchor(xShape);
+ if ((pAddress && pData->pRelationCell && (*pAddress != *(pData->pRelationCell))) ||
+ (!pAddress && pData->pRelationCell) || (pAddress && !pData->pRelationCell))
+ {
+ if (pData->pRelationCell)
+ delete pData->pRelationCell;
+ pData->pRelationCell = pAddress;
+ if (pData->pAccShape)
+ pData->pAccShape->SetRelationSet(GetRelationSet(pData));
+ }
+ }
+}
+
+void ScChildrenShapes::AddShape(const uno::Reference<drawing::XShape>& xShape, sal_Bool bCommitChange) const
+{
+ SortedShapes::iterator aFindItr;
+ if (!FindShape(xShape, aFindItr))
+ {
+ ScAccessibleShapeData* pShape = new ScAccessibleShapeData();
+ pShape->xShape = xShape;
+ SortedShapes::iterator aNewItr = maZOrderedShapes.insert(aFindItr, pShape);
+ SetAnchor(xShape, pShape);
+
+ uno::Reference< beans::XPropertySet > xShapeProp(xShape, uno::UNO_QUERY);
+ if (xShapeProp.is())
+ {
+ uno::Any aPropAny = xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "LayerID" )));
+ sal_Int16 nLayerID = 0;
+ if( aPropAny >>= nLayerID )
+ {
+ if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
+ pShape->bSelectable = sal_False;
+ else
+ pShape->bSelectable = sal_True;
+ }
+ }
+
+
+ if (!xSelectionSupplier.is())
+ throw uno::RuntimeException();
+
+ uno::Reference<container::XEnumerationAccess> xEnumAcc(xSelectionSupplier->getSelection(), uno::UNO_QUERY);
+ if (xEnumAcc.is())
+ {
+ uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration();
+ if (xEnum.is())
+ {
+ uno::Reference<drawing::XShape> xSelectedShape;
+ sal_Bool bFound(sal_False);
+ while (!bFound && xEnum->hasMoreElements())
+ {
+ xEnum->nextElement() >>= xSelectedShape;
+ if (xShape.is() && (xShape.get() == xSelectedShape.get()))
+ {
+ pShape->bSelected = sal_True;
+ bFound = sal_True;
+ }
+ }
+ }
+ }
+ if (mpAccessibleDocument && bCommitChange)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.NewValue <<= Get(aNewItr - maZOrderedShapes.begin());
+
+ mpAccessibleDocument->CommitChange(aEvent); // new child - event
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("shape is always in the list");
+ }
+}
+
+void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
+{
+ SortedShapes::iterator aItr;
+ if (FindShape(xShape, aItr))
+ {
+ if (mpAccessibleDocument)
+ {
+ uno::Reference<XAccessible> xOldAccessible (Get(aItr - maZOrderedShapes.begin()));
+
+ delete *aItr;
+ maZOrderedShapes.erase(aItr);
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccessibleDocument);
+ aEvent.OldValue <<= uno::makeAny(xOldAccessible);
+
+ mpAccessibleDocument->CommitChange(aEvent); // child is gone - event
+ }
+ else
+ {
+ delete *aItr;
+ maZOrderedShapes.erase(aItr);
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("shape was not in internal list");
+ }
+}
+
+sal_Bool ScChildrenShapes::FindShape(const uno::Reference<drawing::XShape>& xShape, ScChildrenShapes::SortedShapes::iterator& rItr) const
+{
+ sal_Bool bResult(sal_False);
+ ScAccessibleShapeData aShape;
+ aShape.xShape = xShape;
+ ScShapeDataLess aLess;
+ rItr = std::lower_bound(maZOrderedShapes.begin(), maZOrderedShapes.end(), &aShape, aLess);
+ if ((rItr != maZOrderedShapes.end()) && (*rItr != NULL) && ((*rItr)->xShape.get() == xShape.get()))
+ bResult = sal_True; // if the shape is found
+
+#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
+ SortedShapes::iterator aDebugItr = maZOrderedShapes.begin();
+ SortedShapes::iterator aEndItr = maZOrderedShapes.end();
+ sal_Bool bFound(sal_False);
+ while (!bFound && aDebugItr != aEndItr)
+ {
+ if (*aDebugItr && ((*aDebugItr)->xShape.get() == xShape.get()))
+ bFound = sal_True;
+ else
+ ++aDebugItr;
+ }
+ sal_Bool bResult2 = (aDebugItr != maZOrderedShapes.end());
+ DBG_ASSERT((bResult == bResult2) && ((bResult && (rItr == aDebugItr)) || !bResult), "wrong Shape found");
+#endif
+ return bResult;
+}
+
+sal_Int8 ScChildrenShapes::Compare(const ScAccessibleShapeData* pData1,
+ const ScAccessibleShapeData* pData2) const
+{
+ ScShapeDataLess aLess;
+
+ sal_Bool bResult1(aLess(pData1, pData2));
+ sal_Bool bResult2(aLess(pData2, pData1));
+
+ sal_Int8 nResult(0);
+ if (!bResult1 && bResult2)
+ nResult = 1;
+ else if (bResult1 && !bResult2)
+ nResult = -1;
+
+ return nResult;
+}
+
+struct ScVisAreaChanged
+{
+ ScAccessibleDocument* mpAccDoc;
+ ScVisAreaChanged(ScAccessibleDocument* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const ScAccessibleShapeData* pAccShapeData) const
+ {
+ if (pAccShapeData && pAccShapeData->pAccShape)
+ {
+ pAccShapeData->pAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpAccDoc);
+ }
+ }
+};
+
+void ScChildrenShapes::VisAreaChanged() const
+{
+ ScVisAreaChanged aVisAreaChanged(mpAccessibleDocument);
+ std::for_each(maZOrderedShapes.begin(), maZOrderedShapes.end(), aVisAreaChanged);
+}
+
+// ============================================================================
+
+ScAccessibleDocument::ScAccessibleDocument(
+ const uno::Reference<XAccessible>& rxParent,
+ ScTabViewShell* pViewShell,
+ ScSplitPos eSplitPos)
+ : ScAccessibleDocumentBase(rxParent),
+ mpViewShell(pViewShell),
+ meSplitPos(eSplitPos),
+ mpAccessibleSpreadsheet(NULL),
+ mpChildrenShapes(NULL),
+ mpTempAccEdit(NULL),
+ mbCompleteSheetSelected(sal_False)
+{
+ if (pViewShell)
+ {
+ pViewShell->AddAccessibilityObject(*this);
+ Window *pWin = pViewShell->GetWindowByPos(eSplitPos);
+ if( pWin )
+ {
+ pWin->AddChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
+ USHORT nCount = pWin->GetChildCount();
+ for( sal_uInt16 i=0; i < nCount; ++i )
+ {
+ Window *pChildWin = pWin->GetChild( i );
+ if( pChildWin &&
+ AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ AddChild( pChildWin->GetAccessible(), sal_False );
+ }
+ }
+ if (pViewShell->GetViewData()->HasEditView( eSplitPos ))
+ {
+ uno::Reference<XAccessible> xAcc = new ScAccessibleEditObject(this, pViewShell->GetViewData()->GetEditView(eSplitPos),
+ pViewShell->GetWindowByPos(eSplitPos), GetCurrentCellName(), GetCurrentCellDescription(),
+ CellInEditMode);
+ AddChild(xAcc, sal_False);
+ }
+ }
+ maVisArea = GetVisibleArea_Impl();
+}
+
+void ScAccessibleDocument::Init()
+{
+ if(!mpChildrenShapes)
+ mpChildrenShapes = new ScChildrenShapes(this, mpViewShell, meSplitPos);
+}
+
+ScAccessibleDocument::~ScAccessibleDocument(void)
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleDocument::disposing()
+{
+ ScUnoGuard aGuard;
+ FreeAccessibleSpreadsheet();
+ if (mpViewShell)
+ {
+ Window *pWin = mpViewShell->GetWindowByPos(meSplitPos);
+ if( pWin )
+ pWin->RemoveChildEventListener( LINK( this, ScAccessibleDocument, WindowChildEventListener ));
+
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpChildrenShapes)
+ DELETEZ(mpChildrenShapes);
+
+ ScAccessibleDocumentBase::disposing();
+}
+
+void SAL_CALL ScAccessibleDocument::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ disposing();
+}
+
+ //===== SfxListener =====================================================
+
+IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
+{
+ DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
+ if ( pEvent && pEvent->ISA( VclWindowEvent ) )
+ {
+ VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
+ DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
+ switch ( pVclEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
+ {
+ Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
+ if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ {
+ AddChild( pChildWin->GetAccessible(), sal_True );
+ }
+ }
+ break;
+ case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
+ {
+ Window* pChildWin = static_cast < Window * >( pVclEvent->GetData() );
+ if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
+ {
+ RemoveChild( pChildWin->GetAccessible(), sal_True );
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( ScAccGridWinFocusLostHint ) )
+ {
+ const ScAccGridWinFocusLostHint& rRef = (const ScAccGridWinFocusLostHint&)rHint;
+ if (rRef.GetOldGridWin() == meSplitPos)
+ {
+ if (mxTempAcc.is() && mpTempAccEdit)
+ mpTempAccEdit->LostFocus();
+ else if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->LostFocus();
+ else
+ CommitFocusLost();
+ }
+ }
+ else if (rHint.ISA( ScAccGridWinFocusGotHint ) )
+ {
+ const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint;
+ if (rRef.GetNewGridWin() == meSplitPos)
+ {
+ if (mxTempAcc.is() && mpTempAccEdit)
+ mpTempAccEdit->GotFocus();
+ else if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->GotFocus();
+ else
+ CommitFocusGained();
+ }
+ }
+ else if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
+ mpAccessibleSpreadsheet)
+ {
+ FreeAccessibleSpreadsheet();
+ if (mpChildrenShapes)
+ DELETEZ(mpChildrenShapes);
+
+ // #124567# Accessibility: Shapes / form controls after reload not accessible
+ if ( !mpChildrenShapes )
+ {
+ mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos );
+ }
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent); // all childs changed
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
+ {
+ if (mpChildrenShapes)
+ mpChildrenShapes->SetDrawBroadcaster();
+ }
+ else if ((rRef.GetId() == SC_HINT_ACC_ENTEREDITMODE)) // this event comes only on creating edit field of a cell
+ {
+ if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos))
+ {
+ mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos),
+ mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
+ rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), CellInEditMode);
+ uno::Reference<XAccessible> xAcc = mpTempAccEdit;
+
+ AddChild(xAcc, sal_True);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->LostFocus();
+ else
+ CommitFocusLost();
+
+ mpTempAccEdit->GotFocus();
+ }
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE)
+ {
+ if (mxTempAcc.is())
+ {
+ if (mpTempAccEdit)
+ mpTempAccEdit->LostFocus();
+
+ mpTempAccEdit = NULL;
+ RemoveChild(mxTempAcc, sal_True);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->GotFocus();
+ else
+ CommitFocusGained();
+ }
+ }
+ else if ((rRef.GetId() == SC_HINT_ACC_VISAREACHANGED) || (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED))
+ {
+ Rectangle aOldVisArea(maVisArea);
+ maVisArea = GetVisibleArea_Impl();
+
+ if (maVisArea != aOldVisArea)
+ {
+ if (maVisArea.GetSize() != aOldVisArea.GetSize())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+
+ if (mpAccessibleSpreadsheet)
+ mpAccessibleSpreadsheet->BoundingBoxChanged();
+ }
+ else if (mpAccessibleSpreadsheet)
+ {
+ mpAccessibleSpreadsheet->VisAreaChanged();
+ }
+ if (mpChildrenShapes)
+ mpChildrenShapes->VisAreaChanged();
+ }
+ }
+ }
+
+ ScAccessibleDocumentBase::Notify(rBC, rHint);
+}
+
+void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /* aEvent */ )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bSelectionChanged(sal_False);
+ if (mpAccessibleSpreadsheet)
+ {
+ sal_Bool bOldSelected(mbCompleteSheetSelected);
+ mbCompleteSheetSelected = IsTableSelected();
+ if (bOldSelected != mbCompleteSheetSelected)
+ {
+ mpAccessibleSpreadsheet->CompleteSelectionChanged(mbCompleteSheetSelected);
+ bSelectionChanged = sal_True;
+ }
+ }
+
+ if (mpChildrenShapes && mpChildrenShapes->SelectionChanged())
+ bSelectionChanged = sal_True;
+
+ if (bSelectionChanged)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+ }
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleDocument::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleDocument::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAccessible = NULL;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpChildrenShapes)
+ xAccessible = mpChildrenShapes->GetAt(rPoint);
+ if(!xAccessible.is())
+ {
+ if (mxTempAcc.is())
+ {
+ uno::Reference< XAccessibleContext > xCont(mxTempAcc->getAccessibleContext());
+ uno::Reference< XAccessibleComponent > xComp(xCont, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ Rectangle aBound(VCLRectangle(xComp->getBounds()));
+ if (aBound.IsInside(VCLPoint(rPoint)))
+ xAccessible = mxTempAcc;
+ }
+ }
+ if (!xAccessible.is())
+ xAccessible = GetAccessibleSpreadsheet();
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleDocument::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ 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() &&
+ (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
+ mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
+ {
+ mpViewShell->ActivatePart(meSplitPos);
+ }
+ }
+ }
+}
+
+ //===== XAccessibleContext ==============================================
+
+ /// Return the number of currently visible children.
+sal_Int32 SAL_CALL
+ ScAccessibleDocument::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 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_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+ if (nIndex >= 0)
+ {
+ sal_Int32 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();
+ else if (nIndex == nCount && mxTempAcc.is())
+ xAccessible = mxTempAcc;
+ }
+ }
+
+ if (!xAccessible.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+ /// Return the set of current states.
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleDocument::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ if (IsEditable(xParentStates))
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ 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())
+ {
+ sal_Bool bWasTableSelected(IsTableSelected());
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
+
+ if (bWasTableSelected)
+ mpViewShell->SelectAll();
+ }
+ else
+ {
+ if (mpViewShell)
+ mpViewShell->SelectAll();
+ }
+ }
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleDocument::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Bool bResult(sal_False);
+
+ 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 to high
+ }
+ else
+ {
+ if (mxTempAcc.is() && nChildIndex == nCount)
+ bResult = sal_True;
+ else
+ bResult = IsTableSelected();
+ }
+ }
+ return bResult;
+}
+
+void SAL_CALL
+ ScAccessibleDocument::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->DeselectAll(); //deselects all (also the table)
+}
+
+void SAL_CALL
+ ScAccessibleDocument::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ mpChildrenShapes->SelectAll();
+
+ // select table after shapes, because while selecting shapes the table will be deselected
+ if (mpViewShell)
+ {
+ mpViewShell->SelectAll();
+ }
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleDocument::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nCount(0);
+
+ if (mpChildrenShapes)
+ nCount = mpChildrenShapes->GetSelectedCount();
+
+ if (IsTableSelected())
+ ++nCount;
+
+ if (mxTempAcc.is())
+ ++nCount;
+
+ return nCount;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleDocument::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(getSelectedAccessibleChildCount()); //all shapes and the table
+ if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bTabMarked(IsTableSelected());
+
+ if (mpChildrenShapes)
+ xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is to high
+ if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
+ xAccessible = mxTempAcc;
+ else if (bTabMarked)
+ xAccessible = GetAccessibleSpreadsheet();
+ }
+
+ DBG_ASSERT(xAccessible.is(), "here should always be an accessible object or a exception throwed");
+
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleDocument::deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (mpChildrenShapes)
+ {
+ sal_Int32 nCount(mpChildrenShapes->GetCount()); //all shapes and the table
+ if (mxTempAcc.is())
+ ++nCount;
+ if (nChildIndex < 0 || nChildIndex >= nCount)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bTabMarked(IsTableSelected());
+
+ uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex);
+ if (xAccessible.is())
+ {
+ if (mpChildrenShapes)
+ mpChildrenShapes->Deselect(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is to high
+
+ if (bTabMarked)
+ mpViewShell->SelectAll(); // select the table again
+ }
+ else if (bTabMarked)
+ mpViewShell->Unmark();
+ }
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleDocument::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetDocumentView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleDocument::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleDocumentImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleDocument::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+///===== IAccessibleViewForwarder ========================================
+
+sal_Bool ScAccessibleDocument::IsValid (void) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose);
+}
+
+Rectangle ScAccessibleDocument::GetVisibleArea_Impl() const
+{
+ Rectangle aVisRect(GetBoundingBox());
+
+ Point aPoint(mpViewShell->GetViewData()->GetPixPos(meSplitPos)); // returns a negative Point
+ aPoint.setX(-aPoint.getX());
+ aPoint.setY(-aPoint.getY());
+ aVisRect.SetPos(aPoint);
+
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aVisRect = pWin->PixelToLogic(aVisRect, pWin->GetDrawMapMode());
+
+ return aVisRect;
+}
+
+Rectangle ScAccessibleDocument::GetVisibleArea() const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maVisArea;
+}
+
+Point ScAccessibleDocument::LogicToPixel (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Point aPoint;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ {
+ aPoint = pWin->LogicToPixel(rPoint, pWin->GetDrawMapMode());
+ aPoint += pWin->GetWindowExtentsRelative(NULL).TopLeft();
+ }
+ return aPoint;
+}
+
+Size ScAccessibleDocument::LogicToPixel (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Size aSize;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aSize = pWin->LogicToPixel(rSize, pWin->GetDrawMapMode());
+ return aSize;
+}
+
+Point ScAccessibleDocument::PixelToLogic (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Point aPoint;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ {
+ aPoint -= pWin->GetWindowExtentsRelative(NULL).TopLeft();
+ aPoint = pWin->PixelToLogic(rPoint, pWin->GetDrawMapMode());
+ }
+ return aPoint;
+}
+
+Size ScAccessibleDocument::PixelToLogic (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ Size aSize;
+ ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos));
+ if (pWin)
+ aSize = pWin->PixelToLogic(rSize, pWin->GetDrawMapMode());
+ return aSize;
+}
+
+ //===== internal ========================================================
+
+utl::AccessibleRelationSetHelper* ScAccessibleDocument::GetRelationSet(const ScAddress* pAddress) const
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if (mpChildrenShapes)
+ pRelationSet = mpChildrenShapes->GetRelationSet(pAddress);
+ return pRelationSet;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_DOC_DESCR));
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleDocument::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ rtl::OUString sName = String(ScResId(STR_ACC_DOC_NAME));
+ sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
+ sName += rtl::OUString::valueOf(nNumber);
+ return sName;
+}
+
+Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleDocument::GetBoundingBox() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ }
+ return aRect;
+}
+
+SCTAB ScAccessibleDocument::getVisibleTable() const
+{
+ SCTAB nVisibleTable(0);
+ if (mpViewShell && mpViewShell->GetViewData())
+ nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
+ return nVisibleTable;
+}
+
+uno::Reference < XAccessible >
+ ScAccessibleDocument::GetAccessibleSpreadsheet()
+{
+ if (!mpAccessibleSpreadsheet && mpViewShell)
+ {
+ mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
+ mpAccessibleSpreadsheet->acquire();
+ mpAccessibleSpreadsheet->Init();
+ mbCompleteSheetSelected = IsTableSelected();
+ }
+ return mpAccessibleSpreadsheet;
+}
+
+void ScAccessibleDocument::FreeAccessibleSpreadsheet()
+{
+ if (mpAccessibleSpreadsheet)
+ {
+ mpAccessibleSpreadsheet->dispose();
+ mpAccessibleSpreadsheet->release();
+ mpAccessibleSpreadsheet = NULL;
+ }
+}
+
+sal_Bool ScAccessibleDocument::IsTableSelected() const
+{
+ sal_Bool bResult (sal_False);
+ if(mpViewShell)
+ {
+ SCTAB nTab(getVisibleTable());
+ //#103800#; use a copy of MarkData
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ if (aMarkData.IsAllMarked(ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))))
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+sal_Bool ScAccessibleDocument::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleDocument::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // what is with document protection or readonly documents?
+ return sal_True;
+}
+
+void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
+{
+ DBG_ASSERT(!mxTempAcc.is(), "this object should be removed before");
+ if (xAcc.is())
+ {
+ mxTempAcc = xAcc;
+ if( bFireEvent )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext>(this);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= mxTempAcc;
+ CommitChange( aEvent );
+ }
+ }
+}
+
+void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, sal_Bool bFireEvent)
+{
+ DBG_ASSERT(mxTempAcc.is(), "this object should be added before");
+ if (xAcc.is())
+ {
+ DBG_ASSERT(xAcc.get() == mxTempAcc.get(), "only the same object should be removed");
+ if( bFireEvent )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext>(this);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= mxTempAcc;
+ CommitChange( aEvent );
+ }
+ mxTempAcc = NULL;
+ }
+}
+
+rtl::OUString ScAccessibleDocument::GetCurrentCellName() const
+{
+ String sName( ScResId(STR_ACC_CELL_NAME) );
+ if (mpViewShell)
+ {
+ String sAddress;
+ // Document not needed, because only the cell address, but not the tablename is needed
+ mpViewShell->GetViewData()->GetCurPos().Format( sAddress, SCA_VALID, NULL );
+ sName.SearchAndReplaceAscii("%1", sAddress);
+ }
+ return rtl::OUString(sName);
+}
+
+rtl::OUString ScAccessibleDocument::GetCurrentCellDescription() const
+{
+ return rtl::OUString();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx
new file mode 100644
index 000000000000..76be8e67aa07
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleDocumentBase.hxx"
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+ //===== internal ========================================================
+
+ScAccessibleDocumentBase::ScAccessibleDocumentBase(
+ const uno::Reference<XAccessible>& rxParent)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::DOCUMENT)
+{
+}
+
+ScAccessibleDocumentBase::~ScAccessibleDocumentBase(void)
+{
+}
diff --git a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx
new file mode 100644
index 000000000000..894e57d3802e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx
@@ -0,0 +1,1942 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "AccessibleDocumentPagePreview.hxx"
+#include "AccessiblePreviewTable.hxx"
+#include "AccessiblePageHeader.hxx"
+#include "AccessibilityHints.hxx"
+#include "AccessibleText.hxx"
+#include "document.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "unoguard.hxx"
+#include "drwlayer.hxx"
+#include "editsrc.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "DrawModelBroadcaster.hxx"
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include "preview.hxx"
+#include "postit.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+
+#include <unotools/accessiblestatesethelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <svx/AccessibleShape.hxx>
+#include <svx/ShapeTypeHandler.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <svx/unoshape.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//=========================================================================
+
+typedef std::list< uno::Reference< XAccessible > > ScXAccList;
+
+
+struct ScAccNote
+{
+ String maNoteText;
+ Rectangle maRect;
+ ScAddress maNoteCell;
+ ::accessibility::AccessibleTextHelper* mpTextHelper;
+ sal_Int32 mnParaCount;
+ sal_Bool mbMarkNote;
+
+ ScAccNote() : mpTextHelper(NULL), mnParaCount(0) {}
+};
+
+class ScNotesChilds
+{
+public:
+ ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
+ ~ScNotesChilds();
+ void Init(const Rectangle& rVisRect, sal_Int32 nOffset);
+
+ sal_Int32 GetChildsCount() const;
+ uno::Reference<XAccessible> GetChild(sal_Int32 nIndex) const;
+ uno::Reference<XAccessible> GetAt(const awt::Point& rPoint) const;
+
+ void DataChanged(const Rectangle& rVisRect);
+ void SetOffset(sal_Int32 nNewOffset);
+private:
+ ScPreviewShell* mpViewShell;
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ typedef std::vector<ScAccNote> ScAccNotes;
+ mutable ScAccNotes maNotes;
+ mutable ScAccNotes maMarks;
+ sal_Int32 mnParagraphs;
+ sal_Int32 mnOffset;
+
+ ::accessibility::AccessibleTextHelper* CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const;
+ sal_Int32 AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes);
+
+ sal_Int8 CompareCell(const ScAddress& aCell1, const ScAddress& aCell2);
+ void CollectChilds(const ScAccNote& rNote, ScXAccList& rList);
+ sal_Int32 CheckChanges(const ScPreviewLocationData& rData, const Rectangle& rVisRect,
+ sal_Bool bMark, ScAccNotes& rOldNotes, ScAccNotes& rNewNotes,
+ ScXAccList& rOldParas, ScXAccList& rNewParas);
+
+ inline ScDocument* GetDocument() const;
+};
+
+ScNotesChilds::ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
+ : mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ mnParagraphs(0),
+ mnOffset(0)
+{
+}
+
+struct DeleteAccNote
+{
+ void operator()(ScAccNote& rNote)
+ {
+ if (rNote.mpTextHelper)
+ DELETEZ( rNote.mpTextHelper);
+ }
+};
+
+ScNotesChilds::~ScNotesChilds()
+{
+ std::for_each(maNotes.begin(), maNotes.end(), DeleteAccNote());
+ std::for_each(maMarks.begin(), maMarks.end(), DeleteAccNote());
+}
+
+::accessibility::AccessibleTextHelper* ScNotesChilds::CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const
+{
+ ::accessibility::AccessibleTextHelper* pTextHelper = NULL;
+
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
+ (new ScAccessibleNoteTextData(mpViewShell, rString, aCellPos, bMarkNote));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
+
+ pTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource);
+
+ if (pTextHelper)
+ {
+ pTextHelper->SetEventSource(mpAccDoc);
+ pTextHelper->SetStartIndex(nChildOffset);
+ pTextHelper->SetOffset(rVisRect.TopLeft());
+ }
+
+ return pTextHelper;
+}
+
+sal_Int32 ScNotesChilds::AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes)
+{
+ sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
+
+ rNotes.reserve(nCount);
+
+ sal_Int32 nParagraphs(0);
+ ScDocument* pDoc = GetDocument();
+ if (pDoc)
+ {
+ ScAccNote aNote;
+ aNote.mbMarkNote = bMark;
+ if (bMark)
+ aNote.mnParaCount = 1;
+ for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
+ {
+ if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
+ {
+ if (bMark)
+ {
+ // Document not needed, because only the cell address, but not the tablename is needed
+ aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
+ }
+ else
+ {
+ if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
+ aNote.maNoteText = pNote->GetText();
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ }
+ nParagraphs += aNote.mnParaCount;
+ rNotes.push_back(aNote);
+ }
+ }
+ }
+ return nParagraphs;
+}
+
+void ScNotesChilds::Init(const Rectangle& rVisRect, sal_Int32 nOffset)
+{
+ if (mpViewShell && !mnParagraphs)
+ {
+ mnOffset = nOffset;
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+
+ mnParagraphs = AddNotes(rData, rVisRect, sal_False, maMarks);
+ mnParagraphs += AddNotes(rData, rVisRect, sal_True, maNotes);
+ }
+}
+
+sal_Int32 ScNotesChilds::GetChildsCount() const
+{
+ return mnParagraphs;
+}
+
+struct ScParaFound
+{
+ sal_Int32 mnIndex;
+ ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {}
+ sal_Bool operator() (const ScAccNote& rNote)
+ {
+ sal_Bool bResult(sal_False);
+ if (rNote.mnParaCount > mnIndex)
+ bResult = sal_True;
+ else
+ mnIndex -= rNote.mnParaCount;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScNotesChilds::GetChild(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+
+ if (nIndex < mnParagraphs)
+ {
+ if (nIndex < static_cast<sal_Int32>(maMarks.size()))
+ {
+ ScAccNotes::iterator aEndItr = maMarks.end();
+ ScParaFound aParaFound(nIndex);
+ ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound);
+ if (aItr != aEndItr)
+ {
+ DBG_ASSERT((aItr->maNoteCell == maMarks[nIndex].maNoteCell) && (aItr->mbMarkNote == maMarks[nIndex].mbMarkNote), "wrong note found");
+ }
+ else
+ {
+ DBG_ERRORFILE("wrong note found");
+ }
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(maMarks[nIndex].maNoteText, maMarks[nIndex].maRect, maMarks[nIndex].maNoteCell, maMarks[nIndex].mbMarkNote, nIndex + mnOffset); // the marks are the first and every mark has only one paragraph
+ xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
+ }
+ else
+ {
+ nIndex -= maMarks.size();
+ ScAccNotes::iterator aEndItr = maNotes.end();
+ ScParaFound aParaFound(nIndex);
+ ScAccNotes::iterator aItr = std::find_if(maNotes.begin(), aEndItr, aParaFound);
+ if (aEndItr != aItr)
+ {
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, (nIndex - aParaFound.mnIndex) + mnOffset + maMarks.size());
+ xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
+ }
+ }
+ }
+
+ return xAccessible;
+}
+
+struct ScPointFound
+{
+ Rectangle maPoint;
+ sal_Int32 mnParagraphs;
+ ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {}
+ sal_Bool operator() (const ScAccNote& rNote)
+ {
+ sal_Bool bResult(sal_False);
+ if (maPoint.IsInside(rNote.maRect))
+ bResult = sal_True;
+ else
+ mnParagraphs += rNote.mnParaCount;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScNotesChilds::GetAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAccessible;
+
+ ScPointFound aPointFound(Point(rPoint.X, rPoint.Y));
+
+ ScAccNotes::iterator aEndItr = maMarks.end();
+ ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound);
+ if (aEndItr == aItr)
+ {
+ aEndItr = maNotes.end();
+ aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound);
+ }
+ if (aEndItr != aItr)
+ {
+ if (!aItr->mpTextHelper)
+ aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, aPointFound.mnParagraphs + mnOffset);
+ xAccessible = aItr->mpTextHelper->GetAt(rPoint);
+ }
+
+ return xAccessible;
+}
+
+sal_Int8 ScNotesChilds::CompareCell(const ScAddress& aCell1, const ScAddress& aCell2)
+{
+ DBG_ASSERT(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table");
+ sal_Int8 nResult(0);
+ if (aCell1 != aCell2)
+ {
+ if (aCell1.Row() == aCell2.Row())
+ nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1;
+ else
+ nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1;
+ }
+ return nResult;
+}
+
+void ScNotesChilds::CollectChilds(const ScAccNote& rNote, ScXAccList& rList)
+{
+ if (rNote.mpTextHelper)
+ for (sal_Int32 i = 0; i < rNote.mnParaCount; ++i)
+ rList.push_back(rNote.mpTextHelper->GetChild(i + rNote.mpTextHelper->GetStartIndex()));
+}
+
+sal_Int32 ScNotesChilds::CheckChanges(const ScPreviewLocationData& rData,
+ const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rOldNotes,
+ ScAccNotes& rNewNotes, ScXAccList& rOldParas, ScXAccList& rNewParas)
+{
+ sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);
+
+ rNewNotes.reserve(nCount);
+
+ sal_Int32 nParagraphs(0);
+ ScDocument* pDoc = GetDocument();
+ if (pDoc)
+ {
+ ScAccNote aNote;
+ aNote.mbMarkNote = bMark;
+ if (bMark)
+ aNote.mnParaCount = 1;
+ ScAccNotes::iterator aItr = rOldNotes.begin();
+ ScAccNotes::iterator aEndItr = rOldNotes.end();
+ sal_Bool bAddNote(sal_False);
+ for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
+ {
+ if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
+ {
+ if (bMark)
+ {
+ // Document not needed, because only the cell address, but not the tablename is needed
+ aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
+ }
+ else
+ {
+ if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
+ aNote.maNoteText = pNote->GetText();
+ }
+
+ sal_Int8 nCompare(-1); // if there are no more old childs it is always a new one
+ if (aItr != aEndItr)
+ nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell);
+ if (nCompare == 0)
+ {
+ if (aNote.maNoteText == aItr->maNoteText)
+ {
+ aNote.mpTextHelper = aItr->mpTextHelper;
+ if (aNote.maRect != aItr->maRect) //neue VisArea setzen
+ {
+ aNote.mpTextHelper->SetOffset(aNote.maRect.TopLeft());
+ aNote.mpTextHelper->UpdateChildren();
+ //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
+ // could be changed, because only a part of the note is visible
+ }
+ }
+ else
+ {
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ // collect removed childs
+ CollectChilds(*aItr, rOldParas);
+ DELETEZ(aItr->mpTextHelper);
+ // collect new childs
+ CollectChilds(aNote, rNewParas);
+ }
+ bAddNote = sal_True;
+ // not necessary, because this branch should not be reached if it is the end
+ //if (aItr != aEndItr)
+ ++aItr;
+ }
+ else if (nCompare < 0)
+ {
+ aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
+ if (aNote.mpTextHelper)
+ aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
+ // collect new childs
+ CollectChilds(aNote, rNewParas);
+ bAddNote = sal_True;
+ }
+ else
+ {
+ // collect removed childs
+ CollectChilds(*aItr, rOldParas);
+ DELETEZ(aItr->mpTextHelper);
+
+ // no note to add
+ // not necessary, because this branch should not be reached if it is the end
+ //if (aItr != aEndItr)
+ ++aItr;
+ }
+ if (bAddNote)
+ {
+ nParagraphs += aNote.mnParaCount;
+ rNewNotes.push_back(aNote);
+ bAddNote = sal_False;
+ }
+ }
+ }
+ }
+ return nParagraphs;
+}
+
+struct ScChildGone
+{
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const uno::Reference<XAccessible>& xAccessible) const
+ {
+ if (mpAccDoc)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
+ aEvent.OldValue <<= xAccessible;
+
+ mpAccDoc->CommitChange(aEvent); // gone child - event
+ }
+ }
+};
+
+struct ScChildNew
+{
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
+ void operator() (const uno::Reference<XAccessible>& xAccessible) const
+ {
+ if (mpAccDoc)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
+ aEvent.NewValue <<= xAccessible;
+
+ mpAccDoc->CommitChange(aEvent); // new child - event
+ }
+ }
+};
+
+void ScNotesChilds::DataChanged(const Rectangle& rVisRect)
+{
+ if (mpViewShell && mpAccDoc)
+ {
+ ScXAccList aNewParas;
+ ScXAccList aOldParas;
+ ScAccNotes aNewMarks;
+ mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_True, maMarks, aNewMarks, aOldParas, aNewParas);
+ maMarks = aNewMarks;
+ ScAccNotes aNewNotes;
+ mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_False, maNotes, aNewNotes, aOldParas, aNewParas);
+ maNotes = aNewNotes;
+
+ std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc));
+ std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc));
+ }
+}
+
+struct ScChangeOffset
+{
+ sal_Int32 mnDiff;
+ ScChangeOffset(sal_Int32 nDiff) : mnDiff(nDiff) {}
+ void operator() (const ScAccNote& rNote)
+ {
+ if (rNote.mpTextHelper)
+ rNote.mpTextHelper->SetStartIndex(rNote.mpTextHelper->GetStartIndex() + mnDiff);
+ }
+};
+
+void ScNotesChilds::SetOffset(sal_Int32 nNewOffset)
+{
+ sal_Int32 nDiff(nNewOffset - mnOffset);
+ if (nDiff != 0)
+ {
+ std::for_each(maMarks.begin(), maMarks.end(), ScChangeOffset(nDiff));
+ std::for_each(maNotes.begin(), maNotes.end(), ScChangeOffset(nDiff));
+ mnOffset = nNewOffset;
+ }
+}
+
+inline ScDocument* ScNotesChilds::GetDocument() const
+{
+ ScDocument* pDoc = NULL;
+ if (mpViewShell)
+ pDoc = mpViewShell->GetDocument();
+ return pDoc;
+}
+
+class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder
+{
+public:
+ ScIAccessibleViewForwarder();
+ ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
+ ScAccessibleDocumentPagePreview* pAccDoc,
+ const MapMode& aMapMode);
+ ~ScIAccessibleViewForwarder();
+
+ ///===== IAccessibleViewForwarder ========================================
+
+ virtual sal_Bool IsValid (void) const;
+ virtual Rectangle GetVisibleArea() const;
+ virtual Point LogicToPixel (const Point& rPoint) const;
+ virtual Size LogicToPixel (const Size& rSize) const;
+ virtual Point PixelToLogic (const Point& rPoint) const;
+ virtual Size PixelToLogic (const Size& rSize) const;
+
+private:
+ ScPreviewShell* mpViewShell;
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ MapMode maMapMode;
+ sal_Bool mbValid;
+};
+
+ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
+ : mbValid(sal_False)
+{
+}
+
+ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
+ ScAccessibleDocumentPagePreview* pAccDoc,
+ const MapMode& aMapMode)
+ : mpViewShell(pViewShell),
+ mpAccDoc(pAccDoc),
+ maMapMode(aMapMode),
+ mbValid(sal_True)
+{
+}
+
+ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder()
+{
+}
+
+///===== IAccessibleViewForwarder ========================================
+
+sal_Bool ScIAccessibleViewForwarder::IsValid (void) const
+{
+ ScUnoGuard aGuard;
+ return mbValid;
+}
+
+Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const
+{
+ ScUnoGuard aGuard;
+ Rectangle aVisRect;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ {
+ aVisRect.SetSize(pWin->GetOutputSizePixel());
+ aVisRect.SetPos(Point(0, 0));
+
+ aVisRect = pWin->PixelToLogic(aVisRect, maMapMode);
+ }
+
+ return aVisRect;
+}
+
+Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ Point aPoint;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin && mpAccDoc)
+ {
+ Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
+ aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft();
+ }
+
+ return aPoint;
+}
+
+Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ Size aSize;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->LogicToPixel(rSize, maMapMode);
+ return aSize;
+}
+
+Point ScIAccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
+{
+ ScUnoGuard aGuard;
+ Point aPoint;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin && mpAccDoc)
+ {
+ Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
+ aPoint = pWin->PixelToLogic(rPoint - aRect.TopLeft(), maMapMode);
+ }
+ return aPoint;
+}
+
+Size ScIAccessibleViewForwarder::PixelToLogic (const Size& rSize) const
+{
+ ScUnoGuard aGuard;
+ Size aSize;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(rSize, maMapMode);
+ return aSize;
+}
+
+struct ScShapeChild
+{
+ ScShapeChild() : mpAccShape(NULL) {}
+ ScShapeChild(const ScShapeChild& rOld);
+ ~ScShapeChild();
+ mutable ::accessibility::AccessibleShape* mpAccShape;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape;
+ sal_Int32 mnRangeId;
+};
+
+ScShapeChild::ScShapeChild(const ScShapeChild& rOld)
+:
+mpAccShape(rOld.mpAccShape),
+mxShape(rOld.mxShape),
+mnRangeId(rOld.mnRangeId)
+{
+ if (mpAccShape)
+ mpAccShape->acquire();
+}
+
+ScShapeChild::~ScShapeChild()
+{
+ if (mpAccShape)
+ {
+ mpAccShape->dispose();
+ mpAccShape->release();
+ }
+}
+
+struct ScShapeChildLess
+{
+ sal_Bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const
+ {
+ sal_Bool bResult(sal_False);
+ if (rChild1.mxShape.is() && rChild2.mxShape.is())
+ bResult = (rChild1.mxShape.get() < rChild2.mxShape.get());
+ return bResult;
+ }
+};
+
+typedef std::vector<ScShapeChild> ScShapeChildVec;
+
+struct ScShapeRange
+{
+ ScShapeChildVec maBackShapes;
+ ScShapeChildVec maForeShapes; // inclusive internal shapes
+ ScShapeChildVec maControls;
+ Rectangle maPixelRect;
+ MapMode maMapMode;
+ ScIAccessibleViewForwarder maViewForwarder;
+};
+
+typedef std::vector<ScShapeRange> ScShapeRangeVec;
+
+class ScShapeChilds : public SfxListener,
+ public ::accessibility::IAccessibleParent
+{
+public:
+ ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
+ ~ScShapeChilds();
+
+ ///===== SfxListener =====================================================
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ ///===== IAccessibleParent ==============================================
+
+ virtual sal_Bool ReplaceChild (
+ ::accessibility::AccessibleShape* pCurrentChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
+ const long _nIndex,
+ const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
+ ) throw (::com::sun::star::uno::RuntimeException);
+
+ ///===== Internal ========================================================
+
+ void Init();
+
+ sal_Int32 GetBackShapeCount() const;
+ uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const;
+ sal_Int32 GetForeShapeCount() const;
+ uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const;
+ sal_Int32 GetControlCount() const;
+ uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const;
+ uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls
+ uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const;
+
+ void DataChanged();
+ void VisAreaChanged() const;
+
+ void SetDrawBroadcaster();
+private:
+ ScAccessibleDocumentPagePreview* mpAccDoc;
+ ScPreviewShell* mpViewShell;
+ ScShapeRangeVec maShapeRanges;
+
+ void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const;
+ void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const;
+ ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const;
+ ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const;
+ void FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId);
+//UNUSED2008-05 sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const;
+
+// void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
+// void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
+ SdrPage* GetDrawPage() const;
+};
+
+ScShapeChilds::ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
+ :
+ mpAccDoc(pAccDoc),
+ mpViewShell(pViewShell),
+ maShapeRanges(SC_PREVIEW_MAXRANGES)
+{
+ if (pViewShell)
+ {
+ SfxBroadcaster* pDrawBC = pViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+ }
+}
+
+ScShapeChilds::~ScShapeChilds()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ }
+}
+
+void ScShapeChilds::SetDrawBroadcaster()
+{
+ if (mpViewShell)
+ {
+ SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC, TRUE);
+ }
+}
+
+void ScShapeChilds::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if ( rHint.ISA( SdrHint ) )
+ {
+ const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if (pSdrHint)
+ {
+ SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
+ if (pObj && (pObj->GetPage() == GetDrawPage()))
+ {
+ switch (pSdrHint->GetKind())
+ {
+ case HINT_OBJCHG : // Objekt geaendert
+ {
+ }
+ break;
+ // no longer necessary
+/* case HINT_OBJINSERTED : // Neues Zeichenobjekt eingefuegt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ AddShape(xShape, pObj->GetLayer());
+ }
+ break;
+ case HINT_OBJREMOVED : // Zeichenobjekt aus Liste entfernt
+ {
+ uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ RemoveShape(xShape, pObj->GetLayer());
+ }
+ break;*/
+ default :
+ {
+ // other events are not interesting
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ScShapeChilds::FindChanged(ScShapeChildVec& rOld, ScShapeChildVec& rNew) const
+{
+ ScShapeChildVec::iterator aOldItr = rOld.begin();
+ ScShapeChildVec::iterator aOldEnd = rOld.end();
+ ScShapeChildVec::const_iterator aNewItr = rNew.begin();
+ ScShapeChildVec::const_iterator aNewEnd = rNew.begin();
+ uno::Reference<XAccessible> xAcc;
+ while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd))
+ {
+ if (aNewItr->mxShape.get() == aOldItr->mxShape.get())
+ {
+ ++aOldItr;
+ ++aNewItr;
+ }
+ else if (aNewItr->mxShape.get() < aOldItr->mxShape.get())
+ {
+ xAcc = GetAccShape(*aNewItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aNewItr;
+ }
+ else
+ {
+ xAcc = GetAccShape(*aOldItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aOldItr;
+ }
+ }
+ while (aOldItr != aOldEnd)
+ {
+ xAcc = GetAccShape(*aOldItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aOldItr;
+ }
+ while (aNewItr != aNewEnd)
+ {
+ xAcc = GetAccShape(*aNewItr);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ ++aNewItr;
+ }
+}
+
+void ScShapeChilds::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const
+{
+ FindChanged(rOld.maBackShapes, rNew.maBackShapes);
+ FindChanged(rOld.maForeShapes, rNew.maForeShapes);
+ FindChanged(rOld.maControls, rNew.maControls);
+}
+
+void ScShapeChilds::DataChanged()
+{
+ ScShapeRangeVec aOldShapeRanges(maShapeRanges);
+ maShapeRanges.clear();
+ maShapeRanges.resize(SC_PREVIEW_MAXRANGES);
+ Init();
+ for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i)
+ {
+ FindChanged(aOldShapeRanges[i], maShapeRanges[i]);
+ }
+}
+
+struct ScVisAreaChanged
+{
+ const ScIAccessibleViewForwarder* mpViewForwarder;
+ ScVisAreaChanged(const ScIAccessibleViewForwarder* pViewForwarder) : mpViewForwarder(pViewForwarder) {}
+ void operator() (const ScShapeChild& rAccShapeData) const
+ {
+ if (rAccShapeData.mpAccShape)
+ {
+ rAccShapeData.mpAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpViewForwarder);
+ }
+ }
+};
+
+void ScShapeChilds::VisAreaChanged() const
+{
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while (aItr != aEndItr)
+ {
+ ScVisAreaChanged aVisAreaChanged(&(aItr->maViewForwarder));
+ std::for_each(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), aVisAreaChanged);
+ std::for_each(aItr->maControls.begin(), aItr->maControls.end(), aVisAreaChanged);
+ std::for_each(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), aVisAreaChanged);
+ ++aItr;
+ }
+}
+
+ ///===== IAccessibleParent ==============================================
+
+sal_Bool ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape* /* pCurrentChild */,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& /* _rxShape */,
+ const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */)
+ throw (uno::RuntimeException)
+{
+ DBG_ERRORFILE("should not be called in the page preview");
+ return sal_False;
+}
+
+ ///===== Internal ========================================================
+
+void ScShapeChilds::Init()
+{
+ if(mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ MapMode aMapMode;
+ Rectangle aPixelPaintRect;
+ sal_uInt8 nRangeId;
+ sal_uInt16 nCount(rData.GetDrawRanges());
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
+ FillShapes(aPixelPaintRect, aMapMode, nRangeId);
+ }
+ }
+}
+
+sal_Int32 ScShapeChilds::GetBackShapeCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maBackShapes.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maBackShapes.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maBackShapes, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+sal_Int32 ScShapeChilds::GetForeShapeCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maForeShapes.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maForeShapes.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maForeShapes, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+sal_Int32 ScShapeChilds::GetControlCount() const
+{
+ sal_Int32 nCount(0);
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
+ nCount += aItr->maControls.size();
+ return nCount;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const
+{
+ uno::Reference<XAccessible> xAccessible;
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ while ((aItr != aEndItr) && !xAccessible.is())
+ {
+ sal_Int32 nCount(aItr->maControls.size());
+ if(nIndex < nCount)
+ xAccessible = GetAccShape(aItr->maControls, nIndex);
+ else
+ ++aItr;
+ nIndex -= nCount;
+ }
+
+ if (nIndex >= 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+struct ScShapePointFound
+{
+ Point maPoint;
+ ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
+ sal_Bool operator() (const ScShapeChild& rShape)
+ {
+ sal_Bool bResult(sal_False);
+ if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint))
+ bResult = sal_True;
+ return bResult;
+ }
+};
+
+uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
+{
+ uno::Reference<XAccessible> xAcc;
+
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ while((aItr != aEndItr) && !xAcc.is())
+ {
+ ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint));
+ if (aFindItr != aItr->maForeShapes.end())
+ xAcc = GetAccShape(*aFindItr);
+ else
+ {
+ ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint));
+ if (aCtrlItr != aItr->maControls.end())
+ xAcc = GetAccShape(*aCtrlItr);
+ else
+ ++aItr;
+ }
+ }
+
+ return xAcc;
+}
+
+uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const
+{
+ uno::Reference<XAccessible> xAcc;
+
+ ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
+ ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
+ while((aItr != aEndItr) && !xAcc.is())
+ {
+ ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint));
+ if (aFindItr != aItr->maBackShapes.end())
+ xAcc = GetAccShape(*aFindItr);
+ else
+ ++aItr;
+ }
+
+ return xAcc;
+}
+
+::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const
+{
+ if (!rShape.mpAccShape)
+ {
+ ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
+ ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this));
+
+ if (mpViewShell)
+ {
+ ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo;
+ aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
+ aShapeTreeInfo.SetController(NULL);
+ aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
+ aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
+ rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
+ if (rShape.mpAccShape)
+ {
+ rShape.mpAccShape->acquire();
+ rShape.mpAccShape->Init();
+ }
+ }
+ }
+ return rShape.mpAccShape;
+}
+
+::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const
+{
+ return (GetAccShape(rShapes[nIndex]));
+}
+
+void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
+{
+ DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
+ SdrPage* pPage = GetDrawPage();
+ Window* pWin = mpViewShell->GetWindow();
+ if (pPage && pWin)
+ {
+ sal_Bool bForeAdded(sal_False);
+ sal_Bool bBackAdded(sal_False);
+ sal_Bool bControlAdded(sal_False);
+ Rectangle aClippedPixelPaintRect(aPixelPaintRect);
+ if (mpAccDoc)
+ {
+ Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize());
+ aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
+ }
+ maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect;
+ maShapeRanges[nRangeId].maMapMode = aMapMode;
+ ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
+ maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
+ sal_uInt32 nCount(pPage->GetObjCount());
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ SdrObject* pObj = pPage->GetObj(i);
+ if (pObj)
+ {
+ uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode));
+ if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
+ {
+ ScShapeChild aShape;
+ aShape.mxShape = xShape;
+ aShape.mnRangeId = nRangeId;
+ switch (pObj->GetLayer())
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ maShapeRanges[nRangeId].maForeShapes.push_back(aShape);
+ bForeAdded = sal_True;
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ maShapeRanges[nRangeId].maBackShapes.push_back(aShape);
+ bBackAdded = sal_True;
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ maShapeRanges[nRangeId].maControls.push_back(aShape);
+ bControlAdded = sal_True;
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bForeAdded)
+ std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
+ if (bBackAdded)
+ std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
+ if (bControlAdded)
+ std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
+ }
+}
+
+//UNUSED2008-05 sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_Bool bResult(sal_False);
+//UNUSED2008-05 ScShapeChild aShape;
+//UNUSED2008-05 aShape.mxShape = xShape;
+//UNUSED2008-05 rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
+//UNUSED2008-05 if (rItr->mxShape.get() == xShape.get())
+//UNUSED2008-05 bResult = sal_True; // if the shape is found
+//UNUSED2008-05
+//UNUSED2008-05 /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
+//UNUSED2008-05 ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
+//UNUSED2008-05 DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
+//UNUSED2008-05 #endif*/
+//UNUSED2008-05 return bResult;
+//UNUSED2008-05 }
+
+/*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
+{
+ uno::Reference < XAccessible > xNew;
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ {
+ ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
+ sal_Bool bNotify(sal_False);
+ uno::Reference <XAccessible> xAcc;
+ while (aItr != aEndItr)
+ {
+ Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
+ Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
+ if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
+ {
+ ScShapeChild aShape;
+ aShape.mxShape = xShape;
+ switch (aLayerID)
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ SetAnchor(aShape);
+ aItr->maForeShapes.push_back(aShape);
+ std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());
+
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ aItr->maBackShapes.push_back(aShape);
+ std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ SetAnchor(aShape);
+ aItr->maControls.push_back(aShape);
+ std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ if (bNotify)
+ {
+ xAcc = GetAccShape(aShape);
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.NewValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ bNotify = sal_False;
+ }
+ xAcc = NULL;
+ }
+ ++aItr;
+ }
+ }
+}*/
+
+/*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
+{
+ sal_Bool bResult(sal_False);
+ if (aItr->mpAccShape)
+ {
+ bResult = sal_True;
+ xAcc = aItr->mpAccShape;
+ }
+ else
+ DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
+ return bResult;
+}*/
+
+/*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
+{
+ ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
+ ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
+ ScShapeChildVec::iterator aEraseItr;
+ sal_Bool bNotify(sal_False);
+ uno::Reference <XAccessible> xAcc;
+ while (aItr != aEndItr)
+ {
+ switch (aLayerID)
+ {
+ case SC_LAYER_INTERN:
+ case SC_LAYER_FRONT:
+ {
+ if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maForeShapes.erase(aEraseItr);
+ }
+ }
+ break;
+ case SC_LAYER_BACK:
+ {
+ if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maBackShapes.erase(aEraseItr);
+ }
+ }
+ break;
+ case SC_LAYER_CONTROLS:
+ {
+ if (FindShape(aItr->maControls, xShape, aEraseItr))
+ {
+ bNotify = HaveToNotify(xAcc, aEraseItr);
+ aItr->maControls.erase(aEraseItr);
+ }
+ }
+ break;
+ default:
+ {
+ DBG_ERRORFILE("I don't know this layer.");
+ }
+ break;
+ }
+ if (bNotify)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.OldValue <<= xAcc;
+ mpAccDoc->CommitChange(aEvent);
+ bNotify = sal_False;
+ }
+ xAcc = NULL;
+ ++aItr;
+ }
+}*/
+
+SdrPage* ScShapeChilds::GetDrawPage() const
+{
+ SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() );
+ SdrPage* pDrawPage = NULL;
+ if (mpViewShell)
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
+ }
+ }
+ return pDrawPage;
+}
+
+struct ScPagePreviewCountData
+{
+ // order is background shapes, header, table or notes, footer, foreground shapes, controls
+
+ Rectangle aVisRect;
+ long nBackShapes;
+ long nHeaders;
+ long nTables;
+ long nNoteParagraphs;
+ long nFooters;
+ long nForeShapes;
+ long nControls;
+
+ ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow,
+ ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds );
+
+ long GetTotal() const
+ {
+ return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
+ }
+};
+
+ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
+ Window* pSizeWindow, ScNotesChilds* pNotesChilds,
+ ScShapeChilds* pShapeChilds) :
+ nBackShapes( 0 ),
+ nHeaders( 0 ),
+ nTables( 0 ),
+ nNoteParagraphs( 0 ),
+ nFooters( 0 ),
+ nForeShapes( 0 ),
+ nControls( 0 )
+{
+ Size aOutputSize;
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ aVisRect = Rectangle( aPoint, aOutputSize );
+
+ Rectangle aObjRect;
+
+ if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
+ nHeaders = 1;
+
+ if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
+ nFooters = 1;
+
+ if ( rData.HasCellsInRange( aVisRect ) )
+ nTables = 1;
+
+ //! shapes...
+ nBackShapes = pShapeChilds->GetBackShapeCount();
+ nForeShapes = pShapeChilds->GetForeShapeCount();
+ nControls = pShapeChilds->GetControlCount();
+
+ // there are only notes if there is no table
+ if (nTables == 0)
+ nNoteParagraphs = pNotesChilds->GetChildsCount();
+}
+
+//===== internal ========================================================
+
+ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
+ const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
+ ScAccessibleDocumentBase(rxParent),
+ mpViewShell(pViewShell),
+ mpNotesChilds(NULL),
+ mpShapeChilds(NULL),
+ mpTable(NULL),
+ mpHeader(NULL),
+ mpFooter(NULL)
+{
+ if (pViewShell)
+ pViewShell->AddAccessibilityObject(*this);
+
+// GetNotesChilds(); not neccessary and reduces the creation performance
+// GetShapeChilds();
+}
+
+ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
+{
+ if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleDocumentPagePreview::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpTable)
+ {
+ mpTable->release();
+ mpTable = NULL;
+ }
+ if (mpHeader)
+ {
+ mpHeader->release();
+ mpHeader = NULL;
+ }
+ if (mpFooter)
+ {
+ mpFooter->release();
+ mpFooter = NULL;
+ }
+
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ // #100593# no need to Dispose the AccessibleTextHelper,
+ // as long as mpNotesChilds are destructed here
+ if (mpNotesChilds)
+ DELETEZ(mpNotesChilds);
+
+ if (mpShapeChilds)
+ DELETEZ(mpShapeChilds);
+
+ ScAccessibleDocumentBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change
+ {
+ {
+ uno::Reference<XAccessible> xAcc = mpTable;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= xAcc;
+ CommitChange(aEvent);
+ }
+
+ mpTable->dispose();
+ mpTable->release();
+ mpTable = NULL;
+ }
+
+ Size aOutputSize;
+ Window* pSizeWindow = mpViewShell->GetWindow();
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ GetNotesChilds()->DataChanged(aVisRect);
+
+ GetShapeChilds()->DataChanged();
+
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if (aCount.nTables > 0)
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+
+ {
+ uno::Reference<XAccessible> xAcc = mpTable;
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= xAcc;
+ CommitChange(aEvent);
+ }
+ }
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
+ {
+ GetShapeChilds()->SetDrawBroadcaster();
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ Size aOutputSize;
+ Window* pSizeWindow = mpViewShell->GetWindow();
+ if ( pSizeWindow )
+ aOutputSize = pSizeWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ GetNotesChilds()->DataChanged(aVisRect);
+
+ GetShapeChilds()->VisAreaChanged();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+ else if ( rHint.ISA(ScAccWinFocusLostHint) )
+ {
+ CommitFocusLost();
+ }
+ else if ( rHint.ISA(ScAccWinFocusGotHint) )
+ {
+ CommitFocusGained();
+ }
+ ScAccessibleDocumentBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xAccessible;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ( mpViewShell )
+ {
+ xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint);
+ if (!xAccessible.is())
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+/* if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
+ {
+ if ( !mpTable && (aCount.nTables > 0) )
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ xAccessible = mpTable;
+ }*/
+ if ( !mpTable && (aCount.nTables > 0) )
+ {
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint)))
+ xAccessible = mpTable;
+ }
+ if (!xAccessible.is())
+ xAccessible = GetNotesChilds()->GetAt(rPoint);
+ if (!xAccessible.is())
+ {
+ if (!mpHeader || !mpFooter)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if (!mpHeader)
+ {
+ mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1);
+ mpHeader->acquire();
+ }
+ if (!mpFooter)
+ {
+ mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
+ mpFooter->acquire();
+ }
+ }
+
+ Point aPoint(VCLPoint(rPoint));
+
+ if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint))
+ xAccessible = mpHeader;
+ else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint))
+ xAccessible = mpFooter;
+ }
+ if (!xAccessible.is())
+ xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint);
+ }
+ }
+
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ {
+ // just grab the focus for the window
+ xAccessibleComponent->grabFocus();
+ }
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ long nRet = 0;
+ if ( mpViewShell )
+ {
+ ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+ nRet = aCount.GetTotal();
+ }
+
+ return nRet;
+}
+
+uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference<XAccessible> xAccessible;
+
+ if ( mpViewShell )
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ if ( nIndex < aCount.nBackShapes )
+ {
+ xAccessible = GetShapeChilds()->GetBackShape(nIndex);
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
+ {
+ if ( !mpHeader )
+ {
+ mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex );
+ mpHeader->acquire();
+ }
+
+ xAccessible = mpHeader;
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
+ {
+ if ( !mpTable )
+ {
+ mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+ mpTable->acquire();
+ mpTable->Init();
+ }
+ xAccessible = mpTable;
+ }
+ else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
+ {
+ xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
+ }
+ else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) )
+ {
+ if ( !mpFooter )
+ {
+ mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex );
+ mpFooter->acquire();
+ }
+ xAccessible = mpFooter;
+ }
+ else
+ {
+ sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
+ if (nIdx < aCount.nForeShapes)
+ xAccessible = GetShapeChilds()->GetForeShape(nIdx);
+ else
+ xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes);
+ }
+ }
+
+ if ( !xAccessible.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xAccessible;
+}
+
+ /// Return the set of current states.
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ // never editable
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleDocumentPagePreview::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ========================================================
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR));
+ return sDescription;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME));
+ return sName;
+}
+
+Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessibleDocumentPagePreview::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds()
+{
+ if (!mpNotesChilds && mpViewShell)
+ {
+ mpNotesChilds = new ScNotesChilds(mpViewShell, this);
+
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+
+ //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+ mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
+ }
+ return mpNotesChilds;
+}
+
+ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds()
+{
+ if (!mpShapeChilds && mpViewShell)
+ {
+ mpShapeChilds = new ScShapeChilds(mpViewShell, this);
+ mpShapeChilds->Init();
+ }
+
+ return mpShapeChilds;
+}
+
+//UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
+//UNUSED2009-05 {
+//UNUSED2009-05 if (!mpTable)
+//UNUSED2009-05 {
+//UNUSED2009-05 if ( mpViewShell )
+//UNUSED2009-05 {
+//UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+//UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+//UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+//UNUSED2009-05 sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05
+//UNUSED2009-05 mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
+//UNUSED2009-05 mpTable->acquire();
+//UNUSED2009-05 mpTable->Init();
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 return mpTable;
+//UNUSED2009-05 }
+
+//UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
+//UNUSED2009-05 {
+//UNUSED2009-05 if (mpViewShell)
+//UNUSED2009-05 {
+//UNUSED2009-05 const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+//UNUSED2009-05 ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
+//UNUSED2009-05 //! order is background shapes, header, table or notes, footer, foreground shapes, controls
+//UNUSED2009-05 if(mpHeader)
+//UNUSED2009-05 mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
+//UNUSED2009-05 if (mpTable)
+//UNUSED2009-05 mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05 if (mpFooter)
+//UNUSED2009-05 mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
+//UNUSED2009-05
+//UNUSED2009-05 if (mpNotesChilds)
+//UNUSED2009-05 mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);
+//UNUSED2009-05 }
+//UNUSED2009-05 }
diff --git a/sc/source/ui/Accessibility/AccessibleEditObject.cxx b/sc/source/ui/Accessibility/AccessibleEditObject.cxx
new file mode 100644
index 000000000000..fd7cbaf454c1
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleEditObject.cxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "AccessibleEditObject.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include "unoguard.hxx"
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+#include <svx/svdmodel.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleEditObject::ScAccessibleEditObject(
+ const uno::Reference<XAccessible>& rxParent,
+ EditView* pEditView, Window* pWin, const rtl::OUString& rName,
+ const rtl::OUString& rDescription, EditObjectType eObjectType)
+ :
+ ScAccessibleContextBase(rxParent, AccessibleRole::TEXT_FRAME),
+ mpTextHelper(NULL),
+ mpEditView(pEditView),
+ mpWindow(pWin),
+ meObjectType(eObjectType),
+ mbHasFocus(sal_False)
+{
+ CreateTextHelper();
+ SetName(rName);
+ SetDescription(rDescription);
+}
+
+ScAccessibleEditObject::~ScAccessibleEditObject()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessibleEditObject::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+
+ ScAccessibleContextBase::disposing();
+}
+
+void ScAccessibleEditObject::LostFocus()
+{
+ mbHasFocus = sal_False;
+ if (mpTextHelper)
+ mpTextHelper->SetFocus(sal_False);
+ CommitFocusLost();
+}
+
+void ScAccessibleEditObject::GotFocus()
+{
+ mbHasFocus = sal_True;
+ CommitFocusGained();
+ if (mpTextHelper)
+ mpTextHelper->SetFocus(sal_True);
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aScreenBounds;
+
+ if ( mpWindow )
+ {
+ if ( meObjectType == CellInEditMode )
+ {
+ if ( mpEditView && mpEditView->GetEditEngine() )
+ {
+ MapMode aMapMode( mpEditView->GetEditEngine()->GetRefMapMode() );
+ aScreenBounds = mpWindow->LogicToPixel( mpEditView->GetOutputArea(), aMapMode );
+ Point aCellLoc = aScreenBounds.TopLeft();
+ Rectangle aWindowRect = mpWindow->GetWindowExtentsRelative( NULL );
+ Point aWindowLoc = aWindowRect.TopLeft();
+ Point aPos( aCellLoc.getX() + aWindowLoc.getX(), aCellLoc.getY() + aWindowLoc.getY() );
+ aScreenBounds.SetPos( aPos );
+ }
+ }
+ else
+ {
+ aScreenBounds = mpWindow->GetWindowExtentsRelative( NULL );
+ }
+ }
+
+ return aScreenBounds;
+}
+
+Rectangle ScAccessibleEditObject::GetBoundingBox(void) const
+ throw (uno::RuntimeException)
+{
+ Rectangle aBounds( GetBoundingBoxOnScreen() );
+
+ if ( mpWindow )
+ {
+ uno::Reference< XAccessible > xThis( mpWindow->GetAccessible() );
+ if ( xThis.is() )
+ {
+ uno::Reference< XAccessibleContext > xContext( xThis->getAccessibleContext() );
+ if ( xContext.is() )
+ {
+ uno::Reference< XAccessible > xParent( xContext->getAccessibleParent() );
+ if ( xParent.is() )
+ {
+ uno::Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
+ if ( xParentComponent.is() )
+ {
+ Point aScreenLoc = aBounds.TopLeft();
+ awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen();
+ Point aPos( aScreenLoc.getX() - aParentScreenLoc.X, aScreenLoc.getY() - aParentScreenLoc.Y );
+ aBounds.SetPos( aPos );
+ }
+ }
+ }
+ }
+ }
+
+ return aBounds;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleEditObject::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleEditObject::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ // all states are const, because this object exists only in one state
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::SENSITIVE);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleEditObject::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+// DBG_ERRORFILE("Should never be called, because is set in the constructor.")
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleEditObject::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERRORFILE("Should never be called, because is set in the constructor.");
+ return rtl::OUString();
+}
+
+ ///===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL
+ ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (!mpTextHelper)
+ CreateTextHelper();
+
+ mpTextHelper->AddEventListener(xListener);
+
+ ScAccessibleContextBase::addEventListener(xListener);
+}
+
+void SAL_CALL
+ ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ if (!mpTextHelper)
+ CreateTextHelper();
+
+ mpTextHelper->RemoveEventListener(xListener);
+
+ ScAccessibleContextBase::removeEventListener(xListener);
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject"));
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleEditObject::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+ //==== internal =========================================================
+
+sal_Bool ScAccessibleEditObject::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessibleEditObject::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData;
+ if (meObjectType == CellInEditMode || meObjectType == EditControl)
+ {
+ pAccessibleTextData.reset
+ (new ScAccessibleEditObjectTextData(mpEditView, mpWindow));
+ }
+ else
+ {
+ pAccessibleTextData.reset
+ (new ScAccessibleEditLineTextData(NULL, mpWindow));
+ }
+
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ mpTextHelper->SetFocus(mbHasFocus);
+
+ // #i54814# activate cell in edit mode
+ if( meObjectType == CellInEditMode )
+ {
+ // do not activate cell object, if top edit line is active
+ const ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if( pInputHdl && !pInputHdl->IsTopMode() )
+ {
+ SdrHint aHint( HINT_BEGEDIT );
+ mpTextHelper->GetEditSource().GetBroadcaster().Broadcast( aHint );
+ }
+ }
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
new file mode 100644
index 000000000000..02fb5c12463e
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
@@ -0,0 +1,398 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "unoguard.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+
+#include "tools/gen.hxx"
+#include "editeng/unoedsrc.hxx"
+#include "editeng/editdata.hxx"
+#include "editeng/outliner.hxx"
+#include "vcl/unohelp.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+using ::std::for_each;
+using ::std::vector;
+
+// ============================================================================
+
+namespace {
+
+class AddRemoveEventListener : public ::std::unary_function<void, Reference<XAccessible> >
+{
+public:
+ explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) :
+ mxListener(rListener), mbAdd(bAdd) {}
+
+ void operator() (const Reference<XAccessible>& xAccessible) const
+ {
+ if (!xAccessible.is())
+ return;
+
+ Reference<XAccessibleEventBroadcaster> xBc(xAccessible, UNO_QUERY);
+ if (xBc.is())
+ {
+ if (mbAdd)
+ xBc->addEventListener(mxListener);
+ else
+ xBc->removeEventListener(mxListener);
+ }
+ }
+private:
+ Reference<XAccessibleEventListener> mxListener;
+ bool mbAdd;
+};
+
+}
+
+// ============================================================================
+
+ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos, ScDocument* pDoc) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU),
+ mnMenuPos(nMenuPos),
+ mpWindow(pWin),
+ mpDoc(pDoc),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
+{
+}
+
+// XAccessibleComponent
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& /*rPoint*/ )
+ throw (RuntimeException)
+{
+ return this;
+}
+
+sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException)
+{
+ return mpWindow->IsVisible();
+}
+
+void ScAccessibleFilterMenu::grabFocus()
+ throw (RuntimeException)
+{
+}
+
+sal_Int32 ScAccessibleFilterMenu::getForeground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getBackground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+// XAccessibleContext
+
+OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException)
+{
+ return ScAccessibleContextBase::getAccessibleName();
+}
+
+sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return getMenuItemCount();
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (maMenuItems.size() <= static_cast<size_t>(nIndex))
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nIndex];
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStates();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenu::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenu");
+}
+
+// XAccessibleEventBroadcaster
+
+void ScAccessibleFilterMenu::addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::addEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true));
+}
+
+void ScAccessibleFilterMenu::removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::removeEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false));
+}
+
+// XAccessibleSelection
+
+void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->setSelectedMenuItem(nChildIndex, false, true);
+}
+
+sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return mpWindow->isMenuItemSelected(static_cast<size_t>(nChildIndex));
+}
+
+void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException)
+{
+ mpWindow->clearSelectedMenuItem();
+}
+
+void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException)
+{
+ // not suported - this is a menu, you can't select all menu items.
+}
+
+sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException)
+{
+ // Since this is a menu, either one menu item is selected, or none at all.
+ return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nChildIndex];
+}
+
+void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->selectMenuItem(nChildIndex, false, false);
+}
+
+// XInterface
+
+uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenu_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenu::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenu::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+// XTypeProvider
+
+Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int8> aId(16);
+ return aId;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos)
+{
+ // Check weather this menu item is a sub menu or a regular menu item.
+ ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos);
+ Reference<XAccessible> xAccessible;
+ if (pSubMenu)
+ {
+ xAccessible = pSubMenu->CreateAccessible();
+ ScAccessibleFilterMenu* p =
+ static_cast<ScAccessibleFilterMenu*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ p->setMenuPos(nMenuPos);
+ }
+ else
+ {
+ xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos));
+ ScAccessibleFilterMenuItem* p =
+ static_cast<ScAccessibleFilterMenuItem*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ }
+ maMenuItems.push_back(xAccessible);
+}
+
+void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos)
+{
+ mnMenuPos = nMenuPos;
+}
+
+void ScAccessibleFilterMenu::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const
+{
+ return maMenuItems.size();
+}
+
+bool ScAccessibleFilterMenu::isSelected() const
+{
+ // Check to see if any of the child menu items is selected.
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenu::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenu::updateStates()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
new file mode 100644
index 000000000000..0da1e6858a75
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/TextSegment.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem(
+ const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM),
+ mpWindow(pWin),
+ maName(rName),
+ mnMenuPos(nMenuPos),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem()
+{
+}
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ throw IndexOutOfBoundsException();
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStateSet();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenuItem::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenuItem");
+}
+
+// XAccessibleAction
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException)
+{
+ return 1;
+}
+
+sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ mpWindow->executeMenuItem(mnMenuPos);
+ return true;
+}
+
+OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return OUString::createFromAscii("click");
+}
+
+Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding(
+ sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return Reference<XAccessibleKeyBinding>();
+}
+
+Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenuItem_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+bool ScAccessibleFilterMenuItem::isSelected() const
+{
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenuItem::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenuItem::updateStateSet()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
new file mode 100644
index 000000000000..2af69faa33c8
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleFilterTopWindow.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow(
+ const Reference<XAccessible>& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) :
+ ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED, pDoc),
+ mpWindow(pWin),
+ mpDoc(pDoc)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow()
+{
+}
+
+// XAccessibleContext
+
+sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException)
+{
+ sal_Int32 nMenuCount = getMenuItemCount();
+ return nMenuCount + 6;
+}
+
+Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild(
+ sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (nIndex >= getAccessibleChildCount())
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nMenuCount = getMenuItemCount();
+ if (nIndex < nMenuCount)
+ return ScAccessibleFilterMenu::getAccessibleChild(nIndex);
+
+ nIndex -= nMenuCount;
+ switch (nIndex)
+ {
+ case 0:
+ return mxAccListBox;
+ case 1:
+ return mxAccToggleAll;
+ case 2:
+ return mxAccSingleOnBtn;
+ case 3:
+ return mxAccSingleOffBtn;
+ case 4:
+ return mxAccOkBtn;
+ case 5:
+ return mxAccCancelBtn;
+ default:
+ ;
+ }
+
+ return Reference<XAccessible>();
+}
+
+OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterTopWindow");
+}
+
+void ScAccessibleFilterTopWindow::setAccessibleChild(
+ const Reference<XAccessible>& rAccessible, ChildControlType eType)
+{
+ switch (eType)
+ {
+ case LISTBOX:
+ mxAccListBox = rAccessible;
+ break;
+ case TOGGLE_ALL:
+ mxAccToggleAll = rAccessible;
+ break;
+ case SINGLE_ON_BTN:
+ mxAccSingleOnBtn = rAccessible;
+ break;
+ case SINGLE_OFF_BTN:
+ mxAccSingleOffBtn = rAccessible;
+ break;
+ case OK_BTN:
+ mxAccOkBtn = rAccessible;
+ break;
+ case CANCEL_BTN:
+ mxAccCancelBtn = rAccessible;
+ break;
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleGlobal.cxx b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
new file mode 100644
index 000000000000..ac2562fa9bd5
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::std::set;
+
+ScAccessibleStateSet::ScAccessibleStateSet()
+{
+}
+
+ScAccessibleStateSet::~ScAccessibleStateSet()
+{
+}
+
+// XAccessibleStateSet
+
+sal_Bool SAL_CALL ScAccessibleStateSet::isEmpty() throw (RuntimeException)
+{
+ return maStates.empty();
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::contains(sal_Int16 nState)
+ throw (RuntimeException)
+{
+ return maStates.count(nState) != 0;
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::containsAll(
+ const Sequence<sal_Int16>& aStateSet) throw (RuntimeException)
+{
+ sal_Int32 n = aStateSet.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ if (!maStates.count(aStateSet[i]))
+ // This state is not set.
+ return false;
+ }
+ // All specified states are set.
+ return true;
+}
+
+Sequence<sal_Int16> SAL_CALL ScAccessibleStateSet::getStates()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int16> aSeq(0);
+ set<sal_Int16>::const_iterator itr = maStates.begin(), itrEnd = maStates.end();
+ for (size_t i = 0; itr != itrEnd; ++itr, ++i)
+ {
+ aSeq.realloc(i+1);
+ aSeq[i] = *itr;
+ }
+ return aSeq;
+}
+
+void ScAccessibleStateSet::insert(sal_Int16 nState)
+{
+ maStates.insert(nState);
+}
+
+void ScAccessibleStateSet::clear()
+{
+ maStates.clear();
+}
+
diff --git a/sc/source/ui/Accessibility/AccessiblePageHeader.cxx b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
new file mode 100644
index 000000000000..6c28d22b0236
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
@@ -0,0 +1,441 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "AccessiblePageHeader.hxx"
+#include "AccessiblePageHeaderArea.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <svl/style.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/editobj.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+const sal_uInt8 MAX_AREAS = 3;
+
+//===== internal ============================================================
+struct Acquire
+{
+ void operator() (ScAccessiblePageHeaderArea* pArea)
+ {
+ if (pArea)
+ pArea->acquire();
+ }
+};
+
+struct Release
+{
+ void operator() (ScAccessiblePageHeaderArea*& pArea)
+ {
+ if (pArea)
+ pArea->release();
+ }
+};
+
+struct Dispose
+{
+ void operator() (ScAccessiblePageHeaderArea*& pArea)
+ {
+ if (pArea)
+ {
+ pArea->dispose();
+ pArea->release();
+ }
+ pArea = NULL;
+ }
+};
+
+ScAccessiblePageHeader::ScAccessiblePageHeader( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Bool bHeader, sal_Int32 nIndex ) :
+ScAccessibleContextBase( rxParent, bHeader ? AccessibleRole::HEADER : AccessibleRole::FOOTER ),
+ mpViewShell( pViewShell ),
+ mnIndex( nIndex ),
+ mbHeader( bHeader ),
+ maAreas(MAX_AREAS, NULL),
+ mnChildCount(-1)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePageHeader::~ScAccessiblePageHeader()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePageHeader::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ std::for_each(maAreas.begin(), maAreas.end(), Dispose());
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePageHeader::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ ScHFAreas aOldAreas(maAreas);
+ std::for_each(aOldAreas.begin(), aOldAreas.end(), Acquire());
+ mnChildCount = -1;
+ getAccessibleChildCount();
+ for (sal_uInt8 i = 0; i < MAX_AREAS; ++i)
+ {
+ if ((aOldAreas[i] && maAreas[i] && !ScGlobal::EETextObjEqual(aOldAreas[i]->GetEditTextObject(), maAreas[i]->GetEditTextObject())) ||
+ (aOldAreas[i] && !maAreas[i]) || (!aOldAreas[i] && maAreas[i]))
+ {
+ if (aOldAreas[i] && aOldAreas[i]->GetEditTextObject())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue = uno::makeAny(uno::Reference<XAccessible>(aOldAreas[i]));
+
+ CommitChange(aEvent); // child gone - event
+ aOldAreas[i]->dispose();
+ }
+ if (maAreas[i] && maAreas[i]->GetEditTextObject())
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::CHILD;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue = uno::makeAny(uno::Reference<XAccessible>(maAreas[i]));
+
+ CommitChange(aEvent); // new child - event
+ }
+ }
+ }
+ std::for_each(aOldAreas.begin(), aOldAreas.end(), Release());
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+
+ if (containsPoint(aPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ sal_Int32 nCount(getAccessibleChildCount()); // fill the areas
+
+ if (nCount)
+ {
+ // return the first with content, because they have all the same Bounding Box
+ sal_uInt8 i(0);
+ while(!xRet.is() && i < MAX_AREAS)
+ {
+ if (maAreas[i])
+ xRet = maAreas[i];
+ else
+ ++i;
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePageHeader::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleChildCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if((mnChildCount < 0) && mpViewShell)
+ {
+ mnChildCount = 0;
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ if (pDoc)
+ {
+ // find out how many regions (left,center, right) are with content
+
+ SfxStyleSheetBase* pStyle = pDoc->GetStyleSheetPool()->Find(pDoc->GetPageStyle(mpViewShell->GetLocationData().GetPrintTab()), SFX_STYLE_FAMILY_PAGE);
+ if (pStyle)
+ {
+ sal_uInt16 nPageWhichId(0);
+ if (mbHeader)
+ nPageWhichId = mpViewShell->GetLocationData().IsHeaderLeft() ? ATTR_PAGE_HEADERLEFT : ATTR_PAGE_HEADERRIGHT;
+ else
+ nPageWhichId = mpViewShell->GetLocationData().IsFooterLeft() ? ATTR_PAGE_FOOTERLEFT : ATTR_PAGE_FOOTERRIGHT;
+
+ const ScPageHFItem& rPageItem = static_cast<const ScPageHFItem&>(pStyle->GetItemSet().Get(nPageWhichId));
+ AddChild(rPageItem.GetLeftArea(), 0, SVX_ADJUST_LEFT);
+ AddChild(rPageItem.GetCenterArea(), 1, SVX_ADJUST_CENTER);
+ AddChild(rPageItem.GetRightArea(), 2, SVX_ADJUST_RIGHT);
+ }
+ }
+ }
+
+ return mnChildCount;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleChild( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ uno::Reference<XAccessible> xRet;
+
+ if(mnChildCount < 0)
+ getAccessibleChildCount();
+
+ ScHFAreas::iterator aItr = maAreas.begin();
+ ScHFAreas::iterator aEndItr = maAreas.end();
+ while (!xRet.is() && (nIndex >= 0) && (aItr != aEndItr))
+ {
+ if (*aItr)
+ {
+ if (nIndex == 0)
+ xRet = *aItr;
+ else
+ --nIndex;
+ }
+ else
+ ++aItr;
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePageHeader::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePageHeader::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePageHeader"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePageHeader::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleHeaderFooterView"));
+
+ return aSequence;
+}
+
+//==== internal =========================================================
+
+::rtl::OUString SAL_CALL ScAccessiblePageHeader::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(mbHeader ? STR_ACC_HEADER_DESCR : STR_ACC_FOOTER_DESCR));
+ sDesc.SearchAndReplaceAscii("%1", String(ScResId(SCSTR_UNKNOWN)));
+ return rtl::OUString( sDesc );
+}
+
+::rtl::OUString SAL_CALL ScAccessiblePageHeader::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(mbHeader ? STR_ACC_HEADER_NAME : STR_ACC_FOOTER_NAME));
+ sName.SearchAndReplaceAscii("%1", String(ScResId(SCSTR_UNKNOWN)));
+ return rtl::OUString( sName );
+}
+
+Rectangle ScAccessiblePageHeader::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePageHeader::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ if ( mbHeader )
+ rData.GetHeaderPosition( aRect );
+ else
+ rData.GetFooterPosition( aRect );
+
+ // the Rectangle could contain negative coordinates so it should be cliped
+ Rectangle aClipRect(Point(0, 0), aRect.GetSize());
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ aClipRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
+ aRect = aClipRect.GetIntersection(aRect);
+ }
+ if (aRect.IsEmpty())
+ aRect.SetSize(Size(-1, -1));
+
+ return aRect;
+}
+
+sal_Bool ScAccessiblePageHeader::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePageHeader::AddChild(const EditTextObject* pArea, sal_uInt32 nIndex, SvxAdjust eAdjust)
+{
+ if (pArea && (pArea->GetText(0).Len() || (pArea->GetParagraphCount() > 1)))
+ {
+ if (maAreas[nIndex])
+ {
+ if (!ScGlobal::EETextObjEqual(maAreas[nIndex]->GetEditTextObject(), pArea))
+ {
+ maAreas[nIndex]->release();
+ maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
+ maAreas[nIndex]->acquire();
+ }
+ }
+ else
+ {
+ maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
+ maAreas[nIndex]->acquire();
+ }
+ ++mnChildCount;
+ }
+ else
+ {
+ if (maAreas[nIndex])
+ {
+ maAreas[nIndex]->release();
+ maAreas[nIndex] = NULL;
+ }
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx b/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx
new file mode 100644
index 000000000000..10c6a9eff13f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <tools/gen.hxx>
+#include "AccessiblePageHeaderArea.hxx"
+#include "AccessibleText.hxx"
+#include "AccessibilityHints.hxx"
+#include "unoguard.hxx"
+#include "editsrc.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <editeng/editobj.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <rtl/uuid.h>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+ //===== internal ========================================================
+
+ScAccessiblePageHeaderArea::ScAccessiblePageHeaderArea(
+ const uno::Reference<XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj,
+ sal_Bool bHeader,
+ SvxAdjust eAdjust)
+ : ScAccessibleContextBase(rxParent, AccessibleRole::TEXT),
+ mpEditObj(pEditObj->Clone()),
+ mpTextHelper(NULL),
+ mpViewShell(pViewShell),
+ mbHeader(bHeader),
+ meAdjust(eAdjust)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePageHeaderArea::~ScAccessiblePageHeaderArea(void)
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePageHeaderArea::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+ if (mpEditObj)
+ DELETEZ(mpEditObj);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePageHeaderArea::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeaderArea::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessiblePageHeaderArea::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc())
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ========================================================
+
+::rtl::OUString SAL_CALL
+ ScAccessiblePageHeaderArea::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessiblePageHeaderArea"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessiblePageHeaderArea::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessiblePageHeaderFooterAreasView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePageHeaderArea::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//===== internal ==============================================================
+rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleDescription(void)
+ throw(uno::RuntimeException)
+{
+ rtl::OUString sDesc;
+ switch (meAdjust)
+ {
+ case SVX_ADJUST_LEFT :
+ sDesc = String(ScResId(STR_ACC_LEFTAREA_DESCR));
+ break;
+ case SVX_ADJUST_RIGHT:
+ sDesc = String(ScResId(STR_ACC_RIGHTAREA_DESCR));
+ break;
+ case SVX_ADJUST_CENTER:
+ sDesc = String(ScResId(STR_ACC_CENTERAREA_DESCR));
+ break;
+ default:
+ DBG_ERRORFILE("wrong adjustment found");
+ }
+
+ return sDesc;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sName;
+ switch (meAdjust)
+ {
+ case SVX_ADJUST_LEFT :
+ sName = String(ScResId(STR_ACC_LEFTAREA_NAME));
+ break;
+ case SVX_ADJUST_RIGHT:
+ sName = String(ScResId(STR_ACC_RIGHTAREA_NAME));
+ break;
+ case SVX_ADJUST_CENTER:
+ sName = String(ScResId(STR_ACC_CENTERAREA_NAME));
+ break;
+ default:
+ DBG_ERRORFILE("wrong adjustment found");
+ }
+
+ return sName;
+}
+
+Rectangle ScAccessiblePageHeaderArea::GetBoundingBoxOnScreen(void) const
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ // has the same size and position on screen like the parent
+ aRect = Rectangle(VCLPoint(xComp->getLocationOnScreen()), VCLRectangle(xComp->getBounds()).GetSize());
+ }
+ }
+ return aRect;
+}
+
+Rectangle ScAccessiblePageHeaderArea::GetBoundingBox(void) const
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ // has the same size and position on screen like the parent and so the pos is (0, 0)
+ Rectangle aNewRect(Point(0, 0), VCLRectangle(xComp->getBounds()).GetSize());
+ aRect = aNewRect;
+ }
+ }
+
+ return aRect;
+}
+
+void ScAccessiblePageHeaderArea::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessibleHeaderTextData
+ (new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleHeaderTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx b/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx
new file mode 100644
index 000000000000..c07eb0844b7f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewCell.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <tools/gen.hxx>
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include "AccessiblePreviewCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "prevloc.hxx"
+#include "document.hxx"
+#include <svx/AccessibleTextHelper.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <editeng/brshitem.hxx>
+#include <vcl/window.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewCell::ScAccessiblePreviewCell( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, /* const */ ScAddress& rCellAddress,
+ sal_Int32 nIndex ) :
+ ScAccessibleCellBase( rxParent, ( pViewShell ? pViewShell->GetDocument() : NULL ), rCellAddress, nIndex ),
+ mpViewShell( pViewShell ),
+ mpTextHelper(NULL)
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewCell::~ScAccessiblePreviewCell()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ // call dispose to inform object wich have a weak reference to this object
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePreviewCell::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTextHelper)
+ DELETEZ(mpTextHelper);
+
+ ScAccessibleCellBase::disposing();
+}
+
+void ScAccessiblePreviewCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewCell::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewCell::getAccessibleChildCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewCell::getAccessibleStateSet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (IsOpaque(xParentStates))
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ // #111635# MANAGES_DESCENDANTS (for paragraphs)
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewCell::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewCell"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewCell::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePreviewCell::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+Rectangle ScAccessiblePreviewCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect );
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewCell::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+ if (mpViewShell)
+ {
+ mpViewShell->GetLocationData().GetCellPosition( maCellAddress, aCellRect );
+ uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewCell*>(this)->getAccessibleParent();
+ if (xAccParent.is())
+ {
+ uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
+ if (xAccParentComp.is())
+ {
+ Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
+ aCellRect.setX(aCellRect.getX() - aParentRect.getX());
+ aCellRect.setY(aCellRect.getY() - aParentRect.getY());
+ }
+ }
+ }
+ return aCellRect;
+}
+
+sal_Bool ScAccessiblePreviewCell::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessiblePreviewCell::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ return sal_False;
+}
+
+sal_Bool ScAccessiblePreviewCell::IsOpaque(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ // test whether there is a background color
+ //! could be moved to ScAccessibleCellBase
+
+ sal_Bool bOpaque(sal_True);
+ if (mpDoc)
+ {
+ const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr(
+ maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_BACKGROUND);
+ if (pItem)
+ bOpaque = pItem->GetColor() != COL_TRANSPARENT;
+ }
+ return bOpaque;
+}
+
+void ScAccessiblePreviewCell::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewCellTextData
+ (new ScAccessiblePreviewCellTextData(mpViewShell, maCellAddress));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewCellTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
+ mpTextHelper->SetEventSource( this );
+
+ // #111635# paragraphs in preview are transient
+ ::accessibility::AccessibleTextHelper::VectorOfStates aChildStates;
+ aChildStates.push_back( AccessibleStateType::TRANSIENT );
+ mpTextHelper->SetAdditionalChildStates( aChildStates );
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx b/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx
new file mode 100644
index 000000000000..3bb66ae01d4f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewHeaderCell.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <tools/gen.hxx>
+#include "AccessibleText.hxx"
+#include "editsrc.hxx"
+#include <svx/AccessibleTextHelper.hxx>
+#include "AccessiblePreviewHeaderCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <comphelper/sequence.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewHeaderCell::ScAccessiblePreviewHeaderCell( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell,
+ const ScAddress& rCellPos, sal_Bool bIsColHdr, sal_Bool bIsRowHdr,
+ sal_Int32 nIndex ) :
+ ScAccessibleContextBase( rxParent, AccessibleRole::TABLE_CELL ),
+ mpViewShell( pViewShell ),
+ mpTextHelper( NULL ),
+ mnIndex( nIndex ),
+ maCellPos( rCellPos ),
+ mbColumnHeader( bIsColHdr ),
+ mbRowHeader( bIsRowHdr ),
+ mpTableInfo( NULL )
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewHeaderCell::~ScAccessiblePreviewHeaderCell()
+{
+ if (mpViewShell)
+ mpViewShell->RemoveAccessibilityObject(*this);
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTableInfo)
+ DELETEZ (mpTableInfo);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePreviewHeaderCell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ ULONG nId = rRef.GetId();
+ if (nId == SC_HINT_ACC_VISAREACHANGED)
+ {
+ if (mpTextHelper)
+ mpTextHelper->UpdateChildren();
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // column / row layout may change with any document change,
+ // so it must be invalidated
+ DELETEZ( mpTableInfo );
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessiblePreviewHeaderCellImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+//===== XAccessibleValue ================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getCurrentValue() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ double fValue(0.0);
+ if (mbColumnHeader)
+ fValue = maCellPos.Col();
+ else
+ fValue = maCellPos.Row();
+
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewHeaderCell::setCurrentValue( const uno::Any& /* aNumber */ )
+ throw (uno::RuntimeException)
+{
+ // it is not possible to set a value
+ return sal_False;
+}
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMaximumValue() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ double fValue(0.0);
+ if (mbColumnHeader)
+ fValue = MAXCOL;
+ else
+ fValue = MAXROW;
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+uno::Any SAL_CALL ScAccessiblePreviewHeaderCell::getMinimumValue() throw (uno::RuntimeException)
+{
+ double fValue(0.0);
+ uno::Any aAny;
+ aAny <<= fValue;
+ return aAny;
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleAtPoint( const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if(!mpTextHelper)
+ CreateTextHelper();
+
+ xRet = mpTextHelper->GetAt(rPoint);
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewHeaderCell::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChildCount() throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (!mpTextHelper)
+ CreateTextHelper();
+ return mpTextHelper->GetChild(nIndex);
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessiblePreviewHeaderCell::getAccessibleStateSet()
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::MULTI_LINE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ pStateSet->AddState(AccessibleStateType::TRANSIENT);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewHeaderCell"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewHeaderCell::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleCellView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewHeaderCell::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessiblePreviewHeaderCellImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessiblePreviewHeaderCell::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect;
+
+ FillTableInfo();
+
+ if (mpTableInfo)
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
+
+ aCellRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ }
+
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewHeaderCell::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ FillTableInfo();
+
+ if (mpTableInfo)
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[maCellPos.Col()];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[maCellPos.Row()];
+
+ Rectangle aCellRect( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ uno::Reference<XAccessible> xAccParent = const_cast<ScAccessiblePreviewHeaderCell*>(this)->getAccessibleParent();
+ if (xAccParent.is())
+ {
+ uno::Reference<XAccessibleContext> xAccParentContext = xAccParent->getAccessibleContext();
+ uno::Reference<XAccessibleComponent> xAccParentComp (xAccParentContext, uno::UNO_QUERY);
+ if (xAccParentComp.is())
+ {
+ Rectangle aParentRect (VCLRectangle(xAccParentComp->getBounds()));
+ aCellRect.setX(aCellRect.getX() - aParentRect.getX());
+ aCellRect.setY(aCellRect.getY() - aParentRect.getY());
+ }
+ }
+ return aCellRect;
+ }
+ return Rectangle();
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleDescription() throw(uno::RuntimeException)
+{
+ rtl::OUString sDescription = String(ScResId(STR_ACC_HEADERCELL_DESCR));
+ return sDescription;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewHeaderCell::createAccessibleName() throw(uno::RuntimeException)
+{
+ rtl::OUString sName = String(ScResId(STR_ACC_HEADERCELL_NAME));
+
+ if ( mbColumnHeader )
+ {
+ if ( mbRowHeader )
+ {
+ //! name for corner cell?
+
+// sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column/Row Header"));
+ }
+ else
+ {
+ // name of column header
+ sName += ScColToAlpha( maCellPos.Col() );
+ }
+ }
+ else
+ {
+ // name of row header
+ sName += rtl::OUString::valueOf( (sal_Int32) ( maCellPos.Row() + 1 ) );
+ }
+
+ return sName;
+}
+
+sal_Bool ScAccessiblePreviewHeaderCell::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePreviewHeaderCell::CreateTextHelper()
+{
+ if (!mpTextHelper)
+ {
+ ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
+ (new ScAccessiblePreviewHeaderCellTextData(mpViewShell, String(getAccessibleName()), maCellPos, mbColumnHeader, mbRowHeader));
+ ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));
+
+ mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
+ mpTextHelper->SetEventSource(this);
+ }
+}
+
+void ScAccessiblePreviewHeaderCell::FillTableInfo() const
+{
+ if ( mpViewShell && !mpTableInfo )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+
+ mpTableInfo = new ScPreviewTableInfo;
+ mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
+ }
+}
diff --git a/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx b/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx
new file mode 100644
index 000000000000..e3fe26f47b4d
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessiblePreviewTable.cxx
@@ -0,0 +1,769 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include "AccessiblePreviewTable.hxx"
+#include "AccessiblePreviewCell.hxx"
+#include "AccessiblePreviewHeaderCell.hxx"
+#include "AccessibilityHints.hxx"
+#include "prevwsh.hxx"
+#include "unoguard.hxx"
+#include "miscuno.hxx"
+#include "prevloc.hxx"
+#include "attrib.hxx"
+#include "document.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+
+#include <vcl/window.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessiblePreviewTable::ScAccessiblePreviewTable( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScPreviewShell* pViewShell, sal_Int32 nIndex ) :
+ ScAccessibleContextBase( rxParent, AccessibleRole::TABLE ),
+ mpViewShell( pViewShell ),
+ mnIndex( nIndex ),
+ mpTableInfo( NULL )
+{
+ if (mpViewShell)
+ mpViewShell->AddAccessibilityObject(*this);
+}
+
+ScAccessiblePreviewTable::~ScAccessiblePreviewTable()
+{
+ if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
+ {
+ // increment refcount to prevent double call off dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+void SAL_CALL ScAccessiblePreviewTable::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+
+ if (mpTableInfo)
+ DELETEZ (mpTableInfo);
+
+ ScAccessibleContextBase::disposing();
+}
+
+//===== SfxListener =====================================================
+
+void ScAccessiblePreviewTable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ))
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ ULONG nId = rRef.GetId();
+ if ( nId == SFX_HINT_DATACHANGED )
+ {
+ // column / row layout may change with any document change,
+ // so it must be invalidated
+ DELETEZ( mpTableInfo );
+ }
+ else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ CommitChange(aEvent);
+ }
+ }
+
+ ScAccessibleContextBase::Notify(rBC, rHint);
+}
+
+//===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessiblePreviewTable::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessiblePreviewTableImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessiblePreviewTable::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessiblePreviewTable::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+//===== XAccessibleTable ================================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo )
+ nRet = mpTableInfo->GetRows();
+ return nRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo )
+ nRet = mpTableInfo->GetCols();
+ return nRet;
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleRowDescription( sal_Int32 nRow )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // is not supported or specified so not implemented
+/* ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ rtl::OUString sName;
+ if ( mpTableInfo && nRow >= 0 && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rInfo = mpTableInfo->GetRowInfo()[nRow];
+ if ( rInfo.bIsHeader )
+ {
+ //! name of column headers row?
+
+ sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Column Headers"));
+ }
+ else
+ {
+ // normal row name
+ sName = rtl::OUString::valueOf( (sal_Int32) ( rInfo.nDocIndex + 1 ) );
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();*/
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return rtl::OUString();
+}
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // is not supported or specified so not implemented
+/* ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ rtl::OUString sName;
+ if ( mpTableInfo && nColumn >= 0 && nColumn < mpTableInfo->GetCols() )
+ {
+ const ScPreviewColRowInfo& rInfo = mpTableInfo->GetColInfo()[nColumn];
+ if ( rInfo.bIsHeader )
+ {
+ //! name of row headers column?
+
+ sName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Row Headers"));
+ }
+ else
+ {
+ // normal column name
+ sName = ScColToAlpha( rInfo.nDocIndex );
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();*/
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return rtl::OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRows = 1;
+ if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
+ nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ // header cells only span a single cell
+ }
+ else
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
+ static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
+ if ( pItem && pItem->GetRowMerge() > 0 )
+ nRows = pItem->GetRowMerge();
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRows;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nColumns = 1;
+ if ( mpViewShell && mpTableInfo && nColumn >= 0 && nRow >= 0 &&
+ nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ // header cells only span a single cell
+ }
+ else
+ {
+ ScDocument* pDoc = mpViewShell->GetDocument();
+ const ScMergeAttr* pItem = (const ScMergeAttr*)pDoc->GetAttr(
+ static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab(), ATTR_MERGE );
+ if ( pItem && pItem->GetColMerge() > 0 )
+ nColumns = pItem->GetColMerge();
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nColumns;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleRowHeaders() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessiblePreviewTable::getAccessibleColumnHeaders() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleRows() throw (uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ return uno::Sequence<sal_Int32>(0);
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessiblePreviewTable::getSelectedAccessibleColumns() throw (uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ return uno::Sequence<sal_Int32>(0);
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleRowSelected( sal_Int32 nRow )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nRow < 0 || (mpTableInfo && nRow >= mpTableInfo->GetRows()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+
+ ScUnoGuard aGuard;
+ FillTableInfo();
+ if ( nColumn < 0 || (mpTableInfo && nColumn >= mpTableInfo->GetCols()) )
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ uno::Reference<XAccessible> xRet;
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ long nNewIndex = nRow * mpTableInfo->GetCols() + nColumn;
+
+ const ScPreviewColRowInfo& rColInfo = mpTableInfo->GetColInfo()[nColumn];
+ const ScPreviewColRowInfo& rRowInfo = mpTableInfo->GetRowInfo()[nRow];
+
+ ScAddress aCellPos( static_cast<SCCOL>(rColInfo.nDocIndex), static_cast<SCROW>(rRowInfo.nDocIndex), mpTableInfo->GetTab() );
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ {
+ ScAccessiblePreviewHeaderCell* pHeaderCell = new ScAccessiblePreviewHeaderCell( this, mpViewShell, aCellPos,
+ rRowInfo.bIsHeader, rColInfo.bIsHeader, nNewIndex );
+ xRet = pHeaderCell;
+ pHeaderCell->Init();
+ }
+ else
+ {
+ ScAccessiblePreviewCell* pCell = new ScAccessiblePreviewCell( this, mpViewShell, aCellPos, nNewIndex );
+ xRet = pCell;
+ pCell->Init();
+ }
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleCaption() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleSummary() throw (uno::RuntimeException)
+{
+ //! missing
+ return NULL;
+}
+
+sal_Bool SAL_CALL ScAccessiblePreviewTable::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // in the page preview, there is no selection
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return sal_False;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRet = 0;
+ if ( mpTableInfo && nColumn >= 0 && nRow >= 0 && nColumn < mpTableInfo->GetCols() && nRow < mpTableInfo->GetRows() )
+ {
+ // index iterates horizontally
+ nRet = nRow * mpTableInfo->GetCols() + nColumn;
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleRow( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nRow = 0;
+ if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
+ {
+ nRow = nChildIndex / mpTableInfo->GetCols();
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nRow;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ sal_Int32 nCol = 0;
+ if ( mpTableInfo && nChildIndex >= 0 && nChildIndex < static_cast<sal_Int32>(mpTableInfo->GetRows()) * mpTableInfo->GetCols() )
+ {
+ nCol = nChildIndex % static_cast<sal_Int32>(mpTableInfo->GetCols());
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+
+ return nCol;
+}
+
+//===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference<XAccessible> xRet;
+ if (containsPoint(aPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ SCCOL nCols = mpTableInfo->GetCols();
+ SCROW nRows = mpTableInfo->GetRows();
+ const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
+ const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
+
+ Rectangle aScreenRect(GetBoundingBox());
+
+ awt::Point aMovedPoint = aPoint;
+ aMovedPoint.X += aScreenRect.Left();
+ aMovedPoint.Y += aScreenRect.Top();
+
+ if ( nCols > 0 && nRows > 0 && aMovedPoint.X >= pColInfo[0].nPixelStart && aMovedPoint.Y >= pRowInfo[0].nPixelStart )
+ {
+ SCCOL nColIndex = 0;
+ while ( nColIndex < nCols && aMovedPoint.X > pColInfo[nColIndex].nPixelEnd )
+ ++nColIndex;
+ SCROW nRowIndex = 0;
+ while ( nRowIndex < nRows && aMovedPoint.Y > pRowInfo[nRowIndex].nPixelEnd )
+ ++nRowIndex;
+ if ( nColIndex < nCols && nRowIndex < nRows )
+ {
+ try
+ {
+ xRet = getAccessibleCellAt( nRowIndex, nColIndex );
+ }
+ catch (uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void SAL_CALL ScAccessiblePreviewTable::grabFocus() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+//===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleChildCount() throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ long nRet = 0;
+ if ( mpTableInfo )
+ nRet = static_cast<sal_Int32>(mpTableInfo->GetCols()) * mpTableInfo->GetRows();
+ return nRet;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessiblePreviewTable::getAccessibleChild( sal_Int32 nIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ FillTableInfo();
+
+ uno::Reference<XAccessible> xRet;
+ if ( mpTableInfo )
+ {
+ long nColumns = mpTableInfo->GetCols();
+ if ( nColumns > 0 )
+ {
+ // nCol, nRow are within the visible table, not the document
+ long nCol = nIndex % nColumns;
+ long nRow = nIndex / nColumns;
+
+ xRet = getAccessibleCellAt( nRow, nCol );
+ }
+ }
+
+ if ( !xRet.is() )
+ throw lang::IndexOutOfBoundsException();
+
+ return xRet;
+}
+
+sal_Int32 SAL_CALL ScAccessiblePreviewTable::getAccessibleIndexInParent() throw (uno::RuntimeException)
+{
+ return mnIndex;
+}
+
+uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePreviewTable::getAccessibleStateSet()
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+//===== XServiceInfo ====================================================
+
+rtl::OUString SAL_CALL ScAccessiblePreviewTable::getImplementationName() throw(uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessiblePreviewTable"));
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL ScAccessiblePreviewTable::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.AccessibleTableView"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessiblePreviewTable::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessiblePreviewTableImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScAccessiblePreviewTable::getImplementationId()
+ throw(uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+//==== internal =========================================================
+
+::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(STR_ACC_TABLE_DESCR));
+/* if (mpViewShell && mpViewShell->GetDocument())
+ {
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ String sCoreName;
+ if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
+ sDesc.SearchAndReplaceAscii("%1", sCoreName);
+ }
+ }
+ sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
+ return rtl::OUString(sDesc);
+}
+
+::rtl::OUString SAL_CALL ScAccessiblePreviewTable::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(STR_ACC_TABLE_NAME));
+
+ if (mpViewShell && mpViewShell->GetDocument())
+ {
+ FillTableInfo();
+
+ if ( mpTableInfo )
+ {
+ String sCoreName;
+ if (mpViewShell->GetDocument()->GetName( mpTableInfo->GetTab(), sCoreName ))
+ sName.SearchAndReplaceAscii("%1", sCoreName);
+ }
+ }
+
+ return rtl::OUString(sName);
+}
+
+Rectangle ScAccessiblePreviewTable::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
+{
+ Rectangle aCellRect(GetBoundingBox());
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
+ aCellRect.setX(aCellRect.getX() + aRect.getX());
+ aCellRect.setY(aCellRect.getY() + aRect.getY());
+ }
+ }
+ return aCellRect;
+}
+
+Rectangle ScAccessiblePreviewTable::GetBoundingBox() const throw (uno::RuntimeException)
+{
+ FillTableInfo();
+
+ Rectangle aRect;
+ if ( mpTableInfo )
+ {
+ SCCOL nColumns = mpTableInfo->GetCols();
+ SCROW nRows = mpTableInfo->GetRows();
+ if ( nColumns > 0 && nRows > 0 )
+ {
+ const ScPreviewColRowInfo* pColInfo = mpTableInfo->GetColInfo();
+ const ScPreviewColRowInfo* pRowInfo = mpTableInfo->GetRowInfo();
+
+ aRect = Rectangle( pColInfo[0].nPixelStart,
+ pRowInfo[0].nPixelStart,
+ pColInfo[nColumns-1].nPixelEnd,
+ pRowInfo[nRows-1].nPixelEnd );
+ }
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessiblePreviewTable::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+void ScAccessiblePreviewTable::FillTableInfo() const
+{
+ if ( mpViewShell && !mpTableInfo )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+
+ mpTableInfo = new ScPreviewTableInfo;
+ mpViewShell->GetLocationData().GetTableInfo( aVisRect, *mpTableInfo );
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
new file mode 100644
index 000000000000..f85fb22531aa
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
@@ -0,0 +1,999 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleSpreadsheet.hxx"
+#include "AccessibilityHints.hxx"
+#include "AccessibleCell.hxx"
+#include "AccessibleDocument.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "hints.hxx"
+#include "scmod.hxx"
+
+#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
+#include <unotools/accessiblestatesethelper.hxx>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <tools/gen.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos)
+ :
+ ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell),
+ ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))),
+ mbIsSpreadsheet( sal_True )
+{
+ ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos );
+}
+
+ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
+ ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) :
+ ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange),
+ mbIsSpreadsheet( sal_False )
+{
+ ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos );
+}
+
+ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet()
+{
+ if (mpMarkedRanges)
+ delete mpMarkedRanges;
+ if (mpSortedMarkedCells)
+ delete mpSortedMarkedCells;
+ if (mpViewShell)
+ mpViewShell->RemoveAccessibilityObject(*this);
+}
+
+void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet(
+ ScAccessibleDocument* pAccDoc,
+ ScTabViewShell* pViewShell,
+ SCTAB nTab,
+ ScSplitPos eSplitPos)
+{
+ mpViewShell = pViewShell;
+ mpMarkedRanges = 0;
+ mpSortedMarkedCells = 0;
+ mpAccDoc = pAccDoc;
+ mpAccCell = 0;
+ meSplitPos = eSplitPos;
+ mnTab = nTab;
+ mbHasSelection = sal_False;
+ mbDelIns = sal_False;
+ mbIsFocusSend = sal_False;
+ maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos));
+ if (mpViewShell)
+ {
+ mpViewShell->AddAccessibilityObject(*this);
+
+ const ScViewData& rViewData = *mpViewShell->GetViewData();
+ const ScMarkData& rMarkData = rViewData.GetMarkData();
+ maActiveCell = rViewData.GetCurPos();
+ mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) &&
+ (rMarkData.IsMarked() || rMarkData.IsMultiMarked());
+ mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
+ mpAccCell->acquire();
+ mpAccCell->Init();
+ }
+}
+
+void SAL_CALL ScAccessibleSpreadsheet::disposing()
+{
+ ScUnoGuard aGuard;
+ if (mpViewShell)
+ {
+ mpViewShell->RemoveAccessibilityObject(*this);
+ mpViewShell = NULL;
+ }
+ if (mpAccCell)
+ {
+ mpAccCell->release();
+ mpAccCell = NULL;
+ }
+
+ ScAccessibleTableBase::disposing();
+}
+
+void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState)
+{
+ if (mpMarkedRanges)
+ DELETEZ(mpMarkedRanges);
+ if (mpSortedMarkedCells)
+ DELETEZ(mpSortedMarkedCells);
+
+ mbHasSelection = bNewState;
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::STATE_CHANGED;
+ if (bNewState)
+ aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED);
+ else
+ aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED);
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::LostFocus()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xOld = mpAccCell;
+ aEvent.OldValue <<= xOld;
+
+ CommitChange(aEvent);
+
+ CommitFocusLost();
+}
+
+void ScAccessibleSpreadsheet::GotFocus()
+{
+ CommitFocusGained();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ aEvent.NewValue <<= xNew;
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::BoundingBoxChanged()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+void ScAccessibleSpreadsheet::VisAreaChanged()
+{
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+}
+
+ //===== SfxListener =====================================================
+
+void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA( SfxSimpleHint ) )
+ {
+ const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
+ // only notify if child exist, otherwise it is not necessary
+ if ((rRef.GetId() == SC_HINT_ACC_CURSORCHANGED))
+ {
+ if (mpViewShell)
+ {
+ ScAddress aNewCell = mpViewShell->GetViewData()->GetCurPos();
+ sal_Bool bNewMarked(mpViewShell->GetViewData()->GetMarkData().GetTableSelect(aNewCell.Tab()) &&
+ (mpViewShell->GetViewData()->GetMarkData().IsMarked() ||
+ mpViewShell->GetViewData()->GetMarkData().IsMultiMarked()));
+ sal_Bool bNewCellSelected(isAccessibleSelected(aNewCell.Row(), aNewCell.Col()));
+ if ((bNewMarked != mbHasSelection) ||
+ (!bNewCellSelected && bNewMarked) ||
+ (bNewCellSelected && mbHasSelection))
+ {
+ if (mpMarkedRanges)
+ DELETEZ(mpMarkedRanges);
+ if (mpSortedMarkedCells)
+ DELETEZ(mpSortedMarkedCells);
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ mbHasSelection = bNewMarked;
+
+ CommitChange(aEvent);
+ }
+
+ // active descendant changed event (new cell selected)
+ bool bFireActiveDescChanged = (aNewCell != maActiveCell) &&
+ (aNewCell.Tab() == maActiveCell.Tab()) && IsFocused();
+
+ /* Remember old active cell and set new active cell.
+ #i82409# always update the class members mpAccCell and
+ maActiveCell, even if the sheet is not focused, e.g. when
+ using the name box in the toolbar. */
+ uno::Reference< XAccessible > xOld = mpAccCell;
+ mpAccCell->release();
+ mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col());
+ mpAccCell->acquire();
+ mpAccCell->Init();
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ maActiveCell = aNewCell;
+
+ // #i14108# fire event only if sheet is focused
+ if( bFireActiveDescChanged )
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.OldValue <<= xOld;
+ aEvent.NewValue <<= xNew;
+ CommitChange(aEvent);
+ }
+ }
+ }
+ else if ((rRef.GetId() == SC_HINT_DATACHANGED))
+ {
+ if (!mbDelIns)
+ CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE);
+ else
+ mbDelIns = sal_False;
+ }
+ // no longer needed, because the document calls the VisAreaChanged method
+/* else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);*/
+ // commented out, because to use a ModelChangeEvent is not the right way
+ // at the moment there is no way, but the Java/Gnome Api should be extended sometime
+/* if (mpViewShell)
+ {
+ Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos)));
+
+ Rectangle aNewPos(aNewVisCells);
+
+ if (aNewVisCells.IsOver(maVisCells))
+ aNewPos.Union(maVisCells);
+ else
+ CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE);
+
+ maVisCells = aNewVisCells;
+
+ CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE);
+ }
+ }*/
+ // no longer needed, because the document calls the BoundingBoxChanged method
+/* else if (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)
+ {
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+
+ CommitChange(aEvent);
+ }*/
+ }
+ else if (rHint.ISA( ScUpdateRefHint ))
+ {
+ const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+ if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //#107250# test whether table is inserted or deleted
+ {
+ if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) &&
+ (rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) ||
+ ((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) &&
+ (rRef.GetRange().aEnd.Row() == maRange.aEnd.Row())))
+ {
+ // ignore next SC_HINT_DATACHANGED notification
+ mbDelIns = sal_True;
+
+ sal_Int16 nId(0);
+ SCsCOL nX(rRef.GetDx());
+ SCsROW nY(rRef.GetDy());
+ ScRange aRange(rRef.GetRange());
+ if ((nX < 0) || (nY < 0))
+ {
+ DBG_ASSERT(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time");
+ nId = AccessibleTableModelChangeType::DELETE;
+ if (nX < 0)
+ {
+ nX = -nX;
+ nY = aRange.aEnd.Row() - aRange.aStart.Row();
+ }
+ else
+ {
+ nY = -nY;
+ nX = aRange.aEnd.Col() - aRange.aStart.Col();
+ }
+ }
+ else if ((nX > 0) || (nY > 0))
+ {
+ DBG_ASSERT(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time");
+ nId = AccessibleTableModelChangeType::INSERT;
+ if (nX < 0)
+ nY = aRange.aEnd.Row() - aRange.aStart.Row();
+ else
+ nX = aRange.aEnd.Col() - aRange.aStart.Col();
+ }
+ else
+ {
+ DBG_ERROR("is it a deletion or a insertion?");
+ }
+
+ CommitTableModelChange(rRef.GetRange().aStart.Row(),
+ rRef.GetRange().aStart.Col(),
+ rRef.GetRange().aStart.Row() + nY,
+ rRef.GetRange().aStart.Col() + nX, nId);
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ uno::Reference< XAccessible > xNew = mpAccCell;
+ aEvent.NewValue <<= xNew;
+
+ CommitChange(aEvent);
+ }
+ }
+ }
+
+ ScAccessibleTableBase::Notify(rBC, rHint);
+}
+
+ //===== XAccessibleTable ================================================
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ if( mpDoc && mbIsSpreadsheet )
+ {
+ if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) )
+ {
+ SCROW nStart = pRowRange->aStart.Row();
+ SCROW nEnd = pRowRange->aEnd.Row();
+ if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) )
+ xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) );
+ }
+ }
+ return xAccessibleTable;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ if( mpDoc && mbIsSpreadsheet )
+ {
+ if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) )
+ {
+ SCCOL nStart = pColRange->aStart.Col();
+ SCCOL nEnd = pColRange->aEnd.Col();
+ if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) )
+ xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) );
+ }
+ }
+ return xAccessibleTable;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Sequence<sal_Int32> aSequence;
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1);
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ sal_Int32* pSequence = aSequence.getArray();
+ sal_Int32 nCount(0);
+ for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i)
+ {
+ if (rMarkdata.IsRowMarked(i))
+ {
+ pSequence[nCount] = i;
+ ++nCount;
+ }
+ }
+ aSequence.realloc(nCount);
+ }
+ else
+ aSequence.realloc(0);
+ return aSequence;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Sequence<sal_Int32> aSequence;
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ sal_Int32* pSequence = aSequence.getArray();
+ sal_Int32 nCount(0);
+ for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i)
+ {
+ if (rMarkdata.IsColumnMarked(i))
+ {
+ pSequence[nCount] = i;
+ ++nCount;
+ }
+ }
+ aSequence.realloc(nCount);
+ }
+ else
+ aSequence.realloc(0);
+ return aSequence;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsRowMarked((SCROW)nRow);
+ }
+ return bResult;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData())
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn);
+ }
+ return bResult;
+}
+
+ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn)
+{
+ ScAccessibleCell* pAccessibleCell = NULL;
+ ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn),
+ static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab());
+ if ((aCellAddress == maActiveCell) && mpAccCell)
+ {
+ pAccessibleCell = mpAccCell;
+ }
+ else
+ pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc);
+
+ return pAccessibleCell;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
+ nRow < 0 ||
+ nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
+ nColumn < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference<XAccessible> xAccessible;
+ ScAccessibleCell* pAccessibleCell = GetAccessibleCellAt(nRow, nColumn);
+ xAccessible = pAccessibleCell;
+ pAccessibleCell->Init();
+ return xAccessible;
+}
+
+sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Bool bResult(sal_False);
+ if (mpViewShell)
+ {
+ const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
+ bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow));
+ }
+ return bResult;
+}
+
+ //===== XAccessibleComponent ============================================
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint(
+ const awt::Point& rPoint )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessible > xAccessible;
+ if (containsPoint(rPoint))
+ {
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ SCsCOL nX;
+ SCsROW nY;
+ mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY);
+ xAccessible = getAccessibleCellAt(nY, nX);
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL ScAccessibleSpreadsheet::grabFocus( )
+ throw (uno::RuntimeException)
+{
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
+ if (xAccessibleComponent.is())
+ xAccessibleComponent->grabFocus();
+ }
+}
+
+sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground( )
+ throw (uno::RuntimeException)
+{
+ return COL_BLACK;
+}
+
+sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
+}
+
+ //===== XAccessibleContext ==============================================
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ utl::AccessibleRelationSetHelper* pRelationSet = NULL;
+ if(mpAccDoc)
+ pRelationSet = mpAccDoc->GetRelationSet(NULL);
+ if (!pRelationSet)
+ pRelationSet = new utl::AccessibleRelationSetHelper();
+ return pRelationSet;
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleSpreadsheet::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ uno::Reference<XAccessibleStateSet> xParentStates;
+ if (getAccessibleParent().is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
+ xParentStates = xParentContext->getAccessibleStateSet();
+ }
+ utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
+ if (IsDefunc(xParentStates))
+ pStateSet->AddState(AccessibleStateType::DEFUNC);
+ else
+ {
+ pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
+ if (IsEditable(xParentStates))
+ pStateSet->AddState(AccessibleStateType::EDITABLE);
+ pStateSet->AddState(AccessibleStateType::ENABLED);
+ pStateSet->AddState(AccessibleStateType::FOCUSABLE);
+ if (IsFocused())
+ pStateSet->AddState(AccessibleStateType::FOCUSED);
+ pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
+ pStateSet->AddState(AccessibleStateType::OPAQUE);
+ pStateSet->AddState(AccessibleStateType::SELECTABLE);
+ if (IsCompleteSheetSelected())
+ pStateSet->AddState(AccessibleStateType::SELECTED);
+ if (isShowing())
+ pStateSet->AddState(AccessibleStateType::SHOWING);
+ if (isVisible())
+ pStateSet->AddState(AccessibleStateType::VISIBLE);
+ }
+ return pStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+
+ if (mpViewShell)
+ {
+ sal_Int32 nCol(getAccessibleColumn(nChildIndex));
+ sal_Int32 nRow(getAccessibleRow(nChildIndex));
+
+ SelectCell(nRow, nCol, sal_False);
+ }
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ mpViewShell->Unmark();
+ }
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ if (mpViewShell)
+ {
+ mpViewShell->SelectAll();
+ }
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleSpreadsheet::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ sal_Int32 nResult(0);
+ if (mpViewShell)
+ {
+ if (!mpMarkedRanges)
+ {
+ mpMarkedRanges = new ScRangeList();
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ aMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_False);
+ }
+ // is possible, because there shouldn't be overlapped ranges in it
+ if (mpMarkedRanges)
+ nResult = mpMarkedRanges->GetCellCount();
+ }
+ return nResult;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ uno::Reference < XAccessible > xAccessible;
+ if (mpViewShell)
+ {
+ if (!mpMarkedRanges)
+ {
+ mpMarkedRanges = new ScRangeList();
+ mpViewShell->GetViewData()->GetMarkData().FillRangeListWithMarks(mpMarkedRanges, sal_False);
+ }
+ if (mpMarkedRanges)
+ {
+ if (!mpSortedMarkedCells)
+ CreateSortedMarkedCells();
+ if (mpSortedMarkedCells)
+ {
+ if ((nSelectedChildIndex < 0) ||
+ (mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex)))
+ throw lang::IndexOutOfBoundsException();
+ else
+ xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col());
+ }
+ }
+ }
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+
+ if (mpViewShell)
+ {
+ sal_Int32 nCol(getAccessibleColumn(nChildIndex));
+ sal_Int32 nRow(getAccessibleRow(nChildIndex));
+
+ if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)))
+ SelectCell(nRow, nCol, sal_True);
+ }
+}
+
+void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect)
+{
+ mpViewShell->SetTabNo( maRange.aStart.Tab() );
+
+ mpViewShell->DoneBlockMode( sal_True ); // continue selecting
+ mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False );
+
+ mpViewShell->SelectionChanged();
+}
+
+void ScAccessibleSpreadsheet::CreateSortedMarkedCells()
+{
+ mpSortedMarkedCells = new std::vector<ScMyAddress>();
+ mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount());
+ ScRange* pRange = mpMarkedRanges->First();
+ while (pRange)
+ {
+ if (pRange->aStart.Tab() != pRange->aEnd.Tab())
+ {
+ if ((maActiveCell.Tab() >= pRange->aStart.Tab()) ||
+ maActiveCell.Tab() <= pRange->aEnd.Tab())
+ {
+ ScRange aRange(*pRange);
+ aRange.aStart.SetTab(maActiveCell.Tab());
+ aRange.aEnd.SetTab(maActiveCell.Tab());
+ AddMarkedRange(aRange);
+ }
+ else
+ {
+ DBG_ERROR("Range of wrong table");
+ }
+ }
+ else if(pRange->aStart.Tab() == maActiveCell.Tab())
+ AddMarkedRange(*pRange);
+ else
+ {
+ DBG_ERROR("Range of wrong table");
+ }
+ pRange = mpMarkedRanges->Next();
+ }
+ std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end());
+}
+
+void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange)
+{
+ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+ {
+ for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+ {
+ ScMyAddress aCell(nCol, nRow, maActiveCell.Tab());
+ mpSortedMarkedCells->push_back(aCell);
+ }
+ }
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleSpreadsheet"));
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ ScAccessibleSpreadsheet::getSupportedServiceNames (void)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames();
+ sal_Int32 nOldSize(aSequence.getLength());
+ aSequence.realloc(nOldSize + 1);
+ ::rtl::OUString* pNames = aSequence.getArray();
+
+ pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheet"));
+
+ return aSequence;
+}
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleSpreadsheet::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+///===== XAccessibleEventBroadcaster =====================================
+
+void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ ScAccessibleTableBase::addEventListener(xListener);
+
+ if (!mbIsFocusSend)
+ {
+ mbIsFocusSend = sal_True;
+ CommitFocusGained();
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
+
+ CommitChange(aEvent);
+ }
+}
+
+ //==== internal =========================================================
+
+Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ aRect = pWindow->GetWindowExtentsRelative(NULL);
+ }
+ return aRect;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const
+ throw (uno::RuntimeException)
+{
+ Rectangle aRect;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ //#101986#; extends to the same window, because the parent is the document and it has the same window
+ aRect = pWindow->GetWindowExtentsRelative(pWindow);
+ }
+ return aRect;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsDefunc(
+ const uno::Reference<XAccessibleStateSet>& rxParentStates)
+{
+ return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
+ (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsEditable(
+ const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
+{
+ sal_Bool bProtected(sal_False);
+ if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab()))
+ bProtected = sal_True;
+ return !bProtected;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsFocused()
+{
+ sal_Bool bFocused(sal_False);
+ if (mpViewShell)
+ {
+ if (mpViewShell->GetViewData()->GetActivePart() == meSplitPos)
+ bFocused = mpViewShell->GetActiveWin()->HasFocus();
+ }
+ return bFocused;
+}
+
+sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected()
+{
+ sal_Bool bResult(sal_False);
+ if(mpViewShell)
+ {
+ //#103800#; use a copy of MarkData
+ ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
+ aMarkData.MarkToMulti();
+ if (aMarkData.IsAllMarked(maRange))
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell)
+{
+ ScDocument* pDoc = NULL;
+ if (pViewShell)
+ pDoc = pViewShell->GetViewData()->GetDocument();
+ return pDoc;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
+{
+ Rectangle aVisArea;
+ if (pViewShell)
+ {
+ Window* pWindow = pViewShell->GetWindowByPos(eSplitPos);
+ if (pWindow)
+ {
+ aVisArea.SetPos(pViewShell->GetViewData()->GetPixPos(eSplitPos));
+ aVisArea.SetSize(pWindow->GetSizePixel());
+ }
+ }
+ return aVisArea;
+}
+
+Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea)
+{
+ if (mpViewShell)
+ {
+ SCsCOL nStartX, nEndX;
+ SCsROW nStartY, nEndY;
+
+ mpViewShell->GetViewData()->GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY);
+ mpViewShell->GetViewData()->GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY);
+
+ return Rectangle(nStartX, nStartY, nEndX, nEndY);
+ }
+ else
+ return Rectangle();
+}
diff --git a/sc/source/ui/Accessibility/AccessibleTableBase.cxx b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
new file mode 100644
index 000000000000..2d46d3eb776b
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
@@ -0,0 +1,495 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "AccessibleTableBase.hxx"
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "unoguard.hxx"
+#include "scresid.hxx"
+#ifndef SC_SC_HRC
+#include "sc.hrc"
+#endif
+
+#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#endif
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <rtl/uuid.h>
+#include <tools/debug.hxx>
+#include <comphelper/sequence.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+//===== internal ============================================================
+
+ScAccessibleTableBase::ScAccessibleTableBase(
+ const uno::Reference<XAccessible>& rxParent,
+ ScDocument* pDoc,
+ const ScRange& rRange)
+ :
+ ScAccessibleContextBase (rxParent, AccessibleRole::TABLE),
+ maRange(rRange),
+ mpDoc(pDoc)
+{
+}
+
+ScAccessibleTableBase::~ScAccessibleTableBase()
+{
+}
+
+void SAL_CALL ScAccessibleTableBase::disposing()
+{
+ ScUnoGuard aGuard;
+ mpDoc = NULL;
+
+ ScAccessibleContextBase::disposing();
+}
+
+ //===== XInterface =====================================================
+
+uno::Any SAL_CALL ScAccessibleTableBase::queryInterface( uno::Type const & rType )
+ throw (uno::RuntimeException)
+{
+ uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
+ return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleTableBase::acquire()
+ throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleTableBase::release()
+ throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+ //===== XAccessibleTable ================================================
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount( )
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
+}
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("Here should be a implementation to fill the description");
+
+ if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
+ return rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("Here should be a implementation to fill the description");
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
+ return rtl::OUString();
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nCount(1); // the same cell
+ nRow += maRange.aStart.Row();
+ nColumn += maRange.aStart.Col();
+
+ if (mpDoc)
+ {
+ SCROW nEndRow(0);
+ SCCOL nEndCol(0);
+ if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
+ nEndCol, nEndRow, maRange.aStart.Tab()))
+ {
+ if (nEndRow > nRow)
+ nCount = nEndRow - nRow + 1;
+ }
+ }
+
+ return nCount;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
+ (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nCount(1); // the same cell
+ nRow += maRange.aStart.Row();
+ nColumn += maRange.aStart.Col();
+
+ if (mpDoc)
+ {
+ SCROW nEndRow(0);
+ SCCOL nEndCol(0);
+ if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
+ nEndCol, nEndRow, maRange.aStart.Tab()))
+ {
+ if (nEndCol > nColumn)
+ nCount = nEndCol - nColumn + 1;
+ }
+ }
+
+ return nCount;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ DBG_ERROR("Here should be a implementation to fill the row headers");
+
+ //CommitChange
+ return xAccessibleTable;
+}
+
+uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< XAccessibleTable > xAccessibleTable;
+ DBG_ERROR("Here should be a implementation to fill the column headers");
+
+ //CommitChange
+ return xAccessibleTable;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Sequence< sal_Int32 > aSequence;
+ return aSequence;
+}
+
+uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Sequence< sal_Int32 > aSequence;
+ return aSequence;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary( )
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("not implemented yet");
+ uno::Reference< XAccessible > xAccessible;
+ return xAccessible;
+}
+
+sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ DBG_ERROR("not implemented yet");
+ return sal_False;
+}
+
+ //===== XAccessibleExtendedTable ========================================
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
+ nRow < 0 ||
+ nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
+ nColumn < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ nRow -= maRange.aStart.Row();
+ nColumn -= maRange.aStart.Col();
+ return (nRow * (maRange.aEnd.Col() + 1)) + nColumn;
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+}
+
+sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex )
+ throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+}
+
+ //===== XAccessibleContext ==============================================
+
+sal_Int32 SAL_CALL
+ ScAccessibleTableBase::getAccessibleChildCount(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
+ (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+// return 1;
+}
+
+uno::Reference< XAccessible > SAL_CALL
+ ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex)
+ throw (uno::RuntimeException,
+ lang::IndexOutOfBoundsException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+
+ if (nIndex >= getAccessibleChildCount() || nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+
+ sal_Int32 nRow(0);
+ sal_Int32 nColumn(0);
+ sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
+ nRow = nIndex / nTemp;
+ nColumn = nIndex % nTemp;
+ return getAccessibleCellAt(nRow, nColumn);
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleTableBase::createAccessibleDescription(void)
+ throw (uno::RuntimeException)
+{
+ String sDesc(ScResId(STR_ACC_TABLE_DESCR));
+/* String sCoreName;
+ if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
+ sDesc.SearchAndReplaceAscii("%1", sCoreName);
+ sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
+ return rtl::OUString(sDesc);
+}
+
+::rtl::OUString SAL_CALL
+ ScAccessibleTableBase::createAccessibleName(void)
+ throw (uno::RuntimeException)
+{
+ String sName(ScResId(STR_ACC_TABLE_NAME));
+ String sCoreName;
+ if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
+ sName.SearchAndReplaceAscii("%1", sCoreName);
+ return rtl::OUString(sName);
+}
+
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ ScAccessibleTableBase::getAccessibleRelationSet(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ return uno::Reference<XAccessibleRelationSet>();
+}
+
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ ScAccessibleTableBase::getAccessibleStateSet(void)
+ throw (uno::RuntimeException)
+{
+ DBG_ERROR("should be implemented in the abrevated class");
+ uno::Reference< XAccessibleStateSet > xAccessibleStateSet;
+ return xAccessibleStateSet;
+}
+
+ ///===== XAccessibleSelection ===========================================
+
+void SAL_CALL
+ ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+}
+
+sal_Bool SAL_CALL
+ ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ // I don't need to guard, because the called funtions have a guard
+// ScUnoGuard aGuard;
+ if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
+ throw lang::IndexOutOfBoundsException();
+ return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::clearAccessibleSelection( )
+ throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::selectAllAccessibleChildren( )
+ throw (uno::RuntimeException)
+{
+}
+
+sal_Int32 SAL_CALL
+ ScAccessibleTableBase::getSelectedAccessibleChildCount( )
+ throw (uno::RuntimeException)
+{
+ sal_Int32 nResult(0);
+ return nResult;
+}
+
+uno::Reference<XAccessible > SAL_CALL
+ ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference < XAccessible > xAccessible;
+ return xAccessible;
+}
+
+void SAL_CALL
+ ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+}
+
+ //===== XServiceInfo ====================================================
+
+::rtl::OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleTableBase"));
+}
+
+ //===== XTypeProvider ===================================================
+
+uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+ ScAccessibleTableBase::getImplementationId(void)
+ throw (uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ IsObjectValid();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ aId.realloc (16);
+ rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
+ }
+ return aId;
+}
+
+void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
+{
+ AccessibleTableModelChange aModelChange;
+ aModelChange.FirstRow = nStartRow;
+ aModelChange.FirstColumn = nStartCol;
+ aModelChange.LastRow = nEndRow;
+ aModelChange.LastColumn = nEndCol;
+ aModelChange.Type = nId;
+
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
+ aEvent.Source = uno::Reference< XAccessibleContext >(this);
+ aEvent.NewValue <<= aModelChange;
+
+ CommitChange(aEvent);
+}
diff --git a/sc/source/ui/Accessibility/AccessibleText.cxx b/sc/source/ui/Accessibility/AccessibleText.cxx
new file mode 100644
index 000000000000..4073e23f837f
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleText.cxx
@@ -0,0 +1,1911 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <memory>
+#include "AccessibleText.hxx"
+#include "AccessibleCell.hxx"
+#include "tabvwsh.hxx"
+#include "editutil.hxx"
+#include "document.hxx"
+#include "scmod.hxx"
+#include "prevwsh.hxx"
+#include "docsh.hxx"
+#include "prevloc.hxx"
+#include "unoguard.hxx"
+#include "patattr.hxx"
+#include "inputwin.hxx"
+#include <editeng/unofored.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <vcl/virdev.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/algitem.hxx>
+
+
+// ============================================================================
+
+class ScViewForwarder : public SvxViewForwarder
+{
+ ScTabViewShell* mpViewShell;
+ ScAddress maCellPos;
+ ScSplitPos meSplitPos;
+public:
+ ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell);
+ virtual ~ScViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+ScViewForwarder::ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell)
+ :
+ mpViewShell(pViewShell),
+ maCellPos(rCell),
+ meSplitPos(eSplitPos)
+{
+}
+
+ScViewForwarder::~ScViewForwarder()
+{
+}
+
+BOOL ScViewForwarder::IsValid() const
+{
+ return mpViewShell != NULL;
+}
+
+Rectangle ScViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ {
+ aVisArea.SetSize(pWindow->GetSizePixel());
+
+ ScHSplitPos eWhichH = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_BOTTOMLEFT)) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ ScVSplitPos eWhichV = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_TOPRIGHT)) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+
+ Point aBaseCellPos(mpViewShell->GetViewData()->GetScrPos(mpViewShell->GetViewData()->GetPosX(eWhichH),
+ mpViewShell->GetViewData()->GetPosY(eWhichV), meSplitPos, sal_True));
+ Point aCellPos(mpViewShell->GetViewData()->GetScrPos(maCellPos.Col(), maCellPos.Row(), meSplitPos, sal_True));
+ aVisArea.SetPos(aCellPos - aBaseCellPos);
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+Point ScViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ return pWindow->LogicToPixel( rPoint, rMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
+ if (pWindow)
+ return pWindow->PixelToLogic( rPoint, rMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScViewForwarder::SetInvalid()
+{
+ mpViewShell = NULL;
+}
+
+// ============================================================================
+
+class ScEditObjectViewForwarder : public SvxViewForwarder
+{
+ Window* mpWindow;
+ // --> OD 2005-12-21 #i49561#
+ // - EditView needed for access to its visible area.
+ const EditView* mpEditView;
+ // <--
+public:
+ // --> OD 2005-12-21 #i49561#
+ ScEditObjectViewForwarder( Window* pWindow,
+ const EditView* _pEditView);
+ // <--
+ virtual ~ScEditObjectViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+// --> OD 2005-12-21 #i49561#
+ScEditObjectViewForwarder::ScEditObjectViewForwarder( Window* pWindow,
+ const EditView* _pEditView )
+ :
+ mpWindow(pWindow),
+ mpEditView( _pEditView )
+{
+}
+// <--
+
+ScEditObjectViewForwarder::~ScEditObjectViewForwarder()
+{
+}
+
+BOOL ScEditObjectViewForwarder::IsValid() const
+{
+ return (mpWindow != NULL);
+}
+
+Rectangle ScEditObjectViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpWindow)
+ {
+ Rectangle aVisRect(mpWindow->GetWindowExtentsRelative(mpWindow->GetAccessibleParentWindow()));
+
+ aVisRect.SetPos(Point(0, 0));
+
+ aVisArea = aVisRect;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+Point ScEditObjectViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ {
+ // --> OD 2005-12-21 #i49561# - consider offset of the visible area
+ // of the EditView before converting point to pixel.
+ Point aPoint( rPoint );
+ if ( mpEditView )
+ {
+ Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
+ aPoint += aEditViewVisArea.TopLeft();
+ }
+ return mpWindow->LogicToPixel( aPoint, rMapMode );
+ // <--
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScEditObjectViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ {
+ // --> OD 2005-12-21 #i49561# - consider offset of the visible area
+ // of the EditView after converting point to logic.
+ Point aPoint( mpWindow->PixelToLogic( rPoint, rMapMode ) );
+ if ( mpEditView )
+ {
+ Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
+ aPoint -= aEditViewVisArea.TopLeft();
+ }
+ return aPoint;
+ // <--
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScEditObjectViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+}
+
+// ============================================================================
+
+class ScPreviewViewForwarder : public SvxViewForwarder
+{
+protected:
+ ScPreviewShell* mpViewShell;
+ mutable ScPreviewTableInfo* mpTableInfo;
+public:
+ ScPreviewViewForwarder(ScPreviewShell* pViewShell);
+ virtual ~ScPreviewViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+
+ Rectangle GetVisRect() const;
+
+ // clips the VisArea and calculates with the negativ coordinates
+ Rectangle CorrectVisArea(const Rectangle& rVisArea) const;
+};
+
+ScPreviewViewForwarder::ScPreviewViewForwarder(ScPreviewShell* pViewShell)
+ :
+ mpViewShell(pViewShell),
+ mpTableInfo(NULL)
+{
+}
+
+ScPreviewViewForwarder::~ScPreviewViewForwarder()
+{
+ delete mpTableInfo;
+}
+
+BOOL ScPreviewViewForwarder::IsValid() const
+{
+ return mpViewShell != NULL;
+}
+
+Rectangle ScPreviewViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ DBG_ERROR("should be implemented in an abrevated class");
+ return aVisArea;
+}
+
+Point ScPreviewViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ MapMode aMapMode(pWindow->GetMapMode().GetMapUnit());
+ Point aPoint2( OutputDevice::LogicToLogic( rPoint, rMapMode, aMapMode) );
+ return pWindow->LogicToPixel(aPoint2);
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScPreviewViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpViewShell)
+ {
+ Window* pWindow = mpViewShell->GetWindow();
+ if (pWindow)
+ {
+ MapMode aMapMode(pWindow->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint1( pWindow->PixelToLogic( rPoint ) );
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
+ aMapMode.GetMapUnit(),
+ rMapMode ) );
+ return aPoint2;
+ }
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+void ScPreviewViewForwarder::SetInvalid()
+{
+ mpViewShell = NULL;
+}
+
+Rectangle ScPreviewViewForwarder::GetVisRect() const
+{
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ return aVisRect;
+ }
+ return Rectangle();
+}
+
+Rectangle ScPreviewViewForwarder::CorrectVisArea(const Rectangle& rVisArea) const
+{
+ Rectangle aVisArea(rVisArea);
+ Point aPos = aVisArea.TopLeft(); // get first the position to remember negative positions after clipping
+
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aVisArea = pWin->GetWindowExtentsRelative(pWin).GetIntersection(aVisArea);
+
+ sal_Int32 nX(aPos.getX());
+ sal_Int32 nY(aPos.getY());
+
+ if (nX > 0)
+ nX = 0;
+ else if (nX < 0)
+ nX = -nX;
+ if (nY > 0)
+ nY = 0;
+ else if (nY < 0)
+ nY = -nY;
+ aVisArea.SetPos(Point(nX, nY));
+
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewHeaderFooterViewForwarder : public ScPreviewViewForwarder
+{
+ sal_Bool mbHeader;
+public:
+ ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader);
+ virtual ~ScPreviewHeaderFooterViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewHeaderFooterViewForwarder::ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ mbHeader(bHeader)
+{
+}
+
+ScPreviewHeaderFooterViewForwarder::~ScPreviewHeaderFooterViewForwarder()
+{
+}
+
+Rectangle ScPreviewHeaderFooterViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ if ( mbHeader )
+ rData.GetHeaderPosition( aVisArea );
+ else
+ rData.GetFooterPosition( aVisArea );
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewCellViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+public:
+ ScPreviewCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos);
+ virtual ~ScPreviewCellViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewCellViewForwarder::ScPreviewCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos)
+{
+}
+
+ScPreviewCellViewForwarder::~ScPreviewCellViewForwarder()
+{
+}
+
+Rectangle ScPreviewCellViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetCellOutputRect(maCellPos);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewHeaderCellViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+ sal_Bool mbColHeader;
+ sal_Bool mbRowHeader;
+public:
+ ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bColHeader, sal_Bool bRowHeader);
+ virtual ~ScPreviewHeaderCellViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewHeaderCellViewForwarder::ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bColHeader, sal_Bool bRowHeader)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos),
+ mbColHeader(bColHeader),
+ mbRowHeader(bRowHeader)
+{
+}
+
+ScPreviewHeaderCellViewForwarder::~ScPreviewHeaderCellViewForwarder()
+{
+}
+
+Rectangle ScPreviewHeaderCellViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetHeaderCellOutputRect(GetVisRect(), maCellPos, mbColHeader);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScPreviewNoteViewForwarder : public ScPreviewViewForwarder
+{
+ ScAddress maCellPos;
+ sal_Bool mbNoteMark;
+public:
+ ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bNoteMark);
+ virtual ~ScPreviewNoteViewForwarder();
+
+ virtual Rectangle GetVisArea() const;
+};
+
+ScPreviewNoteViewForwarder::ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell,
+ ScAddress aCellPos,
+ sal_Bool bNoteMark)
+ :
+ ScPreviewViewForwarder(pViewShell),
+ maCellPos(aCellPos),
+ mbNoteMark(bNoteMark)
+{
+}
+
+ScPreviewNoteViewForwarder::~ScPreviewNoteViewForwarder()
+{
+}
+
+Rectangle ScPreviewNoteViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (mpViewShell)
+ {
+ const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
+ aVisArea = rData.GetNoteInRangeOutputRect(GetVisRect(), mbNoteMark, maCellPos);
+
+ aVisArea = CorrectVisArea(aVisArea);
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return aVisArea;
+}
+
+// ============================================================================
+
+class ScEditViewForwarder : public SvxEditViewForwarder
+{
+ EditView* mpEditView;
+ Window* mpWindow;
+public:
+ ScEditViewForwarder(EditView* pEditView, Window* pWin);
+ virtual ~ScEditViewForwarder();
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual sal_Bool GetSelection( ESelection& rSelection ) const;
+ virtual sal_Bool SetSelection( const ESelection& rSelection );
+ virtual sal_Bool Copy();
+ virtual sal_Bool Cut();
+ virtual sal_Bool Paste();
+
+ void GrabFocus();
+
+ void SetInvalid();
+};
+
+ScEditViewForwarder::ScEditViewForwarder(EditView* pEditView, Window* pWin)
+ : mpEditView(pEditView),
+ mpWindow(pWin)
+{
+ GrabFocus();
+}
+
+ScEditViewForwarder::~ScEditViewForwarder()
+{
+}
+
+BOOL ScEditViewForwarder::IsValid() const
+{
+ sal_Bool bResult(sal_False);
+ if (mpWindow && mpEditView)
+ {
+ bResult = sal_True;
+ }
+ return bResult;
+}
+
+Rectangle ScEditViewForwarder::GetVisArea() const
+{
+ Rectangle aVisArea;
+ if (IsValid() && mpEditView->GetEditEngine())
+ {
+ MapMode aMapMode(mpEditView->GetEditEngine()->GetRefMapMode());
+
+ aVisArea = mpWindow->LogicToPixel( mpEditView->GetVisArea(), aMapMode );
+ }
+ else
+ {
+ DBG_ERROR("this EditViewForwarder is no longer valid");
+ }
+ return aVisArea;
+}
+
+Point ScEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ return mpWindow->LogicToPixel( rPoint, rMapMode );
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+Point ScEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if (mpWindow)
+ return mpWindow->PixelToLogic( rPoint, rMapMode );
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return Point();
+}
+
+sal_Bool ScEditViewForwarder::GetSelection( ESelection& rSelection ) const
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ rSelection = mpEditView->GetSelection();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::SetSelection( const ESelection& rSelection )
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->SetSelection(rSelection);
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Copy()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Copy();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Cut()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Cut();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+sal_Bool ScEditViewForwarder::Paste()
+{
+ sal_Bool bResult(sal_False);
+ if (IsValid())
+ {
+ mpEditView->Paste();
+ bResult = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("this ViewForwarder is not valid");
+ }
+ return bResult;
+}
+
+void ScEditViewForwarder::GrabFocus()
+{
+}
+
+void ScEditViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+ mpEditView = NULL;
+}
+
+// ============================================================================
+
+// ScAccessibleCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessibleCellTextData::ScAccessibleCellTextData(ScTabViewShell* pViewShell,
+ const ScAddress& rP, ScSplitPos eSplitPos, ScAccessibleCell* pAccCell)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpEditViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ meSplitPos(eSplitPos),
+ mbViewEditEngine(sal_False),
+ mpAccessibleCell( pAccCell )
+{
+}
+
+ScAccessibleCellTextData::~ScAccessibleCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+ if (mpEditViewForwarder)
+ delete mpEditViewForwarder;
+}
+
+void ScAccessibleCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ if (mpEditViewForwarder)
+ mpEditViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessibleCellTextData::Clone() const
+{
+ return new ScAccessibleCellTextData( mpViewShell, aCellPos, meSplitPos, mpAccessibleCell );
+}
+
+void ScAccessibleCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
+{
+// #104893#; don't use the input string
+// ScCellTextData::GetCellText(rCellPos, rText);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if (pDoc)
+ {
+ // #104893#; use the displayed string
+ pDoc->GetString(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText);
+ if (mpViewShell)
+ {
+ const ScViewOptions& aOptions = mpViewShell->GetViewData()->GetOptions();
+ CellType aCellType;
+ pDoc->GetCellType(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), aCellType);
+ if (aCellType == CELLTYPE_FORMULA && aOptions.GetOption( VOPT_FORMULAS ))
+ {
+ pDoc->GetFormula( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText);
+ }
+ else if (!aOptions.GetOption( VOPT_NULLVALS ))
+ {
+ if ((aCellType == CELLTYPE_VALUE || aCellType == CELLTYPE_FORMULA) && pDoc->GetValue(rCellPos) == 0.0)
+ rText.Erase();
+ }
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleCellTextData::GetTextForwarder()
+{
+/* sal_Bool bHasForwarder(sal_False);
+ if (mpViewShell && mpViewShell->GetViewData() &&
+ (mpViewShell->GetViewData()->GetCurPos() == aCellPos) &&
+ (mpViewShell->GetViewData()->HasEditView(meSplitPos)) &&
+ (mpViewShell->GetViewData()->GetEditViewCol() == aCellPos.Col()) &&
+ (mpViewShell->GetViewData()->GetEditViewRow() == aCellPos.Row()))
+ {
+ if (!mbViewEditEngine)
+ {
+ if (pForwarder)
+ DELETEZ( pForwarder );
+ if (pEditEngine)
+ DELETEZ( pEditEngine );
+
+ SCCOL nCol;
+ SCROW nRow;
+ EditView* pEditView;
+ mpViewShell->GetViewData()->GetEditView( meSplitPos, pEditView, nCol, nRow );
+ if (pEditView)
+ {
+ pEditEngine = (ScFieldEditEngine*)pEditView->GetEditEngine();
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ bHasForwarder = sal_True;
+ }
+ }
+ else
+ bHasForwarder = sal_True;
+ }
+ else if (mbViewEditEngine)
+ {
+ // remove Forwarder created with EditEngine from EditView
+ if (pForwarder)
+ DELETEZ( pForwarder );
+ pEditEngine->SetNotifyHdl(Link());
+ // don't delete, because it is the EditEngine of the EditView
+ pEditEngine = NULL;
+ mbViewEditEngine = sal_False;
+ }
+
+ if (!bHasForwarder)*/
+ ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
+
+ ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
+ if ( pDoc && pEditEngine && mpViewShell )
+ {
+ long nSizeX, nSizeY;
+ mpViewShell->GetViewData()->GetMergeSizePixel(
+ aCellPos.Col(), aCellPos.Row(), nSizeX, nSizeY);
+
+ Size aSize(nSizeX, nSizeY);
+
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ long nIndent = 0;
+ const SvxHorJustifyItem* pHorJustifyItem = static_cast< const SvxHorJustifyItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY ) );
+ SvxCellHorJustify eHorJust = ( pHorJustifyItem ? static_cast< SvxCellHorJustify >( pHorJustifyItem->GetValue() ) : SVX_HOR_JUSTIFY_STANDARD );
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ {
+ const SfxUInt16Item* pIndentItem = static_cast< const SfxUInt16Item* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_INDENT ) );
+ if ( pIndentItem )
+ {
+ nIndent = static_cast< long >( pIndentItem->GetValue() );
+ }
+ }
+
+ const SvxMarginItem* pMarginItem = static_cast< const SvxMarginItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_MARGIN ) );
+ ScViewData* pViewData = mpViewShell->GetViewData();
+ double nPPTX = ( pViewData ? pViewData->GetPPTX() : 0 );
+ double nPPTY = ( pViewData ? pViewData->GetPPTY() : 0 );
+ long nLeftM = ( pMarginItem ? static_cast< long >( ( pMarginItem->GetLeftMargin() + nIndent ) * nPPTX ) : 0 );
+ long nTopM = ( pMarginItem ? static_cast< long >( pMarginItem->GetTopMargin() * nPPTY ) : 0 );
+ long nRightM = ( pMarginItem ? static_cast< long >( pMarginItem->GetRightMargin() * nPPTX ) : 0 );
+ long nBottomM = ( pMarginItem ? static_cast< long >( pMarginItem->GetBottomMargin() * nPPTY ) : 0 );
+ long nWidth = aSize.getWidth() - nLeftM - nRightM;
+ aSize.setWidth( nWidth );
+ aSize.setHeight( aSize.getHeight() - nTopM - nBottomM );
+
+ Window* pWin = mpViewShell->GetWindowByPos( meSplitPos );
+ if ( pWin )
+ {
+ aSize = pWin->PixelToLogic( aSize, pEditEngine->GetRefMapMode() );
+ }
+
+ /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
+ boundaries. This leads to wrong results in cases where the cell text
+ is rotated, because rotation is not taken into account when calcu-
+ lating the visible part of the text. In these cases we will expand
+ the cell size passed as paper size to the edit engine. The function
+ accessibility::AccessibleStaticTextBase::GetParagraphBoundingBox()
+ (see svx/source/accessibility/AccessibleStaticTextBase.cxx) will
+ return the size of the complete text then, which is used to expand
+ the cell bounding box in ScAccessibleCell::GetBoundingBox()
+ (see sc/source/ui/Accessibility/AccessibleCell.cxx). */
+ const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_ROTATE_VALUE ) );
+ if( pItem && (pItem->GetValue() != 0) )
+ {
+ pEditEngine->SetPaperSize( Size( LONG_MAX, aSize.getHeight() ) );
+ long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() );
+ aSize.setWidth( std::max( aSize.getWidth(), nTxtWidth + 2 ) );
+ }
+ else
+ {
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ const SfxBoolItem* pLineBreakItem = static_cast< const SfxBoolItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_LINEBREAK ) );
+ bool bLineBreak = ( pLineBreakItem && pLineBreakItem->GetValue() );
+ if ( !bLineBreak )
+ {
+ long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() );
+ aSize.setWidth( ::std::max( aSize.getWidth(), nTxtWidth ) );
+ }
+ }
+
+ pEditEngine->SetPaperSize( aSize );
+
+ // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
+ if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD && pDoc->HasValueData( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
+ {
+ pEditEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ }
+
+ Size aTextSize;
+ if ( pWin )
+ {
+ aTextSize = pWin->LogicToPixel( Size( pEditEngine->CalcTextWidth(), pEditEngine->GetTextHeight() ), pEditEngine->GetRefMapMode() );
+ }
+ long nTextWidth = aTextSize.Width();
+ long nTextHeight = aTextSize.Height();
+
+ long nOffsetX = nLeftM;
+ long nDiffX = nTextWidth - nWidth;
+ if ( nDiffX > 0 )
+ {
+ switch ( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_RIGHT:
+ {
+ nOffsetX -= nDiffX;
+ }
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ {
+ nOffsetX -= nDiffX / 2;
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+ }
+
+ long nOffsetY = 0;
+ const SvxVerJustifyItem* pVerJustifyItem = static_cast< const SvxVerJustifyItem* >(
+ pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_VER_JUSTIFY ) );
+ SvxCellVerJustify eVerJust = ( pVerJustifyItem ? static_cast< SvxCellVerJustify >( pVerJustifyItem->GetValue() ) : SVX_VER_JUSTIFY_STANDARD );
+ switch ( eVerJust )
+ {
+ case SVX_VER_JUSTIFY_STANDARD:
+ case SVX_VER_JUSTIFY_BOTTOM:
+ {
+ nOffsetY = nSizeY - nBottomM - nTextHeight;
+ }
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ {
+ nOffsetY = ( nSizeY - nTopM - nBottomM - nTextHeight ) / 2 + nTopM;
+ }
+ break;
+ default:
+ {
+ nOffsetY = nTopM;
+ }
+ break;
+ }
+
+ if ( mpAccessibleCell )
+ {
+ mpAccessibleCell->SetOffset( Point( nOffsetX, nOffsetY ) );
+ }
+
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+ }
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessibleCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScViewForwarder(mpViewShell, meSplitPos, aCellPos);
+ return mpViewForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleCellTextData::GetEditViewForwarder( sal_Bool /* bCreate */ )
+{
+ //#102219#; there should no EditViewForwarder be, because the cell is now readonly in this interface
+/* if (!mpEditViewForwarder)
+ {
+ SCCOL nCol;
+ SCROW nRow;
+ EditView* pEditView;
+ mpViewShell->GetViewData()->GetEditView( meSplitPos, pEditView, nCol, nRow );
+
+ mpEditViewForwarder = new ScEditViewForwarder(pEditView, mpViewShell->GetWindowByPos(meSplitPos));
+ }
+ else if (bCreate)
+ mpEditViewForwarder->GrabFocus();
+ return mpEditViewForwarder;*/
+ return NULL;
+}
+
+IMPL_LINK(ScAccessibleCellTextData, NotifyHdl, EENotify*, aNotify)
+{
+ if( aNotify )
+ {
+ ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
+
+ if( aHint.get() )
+ GetBroadcaster().Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+ScDocShell* ScAccessibleCellTextData::GetDocShell(ScTabViewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell)
+ pDocSh = pViewShell->GetViewData()->GetDocShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin)
+ :
+ mpViewForwarder(NULL),
+ mpEditViewForwarder(NULL),
+ mpEditView(pEditView),
+ mpEditEngine(pEditView ? pEditView->GetEditEngine() : 0),
+ mpForwarder(NULL),
+ mpWindow(pWin)
+{
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+}
+
+ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData()
+{
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+ if (mpEditViewForwarder)
+ delete mpEditViewForwarder;
+ if (mpForwarder)
+ delete mpForwarder;
+}
+
+void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpWindow = NULL;
+ mpEditView = NULL;
+ mpEditEngine = NULL;
+ DELETEZ(mpForwarder);
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ if (mpEditViewForwarder)
+ mpEditViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessibleEditObjectTextData::Clone() const
+{
+ return new ScAccessibleEditObjectTextData(mpEditView, mpWindow);
+}
+
+SvxTextForwarder* ScAccessibleEditObjectTextData::GetTextForwarder()
+{
+ if ((!mpForwarder && mpEditView) || (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet()))
+ {
+ if (!mpEditEngine)
+ mpEditEngine = mpEditView->GetEditEngine();
+ if (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet())
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+ if(!mpForwarder)
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleEditObjectTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ {
+ // --> OD 2005-12-21 #i49561#
+ mpViewForwarder = new ScEditObjectViewForwarder( mpWindow, mpEditView );
+ // <--
+ }
+ return mpViewForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleEditObjectTextData::GetEditViewForwarder( sal_Bool bCreate )
+{
+ if (!mpEditViewForwarder && mpEditView)
+ mpEditViewForwarder = new ScEditViewForwarder(mpEditView, mpWindow);
+ if (bCreate)
+ {
+ if (!mpEditView && mpEditViewForwarder)
+ {
+ DELETEZ(mpEditViewForwarder);
+ }
+ else if (mpEditViewForwarder)
+ mpEditViewForwarder->GrabFocus();
+ }
+ return mpEditViewForwarder;
+}
+
+IMPL_LINK(ScAccessibleEditObjectTextData, NotifyHdl, EENotify*, aNotify)
+{
+ if( aNotify )
+ {
+ ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
+
+ if( aHint.get() )
+ GetBroadcaster().Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+
+// ============================================================================
+
+ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView* pEditView, Window* pWin)
+ :
+ ScAccessibleEditObjectTextData(pEditView, pWin),
+ mbEditEngineCreated(sal_False)
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)pWin;
+
+ if (pTxtWnd)
+ pTxtWnd->InsertAccessibleTextData( *this );
+}
+
+ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ pTxtWnd->RemoveAccessibleTextData( *this );
+
+ if (mbEditEngineCreated && mpEditEngine)
+ {
+ delete mpEditEngine;
+ mpEditEngine = NULL; // #103346# don't access in ScAccessibleEditObjectTextData dtor!
+ }
+ else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine())
+ {
+ // #103346# the NotifyHdl also has to be removed from the ScTextWnd's EditEngine
+ // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine
+ // is reset there)
+ pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link());
+ }
+}
+
+void ScAccessibleEditLineTextData::Dispose()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ pTxtWnd->RemoveAccessibleTextData( *this );
+
+ ResetEditMode();
+ mpWindow = NULL;
+}
+
+ScAccessibleTextData* ScAccessibleEditLineTextData::Clone() const
+{
+ return new ScAccessibleEditLineTextData(mpEditView, mpWindow);
+}
+
+SvxTextForwarder* ScAccessibleEditLineTextData::GetTextForwarder()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ {
+ mpEditView = pTxtWnd->GetEditView();
+ if (mpEditView)
+ {
+ if (mbEditEngineCreated && mpEditEngine)
+ ResetEditMode();
+ mbEditEngineCreated = sal_False;
+
+ mpEditView = pTxtWnd->GetEditView();
+ ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder
+ mpEditEngine = NULL;
+ }
+ else
+ {
+ if (mpEditEngine && !mbEditEngineCreated)
+ ResetEditMode();
+ if (!mpEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ mbEditEngineCreated = sal_True;
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+ // pEditEngine->SetUpdateMode( FALSE );
+ mpEditEngine->EnableUndo( FALSE );
+ mpEditEngine->SetRefMapMode( MAP_100TH_MM );
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+
+ mpEditEngine->SetText(pTxtWnd->GetTextString());
+
+ Size aSize(pTxtWnd->GetSizePixel());
+
+ aSize = pTxtWnd->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+
+ mpEditEngine->SetPaperSize(aSize);
+
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
+ }
+ }
+ }
+ return mpForwarder;
+}
+
+SvxEditViewForwarder* ScAccessibleEditLineTextData::GetEditViewForwarder( sal_Bool bCreate )
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ {
+ mpEditView = pTxtWnd->GetEditView();
+ if (!mpEditView && bCreate)
+ {
+ if ( !pTxtWnd->IsInputActive() )
+ {
+ pTxtWnd->StartEditEngine();
+ pTxtWnd->GrabFocus();
+// pTxtWnd->SetTextString( rText );
+// pTxtWnd->GetEditView()->SetSelection( rSel );
+
+ mpEditView = pTxtWnd->GetEditView();
+ }
+ }
+ }
+
+ return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate);
+}
+
+void ScAccessibleEditLineTextData::ResetEditMode()
+{
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (mbEditEngineCreated && mpEditEngine)
+ delete mpEditEngine;
+ else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine())
+ pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link());
+ mpEditEngine = NULL;
+
+ DELETEZ(mpForwarder);
+ DELETEZ(mpEditViewForwarder);
+ DELETEZ(mpViewForwarder);
+ mbEditEngineCreated = sal_False;
+}
+
+void ScAccessibleEditLineTextData::TextChanged()
+{
+ if (mbEditEngineCreated && mpEditEngine)
+ {
+ ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow;
+
+ if (pTxtWnd)
+ mpEditEngine->SetText(pTxtWnd->GetTextString());
+ }
+}
+
+void ScAccessibleEditLineTextData::StartEdit()
+{
+ ResetEditMode();
+ mpEditView = NULL;
+
+ // send HINT_BEGEDIT
+ SdrHint aHint(HINT_BEGEDIT);
+ GetBroadcaster().Broadcast( aHint );
+}
+
+void ScAccessibleEditLineTextData::EndEdit()
+{
+ // send HINT_ENDEDIT
+ SdrHint aHint(HINT_ENDEDIT);
+ GetBroadcaster().Broadcast( aHint );
+
+ ResetEditMode();
+ mpEditView = NULL;
+}
+
+
+// ============================================================================
+
+// ScAccessiblePreviewCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell* pViewShell,
+ const ScAddress& rP)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell)
+{
+}
+
+ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+}
+
+void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessiblePreviewCellTextData::Clone() const
+{
+ return new ScAccessiblePreviewCellTextData(mpViewShell, aCellPos);
+}
+
+SvxTextForwarder* ScAccessiblePreviewCellTextData::GetTextForwarder()
+{
+ sal_Bool bEditEngineBefore(pEditEngine != NULL);
+
+ ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
+
+ if (!bEditEngineBefore && pEditEngine)
+ {
+ Size aSize(mpViewShell->GetLocationData().GetCellOutputRect(aCellPos).GetSize());
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
+ pEditEngine->SetPaperSize(aSize);
+ }
+
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessiblePreviewCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewCellViewForwarder(mpViewShell, aCellPos);
+ return mpViewForwarder;
+}
+
+//UNUSED2008-05 IMPL_LINK(ScAccessiblePreviewCellTextData, NotifyHdl, EENotify*, aNotify)
+//UNUSED2008-05 {
+//UNUSED2008-05 if( aNotify )
+//UNUSED2008-05 {
+//UNUSED2008-05 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify);
+//UNUSED2008-05
+//UNUSED2008-05 if( aHint.get() )
+//UNUSED2008-05 GetBroadcaster().Broadcast( *aHint.get() );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+ScDocShell* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell && pViewShell->GetDocument())
+ pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+// ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of a accessible cell text object
+
+ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell* pViewShell,
+ const String& rText, const ScAddress& rP, sal_Bool bColHeader, sal_Bool bRowHeader)
+ : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ maText(rText),
+ mbColHeader(bColHeader),
+ mbRowHeader(bRowHeader)
+{
+}
+
+ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData()
+{
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl(Link());
+ if (mpViewForwarder)
+ delete mpViewForwarder;
+}
+
+void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL; // invalid now
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleCellBaseTextData::Notify(rBC, rHint);
+}
+
+ScAccessibleTextData* ScAccessiblePreviewHeaderCellTextData::Clone() const
+{
+ return new ScAccessiblePreviewHeaderCellTextData(mpViewShell, maText, aCellPos, mbColHeader, mbRowHeader);
+}
+
+SvxTextForwarder* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( FALSE );
+ pEditEngine->EnableUndo( FALSE );
+ if (pDocShell)
+ pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
+ else
+ pEditEngine->SetRefMapMode( MAP_100TH_MM );
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ if (maText.Len() && pEditEngine)
+ {
+
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ Size aSize(mpViewShell->GetLocationData().GetHeaderCellOutputRect(aVisRect, aCellPos, mbColHeader).GetSize());
+ if (pWindow)
+ aSize = pWindow->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
+ pEditEngine->SetPaperSize(aSize);
+ }
+ pEditEngine->SetText( maText );
+ }
+
+ bDataValid = TRUE;
+
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return pForwarder;
+}
+
+SvxViewForwarder* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewHeaderCellViewForwarder(mpViewShell, aCellPos, mbColHeader, mbRowHeader);
+ return mpViewForwarder;
+}
+
+//UNUSED2008-05 IMPL_LINK(ScAccessiblePreviewHeaderCellTextData, NotifyHdl, EENotify*, aNotify)
+//UNUSED2008-05 {
+//UNUSED2008-05 if( aNotify )
+//UNUSED2008-05 {
+//UNUSED2008-05 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify);
+//UNUSED2008-05
+//UNUSED2008-05 if( aHint.get() )
+//UNUSED2008-05 GetBroadcaster().Broadcast( *aHint.get() );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+
+ScDocShell* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell* pViewShell)
+{
+ ScDocShell* pDocSh = NULL;
+ if (pViewShell && pViewShell->GetDocument())
+ pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ return pDocSh;
+}
+
+
+// ============================================================================
+
+ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell* pViewShell,
+ const EditTextObject* pEditObj, sal_Bool bHeader, SvxAdjust eAdjust)
+ :
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ mpEditEngine(NULL),
+ mpForwarder(NULL),
+ mpDocSh(NULL),
+ mpEditObj(pEditObj),
+ mbHeader(bHeader),
+ mbDataValid(sal_False),
+ meAdjust(eAdjust)
+{
+ if (pViewShell && pViewShell->GetDocument())
+ mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ if (mpDocSh)
+ mpDocSh->GetDocument()->AddUnoObject(*this);
+}
+
+ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (mpDocSh)
+ mpDocSh->GetDocument()->RemoveUnoObject(*this);
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ delete mpEditEngine;
+ delete mpForwarder;
+}
+
+ScAccessibleTextData* ScAccessibleHeaderTextData::Clone() const
+{
+ return new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust);
+}
+
+void ScAccessibleHeaderTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL;// invalid now
+ mpDocSh = NULL;
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleHeaderTextData::GetTextForwarder()
+{
+ if (!mpEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, TRUE );
+
+ pHdrEngine->EnableUndo( FALSE );
+ pHdrEngine->SetRefMapMode( MAP_TWIP );
+
+ // default font must be set, independently of document
+ // -> use global pool from module
+
+ SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( &aDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ aDefaults.Put( SvxAdjustItem( meAdjust, EE_PARA_JUST ) );
+ pHdrEngine->SetDefaults( aDefaults );
+
+ ScHeaderFieldData aData;
+ if (mpViewShell)
+ mpViewShell->FillFieldData(aData);
+ else
+ ScHeaderFooterTextObj::FillDummyFieldData( aData );
+ pHdrEngine->SetData( aData );
+
+ mpEditEngine = pHdrEngine;
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+
+ if (mbDataValid)
+ return mpForwarder;
+
+ if ( mpViewShell )
+ {
+ Rectangle aVisRect;
+ mpViewShell->GetLocationData().GetHeaderPosition(aVisRect);
+ Size aSize(aVisRect.GetSize());
+ Window* pWin = mpViewShell->GetWindow();
+ if (pWin)
+ aSize = pWin->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+ mpEditEngine->SetPaperSize(aSize);
+ }
+ if (mpEditObj)
+ mpEditEngine->SetText(*mpEditObj);
+
+ mbDataValid = sal_True;
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleHeaderTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewHeaderFooterViewForwarder(mpViewShell, mbHeader);
+ return mpViewForwarder;
+}
+
+
+// ============================================================================
+
+ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell* pViewShell,
+ const String& sText, const ScAddress& aCellPos, sal_Bool bMarkNote)
+ :
+ mpViewForwarder(NULL),
+ mpViewShell(pViewShell),
+ mpEditEngine(NULL),
+ mpForwarder(NULL),
+ mpDocSh(NULL),
+ msText(sText),
+ maCellPos(aCellPos),
+ mbMarkNote(bMarkNote),
+ mbDataValid(sal_False)
+{
+ if (pViewShell && pViewShell->GetDocument())
+ mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell();
+ if (mpDocSh)
+ mpDocSh->GetDocument()->AddUnoObject(*this);
+}
+
+ScAccessibleNoteTextData::~ScAccessibleNoteTextData()
+{
+ ScUnoGuard aGuard; // needed for EditEngine dtor
+
+ if (mpDocSh)
+ mpDocSh->GetDocument()->RemoveUnoObject(*this);
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl(Link());
+ delete mpEditEngine;
+ delete mpForwarder;
+}
+
+ScAccessibleTextData* ScAccessibleNoteTextData::Clone() const
+{
+ return new ScAccessibleNoteTextData(mpViewShell, msText, maCellPos, mbMarkNote);
+}
+
+void ScAccessibleNoteTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ mpViewShell = NULL;// invalid now
+ mpDocSh = NULL;
+ if (mpViewForwarder)
+ mpViewForwarder->SetInvalid();
+ }
+ }
+}
+
+SvxTextForwarder* ScAccessibleNoteTextData::GetTextForwarder()
+{
+ if (!mpEditEngine)
+ {
+ if ( mpDocSh )
+ {
+ ScDocument* pDoc = mpDocSh->GetDocument();
+ mpEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is FALSE,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( FALSE );
+ mpEditEngine->EnableUndo( FALSE );
+ if (mpDocSh)
+ mpEditEngine->SetRefDevice(mpDocSh->GetRefDevice());
+ else
+ mpEditEngine->SetRefMapMode( MAP_100TH_MM );
+ mpForwarder = new SvxEditEngineForwarder(*mpEditEngine);
+ }
+
+ if (mbDataValid)
+ return mpForwarder;
+
+ if (msText.Len() && mpEditEngine)
+ {
+
+ if ( mpViewShell )
+ {
+ Size aOutputSize;
+ Window* pWindow = mpViewShell->GetWindow();
+ if ( pWindow )
+ aOutputSize = pWindow->GetOutputSizePixel();
+ Point aPoint;
+ Rectangle aVisRect( aPoint, aOutputSize );
+ Size aSize(mpViewShell->GetLocationData().GetNoteInRangeOutputRect(aVisRect, mbMarkNote, maCellPos).GetSize());
+ if (pWindow)
+ aSize = pWindow->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
+ mpEditEngine->SetPaperSize(aSize);
+ }
+ mpEditEngine->SetText( msText );
+ }
+
+ mbDataValid = TRUE;
+
+ if (mpEditEngine)
+ mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
+
+ return mpForwarder;
+}
+
+SvxViewForwarder* ScAccessibleNoteTextData::GetViewForwarder()
+{
+ if (!mpViewForwarder)
+ mpViewForwarder = new ScPreviewNoteViewForwarder(mpViewShell, maCellPos, mbMarkNote);
+ return mpViewForwarder;
+}
+
+
+// CSV import =================================================================
+
+class ScCsvViewForwarder : public SvxViewForwarder
+{
+ Rectangle maBoundBox;
+ Window* mpWindow;
+
+public:
+ explicit ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox );
+
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ void SetInvalid();
+};
+
+ScCsvViewForwarder::ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox ) :
+ maBoundBox( rBoundBox ),
+ mpWindow( pWindow )
+{
+}
+
+BOOL ScCsvViewForwarder::IsValid() const
+{
+ return mpWindow != NULL;
+}
+
+Rectangle ScCsvViewForwarder::GetVisArea() const
+{
+ return maBoundBox;
+}
+
+Point ScCsvViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if( !mpWindow ) return Point();
+ return mpWindow->LogicToPixel( rPoint, rMapMode );
+}
+
+Point ScCsvViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ if( !mpWindow ) return Point();
+ return mpWindow->PixelToLogic( rPoint, rMapMode );
+}
+
+void ScCsvViewForwarder::SetInvalid()
+{
+ mpWindow = NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+ScAccessibleCsvTextData::ScAccessibleCsvTextData(
+ Window* pWindow, EditEngine* pEditEngine,
+ const String& rCellText, const Rectangle& rBoundBox, const Size& rCellSize ) :
+ mpWindow( pWindow ),
+ mpEditEngine( pEditEngine ),
+ maCellText( rCellText ),
+ maBoundBox( rBoundBox ),
+ maCellSize( rCellSize )
+{
+}
+
+ScAccessibleCsvTextData::~ScAccessibleCsvTextData()
+{
+}
+
+void ScAccessibleCsvTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
+ if( nId == SFX_HINT_DYING )
+ {
+ mpWindow = NULL;
+ mpEditEngine = NULL;
+ if (mpViewForwarder.get())
+ mpViewForwarder->SetInvalid();
+ }
+ }
+ ScAccessibleTextData::Notify( rBC, rHint );
+}
+
+ScAccessibleTextData* ScAccessibleCsvTextData::Clone() const
+{
+ return new ScAccessibleCsvTextData( mpWindow, mpEditEngine, maCellText, maBoundBox, maCellSize );
+}
+
+SvxTextForwarder* ScAccessibleCsvTextData::GetTextForwarder()
+{
+ if( mpEditEngine )
+ {
+ mpEditEngine->SetPaperSize( maCellSize );
+ mpEditEngine->SetText( maCellText );
+ if( !mpTextForwarder.get() )
+ mpTextForwarder.reset( new SvxEditEngineForwarder( *mpEditEngine ) );
+ }
+ else
+ mpTextForwarder.reset( NULL );
+ return mpTextForwarder.get();
+}
+
+SvxViewForwarder* ScAccessibleCsvTextData::GetViewForwarder()
+{
+ if( !mpViewForwarder.get() )
+ mpViewForwarder.reset( new ScCsvViewForwarder( mpWindow, maBoundBox ) );
+ return mpViewForwarder.get();
+}
+
+SvxEditViewForwarder* ScAccessibleCsvTextData::GetEditViewForwarder( sal_Bool /* bCreate */ )
+{
+ return NULL;
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx
new file mode 100644
index 000000000000..31bf438772d0
--- /dev/null
+++ b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "DrawModelBroadcaster.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/unomod.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+
+ScDrawModelBroadcaster::ScDrawModelBroadcaster( SdrModel *pDrawModel ) :
+ maEventListeners( maListenerMutex ),
+ mpDrawModel( pDrawModel )
+{
+ if (mpDrawModel)
+ StartListening( *mpDrawModel );
+}
+
+ScDrawModelBroadcaster::~ScDrawModelBroadcaster()
+{
+ if (mpDrawModel)
+ EndListening( *mpDrawModel );
+}
+
+void SAL_CALL ScDrawModelBroadcaster::addEventListener( const uno::Reference< document::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ maEventListeners.addInterface( xListener );
+}
+
+void SAL_CALL ScDrawModelBroadcaster::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ maEventListeners.removeInterface( xListener );
+}
+
+void ScDrawModelBroadcaster::Notify( SfxBroadcaster&,
+ const SfxHint& rHint )
+{
+ const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
+ if( !pSdrHint )
+ return;
+
+ document::EventObject aEvent;
+ if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
+ return;
+
+ ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
+ while( aIter.hasMoreElements() )
+ {
+ uno::Reference < document::XEventListener > xListener( aIter.next(), uno::UNO_QUERY );
+ try
+ {
+ xListener->notifyEvent( aEvent );
+ }
+ catch( uno::RuntimeException& r )
+ {
+ (void) r;
+#if OSL_DEBUG_LEVEL > 1
+ ByteString aError( "Runtime exception caught while notifying shape.:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ DBG_ERROR( aError.GetBuffer() );
+#endif
+ }
+ }
+}
diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk
new file mode 100644
index 000000000000..32df95750f85
--- /dev/null
+++ b/sc/source/ui/Accessibility/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=accessibility
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/AccessibleContextBase.obj \
+ $(SLO)$/AccessibleTableBase.obj \
+ $(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
+ $(SLO)$/AccessibleSpreadsheet.obj \
+ $(SLO)$/AccessibleCell.obj \
+ $(SLO)$/AccessibilityHints.obj \
+ $(SLO)$/AccessibleDocumentBase.obj \
+ $(SLO)$/AccessibleCellBase.obj \
+ $(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
+ $(SLO)$/AccessiblePreviewTable.obj \
+ $(SLO)$/AccessiblePreviewCell.obj \
+ $(SLO)$/AccessiblePreviewHeaderCell.obj \
+ $(SLO)$/AccessiblePageHeader.obj \
+ $(SLO)$/AccessibleText.obj \
+ $(SLO)$/AccessiblePageHeaderArea.obj \
+ $(SLO)$/DrawModelBroadcaster.obj \
+ $(SLO)$/AccessibleEditObject.obj \
+ $(SLO)$/AccessibleDataPilotControl.obj \
+ $(SLO)$/AccessibleCsvControl.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/AccessibleContextBase.obj \
+ $(SLO)$/AccessibleTableBase.obj \
+ $(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
+ $(SLO)$/AccessibleSpreadsheet.obj \
+ $(SLO)$/AccessibleCell.obj \
+ $(SLO)$/AccessibleDocumentBase.obj \
+ $(SLO)$/AccessibleCellBase.obj \
+ $(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
+ $(SLO)$/AccessiblePreviewTable.obj \
+ $(SLO)$/AccessiblePreviewCell.obj \
+ $(SLO)$/AccessiblePreviewHeaderCell.obj \
+ $(SLO)$/AccessiblePageHeader.obj \
+ $(SLO)$/AccessiblePageHeaderArea.obj \
+ $(SLO)$/DrawModelBroadcaster.obj \
+ $(SLO)$/AccessibleEditObject.obj \
+ $(SLO)$/AccessibleDataPilotControl.obj \
+ $(SLO)$/AccessibleCsvControl.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+