diff options
Diffstat (limited to 'sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx')
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx | 1154 |
1 files changed, 1056 insertions, 98 deletions
diff --git a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx index 1bfb282a380c..571f19832b39 100644 --- a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx +++ b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx @@ -50,12 +50,212 @@ #include <tools/debug.hxx> #include <tools/gen.hxx> #include <svtools/colorcfg.hxx> - +//IAccessibility2 Implementation 2009----- +#include "scresid.hxx" +#include "sc.hrc" +//-----IAccessibility2 Implementation 2009 #include <algorithm> using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; +//IAccessibility2 Implementation 2009----- +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->Count() <= 1) + { + ScRange* pRange = pMarkedRanges->First(); + 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(); + ScRange* pRange = pMarkedRanges->First(); + while (pRange) + { + 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 + DBG_ERROR("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 + DBG_ERROR("Range of wrong table"); + pRange = pMarkedRanges->Next(); + } + 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); + ScRange* pRange = pSrc->First(); + while (pRange) + { + 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())); + } + } + pRange = pSrc->Next(); + } + return sal_False; + } + //the Dest Rang List is not empty + vecRet.reserve(10); + ScRange* pRange = pSrc->First(); + while (pRange) + { + ScRange* pRangeDest = pDest->First(); + while (pRangeDest) + { + if (CalcScRangeDifferenceMax(pRange,pRangeDest,nMax,vecRet,nSize)) + { + return sal_True; + } + pRangeDest = pDest->Next(); + } + pRange = pSrc->Next(); + } + return sal_False; +} +//-----IAccessibility2 Implementation 2009 //===== internal ============================================================ ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( @@ -66,7 +266,13 @@ ScAccessibleSpreadsheet::ScAccessibleSpreadsheet( : ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell), ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))), - mbIsSpreadsheet( sal_True ) + mbIsSpreadsheet( sal_True ), +//IAccessibility2 Implementation 2009----- + m_bFormulaMode(sal_False), + m_bFormulaLastMode(sal_False), + m_pAccFormulaCell(NULL), + m_nMinX(0),m_nMaxX(0),m_nMinY(0),m_nMaxY(0) +//-----IAccessibility2 Implementation 2009 { ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos ); } @@ -83,8 +289,10 @@ ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet() { if (mpMarkedRanges) delete mpMarkedRanges; - if (mpSortedMarkedCells) - delete mpSortedMarkedCells; +//IAccessibility2 Implementation 2009----- + //if (mpSortedMarkedCells) + // delete mpSortedMarkedCells; +//-----IAccessibility2 Implementation 2009 if (mpViewShell) mpViewShell->RemoveAccessibilityObject(*this); } @@ -118,6 +326,13 @@ void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet( mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col()); mpAccCell->acquire(); mpAccCell->Init(); + //IAccessibility2 Implementation 2009----- + ScDocument* pScDoc= GetDocument(mpViewShell); + if (pScDoc) + { + pScDoc->GetName( maActiveCell.Tab(), m_strOldTabName ); + } + //-----IAccessibility2 Implementation 2009 } } @@ -140,11 +355,18 @@ void SAL_CALL ScAccessibleSpreadsheet::disposing() void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState) { +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return ; + } +//-----IAccessibility2 Implementation 2009 if (mpMarkedRanges) DELETEZ(mpMarkedRanges); - if (mpSortedMarkedCells) - DELETEZ(mpSortedMarkedCells); - +//IAccessibility2 Implementation 2009----- + //if (mpSortedMarkedCells) + // DELETEZ(mpSortedMarkedCells); +//-----IAccessibility2 Implementation 2009 mbHasSelection = bNewState; AccessibleEventObject aEvent; @@ -173,12 +395,46 @@ void ScAccessibleSpreadsheet::LostFocus() void ScAccessibleSpreadsheet::GotFocus() { - CommitFocusGained(); - +//IAccessibility2 Implementation 2009----- + //CommitFocusGained(); +//-----IAccessibility2 Implementation 2009 AccessibleEventObject aEvent; aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; aEvent.Source = uno::Reference< XAccessibleContext >(this); - uno::Reference< XAccessible > xNew = mpAccCell; +//IAccessibility2 Implementation 2009----- + //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 ; + } + } +//-----IAccessibility2 Implementation 2009 aEvent.NewValue <<= xNew; CommitChange(aEvent); @@ -211,58 +467,247 @@ void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint if (pSfxSimpleHint) { // only notify if child exist, otherwise it is not necessary +//IAccessibility2 Implementation 2009----- + //if ((pSfxSimpleHint->GetId() == SC_HINT_ACC_CURSORCHANGED)) + //{ + // if (mpViewShell) + // { + // ScAddress aNewCell = mpViewShell->GetViewData()->GetCurPos(); + // sal_Bool bNewMarked(mpViewShell->GetViewData()->GetMarkData().GetTableSelect(aNewCell.Tab()) && + // (mpViewShell->GetViewData()->GetMarkData().IsMarked() || + // mpViewShell->GetViewData()->GetMarkData().IsMultiMarked())); + // sal_Bool bNewCellSelected(isAccessibleSelected(aNewCell.Row(), aNewCell.Col())); + // if ((bNewMarked != mbHasSelection) || + // (!bNewCellSelected && bNewMarked) || + // (bNewCellSelected && mbHasSelection)) + // { + // if (mpMarkedRanges) + // DELETEZ(mpMarkedRanges); + // if (mpSortedMarkedCells) + // DELETEZ(mpSortedMarkedCells); + // AccessibleEventObject aEvent; + // aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + // aEvent.Source = uno::Reference< XAccessibleContext >(this); + + // mbHasSelection = bNewMarked; + + // CommitChange(aEvent); + // } + + // // active descendant changed event (new cell selected) + // bool bFireActiveDescChanged = (aNewCell != maActiveCell) && + // (aNewCell.Tab() == maActiveCell.Tab()) && IsFocused(); + + // /* Remember old active cell and set new active cell. + // #i82409# always update the class members mpAccCell and + // maActiveCell, even if the sheet is not focused, e.g. when + // using the name box in the toolbar. */ + // uno::Reference< XAccessible > xOld = mpAccCell; + // mpAccCell->release(); + // mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col()); + // mpAccCell->acquire(); + // mpAccCell->Init(); + // uno::Reference< XAccessible > xNew = mpAccCell; + // maActiveCell = aNewCell; + + // // #i14108# fire event only if sheet is focused + // if( bFireActiveDescChanged ) + // { + // AccessibleEventObject aEvent; + // aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; + // aEvent.Source = uno::Reference< XAccessibleContext >(this); + // aEvent.OldValue <<= xOld; + // aEvent.NewValue <<= xNew; + // CommitChange(aEvent); + // } + // } + //} + //else if ((rRef.GetId() == SC_HINT_DATACHANGED)) + //{ + // if (!mbDelIns) + // CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE); + // else + // mbDelIns = sal_False; + //} if ((pSfxSimpleHint->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 ((pSfxSimpleHint->GetId() == SC_HINT_DATACHANGED)) @@ -271,7 +716,41 @@ 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 = sal_False; + ScViewData *pViewData = mpViewShell->GetViewData(); + ScAddress aNewCell = pViewData->GetCurPos(); + if( maActiveCell == aNewCell) + { + ScDocument* pScDoc= GetDocument(mpViewShell); + if (pScDoc) + { + String valStr; + pScDoc->GetString(aNewCell.Col(),aNewCell.Row(),aNewCell.Tab(), valStr); + if(m_strCurCellValue != valStr) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::VALUE_CHANGED; + mpAccCell->CommitChange(aEvent); + m_strCurCellValue=valStr; + } + String tabName; + pScDoc->GetName( maActiveCell.Tab(), tabName ); + if( m_strOldTabName != tabName ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::NAME_CHANGED; + String sOldName(ScResId(STR_ACC_TABLE_NAME)); + sOldName.SearchAndReplaceAscii("%1", m_strOldTabName); + aEvent.OldValue <<= ::rtl::OUString( sOldName ); + String sNewName(ScResId(STR_ACC_TABLE_NAME)); + sNewName.SearchAndReplaceAscii("%1", tabName); + aEvent.NewValue <<= ::rtl::OUString( sNewName ); + CommitChange( aEvent ); + m_strOldTabName = tabName; + } + } + } } +//-----IAccessibility2 Implementation 2009 // no longer needed, because the document calls the VisAreaChanged method /* else if (pSfxSimpleHint->GetId() == SC_HINT_ACC_VISAREACHANGED) { @@ -376,7 +855,62 @@ void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ScAccessibleTableBase::Notify(rBC, rHint); } - +//IAccessibility2 Implementation 2009----- +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) + { + pScDoc->GetString(maActiveCell.Col(),maActiveCell.Row(),maActiveCell.Tab(), m_strCurCellValue); + } + CommitChange(aEvent); +} +sal_Bool ScAccessibleSpreadsheet::IsSameMarkCell() +{ + return m_LastMarkedRanges == *mpMarkedRanges; +} +//-----IAccessibility2 Implementation 2009 //===== XAccessibleTable ================================================ uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( ) @@ -423,6 +957,12 @@ uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessib ScUnoGuard aGuard; IsObjectValid(); uno::Sequence<sal_Int32> aSequence; +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return aSequence; + } +//-----IAccessibility2 Implementation 2009 if (mpViewShell && mpViewShell->GetViewData()) { aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1); @@ -450,6 +990,12 @@ uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessib ScUnoGuard aGuard; IsObjectValid(); uno::Sequence<sal_Int32> aSequence; +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return aSequence; + } +//-----IAccessibility2 Implementation 2009 if (mpViewShell && mpViewShell->GetViewData()) { aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1); @@ -476,6 +1022,12 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nR { ScUnoGuard aGuard; IsObjectValid(); +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return sal_False; + } +//-----IAccessibility2 Implementation 2009 if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) throw lang::IndexOutOfBoundsException(); @@ -495,6 +1047,12 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 ScUnoGuard aGuard; IsObjectValid(); +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return sal_False; + } +//-----IAccessibility2 Implementation 2009 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0)) throw lang::IndexOutOfBoundsException(); @@ -510,6 +1068,20 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn) { ScAccessibleCell* pAccessibleCell = NULL; +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + 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 + { +//-----IAccessibility2 Implementation 2009 ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn), static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab()); if ((aCellAddress == maActiveCell) && mpAccCell) @@ -518,6 +1090,7 @@ ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, s } else pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc); + } return pAccessibleCell; } @@ -527,12 +1100,16 @@ uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCel { ScUnoGuard aGuard; IsObjectValid(); +//IAccessibility2 Implementation 2009----- + if (!IsFormulaMode()) + { if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) || nRow < 0 || nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) || nColumn < 0) throw lang::IndexOutOfBoundsException(); - + } +//-----IAccessibility2 Implementation 2009 uno::Reference<XAccessible> xAccessible; ScAccessibleCell* pAccessibleCell = GetAccessibleCellAt(nRow, nColumn); xAccessible = pAccessibleCell; @@ -546,6 +1123,13 @@ sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, ScUnoGuard aGuard; IsObjectValid(); +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + ScAddress addr(static_cast<SCCOL>(nColumn), nRow, 0); + return IsScAddrFormulaSel(addr); + } +//-----IAccessibility2 Implementation 2009 if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) throw lang::IndexOutOfBoundsException(); @@ -575,7 +1159,15 @@ uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtP SCsCOL nX; SCsROW nY; mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY); +//IAccessibility2 Implementation 2009----- + try{ xAccessible = getAccessibleCellAt(nY, nX); + } + catch( ::com::sun::star::lang::IndexOutOfBoundsException e) + { + return NULL; + } +//-----IAccessibility2 Implementation 2009 } } return xAccessible; @@ -683,6 +1275,9 @@ void SAL_CALL IsObjectValid(); if (mpViewShell) { +//IAccessibility2 Implementation 2009----- + if (!IsFormulaMode()) +//-----IAccessibility2 Implementation 2009 mpViewShell->Unmark(); } } @@ -695,6 +1290,17 @@ void SAL_CALL IsObjectValid(); if (mpViewShell) { +//IAccessibility2 Implementation 2009----- + 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 +//-----IAccessibility2 Implementation 2009 mpViewShell->SelectAll(); } } @@ -708,16 +1314,27 @@ sal_Int32 SAL_CALL sal_Int32 nResult(0); if (mpViewShell) { +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + nResult = GetRowAll() * GetColAll() ; + } + else + { +//-----IAccessibility2 Implementation 2009 if (!mpMarkedRanges) { mpMarkedRanges = new ScRangeList(); ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData()); - aMarkData.MarkToMulti(); +//IAccessibility2 Implementation 2009----- + //aMarkData.MarkToMulti(); +//-----IAccessibility2 Implementation 2009 aMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_False); } // is possible, because there shouldn't be overlapped ranges in it if (mpMarkedRanges) nResult = mpMarkedRanges->GetCellCount(); + } } return nResult; } @@ -729,6 +1346,17 @@ uno::Reference<XAccessible > SAL_CALL ScUnoGuard aGuard; IsObjectValid(); uno::Reference < XAccessible > xAccessible; +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + if(CheckChildIndex(nSelectedChildIndex)) + { + ScAddress addr = GetChildIndexAddress(nSelectedChildIndex); + xAccessible = getAccessibleCellAt(addr.Row(), addr.Col()); + } + return xAccessible; + } +//-----IAccessibility2 Implementation 2009 if (mpViewShell) { if (!mpMarkedRanges) @@ -738,16 +1366,27 @@ uno::Reference<XAccessible > SAL_CALL } if (mpMarkedRanges) { - if (!mpSortedMarkedCells) - CreateSortedMarkedCells(); - if (mpSortedMarkedCells) +//IAccessibility2 Implementation 2009----- + //if (!mpSortedMarkedCells) + // CreateSortedMarkedCells(); + //if (mpSortedMarkedCells) + //{ + // if ((nSelectedChildIndex < 0) || + // (mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex))) + // throw lang::IndexOutOfBoundsException(); + // else + // xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col()); + 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()); +//-----IAccessibility2 Implementation 2009 } } return xAccessible; @@ -768,6 +1407,18 @@ void SAL_CALL sal_Int32 nCol(getAccessibleColumn(nChildIndex)); sal_Int32 nRow(getAccessibleRow(nChildIndex)); +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + if(IsScAddrFormulaSel( + ScAddress(static_cast<SCCOL>(nCol), nRow,mpViewShell->GetViewData()->GetTabNo())) + ) + { + SelectCell(nRow, nCol, sal_True); + } + return ; + } +//-----IAccessibility2 Implementation 2009 if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow))) SelectCell(nRow, nCol, sal_True); } @@ -775,48 +1426,65 @@ void SAL_CALL void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect) { - mpViewShell->SetTabNo( maRange.aStart.Tab() ); - - mpViewShell->DoneBlockMode( sal_True ); // continue selecting - mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False ); - - mpViewShell->SelectionChanged(); -} - -void ScAccessibleSpreadsheet::CreateSortedMarkedCells() -{ - mpSortedMarkedCells = new std::vector<ScMyAddress>(); - mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount()); - ScRange* pRange = mpMarkedRanges->First(); - while (pRange) +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) { - if (pRange->aStart.Tab() != pRange->aEnd.Tab()) - { - if ((maActiveCell.Tab() >= pRange->aStart.Tab()) || - maActiveCell.Tab() <= pRange->aEnd.Tab()) - { - ScRange aRange(*pRange); - aRange.aStart.SetTab(maActiveCell.Tab()); - aRange.aEnd.SetTab(maActiveCell.Tab()); - AddMarkedRange(aRange); - } - else - { - DBG_ERROR("Range of wrong table"); - } + if (bDeselect) + {//?? + return ; } - else if(pRange->aStart.Tab() == maActiveCell.Tab()) - AddMarkedRange(*pRange); else { - DBG_ERROR("Range of wrong table"); + 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()); } - pRange = mpMarkedRanges->Next(); + return ; } - std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end()); -} +//-----IAccessibility2 Implementation 2009 + mpViewShell->SetTabNo( maRange.aStart.Tab() ); -void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange) + mpViewShell->DoneBlockMode( sal_True ); // continue selecting + mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False ); + + mpViewShell->SelectionChanged(); +} +//IAccessibility2 Implementation 2009----- +//void ScAccessibleSpreadsheet::CreateSortedMarkedCells() +//{ +// mpSortedMarkedCells = new std::vector<ScMyAddress>(); +// mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount()); +// ScRange* pRange = mpMarkedRanges->First(); +// while (pRange) +// { +// if (pRange->aStart.Tab() != pRange->aEnd.Tab()) +// { +// if ((maActiveCell.Tab() >= pRange->aStart.Tab()) || +// maActiveCell.Tab() <= pRange->aEnd.Tab()) +// { +// ScRange aRange(*pRange); +// aRange.aStart.SetTab(maActiveCell.Tab()); +// aRange.aEnd.SetTab(maActiveCell.Tab()); +// AddMarkedRange(aRange); +// } +// else +// { +// DBG_ERROR("Range of wrong table"); +// } +// } +// else if(pRange->aStart.Tab() == maActiveCell.Tab()) +// AddMarkedRange(*pRange); +// else +// { +// DBG_ERROR("Range of wrong table"); +// } +// pRange = mpMarkedRanges->Next(); +// } +// std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end()); +//} + +/*void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange) { for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow) { @@ -826,7 +1494,8 @@ void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange) mpSortedMarkedCells->push_back(aCell); } } -} +}*/ +//-----IAccessibility2 Implementation 2009 //===== XServiceInfo ==================================================== @@ -876,7 +1545,8 @@ void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAc IsObjectValid(); ScAccessibleTableBase::addEventListener(xListener); - if (!mbIsFocusSend) +//IAccessibility2 Implementation 2009----- +/* if (!mbIsFocusSend) { mbIsFocusSend = sal_True; CommitFocusGained(); @@ -888,6 +1558,8 @@ void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAc CommitChange(aEvent); } +*/ +//-----IAccessibility2 Implementation 2009 } //==== internal ========================================================= @@ -929,6 +1601,12 @@ sal_Bool ScAccessibleSpreadsheet::IsDefunc( sal_Bool ScAccessibleSpreadsheet::IsEditable( const uno::Reference<XAccessibleStateSet>& /* rxParentStates */) { +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return sal_False; + } +//-----IAccessibility2 Implementation 2009 sal_Bool bProtected(sal_False); if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab())) bProtected = sal_True; @@ -948,6 +1626,12 @@ sal_Bool ScAccessibleSpreadsheet::IsFocused() sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected() { +//IAccessibility2 Implementation 2009----- + if (IsFormulaMode()) + { + return sal_False; + } +//-----IAccessibility2 Implementation 2009 sal_Bool bResult(sal_False); if(mpViewShell) { @@ -998,3 +1682,277 @@ Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea) else return Rectangle(); } +//IAccessibility2 Implementation 2009----- +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()); +} +//-----IAccessibility2 Implementation 2009 |