xref: /AOO41X/main/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include "AccessibleSpreadsheet.hxx"
33*cdf0e10cSrcweir #include "AccessibilityHints.hxx"
34*cdf0e10cSrcweir #include "AccessibleCell.hxx"
35*cdf0e10cSrcweir #include "AccessibleDocument.hxx"
36*cdf0e10cSrcweir #include "tabvwsh.hxx"
37*cdf0e10cSrcweir #include "document.hxx"
38*cdf0e10cSrcweir #include "unoguard.hxx"
39*cdf0e10cSrcweir #include "hints.hxx"
40*cdf0e10cSrcweir #include "scmod.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
43*cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
44*cdf0e10cSrcweir #endif
45*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
46*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
47*cdf0e10cSrcweir #endif
48*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
49*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
50*cdf0e10cSrcweir #endif
51*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
53*cdf0e10cSrcweir #include <rtl/uuid.h>
54*cdf0e10cSrcweir #include <tools/debug.hxx>
55*cdf0e10cSrcweir #include <tools/gen.hxx>
56*cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir #include <algorithm>
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir using namespace	::com::sun::star;
61*cdf0e10cSrcweir using namespace	::com::sun::star::accessibility;
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir //=====  internal  ============================================================
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
66*cdf0e10cSrcweir         ScAccessibleDocument* pAccDoc,
67*cdf0e10cSrcweir 		ScTabViewShell* pViewShell,
68*cdf0e10cSrcweir 		SCTAB nTab,
69*cdf0e10cSrcweir 		ScSplitPos eSplitPos)
70*cdf0e10cSrcweir 	:
71*cdf0e10cSrcweir 	ScAccessibleTableBase (pAccDoc, GetDocument(pViewShell),
72*cdf0e10cSrcweir         ScRange(ScAddress(0, 0, nTab),ScAddress(MAXCOL, MAXROW, nTab))),
73*cdf0e10cSrcweir     mbIsSpreadsheet( sal_True )
74*cdf0e10cSrcweir {
75*cdf0e10cSrcweir     ConstructScAccessibleSpreadsheet( pAccDoc, pViewShell, nTab, eSplitPos );
76*cdf0e10cSrcweir }
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
79*cdf0e10cSrcweir         ScAccessibleSpreadsheet& rParent, const ScRange& rRange ) :
80*cdf0e10cSrcweir     ScAccessibleTableBase( rParent.mpAccDoc, rParent.mpDoc, rRange),
81*cdf0e10cSrcweir     mbIsSpreadsheet( sal_False )
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir     ConstructScAccessibleSpreadsheet( rParent.mpAccDoc, rParent.mpViewShell, rParent.mnTab, rParent.meSplitPos );
84*cdf0e10cSrcweir }
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir ScAccessibleSpreadsheet::~ScAccessibleSpreadsheet()
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir 	if (mpMarkedRanges)
89*cdf0e10cSrcweir 		delete mpMarkedRanges;
90*cdf0e10cSrcweir 	if (mpSortedMarkedCells)
91*cdf0e10cSrcweir 		delete mpSortedMarkedCells;
92*cdf0e10cSrcweir 	if (mpViewShell)
93*cdf0e10cSrcweir 		mpViewShell->RemoveAccessibilityObject(*this);
94*cdf0e10cSrcweir }
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir void ScAccessibleSpreadsheet::ConstructScAccessibleSpreadsheet(
97*cdf0e10cSrcweir     ScAccessibleDocument* pAccDoc,
98*cdf0e10cSrcweir     ScTabViewShell* pViewShell,
99*cdf0e10cSrcweir     SCTAB nTab,
100*cdf0e10cSrcweir     ScSplitPos eSplitPos)
101*cdf0e10cSrcweir {
102*cdf0e10cSrcweir     mpViewShell = pViewShell;
103*cdf0e10cSrcweir     mpMarkedRanges = 0;
104*cdf0e10cSrcweir     mpSortedMarkedCells = 0;
105*cdf0e10cSrcweir     mpAccDoc = pAccDoc;
106*cdf0e10cSrcweir     mpAccCell = 0;
107*cdf0e10cSrcweir     meSplitPos = eSplitPos;
108*cdf0e10cSrcweir     mnTab = nTab;
109*cdf0e10cSrcweir     mbHasSelection = sal_False;
110*cdf0e10cSrcweir     mbDelIns = sal_False;
111*cdf0e10cSrcweir     mbIsFocusSend = sal_False;
112*cdf0e10cSrcweir     maVisCells = GetVisCells(GetVisArea(mpViewShell, meSplitPos));
113*cdf0e10cSrcweir     if (mpViewShell)
114*cdf0e10cSrcweir     {
115*cdf0e10cSrcweir         mpViewShell->AddAccessibilityObject(*this);
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir         const ScViewData& rViewData = *mpViewShell->GetViewData();
118*cdf0e10cSrcweir         const ScMarkData& rMarkData = rViewData.GetMarkData();
119*cdf0e10cSrcweir         maActiveCell = rViewData.GetCurPos();
120*cdf0e10cSrcweir         mbHasSelection = rMarkData.GetTableSelect(maActiveCell.Tab()) &&
121*cdf0e10cSrcweir                     (rMarkData.IsMarked() || rMarkData.IsMultiMarked());
122*cdf0e10cSrcweir         mpAccCell = GetAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
123*cdf0e10cSrcweir         mpAccCell->acquire();
124*cdf0e10cSrcweir         mpAccCell->Init();
125*cdf0e10cSrcweir     }
126*cdf0e10cSrcweir }
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir void SAL_CALL ScAccessibleSpreadsheet::disposing()
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     ScUnoGuard aGuard;
131*cdf0e10cSrcweir 	if (mpViewShell)
132*cdf0e10cSrcweir 	{
133*cdf0e10cSrcweir 		mpViewShell->RemoveAccessibilityObject(*this);
134*cdf0e10cSrcweir 		mpViewShell = NULL;
135*cdf0e10cSrcweir 	}
136*cdf0e10cSrcweir     if (mpAccCell)
137*cdf0e10cSrcweir     {
138*cdf0e10cSrcweir         mpAccCell->release();
139*cdf0e10cSrcweir         mpAccCell = NULL;
140*cdf0e10cSrcweir     }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 	ScAccessibleTableBase::disposing();
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir void ScAccessibleSpreadsheet::CompleteSelectionChanged(sal_Bool bNewState)
146*cdf0e10cSrcweir {
147*cdf0e10cSrcweir 	if (mpMarkedRanges)
148*cdf0e10cSrcweir 		DELETEZ(mpMarkedRanges);
149*cdf0e10cSrcweir 	if (mpSortedMarkedCells)
150*cdf0e10cSrcweir 		DELETEZ(mpSortedMarkedCells);
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 	mbHasSelection = bNewState;
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir     AccessibleEventObject aEvent;
155*cdf0e10cSrcweir 	aEvent.EventId = AccessibleEventId::STATE_CHANGED;
156*cdf0e10cSrcweir 	if (bNewState)
157*cdf0e10cSrcweir 		aEvent.NewValue = uno::makeAny(AccessibleStateType::SELECTED);
158*cdf0e10cSrcweir 	else
159*cdf0e10cSrcweir 		aEvent.OldValue = uno::makeAny(AccessibleStateType::SELECTED);
160*cdf0e10cSrcweir 	aEvent.Source = uno::Reference< XAccessibleContext >(this);
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	CommitChange(aEvent);
163*cdf0e10cSrcweir }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir void ScAccessibleSpreadsheet::LostFocus()
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir 	AccessibleEventObject aEvent;
168*cdf0e10cSrcweir 	aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
169*cdf0e10cSrcweir 	aEvent.Source = uno::Reference< XAccessibleContext >(this);
170*cdf0e10cSrcweir     uno::Reference< XAccessible > xOld = mpAccCell;
171*cdf0e10cSrcweir 	aEvent.OldValue <<= xOld;
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir 	CommitChange(aEvent);
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir     CommitFocusLost();
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir void ScAccessibleSpreadsheet::GotFocus()
179*cdf0e10cSrcweir {
180*cdf0e10cSrcweir     CommitFocusGained();
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir 	AccessibleEventObject aEvent;
183*cdf0e10cSrcweir 	aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
184*cdf0e10cSrcweir 	aEvent.Source = uno::Reference< XAccessibleContext >(this);
185*cdf0e10cSrcweir     uno::Reference< XAccessible > xNew = mpAccCell;
186*cdf0e10cSrcweir 	aEvent.NewValue <<= xNew;
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 	CommitChange(aEvent);
189*cdf0e10cSrcweir }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir void ScAccessibleSpreadsheet::BoundingBoxChanged()
192*cdf0e10cSrcweir {
193*cdf0e10cSrcweir     AccessibleEventObject aEvent;
194*cdf0e10cSrcweir     aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
195*cdf0e10cSrcweir     aEvent.Source = uno::Reference< XAccessibleContext >(this);
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir     CommitChange(aEvent);
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir void ScAccessibleSpreadsheet::VisAreaChanged()
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 	AccessibleEventObject aEvent;
203*cdf0e10cSrcweir 	aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
204*cdf0e10cSrcweir 	aEvent.Source = uno::Reference< XAccessibleContext >(this);
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir 	CommitChange(aEvent);
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 	//=====  SfxListener  =====================================================
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir void ScAccessibleSpreadsheet::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir 	if (rHint.ISA( SfxSimpleHint ) )
214*cdf0e10cSrcweir 	{
215*cdf0e10cSrcweir 		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
216*cdf0e10cSrcweir 		// only notify if child exist, otherwise it is not necessary
217*cdf0e10cSrcweir 		if ((rRef.GetId() == SC_HINT_ACC_CURSORCHANGED))
218*cdf0e10cSrcweir 		{
219*cdf0e10cSrcweir 			if (mpViewShell)
220*cdf0e10cSrcweir 			{
221*cdf0e10cSrcweir 				ScAddress aNewCell = mpViewShell->GetViewData()->GetCurPos();
222*cdf0e10cSrcweir 				sal_Bool bNewMarked(mpViewShell->GetViewData()->GetMarkData().GetTableSelect(aNewCell.Tab()) &&
223*cdf0e10cSrcweir 					(mpViewShell->GetViewData()->GetMarkData().IsMarked() ||
224*cdf0e10cSrcweir 					mpViewShell->GetViewData()->GetMarkData().IsMultiMarked()));
225*cdf0e10cSrcweir 				sal_Bool bNewCellSelected(isAccessibleSelected(aNewCell.Row(), aNewCell.Col()));
226*cdf0e10cSrcweir 				if ((bNewMarked != mbHasSelection) ||
227*cdf0e10cSrcweir 					(!bNewCellSelected && bNewMarked) ||
228*cdf0e10cSrcweir 					(bNewCellSelected && mbHasSelection))
229*cdf0e10cSrcweir 				{
230*cdf0e10cSrcweir 					if (mpMarkedRanges)
231*cdf0e10cSrcweir 						DELETEZ(mpMarkedRanges);
232*cdf0e10cSrcweir 					if (mpSortedMarkedCells)
233*cdf0e10cSrcweir 						DELETEZ(mpSortedMarkedCells);
234*cdf0e10cSrcweir 					AccessibleEventObject aEvent;
235*cdf0e10cSrcweir 					aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
236*cdf0e10cSrcweir 					aEvent.Source = uno::Reference< XAccessibleContext >(this);
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 					mbHasSelection = bNewMarked;
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir 					CommitChange(aEvent);
241*cdf0e10cSrcweir 				}
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir                 // active descendant changed event (new cell selected)
244*cdf0e10cSrcweir                 bool bFireActiveDescChanged = (aNewCell != maActiveCell) &&
245*cdf0e10cSrcweir                     (aNewCell.Tab() == maActiveCell.Tab()) && IsFocused();
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir                 /*  Remember old active cell and set new active cell.
248*cdf0e10cSrcweir                     #i82409# always update the class members mpAccCell and
249*cdf0e10cSrcweir                     maActiveCell, even if the sheet is not focused, e.g. when
250*cdf0e10cSrcweir                     using the name box in the toolbar. */
251*cdf0e10cSrcweir                 uno::Reference< XAccessible > xOld = mpAccCell;
252*cdf0e10cSrcweir                 mpAccCell->release();
253*cdf0e10cSrcweir                 mpAccCell = GetAccessibleCellAt(aNewCell.Row(), aNewCell.Col());
254*cdf0e10cSrcweir                 mpAccCell->acquire();
255*cdf0e10cSrcweir                 mpAccCell->Init();
256*cdf0e10cSrcweir                 uno::Reference< XAccessible > xNew = mpAccCell;
257*cdf0e10cSrcweir                 maActiveCell = aNewCell;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir                 // #i14108# fire event only if sheet is focused
260*cdf0e10cSrcweir                 if( bFireActiveDescChanged )
261*cdf0e10cSrcweir                 {
262*cdf0e10cSrcweir                     AccessibleEventObject aEvent;
263*cdf0e10cSrcweir                     aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
264*cdf0e10cSrcweir                     aEvent.Source = uno::Reference< XAccessibleContext >(this);
265*cdf0e10cSrcweir                     aEvent.OldValue <<= xOld;
266*cdf0e10cSrcweir                     aEvent.NewValue <<= xNew;
267*cdf0e10cSrcweir 					CommitChange(aEvent);
268*cdf0e10cSrcweir                 }
269*cdf0e10cSrcweir 			}
270*cdf0e10cSrcweir 		}
271*cdf0e10cSrcweir 		else if ((rRef.GetId() == SC_HINT_DATACHANGED))
272*cdf0e10cSrcweir 		{
273*cdf0e10cSrcweir 			if (!mbDelIns)
274*cdf0e10cSrcweir 				CommitTableModelChange(maRange.aStart.Row(), maRange.aStart.Col(), maRange.aEnd.Row(), maRange.aEnd.Col(), AccessibleTableModelChangeType::UPDATE);
275*cdf0e10cSrcweir 			else
276*cdf0e10cSrcweir 				mbDelIns = sal_False;
277*cdf0e10cSrcweir 		}
278*cdf0e10cSrcweir         // no longer needed, because the document calls the VisAreaChanged method
279*cdf0e10cSrcweir /*		else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 			AccessibleEventObject aEvent;
282*cdf0e10cSrcweir 			aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
283*cdf0e10cSrcweir 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 			CommitChange(aEvent);*/
286*cdf0e10cSrcweir         // commented out, because to use a ModelChangeEvent is not the right way
287*cdf0e10cSrcweir         // at the moment there is no way, but the Java/Gnome Api should be extended sometime
288*cdf0e10cSrcweir /*			if (mpViewShell)
289*cdf0e10cSrcweir 			{
290*cdf0e10cSrcweir 				Rectangle aNewVisCells(GetVisCells(GetVisArea(mpViewShell, meSplitPos)));
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir 				Rectangle aNewPos(aNewVisCells);
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir 				if (aNewVisCells.IsOver(maVisCells))
295*cdf0e10cSrcweir 					aNewPos.Union(maVisCells);
296*cdf0e10cSrcweir 				else
297*cdf0e10cSrcweir 					CommitTableModelChange(maVisCells.Top(), maVisCells.Left(), maVisCells.Bottom(), maVisCells.Right(), AccessibleTableModelChangeType::UPDATE);
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 				maVisCells = aNewVisCells;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir 				CommitTableModelChange(aNewPos.Top(), aNewPos.Left(), aNewPos.Bottom(), aNewPos.Right(), AccessibleTableModelChangeType::UPDATE);
302*cdf0e10cSrcweir 			}
303*cdf0e10cSrcweir 		}*/
304*cdf0e10cSrcweir         // no longer needed, because the document calls the BoundingBoxChanged method
305*cdf0e10cSrcweir /*        else if (rRef.GetId() == SC_HINT_ACC_WINDOWRESIZED)
306*cdf0e10cSrcweir         {
307*cdf0e10cSrcweir 			AccessibleEventObject aEvent;
308*cdf0e10cSrcweir 			aEvent.EventId = AccessibleEventId::BOUNDRECT_CHANGED;
309*cdf0e10cSrcweir 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 			CommitChange(aEvent);
312*cdf0e10cSrcweir         }*/
313*cdf0e10cSrcweir 	}
314*cdf0e10cSrcweir 	else if (rHint.ISA( ScUpdateRefHint ))
315*cdf0e10cSrcweir 	{
316*cdf0e10cSrcweir 		const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
317*cdf0e10cSrcweir 		if (rRef.GetMode() == URM_INSDEL && rRef.GetDz() == 0) //#107250# test whether table is inserted or deleted
318*cdf0e10cSrcweir 		{
319*cdf0e10cSrcweir 			if (((rRef.GetRange().aStart.Col() == maRange.aStart.Col()) &&
320*cdf0e10cSrcweir 				(rRef.GetRange().aEnd.Col() == maRange.aEnd.Col())) ||
321*cdf0e10cSrcweir 				((rRef.GetRange().aStart.Row() == maRange.aStart.Row()) &&
322*cdf0e10cSrcweir 				(rRef.GetRange().aEnd.Row() == maRange.aEnd.Row())))
323*cdf0e10cSrcweir 			{
324*cdf0e10cSrcweir 				// ignore next SC_HINT_DATACHANGED notification
325*cdf0e10cSrcweir 				mbDelIns = sal_True;
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 				sal_Int16 nId(0);
328*cdf0e10cSrcweir                 SCsCOL nX(rRef.GetDx());
329*cdf0e10cSrcweir                 SCsROW nY(rRef.GetDy());
330*cdf0e10cSrcweir                 ScRange aRange(rRef.GetRange());
331*cdf0e10cSrcweir 				if ((nX < 0) || (nY < 0))
332*cdf0e10cSrcweir                 {
333*cdf0e10cSrcweir                     DBG_ASSERT(!((nX < 0) && (nY < 0)), "should not be possible to remove row and column at the same time");
334*cdf0e10cSrcweir 					nId = AccessibleTableModelChangeType::DELETE;
335*cdf0e10cSrcweir                     if (nX < 0)
336*cdf0e10cSrcweir                     {
337*cdf0e10cSrcweir                         nX = -nX;
338*cdf0e10cSrcweir                         nY = aRange.aEnd.Row() - aRange.aStart.Row();
339*cdf0e10cSrcweir                     }
340*cdf0e10cSrcweir                     else
341*cdf0e10cSrcweir                     {
342*cdf0e10cSrcweir                         nY = -nY;
343*cdf0e10cSrcweir                         nX = aRange.aEnd.Col() - aRange.aStart.Col();
344*cdf0e10cSrcweir                     }
345*cdf0e10cSrcweir                 }
346*cdf0e10cSrcweir 				else if ((nX > 0) || (nY > 0))
347*cdf0e10cSrcweir                 {
348*cdf0e10cSrcweir                     DBG_ASSERT(!((nX > 0) && (nY > 0)), "should not be possible to add row and column at the same time");
349*cdf0e10cSrcweir 					nId = AccessibleTableModelChangeType::INSERT;
350*cdf0e10cSrcweir                     if (nX < 0)
351*cdf0e10cSrcweir                         nY = aRange.aEnd.Row() - aRange.aStart.Row();
352*cdf0e10cSrcweir                     else
353*cdf0e10cSrcweir                         nX = aRange.aEnd.Col() - aRange.aStart.Col();
354*cdf0e10cSrcweir                 }
355*cdf0e10cSrcweir 				else
356*cdf0e10cSrcweir 				{
357*cdf0e10cSrcweir 					DBG_ERROR("is it a deletion or a insertion?");
358*cdf0e10cSrcweir 				}
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 				CommitTableModelChange(rRef.GetRange().aStart.Row(),
361*cdf0e10cSrcweir                     rRef.GetRange().aStart.Col(),
362*cdf0e10cSrcweir                     rRef.GetRange().aStart.Row() + nY,
363*cdf0e10cSrcweir                     rRef.GetRange().aStart.Col() + nX, nId);
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 				AccessibleEventObject aEvent;
366*cdf0e10cSrcweir 				aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
367*cdf0e10cSrcweir 				aEvent.Source = uno::Reference< XAccessibleContext >(this);
368*cdf0e10cSrcweir                 uno::Reference< XAccessible > xNew = mpAccCell;
369*cdf0e10cSrcweir 				aEvent.NewValue <<= xNew;
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 				CommitChange(aEvent);
372*cdf0e10cSrcweir 			}
373*cdf0e10cSrcweir 		}
374*cdf0e10cSrcweir 	}
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 	ScAccessibleTableBase::Notify(rBC, rHint);
377*cdf0e10cSrcweir }
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir 	//=====  XAccessibleTable  ================================================
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleRowHeaders(  )
382*cdf0e10cSrcweir                     throw (uno::RuntimeException)
383*cdf0e10cSrcweir {
384*cdf0e10cSrcweir     ScUnoGuard aGuard;
385*cdf0e10cSrcweir     IsObjectValid();
386*cdf0e10cSrcweir     uno::Reference< XAccessibleTable > xAccessibleTable;
387*cdf0e10cSrcweir     if( mpDoc && mbIsSpreadsheet )
388*cdf0e10cSrcweir     {
389*cdf0e10cSrcweir         if( const ScRange* pRowRange = mpDoc->GetRepeatRowRange( mnTab ) )
390*cdf0e10cSrcweir         {
391*cdf0e10cSrcweir             SCROW nStart = pRowRange->aStart.Row();
392*cdf0e10cSrcweir             SCROW nEnd = pRowRange->aEnd.Row();
393*cdf0e10cSrcweir             if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXROW) )
394*cdf0e10cSrcweir                 xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( 0, nStart, mnTab, MAXCOL, nEnd, mnTab ) ) );
395*cdf0e10cSrcweir         }
396*cdf0e10cSrcweir     }
397*cdf0e10cSrcweir     return xAccessibleTable;
398*cdf0e10cSrcweir }
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleSpreadsheet::getAccessibleColumnHeaders(  )
401*cdf0e10cSrcweir                     throw (uno::RuntimeException)
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir     ScUnoGuard aGuard;
404*cdf0e10cSrcweir     IsObjectValid();
405*cdf0e10cSrcweir     uno::Reference< XAccessibleTable > xAccessibleTable;
406*cdf0e10cSrcweir     if( mpDoc && mbIsSpreadsheet )
407*cdf0e10cSrcweir     {
408*cdf0e10cSrcweir         if( const ScRange* pColRange = mpDoc->GetRepeatColRange( mnTab ) )
409*cdf0e10cSrcweir         {
410*cdf0e10cSrcweir             SCCOL nStart = pColRange->aStart.Col();
411*cdf0e10cSrcweir             SCCOL nEnd = pColRange->aEnd.Col();
412*cdf0e10cSrcweir             if( (0 <= nStart) && (nStart <= nEnd) && (nEnd <= MAXCOL) )
413*cdf0e10cSrcweir                 xAccessibleTable.set( new ScAccessibleSpreadsheet( *this, ScRange( nStart, 0, mnTab, nEnd, MAXROW, mnTab ) ) );
414*cdf0e10cSrcweir         }
415*cdf0e10cSrcweir     }
416*cdf0e10cSrcweir     return xAccessibleTable;
417*cdf0e10cSrcweir }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleRows(  )
420*cdf0e10cSrcweir     				throw (uno::RuntimeException)
421*cdf0e10cSrcweir {
422*cdf0e10cSrcweir 	ScUnoGuard aGuard;
423*cdf0e10cSrcweir     IsObjectValid();
424*cdf0e10cSrcweir 	uno::Sequence<sal_Int32> aSequence;
425*cdf0e10cSrcweir 	if (mpViewShell && mpViewShell->GetViewData())
426*cdf0e10cSrcweir 	{
427*cdf0e10cSrcweir 		aSequence.realloc(maRange.aEnd.Row() - maRange.aStart.Row() + 1);
428*cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
429*cdf0e10cSrcweir 		sal_Int32* pSequence = aSequence.getArray();
430*cdf0e10cSrcweir 		sal_Int32 nCount(0);
431*cdf0e10cSrcweir 		for (SCROW i = maRange.aStart.Row(); i <= maRange.aEnd.Row(); ++i)
432*cdf0e10cSrcweir 		{
433*cdf0e10cSrcweir 			if (rMarkdata.IsRowMarked(i))
434*cdf0e10cSrcweir 			{
435*cdf0e10cSrcweir 				pSequence[nCount] = i;
436*cdf0e10cSrcweir 				++nCount;
437*cdf0e10cSrcweir 			}
438*cdf0e10cSrcweir 		}
439*cdf0e10cSrcweir 		aSequence.realloc(nCount);
440*cdf0e10cSrcweir 	}
441*cdf0e10cSrcweir 	else
442*cdf0e10cSrcweir 		aSequence.realloc(0);
443*cdf0e10cSrcweir 	return aSequence;
444*cdf0e10cSrcweir }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleSpreadsheet::getSelectedAccessibleColumns(  )
447*cdf0e10cSrcweir     				throw (uno::RuntimeException)
448*cdf0e10cSrcweir {
449*cdf0e10cSrcweir 	ScUnoGuard aGuard;
450*cdf0e10cSrcweir     IsObjectValid();
451*cdf0e10cSrcweir 	uno::Sequence<sal_Int32> aSequence;
452*cdf0e10cSrcweir 	if (mpViewShell && mpViewShell->GetViewData())
453*cdf0e10cSrcweir 	{
454*cdf0e10cSrcweir 		aSequence.realloc(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
455*cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
456*cdf0e10cSrcweir 		sal_Int32* pSequence = aSequence.getArray();
457*cdf0e10cSrcweir 		sal_Int32 nCount(0);
458*cdf0e10cSrcweir 		for (SCCOL i = maRange.aStart.Col(); i <= maRange.aEnd.Col(); ++i)
459*cdf0e10cSrcweir 		{
460*cdf0e10cSrcweir 			if (rMarkdata.IsColumnMarked(i))
461*cdf0e10cSrcweir 			{
462*cdf0e10cSrcweir 				pSequence[nCount] = i;
463*cdf0e10cSrcweir 				++nCount;
464*cdf0e10cSrcweir 			}
465*cdf0e10cSrcweir 		}
466*cdf0e10cSrcweir 		aSequence.realloc(nCount);
467*cdf0e10cSrcweir 	}
468*cdf0e10cSrcweir 	else
469*cdf0e10cSrcweir 		aSequence.realloc(0);
470*cdf0e10cSrcweir 	return aSequence;
471*cdf0e10cSrcweir }
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleRowSelected( sal_Int32 nRow )
474*cdf0e10cSrcweir     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	ScUnoGuard aGuard;
477*cdf0e10cSrcweir     IsObjectValid();
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir     if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
480*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
483*cdf0e10cSrcweir 	if (mpViewShell && mpViewShell->GetViewData())
484*cdf0e10cSrcweir 	{
485*cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
486*cdf0e10cSrcweir 		bResult = rMarkdata.IsRowMarked((SCROW)nRow);
487*cdf0e10cSrcweir 	}
488*cdf0e10cSrcweir 	return bResult;
489*cdf0e10cSrcweir }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleColumnSelected( sal_Int32 nColumn )
492*cdf0e10cSrcweir     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
493*cdf0e10cSrcweir {
494*cdf0e10cSrcweir 	ScUnoGuard aGuard;
495*cdf0e10cSrcweir     IsObjectValid();
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
498*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir     sal_Bool bResult(sal_False);
501*cdf0e10cSrcweir 	if (mpViewShell && mpViewShell->GetViewData())
502*cdf0e10cSrcweir 	{
503*cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
504*cdf0e10cSrcweir 		bResult = rMarkdata.IsColumnMarked((SCCOL)nColumn);
505*cdf0e10cSrcweir 	}
506*cdf0e10cSrcweir 	return bResult;
507*cdf0e10cSrcweir }
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir ScAccessibleCell* ScAccessibleSpreadsheet::GetAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn)
510*cdf0e10cSrcweir {
511*cdf0e10cSrcweir     ScAccessibleCell* pAccessibleCell = NULL;
512*cdf0e10cSrcweir 	ScAddress aCellAddress(static_cast<SCCOL>(maRange.aStart.Col() + nColumn),
513*cdf0e10cSrcweir 		static_cast<SCROW>(maRange.aStart.Row() + nRow), maRange.aStart.Tab());
514*cdf0e10cSrcweir     if ((aCellAddress == maActiveCell) && mpAccCell)
515*cdf0e10cSrcweir     {
516*cdf0e10cSrcweir         pAccessibleCell = mpAccCell;
517*cdf0e10cSrcweir     }
518*cdf0e10cSrcweir     else
519*cdf0e10cSrcweir 	    pAccessibleCell = new ScAccessibleCell(this, mpViewShell, aCellAddress, getAccessibleIndex(nRow, nColumn), meSplitPos, mpAccDoc);
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     return pAccessibleCell;
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
525*cdf0e10cSrcweir     				throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
526*cdf0e10cSrcweir {
527*cdf0e10cSrcweir 	ScUnoGuard aGuard;
528*cdf0e10cSrcweir     IsObjectValid();
529*cdf0e10cSrcweir     if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
530*cdf0e10cSrcweir         nRow < 0 ||
531*cdf0e10cSrcweir         nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
532*cdf0e10cSrcweir         nColumn < 0)
533*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir     uno::Reference<XAccessible> xAccessible;
536*cdf0e10cSrcweir     ScAccessibleCell* pAccessibleCell = GetAccessibleCellAt(nRow, nColumn);
537*cdf0e10cSrcweir     xAccessible = pAccessibleCell;
538*cdf0e10cSrcweir 	pAccessibleCell->Init();
539*cdf0e10cSrcweir 	return xAccessible;
540*cdf0e10cSrcweir }
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir sal_Bool SAL_CALL ScAccessibleSpreadsheet::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
543*cdf0e10cSrcweir     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
544*cdf0e10cSrcweir {
545*cdf0e10cSrcweir 	ScUnoGuard aGuard;
546*cdf0e10cSrcweir     IsObjectValid();
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
549*cdf0e10cSrcweir         (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
550*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
553*cdf0e10cSrcweir 	if (mpViewShell)
554*cdf0e10cSrcweir 	{
555*cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
556*cdf0e10cSrcweir 		bResult = rMarkdata.IsCellMarked(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow));
557*cdf0e10cSrcweir 	}
558*cdf0e10cSrcweir 	return bResult;
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir 	//=====  XAccessibleComponent  ============================================
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL ScAccessibleSpreadsheet::getAccessibleAtPoint(
564*cdf0e10cSrcweir 	const awt::Point& rPoint )
565*cdf0e10cSrcweir 		throw (uno::RuntimeException)
566*cdf0e10cSrcweir {
567*cdf0e10cSrcweir 	uno::Reference< XAccessible > xAccessible;
568*cdf0e10cSrcweir     if (containsPoint(rPoint))
569*cdf0e10cSrcweir     {
570*cdf0e10cSrcweir     	ScUnoGuard aGuard;
571*cdf0e10cSrcweir         IsObjectValid();
572*cdf0e10cSrcweir 	    if (mpViewShell)
573*cdf0e10cSrcweir 	    {
574*cdf0e10cSrcweir 		    SCsCOL nX;
575*cdf0e10cSrcweir             SCsROW nY;
576*cdf0e10cSrcweir 		    mpViewShell->GetViewData()->GetPosFromPixel( rPoint.X, rPoint.Y, meSplitPos, nX, nY);
577*cdf0e10cSrcweir 		    xAccessible = getAccessibleCellAt(nY, nX);
578*cdf0e10cSrcweir 	    }
579*cdf0e10cSrcweir     }
580*cdf0e10cSrcweir 	return xAccessible;
581*cdf0e10cSrcweir }
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir void SAL_CALL ScAccessibleSpreadsheet::grabFocus(  )
584*cdf0e10cSrcweir 		throw (uno::RuntimeException)
585*cdf0e10cSrcweir {
586*cdf0e10cSrcweir 	if (getAccessibleParent().is())
587*cdf0e10cSrcweir 	{
588*cdf0e10cSrcweir 		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
589*cdf0e10cSrcweir 		if (xAccessibleComponent.is())
590*cdf0e10cSrcweir 			xAccessibleComponent->grabFocus();
591*cdf0e10cSrcweir 	}
592*cdf0e10cSrcweir }
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getForeground(  )
595*cdf0e10cSrcweir         throw (uno::RuntimeException)
596*cdf0e10cSrcweir {
597*cdf0e10cSrcweir     return COL_BLACK;
598*cdf0e10cSrcweir }
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir sal_Int32 SAL_CALL ScAccessibleSpreadsheet::getBackground(  )
601*cdf0e10cSrcweir         throw (uno::RuntimeException)
602*cdf0e10cSrcweir {
603*cdf0e10cSrcweir     ScUnoGuard aGuard;
604*cdf0e10cSrcweir     IsObjectValid();
605*cdf0e10cSrcweir     return SC_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
606*cdf0e10cSrcweir }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir     //=====  XAccessibleContext  ==============================================
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir uno::Reference<XAccessibleRelationSet> SAL_CALL ScAccessibleSpreadsheet::getAccessibleRelationSet(void)
611*cdf0e10cSrcweir         throw (::com::sun::star::uno::RuntimeException)
612*cdf0e10cSrcweir {
613*cdf0e10cSrcweir     utl::AccessibleRelationSetHelper* pRelationSet = NULL;
614*cdf0e10cSrcweir     if(mpAccDoc)
615*cdf0e10cSrcweir         pRelationSet = mpAccDoc->GetRelationSet(NULL);
616*cdf0e10cSrcweir     if (!pRelationSet)
617*cdf0e10cSrcweir         pRelationSet = new utl::AccessibleRelationSetHelper();
618*cdf0e10cSrcweir     return pRelationSet;
619*cdf0e10cSrcweir }
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> SAL_CALL
622*cdf0e10cSrcweir 	ScAccessibleSpreadsheet::getAccessibleStateSet(void)
623*cdf0e10cSrcweir     throw (uno::RuntimeException)
624*cdf0e10cSrcweir {
625*cdf0e10cSrcweir 	ScUnoGuard aGuard;
626*cdf0e10cSrcweir 	uno::Reference<XAccessibleStateSet> xParentStates;
627*cdf0e10cSrcweir 	if (getAccessibleParent().is())
628*cdf0e10cSrcweir 	{
629*cdf0e10cSrcweir 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
630*cdf0e10cSrcweir 		xParentStates = xParentContext->getAccessibleStateSet();
631*cdf0e10cSrcweir 	}
632*cdf0e10cSrcweir 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
633*cdf0e10cSrcweir 	if (IsDefunc(xParentStates))
634*cdf0e10cSrcweir 		pStateSet->AddState(AccessibleStateType::DEFUNC);
635*cdf0e10cSrcweir     else
636*cdf0e10cSrcweir     {
637*cdf0e10cSrcweir         pStateSet->AddState(AccessibleStateType::MANAGES_DESCENDANTS);
638*cdf0e10cSrcweir 	    if (IsEditable(xParentStates))
639*cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::EDITABLE);
640*cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::ENABLED);
641*cdf0e10cSrcweir         pStateSet->AddState(AccessibleStateType::FOCUSABLE);
642*cdf0e10cSrcweir         if (IsFocused())
643*cdf0e10cSrcweir             pStateSet->AddState(AccessibleStateType::FOCUSED);
644*cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
645*cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::OPAQUE);
646*cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::SELECTABLE);
647*cdf0e10cSrcweir 	    if (IsCompleteSheetSelected())
648*cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::SELECTED);
649*cdf0e10cSrcweir 	    if (isShowing())
650*cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::SHOWING);
651*cdf0e10cSrcweir 	    if (isVisible())
652*cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
653*cdf0e10cSrcweir     }
654*cdf0e10cSrcweir 	return pStateSet;
655*cdf0e10cSrcweir }
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 	///=====  XAccessibleSelection  ===========================================
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir void SAL_CALL
660*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::selectAccessibleChild( sal_Int32 nChildIndex )
661*cdf0e10cSrcweir 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
662*cdf0e10cSrcweir {
663*cdf0e10cSrcweir 	ScUnoGuard aGuard;
664*cdf0e10cSrcweir     IsObjectValid();
665*cdf0e10cSrcweir     if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
666*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir     if (mpViewShell)
669*cdf0e10cSrcweir 	{
670*cdf0e10cSrcweir 		sal_Int32 nCol(getAccessibleColumn(nChildIndex));
671*cdf0e10cSrcweir 		sal_Int32 nRow(getAccessibleRow(nChildIndex));
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir 		SelectCell(nRow, nCol, sal_False);
674*cdf0e10cSrcweir 	}
675*cdf0e10cSrcweir }
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir void SAL_CALL
678*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::clearAccessibleSelection(  )
679*cdf0e10cSrcweir 		throw (uno::RuntimeException)
680*cdf0e10cSrcweir {
681*cdf0e10cSrcweir 	ScUnoGuard aGuard;
682*cdf0e10cSrcweir     IsObjectValid();
683*cdf0e10cSrcweir 	if (mpViewShell)
684*cdf0e10cSrcweir 	{
685*cdf0e10cSrcweir 		mpViewShell->Unmark();
686*cdf0e10cSrcweir 	}
687*cdf0e10cSrcweir }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir void SAL_CALL
690*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::selectAllAccessibleChildren(  )
691*cdf0e10cSrcweir 		throw (uno::RuntimeException)
692*cdf0e10cSrcweir {
693*cdf0e10cSrcweir 	ScUnoGuard aGuard;
694*cdf0e10cSrcweir     IsObjectValid();
695*cdf0e10cSrcweir 	if (mpViewShell)
696*cdf0e10cSrcweir 	{
697*cdf0e10cSrcweir 		mpViewShell->SelectAll();
698*cdf0e10cSrcweir 	}
699*cdf0e10cSrcweir }
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir sal_Int32 SAL_CALL
702*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::getSelectedAccessibleChildCount(  )
703*cdf0e10cSrcweir 		throw (uno::RuntimeException)
704*cdf0e10cSrcweir {
705*cdf0e10cSrcweir 	ScUnoGuard aGuard;
706*cdf0e10cSrcweir     IsObjectValid();
707*cdf0e10cSrcweir 	sal_Int32 nResult(0);
708*cdf0e10cSrcweir 	if (mpViewShell)
709*cdf0e10cSrcweir 	{
710*cdf0e10cSrcweir 		if (!mpMarkedRanges)
711*cdf0e10cSrcweir 		{
712*cdf0e10cSrcweir 			mpMarkedRanges = new ScRangeList();
713*cdf0e10cSrcweir             ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
714*cdf0e10cSrcweir             aMarkData.MarkToMulti();
715*cdf0e10cSrcweir 			aMarkData.FillRangeListWithMarks(mpMarkedRanges, sal_False);
716*cdf0e10cSrcweir 		}
717*cdf0e10cSrcweir 		// is possible, because there shouldn't be overlapped ranges in it
718*cdf0e10cSrcweir 		if (mpMarkedRanges)
719*cdf0e10cSrcweir 			nResult = mpMarkedRanges->GetCellCount();
720*cdf0e10cSrcweir 	}
721*cdf0e10cSrcweir 	return nResult;
722*cdf0e10cSrcweir }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir uno::Reference<XAccessible > SAL_CALL
725*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
726*cdf0e10cSrcweir 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
727*cdf0e10cSrcweir {
728*cdf0e10cSrcweir 	ScUnoGuard aGuard;
729*cdf0e10cSrcweir     IsObjectValid();
730*cdf0e10cSrcweir 	uno::Reference < XAccessible > xAccessible;
731*cdf0e10cSrcweir 	if (mpViewShell)
732*cdf0e10cSrcweir 	{
733*cdf0e10cSrcweir 		if (!mpMarkedRanges)
734*cdf0e10cSrcweir 		{
735*cdf0e10cSrcweir 			mpMarkedRanges = new ScRangeList();
736*cdf0e10cSrcweir 			mpViewShell->GetViewData()->GetMarkData().FillRangeListWithMarks(mpMarkedRanges, sal_False);
737*cdf0e10cSrcweir 		}
738*cdf0e10cSrcweir 		if (mpMarkedRanges)
739*cdf0e10cSrcweir 		{
740*cdf0e10cSrcweir 			if (!mpSortedMarkedCells)
741*cdf0e10cSrcweir 				CreateSortedMarkedCells();
742*cdf0e10cSrcweir 			if (mpSortedMarkedCells)
743*cdf0e10cSrcweir 			{
744*cdf0e10cSrcweir 				if ((nSelectedChildIndex < 0) ||
745*cdf0e10cSrcweir 					(mpSortedMarkedCells->size() <= static_cast<sal_uInt32>(nSelectedChildIndex)))
746*cdf0e10cSrcweir 					throw lang::IndexOutOfBoundsException();
747*cdf0e10cSrcweir 				else
748*cdf0e10cSrcweir 					xAccessible = getAccessibleCellAt((*mpSortedMarkedCells)[nSelectedChildIndex].Row(), (*mpSortedMarkedCells)[nSelectedChildIndex].Col());
749*cdf0e10cSrcweir 			}
750*cdf0e10cSrcweir 		}
751*cdf0e10cSrcweir 	}
752*cdf0e10cSrcweir 	return xAccessible;
753*cdf0e10cSrcweir }
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir void SAL_CALL
756*cdf0e10cSrcweir 		ScAccessibleSpreadsheet::deselectAccessibleChild( sal_Int32 nChildIndex )
757*cdf0e10cSrcweir 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
758*cdf0e10cSrcweir {
759*cdf0e10cSrcweir 	ScUnoGuard aGuard;
760*cdf0e10cSrcweir     IsObjectValid();
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir     if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
763*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir     if (mpViewShell)
766*cdf0e10cSrcweir 	{
767*cdf0e10cSrcweir 		sal_Int32 nCol(getAccessibleColumn(nChildIndex));
768*cdf0e10cSrcweir 		sal_Int32 nRow(getAccessibleRow(nChildIndex));
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir 		if (mpViewShell->GetViewData()->GetMarkData().IsCellMarked(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)))
771*cdf0e10cSrcweir 			SelectCell(nRow, nCol, sal_True);
772*cdf0e10cSrcweir 	}
773*cdf0e10cSrcweir }
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir void ScAccessibleSpreadsheet::SelectCell(sal_Int32 nRow, sal_Int32 nCol, sal_Bool bDeselect)
776*cdf0e10cSrcweir {
777*cdf0e10cSrcweir 	mpViewShell->SetTabNo( maRange.aStart.Tab() );
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir 	mpViewShell->DoneBlockMode( sal_True ); // continue selecting
780*cdf0e10cSrcweir 	mpViewShell->InitBlockMode( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), maRange.aStart.Tab(), bDeselect, sal_False, sal_False );
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir 	mpViewShell->SelectionChanged();
783*cdf0e10cSrcweir }
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir void ScAccessibleSpreadsheet::CreateSortedMarkedCells()
786*cdf0e10cSrcweir {
787*cdf0e10cSrcweir 	mpSortedMarkedCells = new std::vector<ScMyAddress>();
788*cdf0e10cSrcweir 	mpSortedMarkedCells->reserve(mpMarkedRanges->GetCellCount());
789*cdf0e10cSrcweir 	ScRange* pRange = mpMarkedRanges->First();
790*cdf0e10cSrcweir 	while (pRange)
791*cdf0e10cSrcweir 	{
792*cdf0e10cSrcweir 		if (pRange->aStart.Tab() != pRange->aEnd.Tab())
793*cdf0e10cSrcweir 		{
794*cdf0e10cSrcweir 			if ((maActiveCell.Tab() >= pRange->aStart.Tab()) ||
795*cdf0e10cSrcweir 				maActiveCell.Tab() <= pRange->aEnd.Tab())
796*cdf0e10cSrcweir 			{
797*cdf0e10cSrcweir 				ScRange aRange(*pRange);
798*cdf0e10cSrcweir 				aRange.aStart.SetTab(maActiveCell.Tab());
799*cdf0e10cSrcweir 				aRange.aEnd.SetTab(maActiveCell.Tab());
800*cdf0e10cSrcweir 				AddMarkedRange(aRange);
801*cdf0e10cSrcweir 			}
802*cdf0e10cSrcweir 			else
803*cdf0e10cSrcweir 			{
804*cdf0e10cSrcweir 				DBG_ERROR("Range of wrong table");
805*cdf0e10cSrcweir 			}
806*cdf0e10cSrcweir 		}
807*cdf0e10cSrcweir 		else if(pRange->aStart.Tab() == maActiveCell.Tab())
808*cdf0e10cSrcweir 			AddMarkedRange(*pRange);
809*cdf0e10cSrcweir 		else
810*cdf0e10cSrcweir 		{
811*cdf0e10cSrcweir 			DBG_ERROR("Range of wrong table");
812*cdf0e10cSrcweir 		}
813*cdf0e10cSrcweir 		pRange = mpMarkedRanges->Next();
814*cdf0e10cSrcweir 	}
815*cdf0e10cSrcweir 	std::sort(mpSortedMarkedCells->begin(), mpSortedMarkedCells->end());
816*cdf0e10cSrcweir }
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir void ScAccessibleSpreadsheet::AddMarkedRange(const ScRange& rRange)
819*cdf0e10cSrcweir {
820*cdf0e10cSrcweir 	for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
821*cdf0e10cSrcweir 	{
822*cdf0e10cSrcweir 		for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
823*cdf0e10cSrcweir 		{
824*cdf0e10cSrcweir 			ScMyAddress aCell(nCol, nRow, maActiveCell.Tab());
825*cdf0e10cSrcweir 			mpSortedMarkedCells->push_back(aCell);
826*cdf0e10cSrcweir 		}
827*cdf0e10cSrcweir 	}
828*cdf0e10cSrcweir }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir 	//=====  XServiceInfo  ====================================================
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir ::rtl::OUString SAL_CALL ScAccessibleSpreadsheet::getImplementationName(void)
833*cdf0e10cSrcweir         throw (uno::RuntimeException)
834*cdf0e10cSrcweir {
835*cdf0e10cSrcweir 	return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleSpreadsheet"));
836*cdf0e10cSrcweir }
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> SAL_CALL
839*cdf0e10cSrcweir 	ScAccessibleSpreadsheet::getSupportedServiceNames (void)
840*cdf0e10cSrcweir         throw (uno::RuntimeException)
841*cdf0e10cSrcweir {
842*cdf0e10cSrcweir 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleTableBase::getSupportedServiceNames();
843*cdf0e10cSrcweir     sal_Int32 nOldSize(aSequence.getLength());
844*cdf0e10cSrcweir     aSequence.realloc(nOldSize + 1);
845*cdf0e10cSrcweir     ::rtl::OUString* pNames = aSequence.getArray();
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheet"));
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir 	return aSequence;
850*cdf0e10cSrcweir }
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir //=====  XTypeProvider  =======================================================
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir uno::Sequence<sal_Int8> SAL_CALL
855*cdf0e10cSrcweir 	ScAccessibleSpreadsheet::getImplementationId(void)
856*cdf0e10cSrcweir     throw (uno::RuntimeException)
857*cdf0e10cSrcweir {
858*cdf0e10cSrcweir     ScUnoGuard aGuard;
859*cdf0e10cSrcweir     IsObjectValid();
860*cdf0e10cSrcweir 	static uno::Sequence<sal_Int8> aId;
861*cdf0e10cSrcweir 	if (aId.getLength() == 0)
862*cdf0e10cSrcweir 	{
863*cdf0e10cSrcweir 		aId.realloc (16);
864*cdf0e10cSrcweir 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
865*cdf0e10cSrcweir 	}
866*cdf0e10cSrcweir 	return aId;
867*cdf0e10cSrcweir }
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir ///=====  XAccessibleEventBroadcaster  =====================================
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir void SAL_CALL ScAccessibleSpreadsheet::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
872*cdf0e10cSrcweir         throw (uno::RuntimeException)
873*cdf0e10cSrcweir {
874*cdf0e10cSrcweir     ScUnoGuard aGuard;
875*cdf0e10cSrcweir     IsObjectValid();
876*cdf0e10cSrcweir     ScAccessibleTableBase::addEventListener(xListener);
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir     if (!mbIsFocusSend)
879*cdf0e10cSrcweir     {
880*cdf0e10cSrcweir         mbIsFocusSend = sal_True;
881*cdf0e10cSrcweir         CommitFocusGained();
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir 		AccessibleEventObject aEvent;
884*cdf0e10cSrcweir 		aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED;
885*cdf0e10cSrcweir 		aEvent.Source = uno::Reference< XAccessibleContext >(this);
886*cdf0e10cSrcweir 		aEvent.NewValue <<= getAccessibleCellAt(maActiveCell.Row(), maActiveCell.Col());
887*cdf0e10cSrcweir 
888*cdf0e10cSrcweir 		CommitChange(aEvent);
889*cdf0e10cSrcweir     }
890*cdf0e10cSrcweir }
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir 	//====  internal  =========================================================
893*cdf0e10cSrcweir 
894*cdf0e10cSrcweir Rectangle ScAccessibleSpreadsheet::GetBoundingBoxOnScreen() const
895*cdf0e10cSrcweir 	throw (uno::RuntimeException)
896*cdf0e10cSrcweir {
897*cdf0e10cSrcweir 	Rectangle aRect;
898*cdf0e10cSrcweir 	if (mpViewShell)
899*cdf0e10cSrcweir 	{
900*cdf0e10cSrcweir 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
901*cdf0e10cSrcweir 		if (pWindow)
902*cdf0e10cSrcweir 			aRect = pWindow->GetWindowExtentsRelative(NULL);
903*cdf0e10cSrcweir 	}
904*cdf0e10cSrcweir 	return aRect;
905*cdf0e10cSrcweir }
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir Rectangle ScAccessibleSpreadsheet::GetBoundingBox() const
908*cdf0e10cSrcweir 	throw (uno::RuntimeException)
909*cdf0e10cSrcweir {
910*cdf0e10cSrcweir 	Rectangle aRect;
911*cdf0e10cSrcweir 	if (mpViewShell)
912*cdf0e10cSrcweir 	{
913*cdf0e10cSrcweir 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
914*cdf0e10cSrcweir 		if (pWindow)
915*cdf0e10cSrcweir             //#101986#; extends to the same window, because the parent is the document and it has the same window
916*cdf0e10cSrcweir 			aRect = pWindow->GetWindowExtentsRelative(pWindow);
917*cdf0e10cSrcweir 	}
918*cdf0e10cSrcweir 	return aRect;
919*cdf0e10cSrcweir }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir sal_Bool ScAccessibleSpreadsheet::IsDefunc(
922*cdf0e10cSrcweir 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
923*cdf0e10cSrcweir {
924*cdf0e10cSrcweir 	return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
925*cdf0e10cSrcweir 		(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
926*cdf0e10cSrcweir }
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir sal_Bool ScAccessibleSpreadsheet::IsEditable(
929*cdf0e10cSrcweir     const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
930*cdf0e10cSrcweir {
931*cdf0e10cSrcweir 	sal_Bool bProtected(sal_False);
932*cdf0e10cSrcweir 	if (mpDoc && mpDoc->IsTabProtected(maRange.aStart.Tab()))
933*cdf0e10cSrcweir 		bProtected = sal_True;
934*cdf0e10cSrcweir 	return !bProtected;
935*cdf0e10cSrcweir }
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir sal_Bool ScAccessibleSpreadsheet::IsFocused()
938*cdf0e10cSrcweir {
939*cdf0e10cSrcweir     sal_Bool bFocused(sal_False);
940*cdf0e10cSrcweir     if (mpViewShell)
941*cdf0e10cSrcweir     {
942*cdf0e10cSrcweir         if (mpViewShell->GetViewData()->GetActivePart() == meSplitPos)
943*cdf0e10cSrcweir             bFocused = mpViewShell->GetActiveWin()->HasFocus();
944*cdf0e10cSrcweir     }
945*cdf0e10cSrcweir     return bFocused;
946*cdf0e10cSrcweir }
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir sal_Bool ScAccessibleSpreadsheet::IsCompleteSheetSelected()
949*cdf0e10cSrcweir {
950*cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
951*cdf0e10cSrcweir 	if(mpViewShell)
952*cdf0e10cSrcweir 	{
953*cdf0e10cSrcweir         //#103800#; use a copy of MarkData
954*cdf0e10cSrcweir         ScMarkData aMarkData(mpViewShell->GetViewData()->GetMarkData());
955*cdf0e10cSrcweir 		aMarkData.MarkToMulti();
956*cdf0e10cSrcweir 		if (aMarkData.IsAllMarked(maRange))
957*cdf0e10cSrcweir 			bResult = sal_True;
958*cdf0e10cSrcweir 	}
959*cdf0e10cSrcweir 	return bResult;
960*cdf0e10cSrcweir }
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir ScDocument* ScAccessibleSpreadsheet::GetDocument(ScTabViewShell* pViewShell)
963*cdf0e10cSrcweir {
964*cdf0e10cSrcweir 	ScDocument* pDoc = NULL;
965*cdf0e10cSrcweir 	if (pViewShell)
966*cdf0e10cSrcweir 		pDoc = pViewShell->GetViewData()->GetDocument();
967*cdf0e10cSrcweir 	return pDoc;
968*cdf0e10cSrcweir }
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir Rectangle ScAccessibleSpreadsheet::GetVisArea(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
971*cdf0e10cSrcweir {
972*cdf0e10cSrcweir 	Rectangle aVisArea;
973*cdf0e10cSrcweir 	if (pViewShell)
974*cdf0e10cSrcweir 	{
975*cdf0e10cSrcweir 		Window* pWindow = pViewShell->GetWindowByPos(eSplitPos);
976*cdf0e10cSrcweir 		if (pWindow)
977*cdf0e10cSrcweir 		{
978*cdf0e10cSrcweir 			aVisArea.SetPos(pViewShell->GetViewData()->GetPixPos(eSplitPos));
979*cdf0e10cSrcweir 			aVisArea.SetSize(pWindow->GetSizePixel());
980*cdf0e10cSrcweir 		}
981*cdf0e10cSrcweir 	}
982*cdf0e10cSrcweir 	return aVisArea;
983*cdf0e10cSrcweir }
984*cdf0e10cSrcweir 
985*cdf0e10cSrcweir Rectangle ScAccessibleSpreadsheet::GetVisCells(const Rectangle& rVisArea)
986*cdf0e10cSrcweir {
987*cdf0e10cSrcweir 	if (mpViewShell)
988*cdf0e10cSrcweir 	{
989*cdf0e10cSrcweir         SCsCOL nStartX, nEndX;
990*cdf0e10cSrcweir         SCsROW nStartY, nEndY;
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir 		mpViewShell->GetViewData()->GetPosFromPixel( 1, 1, meSplitPos, nStartX, nStartY);
993*cdf0e10cSrcweir 		mpViewShell->GetViewData()->GetPosFromPixel( rVisArea.GetWidth(), rVisArea.GetHeight(), meSplitPos, nEndX, nEndY);
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir 		return Rectangle(nStartX, nStartY, nEndX, nEndY);
996*cdf0e10cSrcweir 	}
997*cdf0e10cSrcweir 	else
998*cdf0e10cSrcweir 		return Rectangle();
999*cdf0e10cSrcweir }
1000