Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "AccessibleSpreadsheet.hxx"
21 : #include "AccessibilityHints.hxx"
22 : #include "AccessibleCell.hxx"
23 : #include "AccessibleDocument.hxx"
24 : #include "tabvwsh.hxx"
25 : #include "document.hxx"
26 : #include "hints.hxx"
27 : #include "scmod.hxx"
28 : #include "markdata.hxx"
29 : #include <gridwin.hxx>
30 :
31 : #include <unotools/accessiblestatesethelper.hxx>
32 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35 : #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
36 : #include <comphelper/servicehelper.hxx>
37 : #include <tools/gen.hxx>
38 : #include <svtools/colorcfg.hxx>
39 : #include <vcl/svapp.hxx>
40 : #include "scresid.hxx"
41 : #include "sc.hrc"
42 :
43 : #include <algorithm>
44 :
45 : using namespace ::com::sun::star;
46 : using namespace ::com::sun::star::accessibility;
47 :
48 0 : bool CompMinCol(const std::pair<sal_uInt16,sal_uInt16> & pc1,const std::pair<sal_uInt16,sal_uInt16> &pc2)
49 : {
50 0 : return pc1.first < pc2.first;
51 : }
52 :
53 0 : ScMyAddress ScAccessibleSpreadsheet::CalcScAddressFromRangeList(ScRangeList *pMarkedRanges,sal_Int32 nSelectedChildIndex)
54 : {
55 0 : if (pMarkedRanges->size() <= 1)
56 : {
57 0 : ScRange* pRange = pMarkedRanges->front();
58 0 : if (pRange)
59 : {
60 : // MT IA2: Not used.
61 : // const int nRowNum = pRange->aEnd.Row() - pRange->aStart.Row() + 1;
62 0 : const int nColNum = pRange->aEnd.Col() - pRange->aStart.Col() + 1;
63 0 : const int nCurCol = nSelectedChildIndex % nColNum;
64 0 : const int nCurRow = (nSelectedChildIndex - nCurCol)/nColNum;
65 0 : return ScMyAddress(static_cast<SCCOL>(pRange->aStart.Col() + nCurCol), pRange->aStart.Row() + nCurRow, maActiveCell.Tab());
66 : }
67 : }
68 : else
69 : {
70 0 : sal_Int32 nMinRow = MAXROW;
71 0 : sal_Int32 nMaxRow = 0;
72 0 : m_vecTempRange.clear();
73 0 : size_t nSize = pMarkedRanges->size();
74 0 : for (size_t i = 0; i < nSize; ++i)
75 : {
76 0 : ScRange* pRange = (*pMarkedRanges)[i];
77 0 : if (pRange->aStart.Tab() != pRange->aEnd.Tab())
78 : {
79 0 : if ((maActiveCell.Tab() >= pRange->aStart.Tab()) ||
80 0 : maActiveCell.Tab() <= pRange->aEnd.Tab())
81 : {
82 0 : m_vecTempRange.push_back(pRange);
83 0 : nMinRow = std::min(pRange->aStart.Row(),nMinRow);
84 0 : nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow);
85 : }
86 : else
87 : SAL_WARN("sc", "Range of wrong table");
88 : }
89 0 : else if(pRange->aStart.Tab() == maActiveCell.Tab())
90 : {
91 0 : m_vecTempRange.push_back(pRange);
92 0 : nMinRow = std::min(pRange->aStart.Row(),nMinRow);
93 0 : nMaxRow = std::max(pRange->aEnd.Row(),nMaxRow);
94 : }
95 : else
96 : SAL_WARN("sc", "Range of wrong table");
97 : }
98 0 : int nCurrentIndex = 0 ;
99 0 : for(sal_Int32 row = nMinRow ; row <= nMaxRow ; ++row)
100 : {
101 0 : m_vecTempCol.clear();
102 : {
103 0 : VEC_RANGE::const_iterator vi = m_vecTempRange.begin();
104 0 : for (; vi < m_vecTempRange.end(); ++vi)
105 : {
106 0 : ScRange *p = *vi;
107 0 : if ( row >= p->aStart.Row() && row <= p->aEnd.Row())
108 : {
109 0 : m_vecTempCol.push_back(std::make_pair(p->aStart.Col(),p->aEnd.Col()));
110 : }
111 : }
112 : }
113 0 : std::sort(m_vecTempCol.begin(),m_vecTempCol.end(),CompMinCol);
114 : {
115 0 : VEC_COL::const_iterator vic = m_vecTempCol.begin();
116 0 : for(; vic != m_vecTempCol.end(); ++vic)
117 : {
118 0 : const PAIR_COL &pariCol = *vic;
119 0 : sal_uInt16 nCol = pariCol.second - pariCol.first + 1;
120 0 : if (nCol + nCurrentIndex > nSelectedChildIndex)
121 : {
122 0 : return ScMyAddress(static_cast<SCCOL>(pariCol.first + nSelectedChildIndex - nCurrentIndex), row, maActiveCell.Tab());
123 : }
124 0 : nCurrentIndex += nCol;
125 : }
126 : }
127 : }
128 : }
129 0 : return ScMyAddress(0,0,maActiveCell.Tab());
130 : }
131 :
132 0 : bool ScAccessibleSpreadsheet::CalcScRangeDifferenceMax(ScRange *pSrc,ScRange *pDest,int nMax,VEC_MYADDR &vecRet,int &nSize)
133 : {
134 : //Src Must be :Src > Dest
135 0 : if (pDest->In(*pSrc))
136 : {//Here is Src In Dest,Src <= Dest
137 0 : return false;
138 : }
139 0 : if (!pDest->Intersects(*pSrc))
140 : {
141 0 : int nCellCount = sal_uInt32(pDest->aEnd.Col() - pDest->aStart.Col() + 1)
142 0 : * sal_uInt32(pDest->aEnd.Row() - pDest->aStart.Row() + 1)
143 0 : * sal_uInt32(pDest->aEnd.Tab() - pDest->aStart.Tab() + 1);
144 0 : if (nCellCount + nSize > nMax)
145 : {
146 0 : return true;
147 : }
148 0 : else if(nCellCount > 0)
149 : {
150 0 : nCellCount +=nSize;
151 0 : for (sal_Int32 row = pDest->aStart.Row(); row <= pDest->aEnd.Row();++row)
152 : {
153 0 : for (sal_uInt16 col = pDest->aStart.Col(); col <= pDest->aEnd.Col();++col)
154 : {
155 0 : vecRet.push_back(ScMyAddress(col,row,pDest->aStart.Tab()));
156 : }
157 : }
158 : }
159 0 : return false;
160 : }
161 0 : sal_Int32 nMinRow = pSrc->aStart.Row();
162 0 : sal_Int32 nMaxRow = pSrc->aEnd.Row();
163 0 : for (; nMinRow <= nMaxRow ; ++nMinRow,--nMaxRow)
164 : {
165 0 : for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col)
166 : {
167 0 : if (nSize > nMax)
168 : {
169 0 : return true;
170 : }
171 0 : ScMyAddress cell(col,nMinRow,pSrc->aStart.Tab());
172 0 : if(!pDest->In(cell))
173 : {//In Src ,Not In Dest
174 0 : vecRet.push_back(cell);
175 0 : ++nSize;
176 : }
177 : }
178 0 : if (nMinRow != nMaxRow)
179 : {
180 0 : for (sal_uInt16 col = pSrc->aStart.Col(); col <= pSrc->aEnd.Col();++col)
181 : {
182 0 : if (nSize > nMax)
183 : {
184 0 : return true;
185 : }
186 0 : ScMyAddress cell(col,nMaxRow,pSrc->aStart.Tab());
187 0 : if(!pDest->In(cell))
188 : {//In Src ,Not In Dest
189 0 : vecRet.push_back(cell);
190 0 : ++nSize;
191 : }
192 : }
193 : }
194 : }
195 0 : return false;
196 : }
197 :
198 : //In Src , Not in Dest
199 0 : bool ScAccessibleSpreadsheet::CalcScRangeListDifferenceMax(ScRangeList *pSrc,ScRangeList *pDest,int nMax,VEC_MYADDR &vecRet)
200 : {
201 0 : if (pSrc == NULL || pDest == NULL)
202 : {
203 0 : return false;
204 : }
205 0 : int nSize =0;
206 0 : if (pDest->GetCellCount() == 0)//if the Dest Rang List is empty
207 : {
208 0 : if (pSrc->GetCellCount() > sal_uInt32(nMax))//if the Src Cell count is greater then nMax
209 : {
210 0 : return true;
211 : }
212 : //now the cell count is less then nMax
213 0 : vecRet.reserve(10);
214 0 : size_t nSrcSize = pSrc->size();
215 0 : for (size_t i = 0; i < nSrcSize; ++i)
216 : {
217 0 : ScRange* pRange = (*pSrc)[i];
218 0 : for (sal_Int32 row = pRange->aStart.Row(); row <= pRange->aEnd.Row();++row)
219 : {
220 0 : for (sal_uInt16 col = pRange->aStart.Col(); col <= pRange->aEnd.Col();++col)
221 : {
222 0 : vecRet.push_back(ScMyAddress(col,row,pRange->aStart.Tab()));
223 : }
224 : }
225 : }
226 0 : return false;
227 : }
228 : //the Dest Rang List is not empty
229 0 : vecRet.reserve(10);
230 0 : size_t nSizeSrc = pSrc->size();
231 0 : for (size_t i = 0; i < nSizeSrc; ++i)
232 : {
233 0 : ScRange* pRange = (*pSrc)[i];
234 0 : size_t nSizeDest = pDest->size();
235 0 : for (size_t j = 0; j < nSizeDest; ++j)
236 : {
237 0 : ScRange* pRangeDest = (*pDest)[j];
238 0 : if (CalcScRangeDifferenceMax(pRange,pRangeDest,nMax,vecRet,nSize))
239 : {
240 0 : return true;
241 : }
242 : }
243 : }
244 0 : return false;
245 : }
246 :
247 : //===== internal ============================================================
248 :
249 : // FIXME: really unclear why we have an ScAccessibleTableBase with
250 : // only this single sub-class
251 4 : ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
252 : ScAccessibleDocument* pAccDoc,
253 : ScTabViewShell* pViewShell,
254 : SCTAB nTab,
255 : ScSplitPos eSplitPos)
256 : :
257 : ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell),
258 : ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))),
259 : mbIsSpreadsheet( true ),
260 : m_bFormulaMode( false ),
261 : m_bFormulaLastMode( false ),
262 4 : m_nMinX(0),m_nMaxX(0),m_nMinY(0),m_nMaxY(0)
263 : {
264 4 : ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos );
265 4 : }
266 :
267 0 : ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
268 : ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) :
269 : ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange),
270 0 : mbIsSpreadsheet( false )
271 : {
272 0 : ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos );
273 0 : }
274 :
275 12 : ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet()
276 : {
277 4 : delete mpMarkedRanges;
278 4 : if (mpViewShell)
279 0 : mpViewShell->RemoveAccessibilityObject(*this);
280 8 : }
281 :
282 4 : void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet(
283 : ScAccessibleDocument* pAccDoc,
284 : ScTabViewShell* pViewShell,
285 : SCTAB nTab,
286 : ScSplitPos eSplitPos)
287 : {
288 4 : mpViewShell = pViewShell;
289 4 : mpMarkedRanges = 0;
290 4 : mpSortedMarkedCells = 0;
291 4 : mpAccDoc = pAccDoc;
292 4 : mpAccCell.clear();
293 4 : meSplitPos = eSplitPos;
294 4 : mnTab = nTab;
295 4 : mbHasSelection = false;
296 4 : mbDelIns = false;
297 4 : mbIsFocusSend = false;
298 4 : maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos));
299 4 : if (mpViewShell)
300 : {
301 4 : mpViewShell->AddAccessibilityObject(*this);
302 :
303 4 : const ScViewData& rViewData = mpViewShell->GetViewData();
304 4 : const ScMarkData& rMarkData = rViewData.GetMarkData();
305 4 : maActiveCell = rViewData.GetCurPos();
306 8 : mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) &&
307 12 : (rMarkData.IsMarked() || rMarkData.IsMultiMarked());
308 4 : mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
309 4 : ScDocument* pScDoc= GetDocument(mpViewShell);
310 4 : if (pScDoc)
311 : {
312 4 : pScDoc->GetName( maActiveCell.Tab(), m_strOldTabName );
313 : }
314 : }
315 4 : }
316 :
317 4 : void SAL_CALL ScAccessibleSpreadsheet::disposing()
318 : {
319 4 : SolarMutexGuard aGuard;
320 4 : if (mpViewShell)
321 : {
322 4 : mpViewShell->RemoveAccessibilityObject(*this);
323 4 : mpViewShell = NULL;
324 : }
325 4 : mpAccCell.clear();
326 :
327 4 : ScAccessibleTableBase::disposing();
328 4 : }
329 :
330 0 : void ScAccessibleSpreadsheet::CompleteSelectionChanged(bool bNewState)
331 : {
332 0 : if (IsFormulaMode())
333 : {
334 0 : return ;
335 : }
336 0 : if (mpMarkedRanges)
337 0 : DELETEZ(mpMarkedRanges);
338 0 : mbHasSelection = bNewState;
339 :
340 0 : AccessibleEventObject aEvent;
341 0 : aEvent.EventId = AccessibleEventId::STATE_CHANGED;
342 0 : if (bNewState)
343 0 : aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED);
344 : else
345 0 : aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED);
346 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
347 :
348 0 : CommitChange(aEvent);
349 : }
350 :
351 4 : void ScAccessibleSpreadsheet::LostFocus()
352 : {
353 4 : AccessibleEventObject aEvent;
354 4 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
355 4 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
356 4 : aEvent.OldValue <<= uno::Reference<XAccessible>(mpAccCell.get());
357 :
358 4 : CommitChange(aEvent);
359 :
360 4 : CommitFocusLost();
361 4 : }
362 :
363 0 : void ScAccessibleSpreadsheet::GotFocus()
364 : {
365 0 : CommitFocusGained();
366 0 : AccessibleEventObject aEvent;
367 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
368 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
369 0 : uno::Reference< XAccessible > xNew;
370 0 : if (IsFormulaMode())
371 : {
372 0 : if (!m_pAccFormulaCell.is() || !m_bFormulaLastMode)
373 : {
374 0 : ScAddress aFormulaAddr;
375 0 : if(!GetFormulaCurrentFocusCell(aFormulaAddr))
376 : {
377 0 : return;
378 : }
379 0 : m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(),aFormulaAddr.Col());
380 : }
381 0 : xNew = m_pAccFormulaCell.get();
382 : }
383 : else
384 : {
385 0 : if(mpAccCell->GetCellAddress() == maActiveCell)
386 : {
387 0 : xNew = mpAccCell.get();
388 : }
389 : else
390 : {
391 0 : CommitFocusCell(maActiveCell);
392 0 : return ;
393 : }
394 : }
395 0 : aEvent.NewValue <<= xNew;
396 :
397 0 : CommitChange(aEvent);
398 : }
399 :
400 0 : void ScAccessibleSpreadsheet::BoundingBoxChanged()
401 : {
402 0 : AccessibleEventObject aEvent;
403 0 : aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
404 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
405 :
406 0 : CommitChange(aEvent);
407 0 : }
408 :
409 0 : void ScAccessibleSpreadsheet::VisAreaChanged()
410 : {
411 0 : AccessibleEventObject aEvent;
412 0 : aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
413 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
414 :
415 0 : CommitChange(aEvent);
416 0 : }
417 :
418 : //===== SfxListener =====================================================
419 :
420 28 : void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
421 : {
422 28 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
423 28 : if (pSimpleHint)
424 : {
425 24 : if (pSimpleHint->GetId() == SC_HINT_ACC_CURSORCHANGED)
426 : {
427 2 : if (mpViewShell)
428 : {
429 2 : ScViewData& rViewData = mpViewShell->GetViewData();
430 :
431 2 : m_bFormulaMode = rViewData.IsRefMode() || SC_MOD()->IsFormulaMode();
432 2 : if ( m_bFormulaMode )
433 : {
434 0 : NotifyRefMode();
435 0 : m_bFormulaLastMode = true;
436 0 : return;
437 : }
438 2 : if (m_bFormulaLastMode)
439 : {//Last Notify Mode Is Formula Mode.
440 0 : m_vecFormulaLastMyAddr.clear();
441 0 : RemoveFormulaSelection(true);
442 0 : m_pAccFormulaCell.clear();
443 : //Remove All Selection
444 : }
445 2 : m_bFormulaLastMode = m_bFormulaMode;
446 :
447 2 : AccessibleEventObject aEvent;
448 2 : aEvent.Source = uno::Reference< XAccessible >(this);
449 2 : ScAddress aNewCell = rViewData.GetCurPos();
450 2 : if(aNewCell.Tab() != maActiveCell.Tab())
451 : {
452 0 : aEvent.EventId = AccessibleEventId::PAGE_CHANGED;
453 : ScAccessibleDocument *pAccDoc =
454 0 : static_cast<ScAccessibleDocument*>(getAccessibleParent().get());
455 0 : if(pAccDoc)
456 : {
457 0 : pAccDoc->CommitChange(aEvent);
458 : }
459 : }
460 2 : bool bNewPosCell = (aNewCell != maActiveCell) || mpViewShell->GetForceFocusOnCurCell(); // #i123629#
461 2 : bool bNewPosCellFocus=false;
462 2 : if ( bNewPosCell && IsFocused() && aNewCell.Tab() == maActiveCell.Tab() )
463 : {//single Focus
464 2 : bNewPosCellFocus=true;
465 : }
466 2 : ScMarkData &refScMarkData = rViewData.GetMarkData();
467 : // MT IA2: Not used
468 : // int nSelCount = refScMarkData.GetSelectCount();
469 2 : bool bIsMark =refScMarkData.IsMarked();
470 2 : bool bIsMultMark = refScMarkData.IsMultiMarked();
471 2 : bool bNewMarked = refScMarkData.GetTableSelect(aNewCell.Tab()) && ( bIsMark || bIsMultMark );
472 : // sal_Bool bNewCellSelected = isAccessibleSelected(aNewCell.Row(), aNewCell.Col());
473 2 : sal_uInt16 nTab = rViewData.GetTabNo();
474 2 : ScRange aMarkRange;
475 2 : refScMarkData.GetMarkArea(aMarkRange);
476 2 : aEvent.OldValue <<= ::com::sun::star::uno::Any();
477 : //Mark All
478 8 : if ( !bNewPosCellFocus &&
479 4 : (bNewMarked || bIsMark || bIsMultMark ) &&
480 2 : aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
481 : {
482 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
483 0 : aEvent.NewValue <<= ::com::sun::star::uno::Any();
484 0 : CommitChange(aEvent);
485 0 : return ;
486 : }
487 2 : if (!mpMarkedRanges)
488 : {
489 2 : mpMarkedRanges = new ScRangeList();
490 : }
491 2 : refScMarkData.FillRangeListWithMarks(mpMarkedRanges, true);
492 :
493 : //For Whole Col Row
494 2 : bool bWholeRow = ::labs(aMarkRange.aStart.Row() - aMarkRange.aEnd.Row()) == MAXROW ;
495 2 : bool bWholeCol = ::abs(aMarkRange.aStart.Col() - aMarkRange.aEnd.Col()) == MAXCOL ;
496 2 : if ((bNewMarked || bIsMark || bIsMultMark ) && (bWholeCol || bWholeRow))
497 : {
498 0 : if ( aMarkRange != m_aLastWithInMarkRange )
499 : {
500 0 : RemoveSelection(refScMarkData);
501 0 : if(bNewPosCell)
502 : {
503 0 : CommitFocusCell(aNewCell);
504 : }
505 : bool bLastIsWholeColRow =
506 0 : (::labs(m_aLastWithInMarkRange.aStart.Row() - m_aLastWithInMarkRange.aEnd.Row()) == MAXROW && bWholeRow) ||
507 0 : (::abs(m_aLastWithInMarkRange.aStart.Col() - m_aLastWithInMarkRange.aEnd.Col()) == MAXCOL && bWholeCol);
508 : bool bSelSmaller=
509 0 : bLastIsWholeColRow &&
510 0 : !aMarkRange.In(m_aLastWithInMarkRange) &&
511 0 : aMarkRange.Intersects(m_aLastWithInMarkRange);
512 0 : if( !bSelSmaller )
513 : {
514 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
515 0 : aEvent.NewValue <<= ::com::sun::star::uno::Any();
516 0 : CommitChange(aEvent);
517 : }
518 0 : m_aLastWithInMarkRange = aMarkRange;
519 : }
520 0 : return ;
521 : }
522 2 : m_aLastWithInMarkRange = aMarkRange;
523 2 : int nNewMarkCount = mpMarkedRanges->GetCellCount();
524 2 : bool bSendSingle= (0 == nNewMarkCount) && bNewPosCell;
525 2 : if (bSendSingle)
526 : {
527 2 : RemoveSelection(refScMarkData);
528 2 : if(bNewPosCellFocus)
529 : {
530 2 : CommitFocusCell(aNewCell);
531 : }
532 2 : uno::Reference< XAccessible > xChild ;
533 2 : if (bNewPosCellFocus)
534 : {
535 2 : xChild = mpAccCell.get();
536 : }
537 : else
538 : {
539 0 : mpAccCell = GetAccessibleCellAt(aNewCell.Row(),aNewCell.Col());
540 0 : xChild = mpAccCell.get();
541 :
542 0 : maActiveCell = aNewCell;
543 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS;
544 0 : aEvent.NewValue <<= xChild;
545 0 : aEvent.OldValue <<= uno::Reference< XAccessible >();
546 0 : CommitChange(aEvent);
547 : }
548 2 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
549 2 : aEvent.NewValue <<= xChild;
550 2 : CommitChange(aEvent);
551 : OSL_ASSERT(m_mapSelectionSend.count(aNewCell) == 0 );
552 2 : m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(aNewCell,xChild));
553 :
554 : }
555 : else
556 : {
557 0 : ScRange aDelRange;
558 0 : bool bIsDel = rViewData.GetDelMark( aDelRange );
559 0 : if ( (!bIsDel || (bIsDel && aMarkRange != aDelRange)) &&
560 0 : bNewMarked &&
561 0 : nNewMarkCount > 0 &&
562 0 : !IsSameMarkCell() )
563 : {
564 0 : RemoveSelection(refScMarkData);
565 0 : if(bNewPosCellFocus)
566 : {
567 0 : CommitFocusCell(aNewCell);
568 : }
569 0 : VEC_MYADDR vecNew;
570 0 : if(CalcScRangeListDifferenceMax(mpMarkedRanges,&m_LastMarkedRanges,10,vecNew))
571 : {
572 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
573 0 : aEvent.NewValue <<= ::com::sun::star::uno::Any();
574 0 : CommitChange(aEvent);
575 : }
576 : else
577 : {
578 0 : VEC_MYADDR::iterator viAddr = vecNew.begin();
579 0 : for(; viAddr < vecNew.end() ; ++viAddr )
580 : {
581 0 : uno::Reference< XAccessible > xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col());
582 0 : if (!(bNewPosCellFocus && *viAddr == aNewCell) )
583 : {
584 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS;
585 0 : aEvent.NewValue <<= xChild;
586 0 : CommitChange(aEvent);
587 : }
588 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
589 0 : aEvent.NewValue <<= xChild;
590 0 : CommitChange(aEvent);
591 0 : m_mapSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild));
592 0 : }
593 0 : }
594 : }
595 : }
596 2 : if (bNewPosCellFocus && maActiveCell != aNewCell)
597 : {
598 0 : CommitFocusCell(aNewCell);
599 : }
600 2 : m_LastMarkedRanges = *mpMarkedRanges;
601 : }
602 : }
603 22 : else if (pSimpleHint->GetId() == SC_HINT_DATACHANGED)
604 : {
605 18 : if (!mbDelIns)
606 18 : CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE);
607 : else
608 0 : mbDelIns = false;
609 18 : ScViewData& rViewData = mpViewShell->GetViewData();
610 18 : ScAddress aNewCell = rViewData.GetCurPos();
611 18 : if( maActiveCell == aNewCell)
612 : {
613 18 : ScDocument* pScDoc= GetDocument(mpViewShell);
614 18 : if (pScDoc)
615 : {
616 18 : OUString valStr(pScDoc->GetString(aNewCell.Col(),aNewCell.Row(),aNewCell.Tab()));
617 18 : if(m_strCurCellValue != valStr)
618 : {
619 0 : AccessibleEventObject aEvent;
620 0 : aEvent.EventId = AccessibleEventId::VALUE_CHANGED;
621 0 : mpAccCell->CommitChange(aEvent);
622 0 : m_strCurCellValue=valStr;
623 : }
624 36 : OUString tabName;
625 18 : pScDoc->GetName( maActiveCell.Tab(), tabName );
626 18 : if( m_strOldTabName != tabName )
627 : {
628 0 : AccessibleEventObject aEvent;
629 0 : aEvent.EventId = AccessibleEventId::NAME_CHANGED;
630 0 : OUString sOldName(ScResId(STR_ACC_TABLE_NAME));
631 0 : sOldName = sOldName.replaceFirst("%1", m_strOldTabName);
632 0 : aEvent.OldValue <<= sOldName;
633 0 : OUString sNewName(ScResId(STR_ACC_TABLE_NAME));
634 0 : sOldName = sNewName.replaceFirst("%1", tabName);
635 0 : aEvent.NewValue <<= sNewName;
636 0 : CommitChange( aEvent );
637 0 : m_strOldTabName = tabName;
638 18 : }
639 : }
640 : }
641 : }
642 : // commented out, because to use a ModelChangeEvent is not the right way
643 : // at the moment there is no way, but the Java/Gnome Api should be extended sometime
644 : /* if (mpViewShell)
645 : {
646 : Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos)));
647 :
648 : Rectangle aNewPos(aNewVisCells);
649 :
650 : if (aNewVisCells.IsOver(maVisCells))
651 : aNewPos.Union(maVisCells);
652 : else
653 : CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE);
654 :
655 : maVisCells = aNewVisCells;
656 :
657 : CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE);
658 : }
659 : }*/
660 : }
661 4 : else if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
662 : {
663 0 : const ScUpdateRefHint& rRef = static_cast<const ScUpdateRefHint&>(rHint);
664 0 : if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //test whether table is inserted or deleted
665 : {
666 0 : if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) &&
667 0 : (rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) ||
668 0 : ((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) &&
669 0 : (rRef.GetRange().aEnd.Row() == maRange.aEnd.Row())))
670 : {
671 : // ignore next SC_HINT_DATACHANGED notification
672 0 : mbDelIns = true;
673 :
674 0 : sal_Int16 nId(0);
675 0 : SCsCOL nX(rRef.GetDx());
676 0 : SCsROW nY(rRef.GetDy());
677 0 : ScRange aRange(rRef.GetRange());
678 0 : if ((nX < 0) || (nY < 0))
679 : {
680 : OSL_ENSURE(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time");
681 0 : nId = AccessibleTableModelChangeType::DELETE;
682 0 : if (nX < 0)
683 : {
684 0 : nX = -nX;
685 0 : nY = aRange.aEnd.Row() - aRange.aStart.Row();
686 : }
687 : else
688 : {
689 0 : nY = -nY;
690 0 : nX = aRange.aEnd.Col() - aRange.aStart.Col();
691 : }
692 : }
693 0 : else if ((nX > 0) || (nY > 0))
694 : {
695 : OSL_ENSURE(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time");
696 0 : nId = AccessibleTableModelChangeType::INSERT;
697 0 : if (nX < 0)
698 0 : nY = aRange.aEnd.Row() - aRange.aStart.Row();
699 : else
700 0 : nX = aRange.aEnd.Col() - aRange.aStart.Col();
701 : }
702 : else
703 : {
704 : OSL_FAIL("is it a deletion or a insertion?");
705 : }
706 :
707 0 : CommitTableModelChange(rRef.GetRange().aStart.Row(),
708 0 : rRef.GetRange().aStart.Col(),
709 0 : rRef.GetRange().aStart.Row() + nY,
710 0 : rRef.GetRange().aStart.Col() + nX, nId);
711 :
712 0 : AccessibleEventObject aEvent;
713 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
714 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
715 0 : aEvent.NewValue <<= uno::Reference<XAccessible>(mpAccCell.get());
716 :
717 0 : CommitChange(aEvent);
718 : }
719 : }
720 : }
721 :
722 28 : ScAccessibleTableBase::Notify(rBC, rHint);
723 : }
724 :
725 2 : void ScAccessibleSpreadsheet::RemoveSelection(ScMarkData &refScMarkData)
726 : {
727 2 : AccessibleEventObject aEvent;
728 2 : aEvent.Source = uno::Reference< XAccessible >(this);
729 2 : aEvent.OldValue <<= ::com::sun::star::uno::Any();
730 2 : MAP_ADDR_XACC::iterator miRemove = m_mapSelectionSend.begin();
731 4 : for(; miRemove != m_mapSelectionSend.end() ;)
732 : {
733 0 : if (refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),true) ||
734 0 : refScMarkData.IsCellMarked(miRemove->first.Col(),miRemove->first.Row(),false) )
735 : {
736 0 : ++miRemove;
737 0 : continue;
738 : }
739 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
740 0 : aEvent.NewValue <<= miRemove->second;
741 0 : CommitChange(aEvent);
742 0 : MAP_ADDR_XACC::iterator miNext = miRemove;
743 0 : ++miNext;
744 0 : m_mapSelectionSend.erase(miRemove);
745 0 : miRemove = miNext;
746 2 : }
747 2 : }
748 2 : void ScAccessibleSpreadsheet::CommitFocusCell(const ScAddress &aNewCell)
749 : {
750 : OSL_ASSERT(!IsFormulaMode());
751 2 : if(IsFormulaMode())
752 : {
753 2 : return ;
754 : }
755 2 : AccessibleEventObject aEvent;
756 2 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
757 2 : aEvent.Source = uno::Reference< XAccessible >(this);
758 2 : aEvent.OldValue <<= uno::Reference<XAccessible>(mpAccCell.get());
759 2 : mpAccCell.clear();
760 2 : mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col());
761 2 : aEvent.NewValue <<= uno::Reference<XAccessible>(mpAccCell.get());
762 2 : maActiveCell = aNewCell;
763 2 : ScDocument* pScDoc= GetDocument(mpViewShell);
764 2 : if (pScDoc)
765 : {
766 2 : m_strCurCellValue = pScDoc->GetString(maActiveCell.Col(),maActiveCell.Row(),maActiveCell.Tab());
767 : }
768 2 : CommitChange(aEvent);
769 : }
770 :
771 0 : bool ScAccessibleSpreadsheet::IsSameMarkCell()
772 : {
773 0 : return m_LastMarkedRanges == *mpMarkedRanges;
774 : }
775 :
776 : //===== XAccessibleTable ================================================
777 :
778 0 : uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders( )
779 : throw (uno::RuntimeException, std::exception)
780 : {
781 0 : SolarMutexGuard aGuard;
782 0 : IsObjectValid();
783 0 : uno::Reference< XAccessibleTable > xAccessibleTable;
784 0 : if( mpDoc && mbIsSpreadsheet )
785 : {
786 0 : if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) )
787 : {
788 0 : SCROW nStart = pRowRange->aStart.Row();
789 0 : SCROW nEnd = pRowRange->aEnd.Row();
790 0 : if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) )
791 0 : xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) );
792 : }
793 : }
794 0 : return xAccessibleTable;
795 : }
796 :
797 0 : uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders( )
798 : throw (uno::RuntimeException, std::exception)
799 : {
800 0 : SolarMutexGuard aGuard;
801 0 : IsObjectValid();
802 0 : uno::Reference< XAccessibleTable > xAccessibleTable;
803 0 : if( mpDoc && mbIsSpreadsheet )
804 : {
805 0 : if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) )
806 : {
807 0 : SCCOL nStart = pColRange->aStart.Col();
808 0 : SCCOL nEnd = pColRange->aEnd.Col();
809 0 : if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) )
810 0 : xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) );
811 : }
812 : }
813 0 : return xAccessibleTable;
814 : }
815 :
816 0 : uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows( )
817 : throw (uno::RuntimeException, std::exception)
818 : {
819 0 : SolarMutexGuard aGuard;
820 0 : IsObjectValid();
821 0 : uno::Sequence<sal_Int32> aSequence;
822 0 : if (IsFormulaMode())
823 : {
824 0 : return aSequence;
825 : }
826 0 : if (mpViewShell)
827 : {
828 0 : aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1);
829 0 : const ScMarkData& rMarkdata = mpViewShell->GetViewData().GetMarkData();
830 0 : sal_Int32* pSequence = aSequence.getArray();
831 0 : sal_Int32 nCount(0);
832 0 : for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i)
833 : {
834 0 : if (rMarkdata.IsRowMarked(i))
835 : {
836 0 : pSequence[nCount] = i;
837 0 : ++nCount;
838 : }
839 : }
840 0 : aSequence.realloc(nCount);
841 : }
842 : else
843 0 : aSequence.realloc(0);
844 0 : return aSequence;
845 : }
846 :
847 0 : uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns( )
848 : throw (uno::RuntimeException, std::exception)
849 : {
850 0 : SolarMutexGuard aGuard;
851 0 : IsObjectValid();
852 0 : uno::Sequence<sal_Int32> aSequence;
853 0 : if (IsFormulaMode())
854 : {
855 0 : return aSequence;
856 : }
857 0 : if (mpViewShell)
858 : {
859 0 : aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
860 0 : const ScMarkData& rMarkdata = mpViewShell->GetViewData().GetMarkData();
861 0 : sal_Int32* pSequence = aSequence.getArray();
862 0 : sal_Int32 nCount(0);
863 0 : for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i)
864 : {
865 0 : if (rMarkdata.IsColumnMarked(i))
866 : {
867 0 : pSequence[nCount] = i;
868 0 : ++nCount;
869 : }
870 : }
871 0 : aSequence.realloc(nCount);
872 : }
873 : else
874 0 : aSequence.realloc(0);
875 0 : return aSequence;
876 : }
877 :
878 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow )
879 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
880 : {
881 0 : SolarMutexGuard aGuard;
882 0 : IsObjectValid();
883 0 : if (IsFormulaMode())
884 : {
885 0 : return sal_False;
886 : }
887 :
888 0 : if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
889 0 : throw lang::IndexOutOfBoundsException();
890 :
891 0 : bool bResult(false);
892 0 : if (mpViewShell)
893 : {
894 0 : const ScMarkData& rMarkdata = mpViewShell->GetViewData().GetMarkData();
895 0 : bResult = rMarkdata.IsRowMarked((SCROW)nRow);
896 : }
897 0 : return bResult;
898 : }
899 :
900 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn )
901 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
902 : {
903 0 : SolarMutexGuard aGuard;
904 0 : IsObjectValid();
905 :
906 0 : if (IsFormulaMode())
907 : {
908 0 : return sal_False;
909 : }
910 0 : if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
911 0 : throw lang::IndexOutOfBoundsException();
912 :
913 0 : bool bResult(false);
914 0 : if (mpViewShell)
915 : {
916 0 : const ScMarkData& rMarkdata = mpViewShell->GetViewData().GetMarkData();
917 0 : bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn);
918 : }
919 0 : return bResult;
920 : }
921 :
922 16 : rtl::Reference<ScAccessibleCell> ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn)
923 : {
924 16 : if (IsFormulaMode())
925 : {
926 0 : ScAddress aCellAddress(static_cast<SCCOL>(nColumn), nRow, mpViewShell->GetViewData().GetTabNo());
927 0 : if ((aCellAddress == m_aFormulaActiveCell) && m_pAccFormulaCell.is())
928 : {
929 0 : return m_pAccFormulaCell;
930 : }
931 : else
932 0 : return ScAccessibleCell::create(this, mpViewShell, aCellAddress, GetAccessibleIndexFormula(nRow, nColumn), meSplitPos, mpAccDoc);
933 : }
934 : else
935 : {
936 16 : ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn),
937 32 : static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab());
938 16 : if ((aCellAddress == maActiveCell) && mpAccCell.is())
939 : {
940 6 : return mpAccCell;
941 : }
942 : else
943 10 : return ScAccessibleCell::create(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc);
944 : }
945 : }
946 :
947 10 : uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
948 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
949 : {
950 10 : SolarMutexGuard aGuard;
951 10 : IsObjectValid();
952 10 : if (!IsFormulaMode())
953 : {
954 30 : if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
955 10 : nRow < 0 ||
956 30 : nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
957 : nColumn < 0)
958 0 : throw lang::IndexOutOfBoundsException();
959 : }
960 20 : rtl::Reference<ScAccessibleCell> pAccessibleCell = GetAccessibleCellAt(nRow, nColumn);
961 20 : return pAccessibleCell.get();
962 : }
963 :
964 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
965 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
966 : {
967 0 : SolarMutexGuard aGuard;
968 0 : IsObjectValid();
969 :
970 0 : if (IsFormulaMode())
971 : {
972 0 : ScAddress addr(static_cast<SCCOL>(nColumn), nRow, 0);
973 0 : return IsScAddrFormulaSel(addr);
974 : }
975 0 : if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
976 0 : (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
977 0 : throw lang::IndexOutOfBoundsException();
978 :
979 0 : bool bResult(false);
980 0 : if (mpViewShell)
981 : {
982 0 : const ScMarkData& rMarkdata = mpViewShell->GetViewData().GetMarkData();
983 0 : bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow));
984 : }
985 0 : return bResult;
986 : }
987 :
988 : //===== XAccessibleComponent ============================================
989 :
990 0 : uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint(const awt::Point& rPoint)
991 : throw (uno::RuntimeException, std::exception)
992 : {
993 0 : uno::Reference< XAccessible > xAccessible;
994 0 : if (containsPoint(rPoint))
995 : {
996 0 : SolarMutexGuard aGuard;
997 0 : IsObjectValid();
998 0 : if (mpViewShell)
999 : {
1000 : SCsCOL nX;
1001 : SCsROW nY;
1002 0 : mpViewShell->GetViewData().GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY);
1003 : try {
1004 0 : xAccessible = getAccessibleCellAt(nY, nX);
1005 : }
1006 0 : catch(const ::com::sun::star::lang::IndexOutOfBoundsException &)
1007 : {
1008 0 : return NULL;
1009 : }
1010 0 : }
1011 : }
1012 0 : return xAccessible;
1013 : }
1014 :
1015 2 : void SAL_CALL ScAccessibleSpreadsheet::grabFocus( )
1016 : throw (uno::RuntimeException, std::exception)
1017 : {
1018 2 : if (getAccessibleParent().is())
1019 : {
1020 2 : uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
1021 2 : if (xAccessibleComponent.is())
1022 2 : xAccessibleComponent->grabFocus();
1023 : }
1024 2 : }
1025 :
1026 0 : sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground( )
1027 : throw (uno::RuntimeException, std::exception)
1028 : {
1029 0 : return COL_BLACK;
1030 : }
1031 :
1032 0 : sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground( )
1033 : throw (uno::RuntimeException, std::exception)
1034 : {
1035 0 : SolarMutexGuard aGuard;
1036 0 : IsObjectValid();
1037 0 : return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
1038 : }
1039 :
1040 : //===== XAccessibleContext ==============================================
1041 :
1042 0 : uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void)
1043 : throw (::com::sun::star::uno::RuntimeException, std::exception)
1044 : {
1045 0 : utl::AccessibleRelationSetHelper* pRelationSet = NULL;
1046 0 : if(mpAccDoc)
1047 0 : pRelationSet = mpAccDoc->GetRelationSet(NULL);
1048 0 : if (!pRelationSet)
1049 0 : pRelationSet = new utl::AccessibleRelationSetHelper();
1050 0 : return pRelationSet;
1051 : }
1052 :
1053 : uno::Reference<XAccessibleStateSet> SAL_CALL
1054 24 : ScAccessibleSpreadsheet::getAccessibleStateSet(void)
1055 : throw (uno::RuntimeException, std::exception)
1056 : {
1057 24 : SolarMutexGuard aGuard;
1058 48 : uno::Reference<XAccessibleStateSet> xParentStates;
1059 24 : if (getAccessibleParent().is())
1060 : {
1061 24 : uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1062 24 : xParentStates = xParentContext->getAccessibleStateSet();
1063 : }
1064 24 : utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
1065 24 : if (IsDefunc(xParentStates))
1066 0 : pStateSet->AddState(AccessibleStateType::DEFUNC);
1067 : else
1068 : {
1069 24 : pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
1070 24 : if (IsEditable(xParentStates))
1071 24 : pStateSet->AddState(AccessibleStateType::EDITABLE);
1072 24 : pStateSet->AddState(AccessibleStateType::ENABLED);
1073 24 : pStateSet->AddState(AccessibleStateType::FOCUSABLE);
1074 24 : if (IsFocused())
1075 24 : pStateSet->AddState(AccessibleStateType::FOCUSED);
1076 24 : pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
1077 24 : pStateSet->AddState(AccessibleStateType::OPAQUE);
1078 24 : pStateSet->AddState(AccessibleStateType::SELECTABLE);
1079 24 : if (IsCompleteSheetSelected())
1080 0 : pStateSet->AddState(AccessibleStateType::SELECTED);
1081 24 : if (isShowing())
1082 24 : pStateSet->AddState(AccessibleStateType::SHOWING);
1083 24 : if (isVisible())
1084 24 : pStateSet->AddState(AccessibleStateType::VISIBLE);
1085 : }
1086 48 : return pStateSet;
1087 : }
1088 :
1089 : ///===== XAccessibleSelection ===========================================
1090 :
1091 0 : void SAL_CALL ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex )
1092 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1093 : {
1094 0 : SolarMutexGuard aGuard;
1095 0 : IsObjectValid();
1096 0 : if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
1097 0 : throw lang::IndexOutOfBoundsException();
1098 :
1099 0 : if (mpViewShell)
1100 : {
1101 0 : sal_Int32 nCol(getAccessibleColumn(nChildIndex));
1102 0 : sal_Int32 nRow(getAccessibleRow(nChildIndex));
1103 :
1104 0 : SelectCell(nRow, nCol, false);
1105 0 : }
1106 0 : }
1107 :
1108 : void SAL_CALL
1109 0 : ScAccessibleSpreadsheet::clearAccessibleSelection( )
1110 : throw (uno::RuntimeException, std::exception)
1111 : {
1112 0 : SolarMutexGuard aGuard;
1113 0 : IsObjectValid();
1114 0 : if (mpViewShell)
1115 : {
1116 0 : if (!IsFormulaMode())
1117 0 : mpViewShell->Unmark();
1118 0 : }
1119 0 : }
1120 :
1121 0 : void SAL_CALL ScAccessibleSpreadsheet::selectAllAccessibleChildren( )
1122 : throw (uno::RuntimeException, std::exception)
1123 : {
1124 0 : SolarMutexGuard aGuard;
1125 0 : IsObjectValid();
1126 0 : if (mpViewShell)
1127 : {
1128 0 : if (IsFormulaMode())
1129 : {
1130 0 : ScViewData& rViewData = mpViewShell->GetViewData();
1131 0 : mpViewShell->InitRefMode( 0, 0, rViewData.GetTabNo(), SC_REFTYPE_REF );
1132 0 : rViewData.SetRefStart(0, 0, rViewData.GetTabNo());
1133 0 : rViewData.SetRefEnd(MAXCOL, MAXROW, rViewData.GetTabNo());
1134 0 : mpViewShell->UpdateRef(MAXCOL, MAXROW, rViewData.GetTabNo());
1135 : }
1136 : else
1137 0 : mpViewShell->SelectAll();
1138 0 : }
1139 0 : }
1140 :
1141 : sal_Int32 SAL_CALL
1142 0 : ScAccessibleSpreadsheet::getSelectedAccessibleChildCount( )
1143 : throw (uno::RuntimeException, std::exception)
1144 : {
1145 0 : SolarMutexGuard aGuard;
1146 0 : IsObjectValid();
1147 0 : sal_Int32 nResult(0);
1148 0 : if (mpViewShell)
1149 : {
1150 0 : if (IsFormulaMode())
1151 : {
1152 0 : nResult = GetRowAll() * GetColAll() ;
1153 : }
1154 : else
1155 : {
1156 0 : if (!mpMarkedRanges)
1157 : {
1158 0 : mpMarkedRanges = new ScRangeList();
1159 0 : ScMarkData aMarkData(mpViewShell->GetViewData().GetMarkData());
1160 0 : aMarkData.FillRangeListWithMarks(mpMarkedRanges, false);
1161 : }
1162 : // is possible, because there shouldn't be overlapped ranges in it
1163 0 : if (mpMarkedRanges)
1164 0 : nResult = mpMarkedRanges->GetCellCount();
1165 : }
1166 : }
1167 0 : return nResult;
1168 : }
1169 :
1170 : uno::Reference<XAccessible > SAL_CALL
1171 0 : ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1172 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1173 : {
1174 0 : SolarMutexGuard aGuard;
1175 0 : IsObjectValid();
1176 0 : uno::Reference < XAccessible > xAccessible;
1177 0 : if (IsFormulaMode())
1178 : {
1179 0 : if(CheckChildIndex(nSelectedChildIndex))
1180 : {
1181 0 : ScAddress addr = GetChildIndexAddress(nSelectedChildIndex);
1182 0 : xAccessible = getAccessibleCellAt(addr.Row(), addr.Col());
1183 : }
1184 0 : return xAccessible;
1185 : }
1186 0 : if (mpViewShell)
1187 : {
1188 0 : if (!mpMarkedRanges)
1189 : {
1190 0 : mpMarkedRanges = new ScRangeList();
1191 0 : mpViewShell->GetViewData().GetMarkData().FillRangeListWithMarks(mpMarkedRanges, false);
1192 : }
1193 0 : if (mpMarkedRanges)
1194 : {
1195 0 : if ((nSelectedChildIndex < 0) ||
1196 0 : (mpMarkedRanges->GetCellCount() <= static_cast<sal_uInt32>(nSelectedChildIndex)))
1197 : {
1198 0 : throw lang::IndexOutOfBoundsException();
1199 : }
1200 0 : ScMyAddress addr = CalcScAddressFromRangeList(mpMarkedRanges,nSelectedChildIndex);
1201 0 : if( m_mapSelectionSend.find(addr) != m_mapSelectionSend.end() )
1202 0 : xAccessible = m_mapSelectionSend[addr];
1203 : else
1204 0 : xAccessible = getAccessibleCellAt(addr.Row(), addr.Col());
1205 : }
1206 : }
1207 0 : return xAccessible;
1208 : }
1209 :
1210 0 : void SAL_CALL ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex )
1211 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1212 : {
1213 0 : SolarMutexGuard aGuard;
1214 0 : IsObjectValid();
1215 :
1216 0 : if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
1217 0 : throw lang::IndexOutOfBoundsException();
1218 :
1219 0 : if (mpViewShell)
1220 : {
1221 0 : sal_Int32 nCol(getAccessibleColumn(nChildIndex));
1222 0 : sal_Int32 nRow(getAccessibleRow(nChildIndex));
1223 :
1224 0 : if (IsFormulaMode())
1225 : {
1226 0 : if(IsScAddrFormulaSel(
1227 0 : ScAddress(static_cast<SCCOL>(nCol), nRow,mpViewShell->GetViewData().GetTabNo()))
1228 : )
1229 : {
1230 0 : SelectCell(nRow, nCol, true);
1231 : }
1232 0 : return ;
1233 : }
1234 0 : if (mpViewShell->GetViewData().GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)))
1235 0 : SelectCell(nRow, nCol, true);
1236 0 : }
1237 : }
1238 :
1239 0 : void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, bool bDeselect)
1240 : {
1241 0 : if (IsFormulaMode())
1242 : {
1243 0 : if (bDeselect)
1244 : {//??
1245 0 : return;
1246 : }
1247 : else
1248 : {
1249 0 : ScViewData& rViewData = mpViewShell->GetViewData();
1250 :
1251 0 : mpViewShell->InitRefMode( static_cast<SCCOL>(nCol), nRow, rViewData.GetTabNo(), SC_REFTYPE_REF );
1252 0 : mpViewShell->UpdateRef(static_cast<SCCOL>(nCol), nRow, rViewData.GetTabNo());
1253 : }
1254 0 : return ;
1255 : }
1256 0 : mpViewShell->SetTabNo( maRange.aStart.Tab() );
1257 :
1258 0 : mpViewShell->DoneBlockMode( true ); // continue selecting
1259 0 : mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, false, false );
1260 :
1261 0 : mpViewShell->SelectionChanged();
1262 : }
1263 :
1264 : /*
1265 : void ScAccessibleSpreadsheet::CreateSortedMarkedCells()
1266 : {
1267 : mpSortedMarkedCells = new std::vector<ScMyAddress>();
1268 : mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount());
1269 : for ( size_t i = 0, ListSize = mpMarkedRanges->size(); i < ListSize; ++i )
1270 : {
1271 : ScRange* pRange = (*mpMarkedRanges)[i];
1272 : if (pRange->aStart.Tab() != pRange->aEnd.Tab())
1273 : {
1274 : if ((maActiveCell.Tab() >= pRange->aStart.Tab()) ||
1275 : maActiveCell.Tab() <= pRange->aEnd.Tab())
1276 : {
1277 : ScRange aRange(*pRange);
1278 : aRange.aStart.SetTab(maActiveCell.Tab());
1279 : aRange.aEnd.SetTab(maActiveCell.Tab());
1280 : AddMarkedRange(aRange);
1281 : }
1282 : else
1283 : {
1284 : OSL_FAIL("Range of wrong table");
1285 : }
1286 : }
1287 : else if(pRange->aStart.Tab() == maActiveCell.Tab())
1288 : AddMarkedRange(*pRange);
1289 : else
1290 : {
1291 : OSL_FAIL("Range of wrong table");
1292 : }
1293 : }
1294 : std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end());
1295 : }
1296 :
1297 : void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange)
1298 : {
1299 : for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
1300 : {
1301 : for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
1302 : {
1303 : ScMyAddress aCell(nCol, nRow, maActiveCell.Tab());
1304 : mpSortedMarkedCells->push_back(aCell);
1305 : }
1306 : }
1307 : }*/
1308 :
1309 : //===== XServiceInfo ====================================================
1310 :
1311 0 : OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void)
1312 : throw (uno::RuntimeException, std::exception)
1313 : {
1314 0 : return OUString("ScAccessibleSpreadsheet");
1315 : }
1316 :
1317 : uno::Sequence< OUString> SAL_CALL
1318 0 : ScAccessibleSpreadsheet::getSupportedServiceNames (void)
1319 : throw (uno::RuntimeException, std::exception)
1320 : {
1321 0 : uno::Sequence< OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames();
1322 0 : sal_Int32 nOldSize(aSequence.getLength());
1323 0 : aSequence.realloc(nOldSize + 1);
1324 :
1325 0 : aSequence[nOldSize] = "com.sun.star.AccessibleSpreadsheet";
1326 :
1327 0 : return aSequence;
1328 : }
1329 :
1330 : //===== XTypeProvider =======================================================
1331 :
1332 : uno::Sequence<sal_Int8> SAL_CALL
1333 0 : ScAccessibleSpreadsheet::getImplementationId(void)
1334 : throw (uno::RuntimeException, std::exception)
1335 : {
1336 0 : return css::uno::Sequence<sal_Int8>();
1337 : }
1338 :
1339 : ///===== XAccessibleEventBroadcaster =====================================
1340 :
1341 10 : void SAL_CALL ScAccessibleSpreadsheet::addAccessibleEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
1342 : throw (uno::RuntimeException, std::exception)
1343 : {
1344 10 : SolarMutexGuard aGuard;
1345 10 : IsObjectValid();
1346 10 : ScAccessibleTableBase::addAccessibleEventListener(xListener);
1347 :
1348 10 : }
1349 :
1350 : //==== internal =========================================================
1351 :
1352 2 : Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const
1353 : throw (uno::RuntimeException, std::exception)
1354 : {
1355 2 : Rectangle aRect;
1356 2 : if (mpViewShell)
1357 : {
1358 2 : vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
1359 2 : if (pWindow)
1360 2 : aRect = pWindow->GetWindowExtentsRelative(NULL);
1361 : }
1362 2 : return aRect;
1363 : }
1364 :
1365 34 : Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const
1366 : throw (uno::RuntimeException, std::exception)
1367 : {
1368 34 : Rectangle aRect;
1369 34 : if (mpViewShell)
1370 : {
1371 34 : vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
1372 34 : if (pWindow)
1373 : //#101986#; extends to the same window, because the parent is the document and it has the same window
1374 34 : aRect = pWindow->GetWindowExtentsRelative(pWindow);
1375 : }
1376 34 : return aRect;
1377 : }
1378 :
1379 24 : bool ScAccessibleSpreadsheet::IsDefunc(
1380 : const uno::Reference<XAccessibleStateSet>& rxParentStates)
1381 : {
1382 96 : return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
1383 96 : (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
1384 : }
1385 :
1386 24 : bool ScAccessibleSpreadsheet::IsEditable(
1387 : const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
1388 : {
1389 24 : if (IsFormulaMode())
1390 : {
1391 0 : return false;
1392 : }
1393 24 : bool bProtected(false);
1394 24 : if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab()))
1395 0 : bProtected = true;
1396 24 : return !bProtected;
1397 : }
1398 :
1399 26 : bool ScAccessibleSpreadsheet::IsFocused()
1400 : {
1401 26 : bool bFocused(false);
1402 26 : if (mpViewShell)
1403 : {
1404 26 : if (mpViewShell->GetViewData().GetActivePart() == meSplitPos)
1405 26 : bFocused = mpViewShell->GetActiveWin()->HasFocus();
1406 : }
1407 26 : return bFocused;
1408 : }
1409 :
1410 24 : bool ScAccessibleSpreadsheet::IsCompleteSheetSelected()
1411 : {
1412 24 : if (IsFormulaMode())
1413 : {
1414 0 : return false;
1415 : }
1416 :
1417 24 : bool bResult(false);
1418 24 : if(mpViewShell)
1419 : {
1420 : //#103800#; use a copy of MarkData
1421 24 : ScMarkData aMarkData(mpViewShell->GetViewData().GetMarkData());
1422 24 : aMarkData.MarkToMulti();
1423 24 : if (aMarkData.IsAllMarked(maRange))
1424 0 : bResult = true;
1425 : }
1426 24 : return bResult;
1427 : }
1428 :
1429 28 : ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell)
1430 : {
1431 28 : ScDocument* pDoc = NULL;
1432 28 : if (pViewShell)
1433 28 : pDoc = pViewShell->GetViewData().GetDocument();
1434 28 : return pDoc;
1435 : }
1436 :
1437 4 : Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
1438 : {
1439 4 : Rectangle aVisArea;
1440 4 : if (pViewShell)
1441 : {
1442 4 : vcl::Window* pWindow = pViewShell->GetWindowByPos(eSplitPos);
1443 4 : if (pWindow)
1444 : {
1445 4 : aVisArea.SetPos(pViewShell->GetViewData().GetPixPos(eSplitPos));
1446 4 : aVisArea.SetSize(pWindow->GetSizePixel());
1447 : }
1448 : }
1449 4 : return aVisArea;
1450 : }
1451 :
1452 4 : Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea)
1453 : {
1454 4 : if (mpViewShell)
1455 : {
1456 : SCsCOL nStartX, nEndX;
1457 : SCsROW nStartY, nEndY;
1458 :
1459 4 : mpViewShell->GetViewData().GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY);
1460 4 : mpViewShell->GetViewData().GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY);
1461 :
1462 4 : return Rectangle(nStartX, nStartY, nEndX, nEndY);
1463 : }
1464 : else
1465 0 : return Rectangle();
1466 : }
1467 :
1468 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectRow( sal_Int32 row )
1469 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1470 : {
1471 0 : SolarMutexGuard g;
1472 :
1473 0 : if (IsFormulaMode())
1474 : {
1475 0 : return sal_False;
1476 : }
1477 :
1478 0 : mpViewShell->SetTabNo( maRange.aStart.Tab() );
1479 0 : mpViewShell->DoneBlockMode( true ); // continue selecting
1480 0 : mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), false, false, true );
1481 0 : mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), false, true );
1482 0 : mpViewShell->SelectionChanged();
1483 0 : return sal_True;
1484 : }
1485 :
1486 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::selectColumn( sal_Int32 column )
1487 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1488 : {
1489 0 : SolarMutexGuard g;
1490 :
1491 0 : if (IsFormulaMode())
1492 : {
1493 0 : return sal_False;
1494 : }
1495 :
1496 0 : mpViewShell->SetTabNo( maRange.aStart.Tab() );
1497 0 : mpViewShell->DoneBlockMode( true ); // continue selecting
1498 0 : mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), false, true, false );
1499 0 : mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), true, false );
1500 0 : mpViewShell->SelectionChanged();
1501 0 : return sal_True;
1502 : }
1503 :
1504 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectRow( sal_Int32 row )
1505 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1506 : {
1507 0 : SolarMutexGuard g;
1508 :
1509 0 : if (IsFormulaMode())
1510 : {
1511 0 : return sal_False;
1512 : }
1513 :
1514 0 : mpViewShell->SetTabNo( maRange.aStart.Tab() );
1515 0 : mpViewShell->DoneBlockMode( true ); // continue selecting
1516 0 : mpViewShell->InitBlockMode( 0, row, maRange.aStart.Tab(), false, false, true, true );
1517 0 : mpViewShell->MarkCursor( MAXCOL, row, maRange.aStart.Tab(), false, true );
1518 0 : mpViewShell->SelectionChanged();
1519 0 : mpViewShell->DoneBlockMode( true );
1520 0 : return sal_True;
1521 : }
1522 :
1523 0 : sal_Bool SAL_CALL ScAccessibleSpreadsheet::unselectColumn( sal_Int32 column )
1524 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1525 : {
1526 0 : SolarMutexGuard g;
1527 :
1528 0 : if (IsFormulaMode())
1529 : {
1530 0 : return sal_False;
1531 : }
1532 :
1533 0 : mpViewShell->SetTabNo( maRange.aStart.Tab() );
1534 0 : mpViewShell->DoneBlockMode( true ); // continue selecting
1535 0 : mpViewShell->InitBlockMode( static_cast<SCCOL>(column), 0, maRange.aStart.Tab(), false, true, false, true );
1536 0 : mpViewShell->MarkCursor( static_cast<SCCOL>(column), MAXROW, maRange.aStart.Tab(), true, false );
1537 0 : mpViewShell->SelectionChanged();
1538 0 : mpViewShell->DoneBlockMode( true );
1539 0 : return sal_True;
1540 : }
1541 :
1542 0 : void ScAccessibleSpreadsheet::FireFirstCellFocus()
1543 : {
1544 0 : if (IsFormulaMode())
1545 : {
1546 0 : return ;
1547 : }
1548 0 : if (mbIsFocusSend)
1549 : {
1550 0 : return ;
1551 : }
1552 0 : mbIsFocusSend = true;
1553 0 : AccessibleEventObject aEvent;
1554 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
1555 0 : aEvent.Source = uno::Reference< XAccessible >(this);
1556 0 : aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
1557 0 : CommitChange(aEvent);
1558 : }
1559 :
1560 0 : void ScAccessibleSpreadsheet::NotifyRefMode()
1561 : {
1562 0 : ScViewData& rViewData = mpViewShell->GetViewData();
1563 0 : if (!rViewData.IsRefMode())
1564 : // Not in reference mode. Bail out.
1565 0 : return;
1566 :
1567 0 : sal_uInt16 nRefStartX = rViewData.GetRefStartX();
1568 0 : sal_Int32 nRefStartY = rViewData.GetRefStartY();
1569 0 : sal_uInt16 nRefEndX = rViewData.GetRefEndX();
1570 0 : sal_Int32 nRefEndY = rViewData.GetRefEndY();
1571 0 : ScAddress aFormulaAddr;
1572 0 : if(!GetFormulaCurrentFocusCell(aFormulaAddr))
1573 : {
1574 0 : return ;
1575 : }
1576 0 : if (m_aFormulaActiveCell != aFormulaAddr)
1577 : {//New Focus
1578 0 : m_nMinX =std::min(nRefStartX,nRefEndX);
1579 0 : m_nMaxX =std::max(nRefStartX,nRefEndX);
1580 0 : m_nMinY = std::min(nRefStartY,nRefEndY);
1581 0 : m_nMaxY = std::max(nRefStartY,nRefEndY);
1582 0 : RemoveFormulaSelection();
1583 0 : AccessibleEventObject aEvent;
1584 0 : aEvent.Source = uno::Reference< XAccessible >(this);
1585 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
1586 0 : aEvent.Source = uno::Reference< XAccessible >(this);
1587 0 : aEvent.OldValue <<= uno::Reference<XAccessible>(m_pAccFormulaCell.get());
1588 0 : m_pAccFormulaCell = GetAccessibleCellAt(aFormulaAddr.Row(), aFormulaAddr.Col());
1589 0 : uno::Reference< XAccessible > xNew = m_pAccFormulaCell.get();
1590 0 : aEvent.NewValue <<= xNew;
1591 0 : CommitChange(aEvent);
1592 0 : if (nRefStartX == nRefEndX && nRefStartY == nRefEndY)
1593 : {//Selection Single
1594 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1595 0 : aEvent.NewValue <<= xNew;
1596 0 : CommitChange(aEvent);
1597 0 : m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(aFormulaAddr,xNew));
1598 0 : m_vecFormulaLastMyAddr.clear();
1599 0 : m_vecFormulaLastMyAddr.push_back(aFormulaAddr);
1600 : }
1601 : else
1602 : {
1603 0 : VEC_MYADDR vecCurSel;
1604 0 : int nCurSize = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) ;
1605 0 : vecCurSel.reserve(nCurSize);
1606 0 : for (sal_uInt16 x = m_nMinX ; x <= m_nMaxX ; ++x)
1607 : {
1608 0 : for (sal_Int32 y = m_nMinY ; y <= m_nMaxY ; ++y)
1609 : {
1610 0 : ScMyAddress aAddr(x,y,0);
1611 0 : vecCurSel.push_back(aAddr);
1612 : }
1613 : }
1614 0 : std::sort(vecCurSel.begin(), vecCurSel.end());
1615 0 : VEC_MYADDR vecNew;
1616 : std::set_difference(vecCurSel.begin(),vecCurSel.end(),
1617 : m_vecFormulaLastMyAddr.begin(),m_vecFormulaLastMyAddr.end(),
1618 0 : std::back_insert_iterator<VEC_MYADDR>(vecNew));
1619 0 : int nNewSize = vecNew.size();
1620 0 : if ( nNewSize > 10 )
1621 : {
1622 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1623 0 : aEvent.NewValue <<= ::com::sun::star::uno::Any();
1624 0 : CommitChange(aEvent);
1625 : }
1626 : else
1627 : {
1628 0 : VEC_MYADDR::iterator viAddr = vecNew.begin();
1629 0 : for(; viAddr != vecNew.end() ; ++viAddr )
1630 : {
1631 0 : uno::Reference< XAccessible > xChild;
1632 0 : if (*viAddr == aFormulaAddr)
1633 : {
1634 0 : xChild = m_pAccFormulaCell.get();
1635 : }
1636 : else
1637 : {
1638 0 : xChild = getAccessibleCellAt(viAddr->Row(),viAddr->Col());
1639 0 : aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS;
1640 0 : aEvent.NewValue <<= xChild;
1641 0 : CommitChange(aEvent);
1642 : }
1643 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_ADD;
1644 0 : aEvent.NewValue <<= xChild;
1645 0 : CommitChange(aEvent);
1646 0 : m_mapFormulaSelectionSend.insert(MAP_ADDR_XACC::value_type(*viAddr,xChild));
1647 0 : }
1648 : }
1649 0 : m_vecFormulaLastMyAddr.swap(vecCurSel);
1650 0 : }
1651 : }
1652 0 : m_aFormulaActiveCell = aFormulaAddr;
1653 : }
1654 :
1655 0 : void ScAccessibleSpreadsheet::RemoveFormulaSelection(bool bRemoveAll )
1656 : {
1657 0 : AccessibleEventObject aEvent;
1658 0 : aEvent.Source = uno::Reference< XAccessible >(this);
1659 0 : aEvent.OldValue <<= ::com::sun::star::uno::Any();
1660 0 : MAP_ADDR_XACC::iterator miRemove = m_mapFormulaSelectionSend.begin();
1661 0 : for(; miRemove != m_mapFormulaSelectionSend.end() ;)
1662 : {
1663 0 : if( !bRemoveAll && IsScAddrFormulaSel(miRemove->first) )
1664 : {
1665 0 : ++miRemove;
1666 0 : continue;
1667 : }
1668 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1669 0 : aEvent.NewValue <<= miRemove->second;
1670 0 : CommitChange(aEvent);
1671 0 : MAP_ADDR_XACC::iterator miNext = miRemove;
1672 0 : ++miNext;
1673 0 : m_mapFormulaSelectionSend.erase(miRemove);
1674 0 : miRemove = miNext;
1675 0 : }
1676 0 : }
1677 :
1678 0 : bool ScAccessibleSpreadsheet::IsScAddrFormulaSel(const ScAddress &addr) const
1679 : {
1680 0 : if( addr.Col() >= m_nMinX && addr.Col() <= m_nMaxX &&
1681 0 : addr.Row() >= m_nMinY && addr.Row() <= m_nMaxY &&
1682 0 : addr.Tab() == mpViewShell->GetViewData().GetTabNo() )
1683 : {
1684 0 : return true;
1685 : }
1686 0 : return false;
1687 : }
1688 :
1689 0 : bool ScAccessibleSpreadsheet::CheckChildIndex(sal_Int32 nIndex) const
1690 : {
1691 0 : sal_Int32 nMaxIndex = (m_nMaxX - m_nMinX +1)*(m_nMaxY - m_nMinY +1) -1 ;
1692 0 : return nIndex <= nMaxIndex && nIndex >= 0 ;
1693 : }
1694 :
1695 0 : ScAddress ScAccessibleSpreadsheet::GetChildIndexAddress(sal_Int32 nIndex) const
1696 : {
1697 0 : sal_Int32 nRowAll = GetRowAll();
1698 0 : sal_uInt16 nColAll = GetColAll();
1699 0 : if (nIndex < 0 || nIndex >= nRowAll * nColAll )
1700 : {
1701 0 : return ScAddress();
1702 : }
1703 : return ScAddress(
1704 0 : static_cast<SCCOL>((nIndex - nIndex % nRowAll) / nRowAll + + m_nMinX),
1705 0 : nIndex % nRowAll + m_nMinY,
1706 0 : mpViewShell->GetViewData().GetTabNo()
1707 0 : );
1708 : }
1709 :
1710 0 : sal_Int32 ScAccessibleSpreadsheet::GetAccessibleIndexFormula( sal_Int32 nRow, sal_Int32 nColumn )
1711 : {
1712 0 : sal_uInt16 nColRelative = sal_uInt16(nColumn) - GetColAll();
1713 0 : sal_Int32 nRowRelative = nRow - GetRowAll();
1714 0 : if (nRow < 0 || nColumn < 0 || nRowRelative >= GetRowAll() || nColRelative >= GetColAll() )
1715 : {
1716 0 : return -1;
1717 : }
1718 0 : return GetRowAll() * nRowRelative + nColRelative;
1719 : }
1720 :
1721 106 : bool ScAccessibleSpreadsheet::IsFormulaMode()
1722 : {
1723 106 : ScViewData& rViewData = mpViewShell->GetViewData();
1724 106 : m_bFormulaMode = rViewData.IsRefMode() || SC_MOD()->IsFormulaMode();
1725 106 : return m_bFormulaMode ;
1726 : }
1727 :
1728 0 : bool ScAccessibleSpreadsheet::GetFormulaCurrentFocusCell(ScAddress &addr)
1729 : {
1730 0 : ScViewData& rViewData = mpViewShell->GetViewData();
1731 0 : sal_uInt16 nRefX=0;
1732 0 : sal_Int32 nRefY=0;
1733 0 : if(m_bFormulaLastMode)
1734 : {
1735 0 : nRefX=rViewData.GetRefEndX();
1736 0 : nRefY=rViewData.GetRefEndY();
1737 : }
1738 : else
1739 : {
1740 0 : nRefX=rViewData.GetRefStartX();
1741 0 : nRefY=rViewData.GetRefStartY();
1742 : }
1743 0 : if( /* Always true: nRefX >= 0 && */ nRefX <= MAXCOL && nRefY >= 0 && nRefY <= MAXROW)
1744 : {
1745 0 : addr = ScAddress(nRefX,nRefY,rViewData.GetTabNo());
1746 0 : return true;
1747 : }
1748 0 : return false;
1749 : }
1750 :
1751 0 : uno::Reference < XAccessible > ScAccessibleSpreadsheet::GetActiveCell()
1752 : {
1753 0 : if( m_mapSelectionSend.find( maActiveCell ) != m_mapSelectionSend.end() )
1754 0 : return m_mapSelectionSend[maActiveCell];
1755 : else
1756 0 : return getAccessibleCellAt(maActiveCell.Row(), maActiveCell .Col());
1757 228 : }
1758 :
1759 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|