diff options
Diffstat (limited to 'sc/source/ui/Accessibility/AccessibleCellBase.cxx')
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleCellBase.cxx | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx new file mode 100644 index 000000000..03ecf65af --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx @@ -0,0 +1,590 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <AccessibleCellBase.hxx> +#include <document.hxx> +#include <docfunc.hxx> +#include <docsh.hxx> +#include <strings.hxx> +#include <unonames.hxx> +#include <detfunc.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp> +#include <com/sun/star/text/XSimpleText.hpp> +#include <com/sun/star/table/BorderLine.hpp> +#include <com/sun/star/table/ShadowFormat.hpp> +#include <comphelper/sequence.hxx> +#include <sfx2/objsh.hxx> +#include <vcl/svapp.hxx> + +#include <float.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +#define DEFAULT_LINE_WIDTH 2 + +//===== 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 ============================================ + +bool ScAccessibleCellBase::isVisible() +{ + SolarMutexGuard aGuard; + IsObjectValid(); + // test whether the cell is hidden (column/row - hidden/filtered) + bool bVisible(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 = false; + } + return bVisible; +} + +sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground() +{ + SolarMutexGuard 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(SC_UNONAME_CCOLOR); + aAny >>= nColor; + } + } + } + } + } + } + } + return nColor; +} + +sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground() +{ + SolarMutexGuard 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(SC_UNONAME_CELLBACK); + aAny >>= nColor; + } + } + } + } + } + } + } + + return nColor; +} + + //===== XInterface ===================================================== + +uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType ) +{ + uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType)); + return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); +} + +void SAL_CALL ScAccessibleCellBase::acquire() + noexcept +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleCellBase::release() + noexcept +{ + ScAccessibleContextBase::release(); +} + + //===== XAccessibleContext ============================================== + +sal_Int32 + ScAccessibleCellBase::getAccessibleIndexInParent() +{ + SolarMutexGuard aGuard; + IsObjectValid(); + return mnIndex; +} + +OUString + ScAccessibleCellBase::createAccessibleDescription() +{ + return STR_ACC_CELL_DESCR; +} + +OUString + ScAccessibleCellBase::createAccessibleName() +{ + // Document not needed, because only the cell address, but not the tablename is needed + // always us OOO notation + return maCellAddress.Format(ScRefFlags::VALID); +} + + //===== XAccessibleValue ================================================ + +uno::Any SAL_CALL + ScAccessibleCellBase::getCurrentValue() +{ + SolarMutexGuard aGuard; + IsObjectValid(); + uno::Any aAny; + if (mpDoc) + { + aAny <<= mpDoc->GetValue(maCellAddress); + } + return aAny; +} + +sal_Bool SAL_CALL + ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber ) +{ + SolarMutexGuard aGuard; + IsObjectValid(); + double fValue = 0; + bool bResult = 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 = static_cast<ScDocShell*>(mpDoc->GetDocumentShell()); + bResult = pDocShell->GetDocFunc().SetValueCell(maCellAddress, fValue, false); + } + } + return bResult; +} + +uno::Any SAL_CALL + ScAccessibleCellBase::getMaximumValue( ) +{ + return uno::Any(DBL_MAX); +} + +uno::Any SAL_CALL + ScAccessibleCellBase::getMinimumValue( ) +{ + return uno::Any(-DBL_MAX); +} + +uno::Any SAL_CALL + ScAccessibleCellBase::getMinimumIncrement( ) +{ + return uno::Any(); +} + + //===== XServiceInfo ==================================================== + +OUString SAL_CALL ScAccessibleCellBase::getImplementationName() +{ + return "ScAccessibleCellBase"; +} + + //===== XTypeProvider =================================================== + +uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes() +{ + return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes()); +} + +uno::Sequence<sal_Int8> SAL_CALL + ScAccessibleCellBase::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +bool ScAccessibleCellBase::IsEditable( + const uno::Reference<XAccessibleStateSet>& rxParentStates) +{ + bool bEditable(false); + if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE)) + bEditable = true; + return bEditable; +} + +OUString ScAccessibleCellBase::GetNote() const +{ + SolarMutexGuard aGuard; + IsObjectValid(); + OUString sNote; + 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 <sheet::XSheetAnnotationAnchor> xAnnotationAnchor ( xCell, uno::UNO_QUERY); + if(xAnnotationAnchor.is()) + { + uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation = xAnnotationAnchor->getAnnotation(); + if (xSheetAnnotation.is()) + { + uno::Reference <text::XSimpleText> xText (xSheetAnnotation, uno::UNO_QUERY); + if (xText.is()) + { + sNote = xText->getString(); + } + } + } + } + } + } + } + } + } + return sNote; +} + +OUString ScAccessibleCellBase::getShadowAttrs() const +{ + SolarMutexGuard aGuard; + IsObjectValid(); + table::ShadowFormat aShadowFmt; + 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(SC_UNONAME_SHADOW); + aAny >>= aShadowFmt; + } + } + } + } + } + } + } + //construct shadow attributes string + OUString sShadowAttrs("Shadow:"); + OUString sInnerSplit(","); + OUString sOuterSplit(";"); + sal_Int32 nLocationVal = 0; + switch( aShadowFmt.Location ) + { + case table::ShadowLocation_TOP_LEFT: + nLocationVal = 1; + break; + case table::ShadowLocation_TOP_RIGHT: + nLocationVal = 2; + break; + case table::ShadowLocation_BOTTOM_LEFT: + nLocationVal = 3; + break; + case table::ShadowLocation_BOTTOM_RIGHT: + nLocationVal = 4; + break; + default: + break; + } + //if there is no shadow property for the cell + if ( nLocationVal == 0 ) + { + sShadowAttrs += sOuterSplit; + return sShadowAttrs; + } + //else return all the shadow properties + sShadowAttrs += "Location=" + + OUString::number( nLocationVal ) + + sInnerSplit + + "ShadowWidth=" + + OUString::number( static_cast<sal_Int32>(aShadowFmt.ShadowWidth) ) + + sInnerSplit + + "IsTransparent=" + + OUString::number( static_cast<int>(aShadowFmt.IsTransparent) ) + + sInnerSplit + + "Color=" + + OUString::number( aShadowFmt.Color ) + + sOuterSplit; + return sShadowAttrs; +} + +OUString ScAccessibleCellBase::getBorderAttrs() +{ + SolarMutexGuard aGuard; + IsObjectValid(); + table::BorderLine aTopBorder; + table::BorderLine aBottomBorder; + table::BorderLine aLeftBorder; + table::BorderLine aRightBorder; + 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(SC_UNONAME_TOPBORDER); + aAny >>= aTopBorder; + aAny = xCellProps->getPropertyValue(SC_UNONAME_BOTTBORDER); + aAny >>= aBottomBorder; + aAny = xCellProps->getPropertyValue(SC_UNONAME_LEFTBORDER); + aAny >>= aLeftBorder; + aAny = xCellProps->getPropertyValue(SC_UNONAME_RIGHTBORDER); + aAny >>= aRightBorder; + } + } + } + } + } + } + } + + Color aColor; + bool bIn = mpDoc && mpDoc->IsCellInChangeTrack(maCellAddress,&aColor); + if (bIn) + { + aTopBorder.Color = sal_Int32(aColor); + aBottomBorder.Color = sal_Int32(aColor); + aLeftBorder.Color = sal_Int32(aColor); + aRightBorder.Color = sal_Int32(aColor); + aTopBorder.OuterLineWidth = DEFAULT_LINE_WIDTH; + aBottomBorder.OuterLineWidth = DEFAULT_LINE_WIDTH; + aLeftBorder.OuterLineWidth = DEFAULT_LINE_WIDTH; + aRightBorder.OuterLineWidth = DEFAULT_LINE_WIDTH; + } + + //construct border attributes string + OUString sBorderAttrs; + OUString sInnerSplit(","); + OUString sOuterSplit(";"); + //top border + //if top of the cell has no border + if ( aTopBorder.InnerLineWidth == 0 && aTopBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "TopBorder:;"; + } + else//add all the border properties to the return string. + { + sBorderAttrs += "TopBorder:Color=" + + OUString::number( aTopBorder.Color ) + + sInnerSplit + + "InnerLineWidth=" + + OUString::number( static_cast<sal_Int32>(aTopBorder.InnerLineWidth) ) + + sInnerSplit + + "OuterLineWidth=" + + OUString::number( static_cast<sal_Int32>(aTopBorder.OuterLineWidth) ) + + sInnerSplit + + "LineDistance=" + + OUString::number( static_cast<sal_Int32>(aTopBorder.LineDistance) ) + + sOuterSplit; + } + //bottom border + if ( aBottomBorder.InnerLineWidth == 0 && aBottomBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "BottomBorder:;"; + } + else + { + sBorderAttrs += "BottomBorder:Color=" + + OUString::number( aBottomBorder.Color ) + + sInnerSplit + + "InnerLineWidth=" + + OUString::number( static_cast<sal_Int32>(aBottomBorder.InnerLineWidth) ) + + sInnerSplit + + "OuterLineWidth=" + + OUString::number( static_cast<sal_Int32>(aBottomBorder.OuterLineWidth) ) + + sInnerSplit + + "LineDistance=" + + OUString::number( static_cast<sal_Int32>(aBottomBorder.LineDistance) ) + + sOuterSplit; + } + //left border + if ( aLeftBorder.InnerLineWidth == 0 && aLeftBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "LeftBorder:;"; + } + else + { + sBorderAttrs += "LeftBorder:Color=" + + OUString::number( aLeftBorder.Color ) + + sInnerSplit + + "InnerLineWidth=" + + OUString::number( static_cast<sal_Int32>(aLeftBorder.InnerLineWidth) ) + + sInnerSplit + + "OuterLineWidth=" + + OUString::number( static_cast<sal_Int32>(aLeftBorder.OuterLineWidth) ) + + sInnerSplit + + "LineDistance=" + + OUString::number( static_cast<sal_Int32>(aLeftBorder.LineDistance) ) + + sOuterSplit; + } + //right border + if ( aRightBorder.InnerLineWidth == 0 && aRightBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "RightBorder:;"; + } + else + { + sBorderAttrs += "RightBorder:Color=" + + OUString::number( aRightBorder.Color ) + + sInnerSplit + + "InnerLineWidth=" + + OUString::number( static_cast<sal_Int32>(aRightBorder.InnerLineWidth) ) + + sInnerSplit + + "OuterLineWidth=" + + OUString::number( static_cast<sal_Int32>(aRightBorder.OuterLineWidth) ) + + sInnerSplit + + "LineDistance=" + + OUString::number( static_cast<sal_Int32>(aRightBorder.LineDistance) ) + + sOuterSplit; + } + return sBorderAttrs; +} +//end of cell attributes + +OUString ScAccessibleCellBase::GetAllDisplayNote() const +{ + OUString strNote; + OUString strTrackText; + if (mpDoc) + { + bool bLeftedge = false; + mpDoc->GetCellChangeTrackNote(maCellAddress,strTrackText,bLeftedge); + } + if (!strTrackText.isEmpty()) + { + ScDetectiveFunc::AppendChangTrackNoteSeparator(strTrackText); + strNote = strTrackText; + } + strNote += GetNote(); + return strNote; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |