diff options
author | Steve Yin <steve_y@apache.org> | 2013-12-02 15:54:29 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-12-02 16:41:08 +0000 |
commit | b41332475783c31136673fb44cf4c411bb0148f8 (patch) | |
tree | 39ba57867ed6ae3f39e60c38180f800542067b49 /sc/source/ui/Accessibility | |
parent | 23fdf75cd6e6cb37bfeac08f503a15d07d9beda9 (diff) |
Integrate branch of IAccessible2
Conflicts:
everything
Change-Id: I3d8cf956f511a0d953a1cefe83b6ef987806da25
Diffstat (limited to 'sc/source/ui/Accessibility')
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleCell.cxx | 180 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleCellBase.cxx | 322 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx | 115 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDocument.cxx | 488 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDocumentBase.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx | 27 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleEditObject.cxx | 202 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx | 1006 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleTableBase.cxx | 58 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleText.cxx | 15 |
10 files changed, 2276 insertions, 142 deletions
diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx index 199ec69295d7..c768f8a63eff 100644 --- a/sc/source/ui/Accessibility/AccessibleCell.cxx +++ b/sc/source/ui/Accessibility/AccessibleCell.cxx @@ -33,6 +33,7 @@ #include "markdata.hxx" #include "cellvalue.hxx" #include "formulaiter.hxx" +#include "validat.hxx" #include <unotools/accessiblestatesethelper.hxx> #include <com/sun/star/accessibility/AccessibleRole.hpp> @@ -44,6 +45,8 @@ #include <float.h> #include <vcl/svapp.hxx> +#include "AccessibleSpreadsheet.hxx" + using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; @@ -103,11 +106,11 @@ void SAL_CALL ScAccessibleCell::disposing() //===== XInterface ===================================================== -IMPLEMENT_FORWARD_XINTERFACE2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase ) +IMPLEMENT_FORWARD_XINTERFACE3( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase, ScAccessibleCellAttributeImpl ) //===== XTypeProvider =================================================== -IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase ) +IMPLEMENT_FORWARD_XTYPEPROVIDER3( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase, ScAccessibleCellAttributeImpl ) //===== XAccessibleComponent ============================================ @@ -226,6 +229,23 @@ uno::Reference<XAccessibleStateSet> SAL_CALL pStateSet->AddState(AccessibleStateType::DEFUNC); else { + if (IsFormulaMode()) + { + 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; + } if (IsEditable(xParentStates)) { pStateSet->AddState(AccessibleStateType::EDITABLE); @@ -234,6 +254,7 @@ uno::Reference<XAccessibleStateSet> SAL_CALL pStateSet->AddState(AccessibleStateType::ENABLED); pStateSet->AddState(AccessibleStateType::MULTI_LINE); pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE); + pStateSet->AddState(AccessibleStateType::FOCUSABLE); if (IsOpaque(xParentStates)) pStateSet->AddState(AccessibleStateType::OPAQUE); pStateSet->AddState(AccessibleStateType::SELECTABLE); @@ -329,6 +350,16 @@ sal_Bool ScAccessibleCell::IsOpaque( sal_Bool ScAccessibleCell::IsSelected() { + if (IsFormulaMode()) + { + const ScAccessibleSpreadsheet *pSheet =static_cast<const ScAccessibleSpreadsheet*>(mxParent.get()); + if (pSheet) + { + return pSheet->IsScAddrFormulaSel(maCellAddress); + } + return sal_False; + } + sal_Bool bResult(false); if (mpViewShell && mpViewShell->GetViewData()) { @@ -349,6 +380,10 @@ ScDocument* ScAccessibleCell::GetDocument(ScTabViewShell* pViewShell) SAL_WNODEPRECATED_DECLARATIONS_PUSH ::std::auto_ptr< SvxEditSource > ScAccessibleCell::CreateEditSource(ScTabViewShell* pViewShell, ScAddress aCell, ScSplitPos eSplitPos) { + if (IsFormulaMode()) + { + return ::std::auto_ptr< SvxEditSource >(); + } ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData ( new ScAccessibleCellTextData( pViewShell, aCell, eSplitPos, this ) ); ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleCellTextData)); @@ -435,4 +470,145 @@ void ScAccessibleCell::AddRelation(const ScRange& rRange, } } +OUString ReplaceOneChar(OUString oldOUString, OUString replacedChar, OUString replaceStr) +{ + int iReplace = -1; + iReplace = oldOUString.lastIndexOf(replacedChar); + if (iReplace > -1) + { + for(;iReplace>-1;) + { + oldOUString = oldOUString.replaceAt(iReplace,1, replaceStr); + iReplace=oldOUString.lastIndexOf(replacedChar,iReplace); + } + } + return oldOUString; +} + +OUString ReplaceFourChar(OUString oldOUString) +{ + oldOUString = ReplaceOneChar(oldOUString, "\\", "\\\\"); + oldOUString = ReplaceOneChar(oldOUString, ";", "\\;"); + oldOUString = ReplaceOneChar(oldOUString, "=", "\\="); + oldOUString = ReplaceOneChar(oldOUString, ",", "\\,"); + oldOUString = ReplaceOneChar(oldOUString, ":", "\\:"); + return oldOUString; +} + +uno::Any SAL_CALL ScAccessibleCell::getExtendedAttributes() + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + uno::Any strRet; + if (mpViewShell) + { + const OUString strAttr(":"); + const OUString strSplit(";"); + OUString strFor = mpViewShell->GetFormula(maCellAddress) ; + strFor = strFor.replaceAt(0,1,""); + strFor = ReplaceFourChar(strFor); + strFor = "Formula:" + strFor; + strFor += strSplit; + strFor += "Note:"; + strFor += ReplaceFourChar(GetAllDisplayNote()); + strFor += strSplit; + strFor += getShadowAttrs();//the string returned contains the spliter ";" + strFor += getBorderAttrs();//the string returned contains the spliter ";" + //end of cell attributes + if( mpDoc ) + { + strFor += "isdropdown:"; + if( IsDropdown() ) + strFor += "true"; + else + strFor += "false"; + strFor += ";"; + } + strRet <<= strFor ; + } + return strRet; +} + +// cell has its own ParaIndent property, so when calling character attributes on cell, the ParaIndent should replace the ParaLeftMargin if its value is not zero. +uno::Sequence< beans::PropertyValue > SAL_CALL ScAccessibleCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + uno::Sequence< beans::PropertyValue > aAttribs = AccessibleStaticTextBase::getCharacterAttributes( nIndex, aRequestedAttributes ); + beans::PropertyValue *pAttribs = aAttribs.getArray(); + + sal_uInt16 nParaIndent = static_cast< const SfxUInt16Item* >( mpDoc->GetAttr( maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_INDENT ) )->GetValue(); + if (nParaIndent > 0) + { + OUString sLeftMarginName ("ParaLeftMargin"); + for (int i = 0; i < aAttribs.getLength(); ++i) + { + if (sLeftMarginName == pAttribs[i].Name) + { + pAttribs[i].Value = uno::makeAny( nParaIndent ); + break; + } + } + } + return aAttribs; +} + +sal_Bool ScAccessibleCell::IsFormulaMode() +{ + ScAccessibleSpreadsheet* pSheet =static_cast<ScAccessibleSpreadsheet*>(mxParent.get()); + if (pSheet) + { + return pSheet->IsFormulaMode(); + } + return sal_False; +} +sal_Bool ScAccessibleCell::IsDropdown() +{ + sal_uInt16 nPosX = maCellAddress.Col(); + sal_uInt16 nPosY = sal_uInt16(maCellAddress.Row()); + sal_uInt16 nTab = maCellAddress.Tab(); + sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( mpDoc->GetAttr( nPosX, nPosY, nTab, ATTR_VALIDDATA ) )->GetValue(); + if( nValidation ) + { + const ScValidationData* pData = mpDoc->GetValidationEntry( nValidation ); + if( pData && pData->HasSelectionList() ) + return sal_True; + } + ScMergeFlagAttr* pAttr; + pAttr = (ScMergeFlagAttr*)mpDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG ); + if( pAttr->HasAutoFilter() ) + { + return sal_True; + } + else + { + sal_uInt16 nTabCount = mpDoc->GetTableCount(); + if ( nTab+1<nTabCount && mpDoc->IsScenario(nTab+1) && !mpDoc->IsScenario(nTab) ) + { + SCTAB i; + ScMarkData aMarks; + for (i=nTab+1; i<nTabCount && mpDoc->IsScenario(i); i++) + mpDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); + ScRangeList aRanges; + aMarks.FillRangeListWithMarks( &aRanges, sal_False ); + sal_Bool bHasScenario; + SCTAB nRangeCount = aRanges.size(); + for (i=0; i<nRangeCount; i++) + { + ScRange aRange = *aRanges[i]; + mpDoc->ExtendTotalMerge( aRange ); + sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); + // MT IA2: Not used: sal_Bool bIsInScen = sal_False; + if ( bTextBelow ) + { + bHasScenario = (aRange.aStart.Col() == nPosX && aRange.aEnd.Row() == nPosY-1); + } + else + { + bHasScenario = (aRange.aStart.Col() == nPosX && aRange.aStart.Row() == nPosY+1); + } + if( bHasScenario ) return sal_True; + } + } + } + return sal_False; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx index 84635248af11..d021dbd90ccb 100644 --- a/sc/source/ui/Accessibility/AccessibleCellBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx @@ -28,11 +28,16 @@ #include "scresid.hxx" #include "sc.hrc" #include "unonames.hxx" +#include "detfunc.hxx" +#include "chgtrack.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/XSheetAnnotation.hpp> +#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp> +#include <com/sun/star/text/XSimpleText.hpp> #include <editeng/brushitem.hxx> #include <comphelper/sequence.hxx> #include <comphelper/servicehelper.hxx> @@ -212,15 +217,9 @@ OUString SAL_CALL ScAccessibleCellBase::createAccessibleName(void) throw (uno::RuntimeException) { - OUString sName( SC_RESSTR(STR_ACC_CELL_NAME) ); // Document not needed, because only the cell address, but not the tablename is needed // always us OOO notation - OUString sAddress(maCellAddress.Format(SCA_VALID, NULL)); - /* #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 = sName.replaceFirst("%1", sAddress) + " "; - return OUString(sName); + return maCellAddress.Format(SCA_VALID, NULL); } //===== XAccessibleValue ================================================ @@ -229,12 +228,14 @@ uno::Any SAL_CALL ScAccessibleCellBase::getCurrentValue( ) throw (uno::RuntimeException) { - SolarMutexGuard aGuard; + SolarMutexGuard aGuard; IsObjectValid(); uno::Any aAny; if (mpDoc) - aAny <<= mpDoc->GetValue(maCellAddress); - + { + OUString valStr(mpDoc->GetString(maCellAddress.Col(),maCellAddress.Row(),maCellAddress.Tab())); + aAny <<= valStr; + } return aAny; } @@ -320,4 +321,305 @@ sal_Bool ScAccessibleCellBase::IsEditable( return bEditable; } +OUString SAL_CALL ScAccessibleCellBase::GetNote(void) + throw (::com::sun::star::uno::RuntimeException) +{ + SolarMutexGuard aGuard; + IsObjectValid(); + OUString msNote; + 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()) + { + msNote = xText->getString(); + } + } + } + } + } + } + } + } + } + return msNote; +} + +#include <com/sun/star/table/ShadowFormat.hpp> + +OUString SAL_CALL ScAccessibleCellBase::getShadowAttrs(void) + throw (::com::sun::star::uno::RuntimeException) +{ + 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(OUString(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="; + sShadowAttrs += OUString::number( (sal_Int32)nLocationVal ); + sShadowAttrs += sInnerSplit; + sShadowAttrs += "ShadowWidth="; + sShadowAttrs += OUString::number( (sal_Int32)aShadowFmt.ShadowWidth ) ; + sShadowAttrs += sInnerSplit; + sShadowAttrs += "IsTransparent="; + sShadowAttrs += OUString::number( (sal_Bool)aShadowFmt.IsTransparent ) ; + sShadowAttrs += sInnerSplit; + sShadowAttrs += "Color="; + sShadowAttrs += OUString::number( (sal_Int32)aShadowFmt.Color ); + sShadowAttrs += sOuterSplit; + return sShadowAttrs; +} + +#include <com/sun/star/table/BorderLine.hpp> + +OUString SAL_CALL ScAccessibleCellBase::getBorderAttrs(void) + throw (::com::sun::star::uno::RuntimeException) +{ + 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(OUString(SC_UNONAME_TOPBORDER)); + aAny >>= aTopBorder; + aAny = xCellProps->getPropertyValue(OUString(SC_UNONAME_BOTTBORDER)); + aAny >>= aBottomBorder; + aAny = xCellProps->getPropertyValue(OUString(SC_UNONAME_LEFTBORDER)); + aAny >>= aLeftBorder; + aAny = xCellProps->getPropertyValue(OUString(SC_UNONAME_RIGHTBORDER)); + aAny >>= aRightBorder; + } + } + } + } + } + } + } + + Color aColor; + sal_Bool bIn = mpDoc ? mpDoc->IsCellInChangeTrack(maCellAddress,&aColor) : sal_False; + if (bIn) + { + aTopBorder.Color = aColor.GetColor(); + aBottomBorder.Color = aColor.GetColor(); + aLeftBorder.Color = aColor.GetColor(); + aRightBorder.Color = aColor.GetColor(); + aTopBorder.OuterLineWidth =2; + aBottomBorder.OuterLineWidth =2; + aLeftBorder.OuterLineWidth =2; + aRightBorder.OuterLineWidth =2; + } + + //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="; + sBorderAttrs += OUString::number( (sal_Int32)aTopBorder.Color ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "InnerLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aTopBorder.InnerLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "OuterLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aTopBorder.OuterLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "LineDistance="; + sBorderAttrs += OUString::number( (sal_Int32)aTopBorder.LineDistance ); + sBorderAttrs += sOuterSplit; + } + //bottom border + if ( aBottomBorder.InnerLineWidth == 0 && aBottomBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "BottomBorde:;"; + } + else + { + sBorderAttrs += "BottomBorder:Color="; + sBorderAttrs += OUString::number( (sal_Int32)aBottomBorder.Color ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "InnerLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aBottomBorder.InnerLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "OuterLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aBottomBorder.OuterLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "LineDistance="; + sBorderAttrs += OUString::number( (sal_Int32)aBottomBorder.LineDistance ); + sBorderAttrs += sOuterSplit; + } + //left border + if ( aLeftBorder.InnerLineWidth == 0 && aLeftBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "LeftBorder:;"; + } + else + { + sBorderAttrs += "LeftBorder:Color="; + sBorderAttrs += OUString::number( (sal_Int32)aLeftBorder.Color ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "InnerLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aLeftBorder.InnerLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "OuterLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aLeftBorder.OuterLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "LineDistance="; + sBorderAttrs += OUString::number( (sal_Int32)aLeftBorder.LineDistance ); + sBorderAttrs += sOuterSplit; + } + //right border + if ( aRightBorder.InnerLineWidth == 0 && aRightBorder.OuterLineWidth == 0 ) + { + sBorderAttrs += "RightBorder:;"; + } + else + { + sBorderAttrs += "RightBorder:Color="; + sBorderAttrs += OUString::number( (sal_Int32)aRightBorder.Color ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "InnerLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aRightBorder.InnerLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "OuterLineWidth="; + sBorderAttrs += OUString::number( (sal_Int32)aRightBorder.OuterLineWidth ); + sBorderAttrs += sInnerSplit; + sBorderAttrs += "LineDistance="; + sBorderAttrs += OUString::number( (sal_Int32)aRightBorder.LineDistance ); + sBorderAttrs += sOuterSplit; + } + return sBorderAttrs; +} +//end of cell attributes + +OUString SAL_CALL ScAccessibleCellBase::GetAllDisplayNote(void) + throw (::com::sun::star::uno::RuntimeException) +{ + OUString strNote; + OUString strTrackText; + if (mpDoc) + { + sal_Bool bLeftedge=sal_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: */ diff --git a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx index 20f18bc2ac33..073682b7c3a0 100644 --- a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx +++ b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx @@ -21,9 +21,15 @@ #include "fieldwnd.hxx" #include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> - +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <comphelper/accessiblekeybindinghelper.hxx> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <vcl/keycodes.hxx> +#include <unotools/accessiblerelationsethelper.hxx> #include <unotools/accessiblestatesethelper.hxx> #include <comphelper/servicehelper.hxx> #include <tools/gen.hxx> @@ -35,6 +41,7 @@ using namespace ::com::sun::star::accessibility; class ScAccessibleDataPilotButton : public ScAccessibleContextBase + , public ::com::sun::star::accessibility::XAccessibleAction { public: //===== internal ======================================================== @@ -56,6 +63,17 @@ public: protected: virtual ~ScAccessibleDataPilotButton(void); public: + // XAccessibleAction + virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + ///===== XInterface ===================================================== + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( + ::com::sun::star::uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); ///===== XAccessibleComponent ============================================ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > @@ -97,7 +115,8 @@ public: ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL getAccessibleStateSet(void) throw (::com::sun::star::uno::RuntimeException); - + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > + SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); ///===== XServiceInfo ==================================================== /** Returns an identifier for the implementation of this object. @@ -313,6 +332,9 @@ void ScAccessibleDataPilotControl::GotFocus() { OSL_ENSURE(mpFieldWindow->GetFieldCount() == maChildren.size(), "did not recognize a child count change"); + if(maChildren.size()==0) + return ; + sal_Int32 nIndex(mpFieldWindow->GetSelectedField()); if (0 <= nIndex && static_cast<size_t>(nIndex) < maChildren.size()) { @@ -333,6 +355,9 @@ void ScAccessibleDataPilotControl::LostFocus() { OSL_ENSURE(mpFieldWindow->GetFieldCount() == maChildren.size(), "did not recognize a child count change"); + if(maChildren.size()==0) + return ; + sal_Int32 nIndex(mpFieldWindow->GetSelectedField()); if (0 <= nIndex && static_cast<size_t>(nIndex) < maChildren.size()) { @@ -553,7 +578,7 @@ ScAccessibleDataPilotButton::ScAccessibleDataPilotButton( ::com::sun::star::accessibility::XAccessible>& rxParent, ScDPFieldControlBase* pFieldWindow, sal_Int32 nIndex) - : ScAccessibleContextBase(rxParent, AccessibleRole::PUSH_BUTTON), + : ScAccessibleContextBase(rxParent, AccessibleRole::BUTTON_MENU), mpFieldWindow(pFieldWindow), mnIndex(nIndex) { @@ -693,7 +718,23 @@ uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotButton::getAcc return pStateSet; } - ///===== XServiceInfo ==================================================== +::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > + SAL_CALL ScAccessibleDataPilotButton::getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException) +{ + utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; + uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; + if(mxParent.is()) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); + aSequence[0] = mxParent; + pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + + return xSet; + +} + +///===== XServiceInfo ==================================================== OUString SAL_CALL ScAccessibleDataPilotButton::getImplementationName(void) throw (::com::sun::star::uno::RuntimeException) @@ -717,6 +758,8 @@ uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotButton::getImplementationI OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleDescription(void) throw (::com::sun::star::uno::RuntimeException) { + if (mpFieldWindow) + return mpFieldWindow->GetHelpText(); return OUString(); } @@ -754,4 +797,68 @@ Rectangle ScAccessibleDataPilotButton::GetBoundingBox(void) const return Rectangle(); } +// ----------------------------------------------------------------------------- +// XAccessibleAction +// ----------------------------------------------------------------------------- +sal_Int32 ScAccessibleDataPilotButton::getAccessibleActionCount( ) throw (uno::RuntimeException) +{ + return 1; +} + +sal_Bool ScAccessibleDataPilotButton::doAccessibleAction ( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) + throw lang::IndexOutOfBoundsException(); + return sal_True; +} + +OUString ScAccessibleDataPilotButton::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) + throw lang::IndexOutOfBoundsException(); + return OUString("press"); +} + +::com::sun::star::uno::Reference< XAccessibleKeyBinding > ScAccessibleDataPilotButton::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) + throw lang::IndexOutOfBoundsException(); + comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = new comphelper::OAccessibleKeyBindingHelper(); + ::com::sun::star::uno::Reference< XAccessibleKeyBinding > xKeyBinding = pKeyBindingHelper; + ScDPFieldControlBase* pWindow = mpFieldWindow; + if ( pWindow ) + { + awt::KeyStroke aKeyStroke; + aKeyStroke.Modifiers = 0; + aKeyStroke.KeyCode = KEY_SPACE; + pKeyBindingHelper->AddKeyBinding( aKeyStroke ); + } + return xKeyBinding; +} + +uno::Any SAL_CALL ScAccessibleDataPilotButton::queryInterface( uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException) +{ + uno::Any aAny (ScAccessibleContextBase::queryInterface(rType)); + if(!aAny.hasValue()) + { + aAny = ::cppu::queryInterface (rType, + static_cast<XAccessibleAction*>(this) + ); + } + return aAny; +} + +void SAL_CALL ScAccessibleDataPilotButton::acquire() + throw () +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleDataPilotButton::release() + throw () +{ + ScAccessibleContextBase::release(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx index 6d3b7f8c1957..7a4a765ee6be 100644 --- a/sc/source/ui/Accessibility/AccessibleDocument.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx @@ -48,6 +48,7 @@ #include "userdat.hxx" #include "scresid.hxx" #include "sc.hrc" +#include "table.hxx" #include "markdata.hxx" #include <com/sun/star/accessibility/AccessibleEventId.hpp> @@ -74,9 +75,22 @@ #include <toolkit/helper/convert.hxx> #include <vcl/svapp.hxx> +#include <svx/AccessibleControlShape.hxx> +#include <svx/AccessibleShape.hxx> +#include <svx/ShapeTypeHandler.hxx> +#include <svx/SvxShapeTypes.hxx> +#include <sfx2/objsh.hxx> +#include <editeng/editview.hxx> +#include <editeng/editeng.hxx> + #include <list> #include <algorithm> +#include "AccessibleCell.hxx" + +#include "svx/unoapi.hxx" +#include "scmod.hxx" + #ifdef indices #undef indices #endif @@ -256,6 +270,14 @@ public: const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo ) throw (::com::sun::star::uno::RuntimeException); + virtual ::accessibility::AccessibleControlShape* GetAccControlShapeFromModel + (::com::sun::star::beans::XPropertySet* pSet) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible> + GetAccessibleCaption (const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XShape>& xShape) + throw (::com::sun::star::uno::RuntimeException); ///===== Internal ======================================================== void SetDrawBroadcaster(); @@ -476,6 +498,44 @@ sal_Bool ScChildrenShapes::ReplaceChild (::accessibility::AccessibleShape* pCurr return bResult; } +::accessibility::AccessibleControlShape * ScChildrenShapes::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException) +{ + sal_Int32 count = GetCount(); + for (sal_Int32 index=0;index<count;index++) + { + ScAccessibleShapeData* pShape = maZOrderedShapes[index]; + if (pShape) + { + ::accessibility::AccessibleShape* pAccShape = pShape->pAccShape; + if (pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL) + { + ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape); + if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet) + return pCtlAccShape; + } + } + } + return NULL; +} + +::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > +ScChildrenShapes::GetAccessibleCaption (const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape>& xShape) + throw (::com::sun::star::uno::RuntimeException) +{ + sal_Int32 count = GetCount(); + for (sal_Int32 index=0;index<count;index++) + { + ScAccessibleShapeData* pShape = maZOrderedShapes[index]; + if (pShape && pShape->xShape == xShape ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xNewChild( pShape->pAccShape ); + if(xNewChild.get()) + return xNewChild; + } + } + return NULL; +} + sal_Int32 ScChildrenShapes::GetCount() const { SdrPage* pDrawPage = GetDrawPage(); @@ -754,6 +814,8 @@ uno::Reference< XAccessible > ScChildrenShapes::GetSelected(sal_Int32 nSelectedC std::vector < uno::Reference < drawing::XShape > > aShapes; FillShapes(aShapes); + if(aShapes.size()<=0) + return xAccessible; SortedShapes::iterator aItr; if (FindShape(aShapes[nSelectedChildIndex], aItr)) xAccessible = Get(aItr - maZOrderedShapes.begin()); @@ -898,9 +960,16 @@ sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawin } else mnShapesSelected = 0; + SdrObject *pFocusedObj = NULL; + if( mnShapesSelected == 1 && aShapesList.size() == 1) + { + pFocusedObj = GetSdrObjectFromXShape(aShapesList[0]->xShape); + } ScShapeDataLess aLess; std::sort(aShapesList.begin(), aShapesList.end(), aLess); - + SortedShapes vecSelectedShapeAdd; + SortedShapes vecSelectedShapeRemove; + sal_Bool bHasSelect=sal_False; SortedShapes::iterator aXShapesItr(aShapesList.begin()); SortedShapes::const_iterator aXShapesEndItr(aShapesList.end()); SortedShapes::iterator aDataItr(maZOrderedShapes.begin()); @@ -925,9 +994,14 @@ sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawin (*aDataItr)->pAccShape->SetState(AccessibleStateType::SELECTED); (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED); bResult = sal_True; + vecSelectedShapeAdd.push_back((*aDataItr)); } aFocusedItr = aDataItr; } + else + { + bHasSelect = sal_True; + } ++aDataItr; ++aXShapesItr; } @@ -941,6 +1015,7 @@ sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawin (*aDataItr)->pAccShape->ResetState(AccessibleStateType::SELECTED); (*aDataItr)->pAccShape->ResetState(AccessibleStateType::FOCUSED); bResult = sal_True; + vecSelectedShapeRemove.push_back(*aDataItr); } } ++aDataItr; @@ -955,9 +1030,120 @@ sal_Bool ScChildrenShapes::FindSelectedShapesChanges(const uno::Reference<drawin else ++aDataItr; } - if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1)) + bool bWinFocus=false; + ScGridWindow* pWin = static_cast<ScGridWindow*>(mpViewShell->GetWindowByPos(meSplitPos)); + if (pWin) + { + bWinFocus = pWin->HasFocus(); + } + const SdrMarkList* pMarkList = NULL; + SdrObject* pMarkedObj = NULL; + SdrObject* pUpObj = NULL; + sal_Bool bIsFocuseMarked = sal_True; + if( mpViewShell && mnShapesSelected == 1 && bWinFocus) + { + ScDrawView* pScDrawView = mpViewShell->GetViewData()->GetScDrawView(); + if( pScDrawView ) + { + if( pScDrawView->GetMarkedObjectList().GetMarkCount() == 1 ) + { + pMarkList = &(pScDrawView->GetMarkedObjectList()); + pMarkedObj = pMarkList->GetMark(0)->GetMarkedSdrObj(); + uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); + if( aFocusedItr != aDataEndItr && + (*aFocusedItr)->xShape.is() && + xMarkedXShape.is() && + (*aFocusedItr)->xShape != xMarkedXShape ) + bIsFocuseMarked = sal_False; + } + } + } + //if ((aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1)) + if ( bIsFocuseMarked && (aFocusedItr != aDataEndItr) && (*aFocusedItr)->pAccShape && (mnShapesSelected == 1) && bWinFocus) + { (*aFocusedItr)->pAccShape->SetState(AccessibleStateType::FOCUSED); + } + else if( pFocusedObj && bWinFocus && pMarkList && pMarkList->GetMarkCount() == 1 && mnShapesSelected == 1 ) + { + if( pMarkedObj ) + { + uno::Reference< drawing::XShape > xMarkedXShape (pMarkedObj->getUnoShape(), uno::UNO_QUERY); + pUpObj = pMarkedObj->GetUpGroup(); + if( pMarkedObj == pFocusedObj ) + { + if( pUpObj ) + { + uno::Reference< drawing::XShape > xUpGroupXShape (pUpObj->getUnoShape(), uno::UNO_QUERY); + uno::Reference < XAccessible > xAccGroupShape = + const_cast<ScChildrenShapes*>(this)->GetAccessibleCaption( xUpGroupXShape ); + if( xAccGroupShape.is() ) + { + ::accessibility::AccessibleShape* pAccGroupShape = + static_cast< ::accessibility::AccessibleShape* >(xAccGroupShape.get()); + if( pAccGroupShape ) + { + sal_Int32 nCount = pAccGroupShape->getAccessibleChildCount(); + for( sal_Int32 i = 0; i < nCount; i++ ) + { + uno::Reference<XAccessible> xAccShape = pAccGroupShape->getAccessibleChild(i); + if (xAccShape.is()) + { + ::accessibility::AccessibleShape* pChildAccShape = static_cast< ::accessibility::AccessibleShape* >(xAccShape.get()); + uno::Reference< drawing::XShape > xChildShape = pChildAccShape->GetXShape(); + if (xChildShape == xMarkedXShape) + { + pChildAccShape->SetState(AccessibleStateType::FOCUSED); + } + else + { + pChildAccShape->ResetState(AccessibleStateType::FOCUSED); + } + } + } + } + } + } + } + } + } + if (vecSelectedShapeAdd.size() >= 10 ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; + aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); + mpAccessibleDocument->CommitChange(aEvent); + } + else + { + SortedShapes::iterator vi = vecSelectedShapeAdd.begin(); + for (; vi != vecSelectedShapeAdd.end() ; ++vi ) + { + AccessibleEventObject aEvent; + if (bHasSelect) + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; + } + else + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + } + aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); + uno::Reference< XAccessible > xChild( (*vi)->pAccShape); + aEvent.NewValue <<= xChild; + mpAccessibleDocument->CommitChange(aEvent); + } + } + SortedShapes::iterator vi = vecSelectedShapeRemove.begin(); + for (; vi != vecSelectedShapeRemove.end() ; ++vi ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; + aEvent.Source = uno::Reference< XAccessible >(mpAccessibleDocument); + uno::Reference< XAccessible > xChild( (*vi)->pAccShape); + aEvent.NewValue <<= xChild; + mpAccessibleDocument->CommitChange(aEvent); + } std::for_each(aShapesList.begin(), aShapesList.end(), Destroy()); return bResult; @@ -1345,12 +1531,30 @@ void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) const ScAccGridWinFocusGotHint& rRef = (const ScAccGridWinFocusGotHint&)rHint; if (rRef.GetNewGridWin() == meSplitPos) { + uno::Reference<XAccessible> xAccessible; + if (mpChildrenShapes) + { + sal_Bool bTabMarked(IsTableSelected()); + xAccessible = mpChildrenShapes->GetSelected(0, bTabMarked); + } + if( xAccessible.is() ) + { + uno::Any aNewValue; + aNewValue<<=AccessibleStateType::FOCUSED; + static_cast< ::accessibility::AccessibleShape* >(xAccessible.get())-> + CommitChange(AccessibleEventId::STATE_CHANGED, + aNewValue, + uno::Any() ); + } + else + { if (mxTempAcc.is() && mpTempAccEdit) mpTempAccEdit->GotFocus(); else if (mpAccessibleSpreadsheet) mpAccessibleSpreadsheet->GotFocus(); else CommitFocusGained(); + } } } else if (rHint.ISA( SfxSimpleHint )) @@ -1370,10 +1574,16 @@ void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) mpChildrenShapes = new ScChildrenShapes( this, mpViewShell, meSplitPos ); } + //Invoke Init() to rebuild the mpChildrenShapes variable + this->Init(); + AccessibleEventObject aEvent; aEvent.EventId = AccessibleEventId::INVALIDATE_ALL_CHILDREN; aEvent.Source = uno::Reference< XAccessibleContext >(this); CommitChange(aEvent); // all children changed + + if (mpAccessibleSpreadsheet) + mpAccessibleSpreadsheet->FireFirstCellFocus(); } else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER) { @@ -1384,19 +1594,23 @@ void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { if (mpViewShell && mpViewShell->GetViewData()->HasEditView(meSplitPos)) { - mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos), - mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(), - OUString(ScResId(STR_ACC_EDITLINE_DESCR)), ScAccessibleEditObject::CellInEditMode); - uno::Reference<XAccessible> xAcc = mpTempAccEdit; + const EditEngine* pEditEng = mpViewShell->GetViewData()->GetEditView(meSplitPos)->GetEditEngine(); + if (pEditEng && pEditEng->GetUpdateMode()) + { + mpTempAccEdit = new ScAccessibleEditObject(this, mpViewShell->GetViewData()->GetEditView(meSplitPos), + mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(), + OUString(ScResId(STR_ACC_EDITLINE_DESCR)), ScAccessibleEditObject::CellInEditMode); + uno::Reference<XAccessible> xAcc = mpTempAccEdit; - AddChild(xAcc, sal_True); + AddChild(xAcc, sal_True); - if (mpAccessibleSpreadsheet) - mpAccessibleSpreadsheet->LostFocus(); - else - CommitFocusLost(); + if (mpAccessibleSpreadsheet) + mpAccessibleSpreadsheet->LostFocus(); + else + CommitFocusLost(); - mpTempAccEdit->GotFocus(); + mpTempAccEdit->GotFocus(); + } } } else if (rRef.GetId() == SC_HINT_ACC_LEAVEEDITMODE) @@ -1408,10 +1622,9 @@ void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) mpTempAccEdit = NULL; RemoveChild(mxTempAcc, sal_True); - - if (mpAccessibleSpreadsheet) + if (mpAccessibleSpreadsheet && mpViewShell->IsActive()) mpAccessibleSpreadsheet->GotFocus(); - else + else if( mpViewShell->IsActive()) CommitFocusGained(); } } @@ -1472,6 +1685,10 @@ void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& / CommitChange(aEvent); } + if(mpChildrenShapes ) + { + mpChildrenShapes->SelectionChanged(); + } } //===== XInterface ===================================================== @@ -1479,6 +1696,13 @@ void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& / uno::Any SAL_CALL ScAccessibleDocument::queryInterface( uno::Type const & rType ) throw (uno::RuntimeException) { + uno::Any aAnyTmp; + if(rType == ::getCppuType((com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> *)NULL) ) + { + com::sun::star::uno::Reference<XAccessibleGetAccFlowTo> AccFromXShape = this; + aAnyTmp <<= AccFromXShape; + return aAnyTmp; + } uno::Any aAny (ScAccessibleDocumentImpl::queryInterface(rType)); return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); } @@ -1630,7 +1854,37 @@ uno::Reference<XAccessibleStateSet> SAL_CALL return pStateSet; } - ///===== XAccessibleSelection =========================================== +OUString SAL_CALL + ScAccessibleDocument::getAccessibleName(void) + throw (::com::sun::star::uno::RuntimeException) +{ + OUString sName = ScResId(STR_ACC_DOC_SPREADSHEET); + ScDocument* pScDoc = GetDocument(); + if ( pScDoc ) + { + OUString sFileName = pScDoc->getDocAccTitle(); + if ( !sFileName.getLength() ) + { + SfxObjectShell* pObjSh = pScDoc->GetDocumentShell(); + if ( pObjSh ) + { + sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME ); + } + } + OUString sReadOnly; + if (pScDoc->getDocReadOnly()) + { + sReadOnly = ScResId(STR_ACC_DOC_SPREADSHEET_READONLY); + } + if ( sFileName.getLength() ) + { + sName = sFileName + sReadOnly + " - " + sName; + } + } + return sName; +} + +///===== XAccessibleSelection =========================================== void SAL_CALL ScAccessibleDocument::selectAccessibleChild( sal_Int32 nChildIndex ) @@ -2098,4 +2352,206 @@ OUString ScAccessibleDocument::GetCurrentCellDescription() const return OUString(); } +ScDocument *ScAccessibleDocument::GetDocument() const +{ + return mpViewShell ? mpViewShell->GetViewData()->GetDocument() : NULL; +} + +ScAddress ScAccessibleDocument::GetCurCellAddress() const +{ + return mpViewShell ? mpViewShell->GetViewData()->GetCurPos() :ScAddress(); +} + +uno::Any SAL_CALL ScAccessibleDocument::getExtendedAttributes() + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + + uno::Any anyAtrribute; + + OUString sName; + OUString sValue; + sal_uInt16 sheetIndex; + OUString sSheetName; + sheetIndex = getVisibleTable(); + if(GetDocument()==NULL) + return anyAtrribute; + GetDocument()->GetName(sheetIndex,sSheetName); + sName = "page-name:"; + sValue = sName + sSheetName ; + sName = ";page-number:"; + sValue += sName; + sValue += OUString::number(sheetIndex+1) ; + sName = ";total-pages:"; + sValue += sName; + sValue += OUString::number(GetDocument()->GetTableCount()); + sValue += ";"; + anyAtrribute <<= sValue; + return anyAtrribute; +} + +com::sun::star::uno::Sequence< com::sun::star::uno::Any > ScAccessibleDocument::GetScAccFlowToSequence() +{ + if ( getAccessibleChildCount() ) + { + uno::Reference < XAccessible > xSCTableAcc = getAccessibleChild( 0 ); // table + if ( xSCTableAcc.is() ) + { + uno::Reference < XAccessibleSelection > xAccSelection( xSCTableAcc, uno::UNO_QUERY ); + sal_Int32 nSelCount = xAccSelection->getSelectedAccessibleChildCount(); + if( nSelCount ) + { + uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); // selected cell + if ( xSel.is() ) + { + uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); + if ( xSelContext.is() ) + { + if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) + { + sal_Int32 nParaCount = 0; + uno::Sequence <uno::Any> aSequence(nSelCount); + for ( sal_Int32 i = 0; i < nSelCount; i++ ) + { + xSel = xAccSelection->getSelectedAccessibleChild( i ) ; + if ( xSel.is() ) + { + xSelContext = xSel->getAccessibleContext(); + if ( xSelContext.is() ) + { + if ( xSelContext->getAccessibleRole() == AccessibleRole::TABLE_CELL ) + { + aSequence[nParaCount] = uno::makeAny( xSel ); + nParaCount++; + } + } + } + } + return aSequence; + } + } + } + } + } + } + uno::Sequence <uno::Any> aEmpty; + return aEmpty; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > + SAL_CALL ScAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType) + throw ( ::com::sun::star::uno::RuntimeException ) +{ + const sal_Int32 SPELLCHECKFLOWTO = 1; + const sal_Int32 FINDREPLACEFLOWTO = 2; + if ( nType == SPELLCHECKFLOWTO ) + { + uno::Reference< ::com::sun::star::drawing::XShape > xShape; + rAny >>= xShape; + if ( xShape.is() ) + { + uno::Reference < XAccessible > xAcc = mpChildrenShapes->GetAccessibleCaption(xShape); + uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY ); + if ( xAccSelection.is() ) + { + if ( xAccSelection->getSelectedAccessibleChildCount() ) + { + uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); + if ( xSel.is() ) + { + uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); + if ( xSelContext.is() ) + { + //if in sw we find the selected paragraph here + if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) + { + uno::Sequence<uno::Any> aRet( 1 ); + aRet[0] = uno::makeAny( xSel ); + return aRet; + } + } + } + } + } + } + else + { + if ( getSelectedAccessibleChildCount() ) + { + uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 ); + if ( xSel.is() ) + { + uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); + if ( xSelContext.is() ) + { + uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY ); + if ( xAccChildSelection.is() ) + { + if ( xAccChildSelection->getSelectedAccessibleChildCount() ) + { + uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 ); + if ( xChildSel.is() ) + { + uno::Reference < ::com::sun::star::accessibility::XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() ); + if ( xChildSelContext.is() && + xChildSelContext->getAccessibleRole() == ::com::sun::star::accessibility::AccessibleRole::PARAGRAPH ) + { + uno::Sequence<uno::Any> aRet( 1 ); + aRet[0] = uno::makeAny( xChildSel ); + return aRet; + } + } + } + } + } + } + } + } + } + else if ( nType == FINDREPLACEFLOWTO ) + { + sal_Bool bSuccess; + rAny >>= bSuccess; + if ( bSuccess ) + { + uno::Sequence< uno::Any> aSeq = GetScAccFlowToSequence(); + if ( aSeq.getLength() ) + { + return aSeq; + } + else if( mpAccessibleSpreadsheet ) + { + uno::Reference < XAccessible > xFindCellAcc = mpAccessibleSpreadsheet->GetActiveCell(); + // add xFindCellAcc to the return the Sequence + uno::Sequence< uno::Any> aSeq2(1); + aSeq2[0] = uno::makeAny( xFindCellAcc ); + return aSeq2; + } + } + } + uno::Sequence< uno::Any> aEmpty; + return aEmpty; +} + +void ScAccessibleDocument::SwitchViewFireFocus() +{ + if (mpAccessibleSpreadsheet) + { + mpAccessibleSpreadsheet->FireFirstCellFocus(); + } +} + +sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( ) + throw (uno::RuntimeException) +{ + return COL_BLACK; +} + +sal_Int32 SAL_CALL ScAccessibleDocument::getBackground( ) + throw (uno::RuntimeException) +{ + SolarMutexGuard aGuard; + IsObjectValid(); + return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx index 1bafb7b7831f..12435ea038b1 100644 --- a/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocumentBase.cxx @@ -36,4 +36,9 @@ ScAccessibleDocumentBase::~ScAccessibleDocumentBase(void) { } +void ScAccessibleDocumentBase::SwitchViewFireFocus() +{ + CommitFocusGained(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx index ee68b61d5db5..94c28ecc4d53 100644 --- a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx @@ -1696,4 +1696,31 @@ ScShapeChildren* ScAccessibleDocumentPagePreview::GetShapeChildren() return mpShapeChildren; } +OUString ScAccessibleDocumentPagePreview::getAccessibleName(void) +throw (::com::sun::star::uno::RuntimeException) +{ + OUString sName = ScResId(STR_ACC_DOC_SPREADSHEET); + ScDocument* pScDoc = mpViewShell->GetDocument(); + if ( pScDoc ) + { + OUString sFileName = pScDoc->getDocAccTitle(); + if ( !sFileName.getLength() ) + { + SfxObjectShell* pObjSh = pScDoc->GetDocumentShell(); + if ( pObjSh ) + { + sFileName = pObjSh->GetTitle( SFX_TITLE_APINAME ); + } + } + if ( sFileName.getLength() ) + { + sName = sFileName + " - " + sName; + sName += ScResId(STR_ACC_DOC_PREVIEW_SUFFIX); + + } + } + + return sName; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleEditObject.cxx b/sc/source/ui/Accessibility/AccessibleEditObject.cxx index b99d4826776d..a45c9c52646e 100644 --- a/sc/source/ui/Accessibility/AccessibleEditObject.cxx +++ b/sc/source/ui/Accessibility/AccessibleEditObject.cxx @@ -28,13 +28,25 @@ #include <unotools/accessiblestatesethelper.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 <comphelper/servicehelper.hxx> #include <svx/AccessibleTextHelper.hxx> #include <editeng/editview.hxx> #include <editeng/editeng.hxx> #include <svx/svdmodel.hxx> #include <vcl/svapp.hxx> +#include <sfx2/objsh.hxx> +#include "unonames.hxx" +#include "document.hxx" +#include "AccessibleDocument.hxx" +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <unotools/accessiblerelationsethelper.hxx> +#include <com/sun/star/accessibility/XAccessibleText.hpp> + +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::uno::RuntimeException; using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; @@ -55,6 +67,21 @@ ScAccessibleEditObject::ScAccessibleEditObject( CreateTextHelper(); SetName(rName); SetDescription(rDescription); + if( meObjectType == CellInEditMode) + { + const ScAccessibleDocument *pAccDoc = const_cast<ScAccessibleDocument*>(static_cast<ScAccessibleDocument*>(rxParent.get())) ; + if (pAccDoc) + { + m_pScDoc = pAccDoc->GetDocument(); + m_curCellAddress =pAccDoc->GetCurCellAddress(); + } + else + { + m_pScDoc=NULL; + } + } + else + m_pScDoc=NULL; } ScAccessibleEditObject::~ScAccessibleEditObject() @@ -93,6 +120,31 @@ void ScAccessibleEditObject::GotFocus() mpTextHelper->SetFocus(sal_True); } +//===== XInterface ========================================================== + +com::sun::star::uno::Any SAL_CALL + ScAccessibleEditObject::queryInterface (const com::sun::star::uno::Type & rType) + throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aReturn = ScAccessibleContextBase::queryInterface (rType); + if ( ! aReturn.hasValue()) + aReturn = ::cppu::queryInterface (rType, + static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this) + ); + return aReturn; +} +void SAL_CALL + ScAccessibleEditObject::acquire (void) + throw () +{ + ScAccessibleContextBase::acquire (); +} +void SAL_CALL + ScAccessibleEditObject::release (void) + throw () +{ + ScAccessibleContextBase::release (); +} //===== XAccessibleComponent ============================================ uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint( @@ -340,4 +392,154 @@ void ScAccessibleEditObject::CreateTextHelper() } } +sal_Int32 SAL_CALL ScAccessibleEditObject::getForeground( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return GetFgBgColor(OUString(SC_UNONAME_CCOLOR)); +} + +sal_Int32 SAL_CALL ScAccessibleEditObject::getBackground( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return GetFgBgColor(OUString(SC_UNONAME_CELLBACK)); +} + +sal_Int32 ScAccessibleEditObject::GetFgBgColor( const OUString &strPropColor) +{ + SolarMutexGuard aGuard; + sal_Int32 nColor(0); + if (m_pScDoc) + { + SfxObjectShell* pObjSh = m_pScDoc->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(m_curCellAddress.Tab()); + uno::Reference<sheet::XSpreadsheet> xTable; + if (aTable>>=xTable) + { + uno::Reference<table::XCell> xCell = xTable->getCellByPosition(m_curCellAddress.Col(), m_curCellAddress.Row()); + if (xCell.is()) + { + uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY); + if (xCellProps.is()) + { + uno::Any aAny = xCellProps->getPropertyValue(strPropColor); + aAny >>= nColor; + } + } + } + } + } + } + } + return nColor; +} +//===== XAccessibleSelection ============================================ +//-------------------------------------------------------------------------------- +void SAL_CALL ScAccessibleEditObject::selectAccessibleChild( sal_Int32 ) +throw ( IndexOutOfBoundsException, RuntimeException ) +{ +} +//---------------------------------------------------------------------------------- +sal_Bool SAL_CALL ScAccessibleEditObject::isAccessibleChildSelected( sal_Int32 nChildIndex ) +throw ( IndexOutOfBoundsException, + RuntimeException ) +{ + uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex ); + uno::Reference<XAccessibleContext> xContext; + if( xAcc.is() ) + xContext = xAcc->getAccessibleContext(); + if( xContext.is() ) + { + if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) + { + uno::Reference< ::com::sun::star::accessibility::XAccessibleText > + xText(xAcc, uno::UNO_QUERY); + if( xText.is() ) + { + if( xText->getSelectionStart() >= 0 ) return sal_True; + } + } + } + return sal_False; +} +//--------------------------------------------------------------------- +void SAL_CALL ScAccessibleEditObject::clearAccessibleSelection( ) +throw ( RuntimeException ) +{ +} +//------------------------------------------------------------------------- +void SAL_CALL ScAccessibleEditObject::selectAllAccessibleChildren( ) +throw ( RuntimeException ) +{ +} +//---------------------------------------------------------------------------- +sal_Int32 SAL_CALL ScAccessibleEditObject::getSelectedAccessibleChildCount() +throw ( RuntimeException ) +{ + sal_Int32 nCount = 0; + sal_Int32 TotalCount = getAccessibleChildCount(); + for( sal_Int32 i = 0; i < TotalCount; i++ ) + if( isAccessibleChildSelected(i) ) nCount++; + return nCount; +} +//-------------------------------------------------------------------------------------- +uno::Reference<XAccessible> SAL_CALL ScAccessibleEditObject::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) +throw ( IndexOutOfBoundsException, RuntimeException) +{ + if ( nSelectedChildIndex > getSelectedAccessibleChildCount() ) + throw IndexOutOfBoundsException(); + sal_Int32 i1, i2; + for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ ) + if( isAccessibleChildSelected(i1) ) + { + if( i2 == nSelectedChildIndex ) + return getAccessibleChild( i1 ); + i2++; + } + return uno::Reference<XAccessible>(); +} + +void SAL_CALL ScAccessibleEditObject::deselectAccessibleChild( + sal_Int32 ) + throw ( IndexOutOfBoundsException, + RuntimeException ) +{ +} + +uno::Reference< XAccessibleRelationSet > ScAccessibleEditObject::getAccessibleRelationSet( ) + throw (uno::RuntimeException) +{ + SolarMutexGuard aGuard; + Window* pWindow = mpWindow; + utl::AccessibleRelationSetHelper* rRelationSet = new utl::AccessibleRelationSetHelper; + uno::Reference< XAccessibleRelationSet > rSet = rRelationSet; + if ( pWindow ) + { + Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy(); + if ( pLabeledBy && pLabeledBy != pWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); + aSequence[0] = pLabeledBy->GetAccessible(); + rRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::LABELED_BY, aSequence ) ); + } + Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf(); + if ( pMemberOf && pMemberOf != pWindow ) + { + uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); + aSequence[0] = pMemberOf->GetAccessible(); + rRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::MEMBER_OF, aSequence ) ); + } + return rSet; + } + return uno::Reference< XAccessibleRelationSet >(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx index c06ea6077c8b..5a525d0c43ff 100644 --- a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx +++ b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx @@ -36,12 +36,213 @@ #include <tools/gen.hxx> #include <svtools/colorcfg.hxx> #include <vcl/svapp.hxx> +#include "scresid.hxx" +#include "sc.hrc" #include <algorithm> using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; +bool CompMinCol(const std::pair<sal_uInt16,sal_uInt16> & pc1,const std::pair<sal_uInt16,sal_uInt16> &pc2) +{ + return pc1.first < pc2.first; +} + +ScMyAddress ScAccessibleSpreadsheet::CalcScAddressFromRangeList(ScRangeList *pMarkedRanges,sal_Int32 nSelectedChildIndex) +{ + if (pMarkedRanges->size() <= 1) + { + ScRange* pRange = pMarkedRanges->front(); + if (pRange) + { + // MT IA2: Not used. + // const int nRowNum = pRange->aEnd.Row() - pRange->aStart.Row() + 1; + const int nColNum = pRange->aEnd.Col() - pRange->aStart.Col() + 1; + const int nCurCol = nSelectedChildIndex % nColNum; + const int nCurRow = (nSelectedChildIndex - nCurCol)/nColNum; + return ScMyAddress(static_cast<SCCOL>(pRange->aStart.Col() + nCurCol), pRange->aStart.Row() + nCurRow, maActiveCell.Tab()); + } + } + else + { + sal_Int32 nMinRow = MAXROW; + sal_Int32 nMaxRow = 0; + m_vecTempRange.clear(); + size_t nSize = pMarkedRanges->size(); + for (size_t i = 0; i < nSize; ++i) + { + ScRange* pRange = (*pMarkedRanges)[i]; + if (pRange->aStart.Tab() != pRange->aEnd.Tab()) + { + if ((maActiveCell.Tab() >= pRange->aStart.Tab()) || + maActiveCell.Tab() <= pRange->aEnd.Tab()) + { + m_vecTempRange.push_back(pRange); + nMinRow = std::min(pRange->aStart.Row(),nMinRow); + nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow); + } + else + SAL_WARN("sc", "Range of wrong table"); + } + else if(pRange->aStart.Tab() == maActiveCell.Tab()) + { + m_vecTempRange.push_back(pRange); + nMinRow = std::min(pRange->aStart.Row(),nMinRow); + nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow); + } + else + SAL_WARN("sc", "Range of wrong table"); + } + int nCurrentIndex = 0 ; + for(sal_Int32 row = nMinRow ; row <= nMaxRow ; ++row) + { + m_vecTempCol.clear(); + { + VEC_RANGE::const_iterator vi = m_vecTempRange.begin(); + for (; vi < m_vecTempRange.end(); ++vi) + { + ScRange *p = *vi; + if ( row >= p->aStart.Row() && row <= p->aEnd.Row()) + { + m_vecTempCol.push_back(std::make_pair(p->aStart.Col(),p->aEnd.Col())); + } + } + } + std::sort(m_vecTempCol.begin(),m_vecTempCol.end(),CompMinCol); + { + VEC_COL::const_iterator vic = m_vecTempCol.begin(); + for(; vic != m_vecTempCol.end(); ++vic) + { + const PAIR_COL &pariCol = *vic; + sal_uInt16 nCol = pariCol.second - pariCol.first + 1; + if (nCol + nCurrentIndex > nSelectedChildIndex) + { + return ScMyAddress(static_cast<SCCOL>(pariCol.first + nSelectedChildIndex - nCurrentIndex), row, maActiveCell.Tab()); + } + nCurrentIndex += nCol; + } + } + } + } + return ScMyAddress(0,0,maActiveCell.Tab()); +} + +sal_Bool ScAccessibleSpreadsheet::CalcScRangeDifferenceMax(ScRange *pSrc,ScRange *pDest,int nMax,VEC_MYADDR &vecRet,int &nSize) +{ + //Src Must be :Src > Dest + if (pDest->In(*pSrc)) + {//Here is Src In Dest,Src <= Dest + return sal_False; + } + if (!pDest->Intersects(*pSrc)) + { + int nCellCount = sal_uInt32(pDest->aEnd.Col() - pDest->aStart.Col() + 1) + * sal_uInt32(pDest->aEnd.Row() - pDest->aStart.Row() + 1) + * sal_uInt32(pDest->aEnd.Tab() - pDest->aStart.Tab() + 1); + if (nCellCount + nSize > nMax) + { + return sal_True; + } + else if(nCellCount > 0) + { + nCellCount +=nSize; + for (sal_Int32 row = pDest->aStart.Row(); row <= pDest->aEnd.Row();++row) + { + for (sal_uInt16 col = pDest->aStart.Col(); col <= pDest->aEnd.Col();++col) + { + vecRet.push_back(ScMyAddress(col,row,pDest->aStart.Tab())); + } + } + } + return sal_False; + } + sal_Int32 nMinRow = pSrc->aStart.Row(); + sal_Int32 nMaxRow = pSrc->aEnd.Row(); + for (; nMinRow <= nMaxRow ; ++nMinRow,--nMaxRow) + { + for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col) + { + if (nSize > nMax) + { + return sal_True; + } + ScMyAddress cell(col,nMinRow,pSrc->aStart.Tab()); + if(!pDest->In(cell)) + {//In Src ,Not In Dest + vecRet.push_back(cell); + ++nSize; + } + } + if (nMinRow != nMaxRow) + { + for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col) + { + if (nSize > nMax) + { + return sal_True; + } + ScMyAddress cell(col,nMaxRow,pSrc->aStart.Tab()); + if(!pDest->In(cell)) + {//In Src ,Not In Dest + vecRet.push_back(cell); + ++nSize; + } + } + } + } + return sal_False; +} + +//In Src , Not in Dest +sal_Bool ScAccessibleSpreadsheet::CalcScRangeListDifferenceMax(ScRangeList *pSrc,ScRangeList *pDest,int nMax,VEC_MYADDR &vecRet) +{ + if (pSrc == NULL || pDest == NULL) + { + return sal_False; + } + int nSize =0; + if (pDest->GetCellCount() == 0)//if the Dest Rang List is empty + { + if (pSrc->GetCellCount() > sal_uInt32(nMax))//if the Src Cell count is greater then nMax + { + return sal_True; + } + //now the cell count is less then nMax + vecRet.reserve(10); + size_t nSrcSize = pSrc->size(); + for (size_t i = 0; i < nSrcSize; ++i) + { + ScRange* pRange = (*pSrc)[i]; + for (sal_Int32 row = pRange->aStart.Row(); row <= pRange->aEnd.Row();++row) + { + for (sal_uInt16 col = pRange->aStart.Col(); col <= pRange->aEnd.Col();++col) + { + vecRet.push_back(ScMyAddress(col,row,pRange->aStart.Tab())); + } + } + } + return sal_False; + } + //the Dest Rang List is not empty + vecRet.reserve(10); + size_t nSizeSrc = pSrc->size(); + for (size_t i = 0; i < nSizeSrc; ++i) + { + ScRange* pRange = (*pSrc)[i]; + size_t nSizeDest = pDest->size(); + for (size_t j = 0; j < nSizeDest; ++j) + { + ScRange* pRangeDest = (*pDest)[j]; + if (CalcScRangeDifferenceMax(pRange,pRangeDest,nMax,vecRet,nSize)) + { + return sal_True; + } + } + } + return sal_False; +} + //===== internal ============================================================ // FIXME: really unclear why we have an ScAccessibleTableBase with @@ -54,7 +255,11 @@ ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( : ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell), ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))), - mbIsSpreadsheet( sal_True ) + mbIsSpreadsheet( sal_True ), + m_bFormulaMode(sal_False), + m_bFormulaLastMode(sal_False), + m_pAccFormulaCell(NULL), + m_nMinX(0),m_nMaxX(0),m_nMinY(0),m_nMaxY(0) { ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos ); } @@ -69,10 +274,7 @@ ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet() { - if (mpMarkedRanges) - delete mpMarkedRanges; - if (mpSortedMarkedCells) - delete mpSortedMarkedCells; + delete mpMarkedRanges; if (mpViewShell) mpViewShell->RemoveAccessibilityObject(*this); } @@ -106,6 +308,11 @@ void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet( mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col()); mpAccCell->acquire(); mpAccCell->Init(); + ScDocument* pScDoc= GetDocument(mpViewShell); + if (pScDoc) + { + pScDoc->GetName( maActiveCell.Tab(), m_strOldTabName ); + } } } @@ -128,11 +335,12 @@ void SAL_CALL ScAccessibleSpreadsheet::disposing() void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState) { + if (IsFormulaMode()) + { + return ; + } if (mpMarkedRanges) DELETEZ(mpMarkedRanges); - if (mpSortedMarkedCells) - DELETEZ(mpSortedMarkedCells); - mbHasSelection = bNewState; AccessibleEventObject aEvent; @@ -161,12 +369,40 @@ void ScAccessibleSpreadsheet::LostFocus() void ScAccessibleSpreadsheet::GotFocus() { - CommitFocusGained(); - AccessibleEventObject aEvent; aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; aEvent.Source = uno::Reference< XAccessibleContext >(this); - uno::Reference< XAccessible > xNew = mpAccCell; + uno::Reference< XAccessible > xNew; + if (IsFormulaMode()) + { + if (!m_pAccFormulaCell || !m_bFormulaLastMode) + { + ScAddress aFormulaAddr; + if(!GetFormulaCurrentFocusCell(aFormulaAddr)) + { + return; + } + m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(),aFormulaAddr.Col()); + + m_pAccFormulaCell->acquire(); + m_pAccFormulaCell->Init(); + + + } + xNew = m_pAccFormulaCell; + } + else + { + if(mpAccCell->GetCellAddress() == maActiveCell) + { + xNew = mpAccCell; + } + else + { + CommitFocusCell(maActiveCell); + return ; + } + } aEvent.NewValue <<= xNew; CommitChange(aEvent); @@ -197,59 +433,185 @@ 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); + ScViewData *pViewData = mpViewShell->GetViewData(); - mbHasSelection = bNewMarked; + m_bFormulaMode = pViewData->IsRefMode() || SC_MOD()->IsFormulaMode(); + if ( m_bFormulaMode ) + { + NotifyRefMode(); + m_bFormulaLastMode = true; + return ; + } + if (m_bFormulaLastMode) + {//Last Notify Mode Is Formula Mode. + m_vecFormulaLastMyAddr.clear(); + RemoveFormulaSelection(sal_True); + if(m_pAccFormulaCell) + { + m_pAccFormulaCell->release(); + m_pAccFormulaCell =NULL; + } + //Remove All Selection + } + m_bFormulaLastMode = m_bFormulaMode; + AccessibleEventObject aEvent; + aEvent.Source = uno::Reference< XAccessible >(this); + ScAddress aNewCell = pViewData->GetCurPos(); + if(aNewCell.Tab() != maActiveCell.Tab()) + { + aEvent.EventId = AccessibleEventId::PAGE_CHANGED; + ScAccessibleDocument *pAccDoc = + static_cast<ScAccessibleDocument*>(getAccessibleParent().get()); + if(pAccDoc) + { + pAccDoc->CommitChange(aEvent); + } + } + sal_Bool bNewPosCell = (aNewCell != maActiveCell); + sal_Bool bNewPosCellFocus=sal_False; + if ( bNewPosCell && IsFocused() && aNewCell.Tab() == maActiveCell.Tab() ) + {//single Focus + bNewPosCellFocus=sal_True; + } + ScMarkData &refScMarkData = pViewData->GetMarkData(); + // MT IA2: Not used + // int nSelCount = refScMarkData.GetSelectCount(); + sal_Bool bIsMark =refScMarkData.IsMarked(); + sal_Bool bIsMultMark = refScMarkData.IsMultiMarked(); + sal_Bool bNewMarked = refScMarkData.GetTableSelect(aNewCell.Tab()) && ( bIsMark || bIsMultMark ); +// sal_Bool bNewCellSelected = isAccessibleSelected(aNewCell.Row(), aNewCell.Col()); + sal_uInt16 nTab = pViewData->GetTabNo(); + ScRange aMarkRange; + refScMarkData.GetMarkArea(aMarkRange); + aEvent.OldValue <<= ::com::sun::star::uno::Any(); + //Mark All + if ( !bNewPosCellFocus && + (bNewMarked || bIsMark || bIsMultMark ) && + aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) ) + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; + aEvent.NewValue <<= ::com::sun::star::uno::Any(); CommitChange(aEvent); + return ; } + if (!mpMarkedRanges) + { + mpMarkedRanges = new ScRangeList(); + } + refScMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_True); - // 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 ) + //For Whole Col Row + sal_Bool bWholeRow = ::labs(aMarkRange.aStart.Row() - aMarkRange.aEnd.Row()) == MAXROW ; + sal_Bool bWholeCol = ::abs(aMarkRange.aStart.Col() - aMarkRange.aEnd.Col()) == MAXCOL ; + if ((bNewMarked || bIsMark || bIsMultMark ) && (bWholeCol || bWholeRow)) { - AccessibleEventObject aEvent; - aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; - aEvent.Source = uno::Reference< XAccessibleContext >(this); - aEvent.OldValue <<= xOld; - aEvent.NewValue <<= xNew; + if ( aMarkRange != m_aLastWithInMarkRange ) + { + RemoveSelection(refScMarkData); + if(bNewPosCell) + { + CommitFocusCell(aNewCell); + } + sal_Bool bLastIsWholeColRow = + (::labs(m_aLastWithInMarkRange.aStart.Row() - m_aLastWithInMarkRange.aEnd.Row()) == MAXROW && bWholeRow) || + (::abs(m_aLastWithInMarkRange.aStart.Col() - m_aLastWithInMarkRange.aEnd.Col()) == MAXCOL && bWholeCol); + sal_Bool bSelSmaller= + bLastIsWholeColRow && + !aMarkRange.In(m_aLastWithInMarkRange) && + aMarkRange.Intersects(m_aLastWithInMarkRange); + if( !bSelSmaller ) + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; + aEvent.NewValue <<= ::com::sun::star::uno::Any(); + CommitChange(aEvent); + } + m_aLastWithInMarkRange = aMarkRange; + } + return ; + } + m_aLastWithInMarkRange = aMarkRange; + int nNewMarkCount = mpMarkedRanges->GetCellCount(); + sal_Bool bSendSingle= (0 == nNewMarkCount) && bNewPosCell; + if (bSendSingle) + { + RemoveSelection(refScMarkData); + if(bNewPosCellFocus) + { + CommitFocusCell(aNewCell); + } + uno::Reference< XAccessible > xChild ; + if (bNewPosCellFocus) + { + xChild = mpAccCell; + } + else + { + xChild = getAccessibleCellAt(aNewCell.Row(),aNewCell.Col()); + + maActiveCell = aNewCell; + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; + aEvent.NewValue <<= xChild; + aEvent.OldValue <<= uno::Reference< XAccessible >(); + CommitChange(aEvent); + } + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + aEvent.NewValue <<= xChild; CommitChange(aEvent); + OSL_ASSERT(m_mapSelectionSend.count(aNewCell) == 0 ); + m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(aNewCell,xChild)); + + } + else + { + ScRange aDelRange; + sal_Bool bIsDel = pViewData->GetDelMark( aDelRange ); + if ( (!bIsDel || (bIsDel && aMarkRange != aDelRange)) && + bNewMarked && + nNewMarkCount > 0 && + !IsSameMarkCell() ) + { + RemoveSelection(refScMarkData); + if(bNewPosCellFocus) + { + CommitFocusCell(aNewCell); + } + VEC_MYADDR vecNew; + if(CalcScRangeListDifferenceMax(mpMarkedRanges,&m_LastMarkedRanges,10,vecNew)) + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; + aEvent.NewValue <<= ::com::sun::star::uno::Any(); + CommitChange(aEvent); + } + else + { + VEC_MYADDR::iterator viAddr = vecNew.begin(); + for(; viAddr < vecNew.end() ; ++viAddr ) + { + uno::Reference< XAccessible > xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col()); + if (!(bNewPosCellFocus && *viAddr == aNewCell) ) + { + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; + aEvent.NewValue <<= xChild; + CommitChange(aEvent); + } + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; + aEvent.NewValue <<= xChild; + CommitChange(aEvent); + m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild)); + } + } + } + } + if (bNewPosCellFocus && maActiveCell != aNewCell) + { + CommitFocusCell(aNewCell); } + m_LastMarkedRanges = *mpMarkedRanges; } } else if ((rRef.GetId() == SC_HINT_DATACHANGED)) @@ -258,6 +620,38 @@ void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE); else mbDelIns = false; + ScViewData *pViewData = mpViewShell->GetViewData(); + ScAddress aNewCell = pViewData->GetCurPos(); + if( maActiveCell == aNewCell) + { + ScDocument* pScDoc= GetDocument(mpViewShell); + if (pScDoc) + { + OUString valStr(pScDoc->GetString(aNewCell.Col(),aNewCell.Row(),aNewCell.Tab())); + if(m_strCurCellValue != valStr) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::VALUE_CHANGED; + mpAccCell->CommitChange(aEvent); + m_strCurCellValue=valStr; + } + OUString tabName; + pScDoc->GetName( maActiveCell.Tab(), tabName ); + if( m_strOldTabName != tabName ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::NAME_CHANGED; + OUString sOldName(ScResId(STR_ACC_TABLE_NAME)); + sOldName = sOldName.replaceFirst("%1", m_strOldTabName); + aEvent.OldValue <<= sOldName; + OUString sNewName(ScResId(STR_ACC_TABLE_NAME)); + sOldName = sNewName.replaceFirst("%1", tabName); + aEvent.NewValue <<= sNewName; + CommitChange( aEvent ); + m_strOldTabName = tabName; + } + } + } } // 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 @@ -343,7 +737,63 @@ void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ScAccessibleTableBase::Notify(rBC, rHint); } - //===== XAccessibleTable ================================================ +void ScAccessibleSpreadsheet::RemoveSelection(ScMarkData &refScMarkData) +{ + AccessibleEventObject aEvent; + aEvent.Source = uno::Reference< XAccessible >(this); + aEvent.OldValue <<= ::com::sun::star::uno::Any(); + MAP_ADDR_XACC::iterator miRemove = m_mapSelectionSend.begin(); + for(; miRemove != m_mapSelectionSend.end() ;) + { + if (refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),sal_True) || + refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),sal_False) ) + { + ++miRemove; + continue; + } + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; + aEvent.NewValue <<= miRemove->second; + CommitChange(aEvent); + MAP_ADDR_XACC::iterator miNext = miRemove; + ++miNext; + m_mapSelectionSend.erase(miRemove); + miRemove = miNext; + } +} +void ScAccessibleSpreadsheet::CommitFocusCell(const ScAddress &aNewCell) +{ + OSL_ASSERT(!IsFormulaMode()); + if(IsFormulaMode()) + { + return ; + } + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; + aEvent.Source = uno::Reference< XAccessible >(this); + uno::Reference< XAccessible > xOld = mpAccCell; + mpAccCell->release(); + mpAccCell=NULL; + aEvent.OldValue <<= xOld; + mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col()); + mpAccCell->acquire(); + mpAccCell->Init(); + uno::Reference< XAccessible > xNew = mpAccCell; + aEvent.NewValue <<= xNew; + maActiveCell = aNewCell; + ScDocument* pScDoc= GetDocument(mpViewShell); + if (pScDoc) + { + m_strCurCellValue = pScDoc->GetString(maActiveCell.Col(),maActiveCell.Row(),maActiveCell.Tab()); + } + CommitChange(aEvent); +} + +sal_Bool ScAccessibleSpreadsheet::IsSameMarkCell() +{ + return m_LastMarkedRanges == *mpMarkedRanges; +} + +//===== XAccessibleTable ================================================ uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( ) throw (uno::RuntimeException) @@ -389,6 +839,10 @@ uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessib SolarMutexGuard aGuard; IsObjectValid(); uno::Sequence<sal_Int32> aSequence; + if (IsFormulaMode()) + { + return aSequence; + } if (mpViewShell && mpViewShell->GetViewData()) { aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1); @@ -416,6 +870,10 @@ uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessib SolarMutexGuard aGuard; IsObjectValid(); uno::Sequence<sal_Int32> aSequence; + if (IsFormulaMode()) + { + return aSequence; + } if (mpViewShell && mpViewShell->GetViewData()) { aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1); @@ -442,6 +900,10 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nR { SolarMutexGuard aGuard; IsObjectValid(); + if (IsFormulaMode()) + { + return sal_False; + } if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) throw lang::IndexOutOfBoundsException(); @@ -461,6 +923,10 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 SolarMutexGuard aGuard; IsObjectValid(); + if (IsFormulaMode()) + { + return sal_False; + } if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0)) throw lang::IndexOutOfBoundsException(); @@ -476,14 +942,27 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 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) + if (IsFormulaMode()) { - pAccessibleCell = mpAccCell; + ScAddress aCellAddress(static_cast<SCCOL>(nColumn), nRow, mpViewShell->GetViewData()->GetTabNo()); + if ((aCellAddress == m_aFormulaActiveCell) && m_pAccFormulaCell) + { + pAccessibleCell = m_pAccFormulaCell; + } + else + pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, GetAccessibleIndexFormula(nRow, nColumn), meSplitPos, mpAccDoc); } else - pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc); + { + 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; } @@ -493,12 +972,14 @@ uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCel { SolarMutexGuard aGuard; IsObjectValid(); + if (!IsFormulaMode()) + { 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; @@ -512,6 +993,11 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, SolarMutexGuard aGuard; IsObjectValid(); + if (IsFormulaMode()) + { + ScAddress addr(static_cast<SCCOL>(nColumn), nRow, 0); + return IsScAddrFormulaSel(addr); + } if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) throw lang::IndexOutOfBoundsException(); @@ -541,7 +1027,13 @@ uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtP SCsCOL nX; SCsROW nY; mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY); + try{ xAccessible = getAccessibleCellAt(nY, nX); + } + catch( ::com::sun::star::lang::IndexOutOfBoundsException e) + { + return NULL; + } } } return xAccessible; @@ -649,7 +1141,8 @@ void SAL_CALL IsObjectValid(); if (mpViewShell) { - mpViewShell->Unmark(); + if (!IsFormulaMode()) + mpViewShell->Unmark(); } } @@ -661,7 +1154,16 @@ void SAL_CALL IsObjectValid(); if (mpViewShell) { - mpViewShell->SelectAll(); + if (IsFormulaMode()) + { + ScViewData *pViewData = mpViewShell->GetViewData(); + mpViewShell->InitRefMode( 0, 0, pViewData->GetTabNo(), SC_REFTYPE_REF ); + pViewData->SetRefStart(0,0,pViewData->GetTabNo()); + pViewData->SetRefStart(MAXCOL,MAXROW,pViewData->GetTabNo()); + mpViewShell->UpdateRef(MAXCOL, MAXROW, pViewData->GetTabNo()); + } + else + mpViewShell->SelectAll(); } } @@ -674,16 +1176,22 @@ sal_Int32 SAL_CALL sal_Int32 nResult(0); if (mpViewShell) { - if (!mpMarkedRanges) + if (IsFormulaMode()) { - mpMarkedRanges = new ScRangeList(); - ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); - aMarkData.MarkToMulti(); - aMarkData.FillRangeListWithMarks(mpMarkedRanges, false); + nResult = GetRowAll() * GetColAll() ; + } + else + { + if (!mpMarkedRanges) + { + mpMarkedRanges = new ScRangeList(); + ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); + aMarkData.FillRangeListWithMarks(mpMarkedRanges, false); + } + // is possible, because there shouldn't be overlapped ranges in it + if (mpMarkedRanges) + nResult = mpMarkedRanges->GetCellCount(); } - // is possible, because there shouldn't be overlapped ranges in it - if (mpMarkedRanges) - nResult = mpMarkedRanges->GetCellCount(); } return nResult; } @@ -695,6 +1203,15 @@ uno::Reference<XAccessible > SAL_CALL SolarMutexGuard aGuard; IsObjectValid(); uno::Reference < XAccessible > xAccessible; + if (IsFormulaMode()) + { + if(CheckChildIndex(nSelectedChildIndex)) + { + ScAddress addr = GetChildIndexAddress(nSelectedChildIndex); + xAccessible = getAccessibleCellAt(addr.Row(), addr.Col()); + } + return xAccessible; + } if (mpViewShell) { if (!mpMarkedRanges) @@ -704,16 +1221,16 @@ uno::Reference<XAccessible > SAL_CALL } if (mpMarkedRanges) { - if (!mpSortedMarkedCells) - CreateSortedMarkedCells(); - if (mpSortedMarkedCells) + if ((nSelectedChildIndex < 0) || + (mpMarkedRanges->GetCellCount() <= static_cast<sal_uInt32>(nSelectedChildIndex))) { - if ((nSelectedChildIndex < 0) || - (mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex))) - throw lang::IndexOutOfBoundsException(); - else - xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col()); + throw lang::IndexOutOfBoundsException(); } + ScMyAddress addr = CalcScAddressFromRangeList(mpMarkedRanges,nSelectedChildIndex); + if( m_mapSelectionSend.find(addr) != m_mapSelectionSend.end() ) + xAccessible = m_mapSelectionSend[addr]; + else + xAccessible = getAccessibleCellAt(addr.Row(), addr.Col()); } } return xAccessible; @@ -734,6 +1251,16 @@ void SAL_CALL sal_Int32 nCol(getAccessibleColumn(nChildIndex)); sal_Int32 nRow(getAccessibleRow(nChildIndex)); + if (IsFormulaMode()) + { + if(IsScAddrFormulaSel( + ScAddress(static_cast<SCCOL>(nCol), nRow,mpViewShell->GetViewData()->GetTabNo())) + ) + { + SelectCell(nRow, nCol, sal_True); + } + return ; + } if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow))) SelectCell(nRow, nCol, sal_True); } @@ -741,14 +1268,30 @@ void SAL_CALL void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect) { + if (IsFormulaMode()) + { + if (bDeselect) + {//?? + return; + } + else + { + ScViewData *pViewData = mpViewShell->GetViewData(); + + mpViewShell->InitRefMode( static_cast<SCCOL>(nCol), nRow, pViewData->GetTabNo(), SC_REFTYPE_REF ); + mpViewShell->UpdateRef(static_cast<SCCOL>(nCol), nRow, pViewData->GetTabNo()); + } + return ; + } 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, false, false ); + 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>(); @@ -791,7 +1334,7 @@ void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange) mpSortedMarkedCells->push_back(aCell); } } -} +}*/ //===== XServiceInfo ==================================================== @@ -837,21 +1380,9 @@ void SAL_CALL ScAccessibleSpreadsheet::addAccessibleEventListener(const uno::Ref IsObjectValid(); ScAccessibleTableBase::addAccessibleEventListener(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 ========================================================= +//==== internal ========================================================= Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const throw (uno::RuntimeException) @@ -890,6 +1421,10 @@ sal_Bool ScAccessibleSpreadsheet::IsDefunc( sal_Bool ScAccessibleSpreadsheet::IsEditable( const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) { + if (IsFormulaMode()) + { + return sal_False; + } sal_Bool bProtected(false); if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab())) bProtected = sal_True; @@ -909,6 +1444,11 @@ sal_Bool ScAccessibleSpreadsheet::IsFocused() sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected() { + if (IsFormulaMode()) + { + return sal_False; + } + sal_Bool bResult(false); if(mpViewShell) { @@ -960,4 +1500,286 @@ Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea) return Rectangle(); } +sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectRow( sal_Int32 row ) +throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if (IsFormulaMode()) + { + return sal_False; + } + + mpViewShell->SetTabNo( maRange.aStart.Tab() ); + mpViewShell->DoneBlockMode( sal_True ); // continue selecting + mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), sal_False, sal_False, sal_True ); + mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), sal_False, sal_True ); + mpViewShell->SelectionChanged(); + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectColumn( sal_Int32 column ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if (IsFormulaMode()) + { + return sal_False; + } + + mpViewShell->SetTabNo( maRange.aStart.Tab() ); + mpViewShell->DoneBlockMode( sal_True ); // continue selecting + mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), sal_False, sal_True, sal_False ); + mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), sal_True, sal_False ); + mpViewShell->SelectionChanged(); + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectRow( sal_Int32 row ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if (IsFormulaMode()) + { + return sal_False; + } + + mpViewShell->SetTabNo( maRange.aStart.Tab() ); + mpViewShell->DoneBlockMode( sal_True ); // continue selecting + mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), sal_False, sal_False, sal_True, sal_True ); + mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), sal_False, sal_True ); + mpViewShell->SelectionChanged(); + mpViewShell->DoneBlockMode( sal_True ); + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectColumn( sal_Int32 column ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + if (IsFormulaMode()) + { + return sal_False; + } + + mpViewShell->SetTabNo( maRange.aStart.Tab() ); + mpViewShell->DoneBlockMode( sal_True ); // continue selecting + mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), sal_False, sal_True, sal_False, sal_True ); + mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), sal_True, sal_False ); + mpViewShell->SelectionChanged(); + mpViewShell->DoneBlockMode( sal_True ); + return sal_True; +} + +void ScAccessibleSpreadsheet::FireFirstCellFocus() +{ + if (IsFormulaMode()) + { + return ; + } + if (mbIsFocusSend) + { + return ; + } + mbIsFocusSend = sal_True; + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; + aEvent.Source = uno::Reference< XAccessible >(this); + aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col()); + CommitChange(aEvent); +} + +void ScAccessibleSpreadsheet::NotifyRefMode() +{ + ScViewData *pViewData = mpViewShell->GetViewData(); + sal_uInt16 nRefStartX =pViewData->GetRefStartX(); + sal_Int32 nRefStartY=pViewData->GetRefStartY(); + sal_uInt16 nRefEndX=pViewData->GetRefEndX(); + sal_Int32 nRefEndY=pViewData->GetRefEndY(); + ScAddress aFormulaAddr; + if(!GetFormulaCurrentFocusCell(aFormulaAddr)) + { + return ; + } + if (m_aFormulaActiveCell != aFormulaAddr) + {//New Focus + m_nMinX =std::min(nRefStartX,nRefEndX); + m_nMaxX =std::max(nRefStartX,nRefEndX); + m_nMinY = std::min(nRefStartY,nRefEndY); + m_nMaxY = std::max(nRefStartY,nRefEndY); + RemoveFormulaSelection(); + AccessibleEventObject aEvent; + aEvent.Source = uno::Reference< XAccessible >(this); + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; + aEvent.Source = uno::Reference< XAccessible >(this); + uno::Reference< XAccessible > xOld = m_pAccFormulaCell; + aEvent.OldValue <<= xOld; + m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(), aFormulaAddr.Col()); + m_pAccFormulaCell->acquire(); + m_pAccFormulaCell->Init(); + uno::Reference< XAccessible > xNew = m_pAccFormulaCell; + aEvent.NewValue <<= xNew; + CommitChange(aEvent); + if (nRefStartX == nRefEndX && nRefStartY == nRefEndY) + {//Selection Single + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + aEvent.NewValue <<= xNew; + CommitChange(aEvent); + m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(aFormulaAddr,xNew)); + m_vecFormulaLastMyAddr.clear(); + m_vecFormulaLastMyAddr.push_back(aFormulaAddr); + } + else + { + VEC_MYADDR vecCurSel; + int nCurSize = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) ; + vecCurSel.reserve(nCurSize); + for (sal_uInt16 x = m_nMinX ; x <= m_nMaxX ; ++x) + { + for (sal_Int32 y = m_nMinY ; y <= m_nMaxY ; ++y) + { + ScMyAddress aAddr(x,y,0); + vecCurSel.push_back(aAddr); + } + } + std::sort(vecCurSel.begin(), vecCurSel.end()); + VEC_MYADDR vecNew; + std::set_difference(vecCurSel.begin(),vecCurSel.end(), + m_vecFormulaLastMyAddr.begin(),m_vecFormulaLastMyAddr.end(), + std::back_insert_iterator<VEC_MYADDR>(vecNew)); + int nNewSize = vecNew.size(); + if ( nNewSize > 10 ) + { + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; + aEvent.NewValue <<= ::com::sun::star::uno::Any(); + CommitChange(aEvent); + } + else + { + VEC_MYADDR::iterator viAddr = vecNew.begin(); + for(; viAddr != vecNew.end() ; ++viAddr ) + { + uno::Reference< XAccessible > xChild; + if (*viAddr == aFormulaAddr) + { + xChild = m_pAccFormulaCell; + } + else + { + xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col()); + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS; + aEvent.NewValue <<= xChild; + CommitChange(aEvent); + } + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD; + aEvent.NewValue <<= xChild; + CommitChange(aEvent); + m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild)); + } + } + m_vecFormulaLastMyAddr.swap(vecCurSel); + } + } + m_aFormulaActiveCell = aFormulaAddr; +} + +void ScAccessibleSpreadsheet::RemoveFormulaSelection(sal_Bool bRemoveAll ) +{ + AccessibleEventObject aEvent; + aEvent.Source = uno::Reference< XAccessible >(this); + aEvent.OldValue <<= ::com::sun::star::uno::Any(); + MAP_ADDR_XACC::iterator miRemove = m_mapFormulaSelectionSend.begin(); + for(; miRemove != m_mapFormulaSelectionSend.end() ;) + { + if( !bRemoveAll && IsScAddrFormulaSel(miRemove->first) ) + { + ++miRemove; + continue; + } + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; + aEvent.NewValue <<= miRemove->second; + CommitChange(aEvent); + MAP_ADDR_XACC::iterator miNext = miRemove; + ++miNext; + m_mapFormulaSelectionSend.erase(miRemove); + miRemove = miNext; + } +} + +sal_Bool ScAccessibleSpreadsheet::IsScAddrFormulaSel(const ScAddress &addr) const +{ + if( addr.Col() >= m_nMinX && addr.Col() <= m_nMaxX && + addr.Row() >= m_nMinY && addr.Row() <= m_nMaxY && + addr.Tab() == mpViewShell->GetViewData()->GetTabNo() ) + { + return sal_True; + } + return sal_False; +} + +sal_Bool ScAccessibleSpreadsheet::CheckChildIndex(sal_Int32 nIndex) const +{ + sal_Int32 nMaxIndex = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) -1 ; + return nIndex <= nMaxIndex && nIndex >= 0 ; +} + +ScAddress ScAccessibleSpreadsheet::GetChildIndexAddress(sal_Int32 nIndex) const +{ + sal_Int32 nRowAll = GetRowAll(); + sal_uInt16 nColAll = GetColAll(); + if (nIndex < 0 || nIndex >= nRowAll * nColAll ) + { + return ScAddress(); + } + return ScAddress( + static_cast<SCCOL>((nIndex - nIndex % nRowAll) / nRowAll + + m_nMinX), + nIndex % nRowAll + m_nMinY, + mpViewShell->GetViewData()->GetTabNo() + ); +} + +sal_Int32 ScAccessibleSpreadsheet::GetAccessibleIndexFormula( sal_Int32 nRow, sal_Int32 nColumn ) +{ + sal_uInt16 nColRelative = sal_uInt16(nColumn) - GetColAll(); + sal_Int32 nRowRelative = nRow - GetRowAll(); + if (nRow < 0 || nColumn < 0 || nRowRelative >= GetRowAll() || nColRelative >= GetColAll() ) + { + return -1; + } + return GetRowAll() * nRowRelative + nColRelative; +} + +sal_Bool ScAccessibleSpreadsheet::IsFormulaMode() +{ + ScViewData *pViewData = mpViewShell->GetViewData(); + m_bFormulaMode = pViewData->IsRefMode() || SC_MOD()->IsFormulaMode(); + return m_bFormulaMode ; +} + +sal_Bool ScAccessibleSpreadsheet::GetFormulaCurrentFocusCell(ScAddress &addr) +{ + ScViewData *pViewData = mpViewShell->GetViewData(); + sal_uInt16 nRefX=0; + sal_Int32 nRefY=0; + if(m_bFormulaLastMode) + { + nRefX=pViewData->GetRefEndX(); + nRefY=pViewData->GetRefEndY(); + } + else + { + nRefX=pViewData->GetRefStartX(); + nRefY=pViewData->GetRefStartY(); + } + if( /* Always true: nRefX >= 0 && */ nRefX <= MAXCOL && nRefY >= 0 && nRefY <= MAXROW) + { + addr = ScAddress(nRefX,nRefY,pViewData->GetTabNo()); + return sal_True; + } + return sal_False; +} + +uno::Reference < XAccessible > ScAccessibleSpreadsheet::GetActiveCell() +{ + if( m_mapSelectionSend.find( maActiveCell ) != m_mapSelectionSend.end() ) + return m_mapSelectionSend[maActiveCell]; + else + return getAccessibleCellAt(maActiveCell.Row(), maActiveCell .Col()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleTableBase.cxx b/sc/source/ui/Accessibility/AccessibleTableBase.cxx index 60a008a637b9..5a74dcf5af72 100644 --- a/sc/source/ui/Accessibility/AccessibleTableBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleTableBase.cxx @@ -22,6 +22,7 @@ #include "document.hxx" #include "scresid.hxx" #include "sc.hrc" +#include "table.hxx" #include <com/sun/star/accessibility/AccessibleRole.hpp> #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> @@ -64,8 +65,19 @@ void SAL_CALL ScAccessibleTableBase::disposing() 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); + uno::Any aRet; + if ( rType == ::getCppuType((uno::Reference<XAccessibleTableSelection> *)0) ) + { + uno::Reference<XAccessibleTableSelection> xThis( this ); + aRet <<= xThis; + return aRet; + } + else + { + uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType)); + return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType); + } + return aRet; } void SAL_CALL ScAccessibleTableBase::acquire() @@ -140,12 +152,10 @@ sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nR { 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; - } + mpDoc->FetchTable(maRange.aStart.Tab())->GetColumnByIndex(nColumn)-> + ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False ); + if (nEndRow > nRow) + nCount = nEndRow - nRow + 1; } return nCount; @@ -169,12 +179,10 @@ sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 { 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) + mpDoc->FetchTable(maRange.aStart.Tab())->GetColumnByIndex(nColumn)-> + ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False ); + if (nEndCol > nColumn) nCount = nEndCol - nColumn + 1; - } } return nCount; @@ -479,4 +487,28 @@ void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int3 CommitChange(aEvent); } +sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 ) +throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + return sal_True; +} + +sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + return sal_True; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleText.cxx b/sc/source/ui/Accessibility/AccessibleText.cxx index 1692e9aa689c..7907bb652293 100644 --- a/sc/source/ui/Accessibility/AccessibleText.cxx +++ b/sc/source/ui/Accessibility/AccessibleText.cxx @@ -976,7 +976,7 @@ ScDocShell* ScAccessibleCellTextData::GetDocShell(ScTabViewShell* pViewShell) } -ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin) +ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin, sal_Bool isClone) : mpViewForwarder(NULL), mpEditViewForwarder(NULL), @@ -985,13 +985,16 @@ ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditVi mpForwarder(NULL), mpWindow(pWin) { - if (mpEditEngine) + // If the object is cloned, do NOT add notify hdl. + mbIsCloned = isClone; + if (mpEditEngine && !mbIsCloned) mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) ); } ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData() { - if (mpEditEngine) + // If the object is cloned, do NOT set notify hdl. + if (mpEditEngine && !mbIsCloned) mpEditEngine->SetNotifyHdl(Link()); if (mpViewForwarder) delete mpViewForwarder; @@ -1023,7 +1026,8 @@ void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster& rBC, const SfxHint& ScAccessibleTextData* ScAccessibleEditObjectTextData::Clone() const { - return new ScAccessibleEditObjectTextData(mpEditView, mpWindow); + // Add para to indicate the object is cloned + return new ScAccessibleEditObjectTextData(mpEditView, mpWindow,sal_True); } SvxTextForwarder* ScAccessibleEditObjectTextData::GetTextForwarder() @@ -1032,7 +1036,8 @@ SvxTextForwarder* ScAccessibleEditObjectTextData::GetTextForwarder() { if (!mpEditEngine) mpEditEngine = mpEditView->GetEditEngine(); - if (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet()) + // If the object is cloned, do NOT add notify hdl. + if (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet()&&!mbIsCloned) mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) ); if(!mpForwarder) mpForwarder = new SvxEditEngineForwarder(*mpEditEngine); |