Else you'd end up with wrong ref range values. Also in selectAllAccessibleChildren(), the code is probably meant to select all sheet, rather than setting the top-left reference position twice in a row. Change-Id: I895896418476ffea0862e8df4e03f6efc4c91dd2
1759 lines
61 KiB
C++
1759 lines
61 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include "AccessibleSpreadsheet.hxx"
|
|
#include "AccessibilityHints.hxx"
|
|
#include "AccessibleCell.hxx"
|
|
#include "AccessibleDocument.hxx"
|
|
#include "tabvwsh.hxx"
|
|
#include "document.hxx"
|
|
#include "hints.hxx"
|
|
#include "scmod.hxx"
|
|
#include "markdata.hxx"
|
|
|
|
#include <unotools/accessiblestatesethelper.hxx>
|
|
#include <com/sun/star/accessibility/AccessibleRole.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
|
|
#include <comphelper/servicehelper.hxx>
|
|
#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
|
|
// only this single sub-class
|
|
ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
|
|
ScAccessibleDocument* pAccDoc,
|
|
ScTabViewShell* pViewShell,
|
|
SCTAB nTab,
|
|
ScSplitPos eSplitPos)
|
|
:
|
|
ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell),
|
|
ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))),
|
|
mbIsSpreadsheet( sal_True ),
|
|
m_bFormulaMode(sal_False),
|
|
m_bFormulaLastMode(sal_False),
|
|
m_nMinX(0),m_nMaxX(0),m_nMinY(0),m_nMaxY(0)
|
|
{
|
|
ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos );
|
|
}
|
|
|
|
ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
|
|
ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) :
|
|
ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange),
|
|
mbIsSpreadsheet( false )
|
|
{
|
|
ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos );
|
|
}
|
|
|
|
ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet()
|
|
{
|
|
delete mpMarkedRanges;
|
|
if (mpViewShell)
|
|
mpViewShell->RemoveAccessibilityObject(*this);
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet(
|
|
ScAccessibleDocument* pAccDoc,
|
|
ScTabViewShell* pViewShell,
|
|
SCTAB nTab,
|
|
ScSplitPos eSplitPos)
|
|
{
|
|
mpViewShell = pViewShell;
|
|
mpMarkedRanges = 0;
|
|
mpSortedMarkedCells = 0;
|
|
mpAccDoc = pAccDoc;
|
|
mpAccCell.clear();
|
|
meSplitPos = eSplitPos;
|
|
mnTab = nTab;
|
|
mbHasSelection = false;
|
|
mbDelIns = false;
|
|
mbIsFocusSend = false;
|
|
maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos));
|
|
if (mpViewShell)
|
|
{
|
|
mpViewShell->AddAccessibilityObject(*this);
|
|
|
|
const ScViewData& rViewData = *mpViewShell->GetViewData();
|
|
const ScMarkData& rMarkData = rViewData.GetMarkData();
|
|
maActiveCell = rViewData.GetCurPos();
|
|
mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) &&
|
|
(rMarkData.IsMarked() || rMarkData.IsMultiMarked());
|
|
mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
|
|
ScDocument* pScDoc= GetDocument(mpViewShell);
|
|
if (pScDoc)
|
|
{
|
|
pScDoc->GetName( maActiveCell.Tab(), m_strOldTabName );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SAL_CALL ScAccessibleSpreadsheet::disposing()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if (mpViewShell)
|
|
{
|
|
mpViewShell->RemoveAccessibilityObject(*this);
|
|
mpViewShell = NULL;
|
|
}
|
|
mpAccCell.clear();
|
|
|
|
ScAccessibleTableBase::disposing();
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState)
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
return ;
|
|
}
|
|
if (mpMarkedRanges)
|
|
DELETEZ(mpMarkedRanges);
|
|
mbHasSelection = bNewState;
|
|
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::STATE_CHANGED;
|
|
if (bNewState)
|
|
aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED);
|
|
else
|
|
aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED);
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
|
|
CommitChange(aEvent);
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::LostFocus()
|
|
{
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
aEvent.OldValue <<= uno::Reference<XAccessible>(mpAccCell.get());
|
|
|
|
CommitChange(aEvent);
|
|
|
|
CommitFocusLost();
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::GotFocus()
|
|
{
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
uno::Reference< XAccessible > xNew;
|
|
if (IsFormulaMode())
|
|
{
|
|
if (!m_pAccFormulaCell.is() || !m_bFormulaLastMode)
|
|
{
|
|
ScAddress aFormulaAddr;
|
|
if(!GetFormulaCurrentFocusCell(aFormulaAddr))
|
|
{
|
|
return;
|
|
}
|
|
m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(),aFormulaAddr.Col());
|
|
}
|
|
xNew = m_pAccFormulaCell.get();
|
|
}
|
|
else
|
|
{
|
|
if(mpAccCell->GetCellAddress() == maActiveCell)
|
|
{
|
|
xNew = mpAccCell.get();
|
|
}
|
|
else
|
|
{
|
|
CommitFocusCell(maActiveCell);
|
|
return ;
|
|
}
|
|
}
|
|
aEvent.NewValue <<= xNew;
|
|
|
|
CommitChange(aEvent);
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::BoundingBoxChanged()
|
|
{
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
|
|
CommitChange(aEvent);
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::VisAreaChanged()
|
|
{
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
|
|
CommitChange(aEvent);
|
|
}
|
|
|
|
//===== SfxListener =====================================================
|
|
|
|
void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
|
|
{
|
|
if (rHint.ISA( SfxSimpleHint ) )
|
|
{
|
|
const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
|
|
if ((rRef.GetId() == SC_HINT_ACC_CURSORCHANGED))
|
|
{
|
|
if (mpViewShell)
|
|
{
|
|
ScViewData *pViewData = mpViewShell->GetViewData();
|
|
|
|
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);
|
|
m_pAccFormulaCell.clear();
|
|
//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);
|
|
|
|
//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))
|
|
{
|
|
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.get();
|
|
}
|
|
else
|
|
{
|
|
mpAccCell = GetAccessibleCellAt(aNewCell.Row(),aNewCell.Col());
|
|
xChild = mpAccCell.get();
|
|
|
|
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))
|
|
{
|
|
if (!mbDelIns)
|
|
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
|
|
/* if (mpViewShell)
|
|
{
|
|
Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos)));
|
|
|
|
Rectangle aNewPos(aNewVisCells);
|
|
|
|
if (aNewVisCells.IsOver(maVisCells))
|
|
aNewPos.Union(maVisCells);
|
|
else
|
|
CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE);
|
|
|
|
maVisCells = aNewVisCells;
|
|
|
|
CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE);
|
|
}
|
|
}*/
|
|
}
|
|
else if (rHint.ISA( ScUpdateRefHint ))
|
|
{
|
|
const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
|
|
if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //test whether table is inserted or deleted
|
|
{
|
|
if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) &&
|
|
(rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) ||
|
|
((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) &&
|
|
(rRef.GetRange().aEnd.Row() == maRange.aEnd.Row())))
|
|
{
|
|
// ignore next SC_HINT_DATACHANGED notification
|
|
mbDelIns = sal_True;
|
|
|
|
sal_Int16 nId(0);
|
|
SCsCOL nX(rRef.GetDx());
|
|
SCsROW nY(rRef.GetDy());
|
|
ScRange aRange(rRef.GetRange());
|
|
if ((nX < 0) || (nY < 0))
|
|
{
|
|
OSL_ENSURE(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time");
|
|
nId = AccessibleTableModelChangeType::DELETE;
|
|
if (nX < 0)
|
|
{
|
|
nX = -nX;
|
|
nY = aRange.aEnd.Row() - aRange.aStart.Row();
|
|
}
|
|
else
|
|
{
|
|
nY = -nY;
|
|
nX = aRange.aEnd.Col() - aRange.aStart.Col();
|
|
}
|
|
}
|
|
else if ((nX > 0) || (nY > 0))
|
|
{
|
|
OSL_ENSURE(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time");
|
|
nId = AccessibleTableModelChangeType::INSERT;
|
|
if (nX < 0)
|
|
nY = aRange.aEnd.Row() - aRange.aStart.Row();
|
|
else
|
|
nX = aRange.aEnd.Col() - aRange.aStart.Col();
|
|
}
|
|
else
|
|
{
|
|
OSL_FAIL("is it a deletion or a insertion?");
|
|
}
|
|
|
|
CommitTableModelChange(rRef.GetRange().aStart.Row(),
|
|
rRef.GetRange().aStart.Col(),
|
|
rRef.GetRange().aStart.Row() + nY,
|
|
rRef.GetRange().aStart.Col() + nX, nId);
|
|
|
|
AccessibleEventObject aEvent;
|
|
aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
|
|
aEvent.Source = uno::Reference< XAccessibleContext >(this);
|
|
aEvent.NewValue <<= uno::Reference<XAccessible>(mpAccCell.get());
|
|
|
|
CommitChange(aEvent);
|
|
}
|
|
}
|
|
}
|
|
|
|
ScAccessibleTableBase::Notify(rBC, rHint);
|
|
}
|
|
|
|
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);
|
|
aEvent.OldValue <<= uno::Reference<XAccessible>(mpAccCell.get());
|
|
mpAccCell.clear();
|
|
mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col());
|
|
aEvent.NewValue <<= uno::Reference<XAccessible>(mpAccCell.get());
|
|
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)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
uno::Reference< XAccessibleTable > xAccessibleTable;
|
|
if( mpDoc && mbIsSpreadsheet )
|
|
{
|
|
if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) )
|
|
{
|
|
SCROW nStart = pRowRange->aStart.Row();
|
|
SCROW nEnd = pRowRange->aEnd.Row();
|
|
if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) )
|
|
xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) );
|
|
}
|
|
}
|
|
return xAccessibleTable;
|
|
}
|
|
|
|
uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
uno::Reference< XAccessibleTable > xAccessibleTable;
|
|
if( mpDoc && mbIsSpreadsheet )
|
|
{
|
|
if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) )
|
|
{
|
|
SCCOL nStart = pColRange->aStart.Col();
|
|
SCCOL nEnd = pColRange->aEnd.Col();
|
|
if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) )
|
|
xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) );
|
|
}
|
|
}
|
|
return xAccessibleTable;
|
|
}
|
|
|
|
uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
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);
|
|
const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
|
|
sal_Int32* pSequence = aSequence.getArray();
|
|
sal_Int32 nCount(0);
|
|
for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i)
|
|
{
|
|
if (rMarkdata.IsRowMarked(i))
|
|
{
|
|
pSequence[nCount] = i;
|
|
++nCount;
|
|
}
|
|
}
|
|
aSequence.realloc(nCount);
|
|
}
|
|
else
|
|
aSequence.realloc(0);
|
|
return aSequence;
|
|
}
|
|
|
|
uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
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);
|
|
const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
|
|
sal_Int32* pSequence = aSequence.getArray();
|
|
sal_Int32 nCount(0);
|
|
for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i)
|
|
{
|
|
if (rMarkdata.IsColumnMarked(i))
|
|
{
|
|
pSequence[nCount] = i;
|
|
++nCount;
|
|
}
|
|
}
|
|
aSequence.realloc(nCount);
|
|
}
|
|
else
|
|
aSequence.realloc(0);
|
|
return aSequence;
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow )
|
|
throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
if (IsFormulaMode())
|
|
{
|
|
return sal_False;
|
|
}
|
|
|
|
if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
sal_Bool bResult(false);
|
|
if (mpViewShell && mpViewShell->GetViewData())
|
|
{
|
|
const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
|
|
bResult = rMarkdata.IsRowMarked((SCROW)nRow);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn )
|
|
throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
|
|
if (IsFormulaMode())
|
|
{
|
|
return sal_False;
|
|
}
|
|
if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
sal_Bool bResult(false);
|
|
if (mpViewShell && mpViewShell->GetViewData())
|
|
{
|
|
const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
|
|
bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
rtl::Reference<ScAccessibleCell> ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn)
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
ScAddress aCellAddress(static_cast<SCCOL>(nColumn), nRow, mpViewShell->GetViewData()->GetTabNo());
|
|
if ((aCellAddress == m_aFormulaActiveCell) && m_pAccFormulaCell.is())
|
|
{
|
|
return m_pAccFormulaCell;
|
|
}
|
|
else
|
|
return ScAccessibleCell::create(this, mpViewShell, aCellAddress, GetAccessibleIndexFormula(nRow, nColumn), meSplitPos, mpAccDoc);
|
|
}
|
|
else
|
|
{
|
|
ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn),
|
|
static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab());
|
|
if ((aCellAddress == maActiveCell) && mpAccCell.is())
|
|
{
|
|
return mpAccCell;
|
|
}
|
|
else
|
|
return ScAccessibleCell::create(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc);
|
|
}
|
|
}
|
|
|
|
uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
|
|
throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
|
|
{
|
|
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();
|
|
}
|
|
rtl::Reference<ScAccessibleCell> pAccessibleCell = GetAccessibleCellAt(nRow, nColumn);
|
|
return pAccessibleCell.get();
|
|
}
|
|
|
|
sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
|
|
throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
|
|
{
|
|
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();
|
|
|
|
sal_Bool bResult(false);
|
|
if (mpViewShell)
|
|
{
|
|
const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
|
|
bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow));
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
//===== XAccessibleComponent ============================================
|
|
|
|
uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint(
|
|
const awt::Point& rPoint )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
uno::Reference< XAccessible > xAccessible;
|
|
if (containsPoint(rPoint))
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
if (mpViewShell)
|
|
{
|
|
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;
|
|
}
|
|
|
|
void SAL_CALL ScAccessibleSpreadsheet::grabFocus( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
if (getAccessibleParent().is())
|
|
{
|
|
uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
|
|
if (xAccessibleComponent.is())
|
|
xAccessibleComponent->grabFocus();
|
|
}
|
|
}
|
|
|
|
sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
return COL_BLACK;
|
|
}
|
|
|
|
sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
|
|
}
|
|
|
|
//===== XAccessibleContext ==============================================
|
|
|
|
uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void)
|
|
throw (::com::sun::star::uno::RuntimeException)
|
|
{
|
|
utl::AccessibleRelationSetHelper* pRelationSet = NULL;
|
|
if(mpAccDoc)
|
|
pRelationSet = mpAccDoc->GetRelationSet(NULL);
|
|
if (!pRelationSet)
|
|
pRelationSet = new utl::AccessibleRelationSetHelper();
|
|
return pRelationSet;
|
|
}
|
|
|
|
uno::Reference<XAccessibleStateSet> SAL_CALL
|
|
ScAccessibleSpreadsheet::getAccessibleStateSet(void)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
uno::Reference<XAccessibleStateSet> xParentStates;
|
|
if (getAccessibleParent().is())
|
|
{
|
|
uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
|
|
xParentStates = xParentContext->getAccessibleStateSet();
|
|
}
|
|
utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
|
|
if (IsDefunc(xParentStates))
|
|
pStateSet->AddState(AccessibleStateType::DEFUNC);
|
|
else
|
|
{
|
|
pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
|
|
if (IsEditable(xParentStates))
|
|
pStateSet->AddState(AccessibleStateType::EDITABLE);
|
|
pStateSet->AddState(AccessibleStateType::ENABLED);
|
|
pStateSet->AddState(AccessibleStateType::FOCUSABLE);
|
|
if (IsFocused())
|
|
pStateSet->AddState(AccessibleStateType::FOCUSED);
|
|
pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
|
|
pStateSet->AddState(AccessibleStateType::OPAQUE);
|
|
pStateSet->AddState(AccessibleStateType::SELECTABLE);
|
|
if (IsCompleteSheetSelected())
|
|
pStateSet->AddState(AccessibleStateType::SELECTED);
|
|
if (isShowing())
|
|
pStateSet->AddState(AccessibleStateType::SHOWING);
|
|
if (isVisible())
|
|
pStateSet->AddState(AccessibleStateType::VISIBLE);
|
|
}
|
|
return pStateSet;
|
|
}
|
|
|
|
///===== XAccessibleSelection ===========================================
|
|
|
|
void SAL_CALL
|
|
ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex )
|
|
throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
if (mpViewShell)
|
|
{
|
|
sal_Int32 nCol(getAccessibleColumn(nChildIndex));
|
|
sal_Int32 nRow(getAccessibleRow(nChildIndex));
|
|
|
|
SelectCell(nRow, nCol, false);
|
|
}
|
|
}
|
|
|
|
void SAL_CALL
|
|
ScAccessibleSpreadsheet::clearAccessibleSelection( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
if (mpViewShell)
|
|
{
|
|
if (!IsFormulaMode())
|
|
mpViewShell->Unmark();
|
|
}
|
|
}
|
|
|
|
void SAL_CALL
|
|
ScAccessibleSpreadsheet::selectAllAccessibleChildren( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
if (mpViewShell)
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
ScViewData *pViewData = mpViewShell->GetViewData();
|
|
mpViewShell->InitRefMode( 0, 0, pViewData->GetTabNo(), SC_REFTYPE_REF );
|
|
pViewData->SetRefStart(0,0,pViewData->GetTabNo());
|
|
pViewData->SetRefEnd(MAXCOL,MAXROW,pViewData->GetTabNo());
|
|
mpViewShell->UpdateRef(MAXCOL, MAXROW, pViewData->GetTabNo());
|
|
}
|
|
else
|
|
mpViewShell->SelectAll();
|
|
}
|
|
}
|
|
|
|
sal_Int32 SAL_CALL
|
|
ScAccessibleSpreadsheet::getSelectedAccessibleChildCount( )
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
sal_Int32 nResult(0);
|
|
if (mpViewShell)
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
return nResult;
|
|
}
|
|
|
|
uno::Reference<XAccessible > SAL_CALL
|
|
ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
|
|
throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
|
|
{
|
|
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)
|
|
{
|
|
mpMarkedRanges = new ScRangeList();
|
|
mpViewShell->GetViewData()->GetMarkData().FillRangeListWithMarks(mpMarkedRanges, false);
|
|
}
|
|
if (mpMarkedRanges)
|
|
{
|
|
if ((nSelectedChildIndex < 0) ||
|
|
(mpMarkedRanges->GetCellCount() <= static_cast<sal_uInt32>(nSelectedChildIndex)))
|
|
{
|
|
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;
|
|
}
|
|
|
|
void SAL_CALL
|
|
ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex )
|
|
throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
|
|
if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
|
|
throw lang::IndexOutOfBoundsException();
|
|
|
|
if (mpViewShell)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
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, sal_False, sal_False );
|
|
|
|
mpViewShell->SelectionChanged();
|
|
}
|
|
|
|
/*
|
|
void ScAccessibleSpreadsheet::CreateSortedMarkedCells()
|
|
{
|
|
mpSortedMarkedCells = new std::vector<ScMyAddress>();
|
|
mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount());
|
|
for ( size_t i = 0, ListSize = mpMarkedRanges->size(); i < ListSize; ++i )
|
|
{
|
|
ScRange* pRange = (*mpMarkedRanges)[i];
|
|
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
|
|
{
|
|
OSL_FAIL("Range of wrong table");
|
|
}
|
|
}
|
|
else if(pRange->aStart.Tab() == maActiveCell.Tab())
|
|
AddMarkedRange(*pRange);
|
|
else
|
|
{
|
|
OSL_FAIL("Range of wrong table");
|
|
}
|
|
}
|
|
std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end());
|
|
}
|
|
|
|
void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange)
|
|
{
|
|
for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
|
|
{
|
|
for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
|
|
{
|
|
ScMyAddress aCell(nCol, nRow, maActiveCell.Tab());
|
|
mpSortedMarkedCells->push_back(aCell);
|
|
}
|
|
}
|
|
}*/
|
|
|
|
//===== XServiceInfo ====================================================
|
|
|
|
OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
return OUString("ScAccessibleSpreadsheet");
|
|
}
|
|
|
|
uno::Sequence< OUString> SAL_CALL
|
|
ScAccessibleSpreadsheet::getSupportedServiceNames (void)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
uno::Sequence< OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames();
|
|
sal_Int32 nOldSize(aSequence.getLength());
|
|
aSequence.realloc(nOldSize + 1);
|
|
|
|
aSequence[nOldSize] = "com.sun.star.AccessibleSpreadsheet";
|
|
|
|
return aSequence;
|
|
}
|
|
|
|
//===== XTypeProvider =======================================================
|
|
|
|
namespace
|
|
{
|
|
class theScAccessibleSpreadsheetImplementationId : public rtl::Static< UnoTunnelIdInit, theScAccessibleSpreadsheetImplementationId > {};
|
|
}
|
|
|
|
uno::Sequence<sal_Int8> SAL_CALL
|
|
ScAccessibleSpreadsheet::getImplementationId(void)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
return theScAccessibleSpreadsheetImplementationId::get().getSeq();
|
|
}
|
|
|
|
///===== XAccessibleEventBroadcaster =====================================
|
|
|
|
void SAL_CALL ScAccessibleSpreadsheet::addAccessibleEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
IsObjectValid();
|
|
ScAccessibleTableBase::addAccessibleEventListener(xListener);
|
|
|
|
}
|
|
|
|
//==== internal =========================================================
|
|
|
|
Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const
|
|
throw (uno::RuntimeException)
|
|
{
|
|
Rectangle aRect;
|
|
if (mpViewShell)
|
|
{
|
|
Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
|
|
if (pWindow)
|
|
aRect = pWindow->GetWindowExtentsRelative(NULL);
|
|
}
|
|
return aRect;
|
|
}
|
|
|
|
Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const
|
|
throw (uno::RuntimeException)
|
|
{
|
|
Rectangle aRect;
|
|
if (mpViewShell)
|
|
{
|
|
Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
|
|
if (pWindow)
|
|
//#101986#; extends to the same window, because the parent is the document and it has the same window
|
|
aRect = pWindow->GetWindowExtentsRelative(pWindow);
|
|
}
|
|
return aRect;
|
|
}
|
|
|
|
sal_Bool ScAccessibleSpreadsheet::IsDefunc(
|
|
const uno::Reference<XAccessibleStateSet>& rxParentStates)
|
|
{
|
|
return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
|
|
(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
|
|
}
|
|
|
|
sal_Bool ScAccessibleSpreadsheet::IsEditable(
|
|
const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
return sal_False;
|
|
}
|
|
sal_Bool bProtected(false);
|
|
if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab()))
|
|
bProtected = sal_True;
|
|
return !bProtected;
|
|
}
|
|
|
|
sal_Bool ScAccessibleSpreadsheet::IsFocused()
|
|
{
|
|
sal_Bool bFocused(false);
|
|
if (mpViewShell)
|
|
{
|
|
if (mpViewShell->GetViewData()->GetActivePart() == meSplitPos)
|
|
bFocused = mpViewShell->GetActiveWin()->HasFocus();
|
|
}
|
|
return bFocused;
|
|
}
|
|
|
|
sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected()
|
|
{
|
|
if (IsFormulaMode())
|
|
{
|
|
return sal_False;
|
|
}
|
|
|
|
sal_Bool bResult(false);
|
|
if(mpViewShell)
|
|
{
|
|
//#103800#; use a copy of MarkData
|
|
ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
|
|
aMarkData.MarkToMulti();
|
|
if (aMarkData.IsAllMarked(maRange))
|
|
bResult = sal_True;
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell)
|
|
{
|
|
ScDocument* pDoc = NULL;
|
|
if (pViewShell)
|
|
pDoc = pViewShell->GetViewData()->GetDocument();
|
|
return pDoc;
|
|
}
|
|
|
|
Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
|
|
{
|
|
Rectangle aVisArea;
|
|
if (pViewShell)
|
|
{
|
|
Window* pWindow = pViewShell->GetWindowByPos(eSplitPos);
|
|
if (pWindow)
|
|
{
|
|
aVisArea.SetPos(pViewShell->GetViewData()->GetPixPos(eSplitPos));
|
|
aVisArea.SetSize(pWindow->GetSizePixel());
|
|
}
|
|
}
|
|
return aVisArea;
|
|
}
|
|
|
|
Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea)
|
|
{
|
|
if (mpViewShell)
|
|
{
|
|
SCsCOL nStartX, nEndX;
|
|
SCsROW nStartY, nEndY;
|
|
|
|
mpViewShell->GetViewData()->GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY);
|
|
mpViewShell->GetViewData()->GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY);
|
|
|
|
return Rectangle(nStartX, nStartY, nEndX, nEndY);
|
|
}
|
|
else
|
|
return Rectangle();
|
|
}
|
|
|
|
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();
|
|
if (!pViewData->IsRefMode())
|
|
// Not in reference mode. Bail out.
|
|
return;
|
|
|
|
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);
|
|
aEvent.OldValue <<= uno::Reference<XAccessible>(m_pAccFormulaCell.get());
|
|
m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(), aFormulaAddr.Col());
|
|
uno::Reference< XAccessible > xNew = m_pAccFormulaCell.get();
|
|
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.get();
|
|
}
|
|
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: */
|