1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19b3f79822SAndrew Rist  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "AccessibleCell.hxx"
29cdf0e10cSrcweir #include "scitems.hxx"
30cdf0e10cSrcweir #include <editeng/eeitem.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "AccessibleText.hxx"
34cdf0e10cSrcweir #include "AccessibleDocument.hxx"
35cdf0e10cSrcweir #include "tabvwsh.hxx"
36cdf0e10cSrcweir #include "document.hxx"
37cdf0e10cSrcweir #include "attrib.hxx"
38cdf0e10cSrcweir #include "miscuno.hxx"
39cdf0e10cSrcweir #include "unoguard.hxx"
40cdf0e10cSrcweir #include "editsrc.hxx"
41cdf0e10cSrcweir #include "dociter.hxx"
42cdf0e10cSrcweir #include "cell.hxx"
43*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
44*0deba7fbSSteve Yin #include "validat.hxx"
45*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
46cdf0e10cSrcweir #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
47cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
50cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
51cdf0e10cSrcweir #endif
52cdf0e10cSrcweir #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
53cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
54cdf0e10cSrcweir #endif
55cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
56cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleTable.hpp>
57cdf0e10cSrcweir #include <rtl/uuid.h>
58cdf0e10cSrcweir #include <tools/debug.hxx>
59cdf0e10cSrcweir #include <editeng/brshitem.hxx>
60cdf0e10cSrcweir #include <comphelper/sequence.hxx>
61cdf0e10cSrcweir #include <float.h>
62cdf0e10cSrcweir 
63*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
64*0deba7fbSSteve Yin #include "AccessibleSpreadsheet.hxx"
65*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
66cdf0e10cSrcweir using namespace	::com::sun::star;
67cdf0e10cSrcweir using namespace	::com::sun::star::accessibility;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir //=====  internal  ============================================================
70cdf0e10cSrcweir 
71cdf0e10cSrcweir ScAccessibleCell::ScAccessibleCell(
72cdf0e10cSrcweir         const uno::Reference<XAccessible>& rxParent,
73cdf0e10cSrcweir 		ScTabViewShell* pViewShell,
74cdf0e10cSrcweir 		ScAddress& rCellAddress,
75cdf0e10cSrcweir 		sal_Int32 nIndex,
76cdf0e10cSrcweir 		ScSplitPos eSplitPos,
77cdf0e10cSrcweir         ScAccessibleDocument* pAccDoc)
78cdf0e10cSrcweir 	:
79cdf0e10cSrcweir 	ScAccessibleCellBase(rxParent, GetDocument(pViewShell), rCellAddress, nIndex),
80cdf0e10cSrcweir         ::accessibility::AccessibleStaticTextBase(CreateEditSource(pViewShell, rCellAddress, eSplitPos)),
81cdf0e10cSrcweir 	mpViewShell(pViewShell),
82cdf0e10cSrcweir     mpAccDoc(pAccDoc),
83cdf0e10cSrcweir 	meSplitPos(eSplitPos)
84cdf0e10cSrcweir {
85cdf0e10cSrcweir 	if (pViewShell)
86cdf0e10cSrcweir 		pViewShell->AddAccessibilityObject(*this);
87cdf0e10cSrcweir }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir ScAccessibleCell::~ScAccessibleCell()
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
92cdf0e10cSrcweir 	{
93cdf0e10cSrcweir 		// increment refcount to prevent double call off dtor
94cdf0e10cSrcweir 		osl_incrementInterlockedCount( &m_refCount );
95cdf0e10cSrcweir 		// call dispose to inform object wich have a weak reference to this object
96cdf0e10cSrcweir 		dispose();
97cdf0e10cSrcweir 	}
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir void ScAccessibleCell::Init()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     ScAccessibleCellBase::Init();
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     SetEventSource(this);
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir void SAL_CALL ScAccessibleCell::disposing()
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     ScUnoGuard aGuard;
110cdf0e10cSrcweir     // #100593# dispose in AccessibleStaticTextBase
111cdf0e10cSrcweir     Dispose();
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 	if (mpViewShell)
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir 		mpViewShell->RemoveAccessibilityObject(*this);
116cdf0e10cSrcweir 		mpViewShell = NULL;
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir     mpAccDoc = NULL;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     ScAccessibleCellBase::disposing();
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 	//=====  XInterface  =====================================================
124cdf0e10cSrcweir 
125*0deba7fbSSteve Yin IMPLEMENT_FORWARD_XINTERFACE3( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase, ScAccessibleCellAttributeImpl )
126cdf0e10cSrcweir 
127cdf0e10cSrcweir     //=====  XTypeProvider  ===================================================
128cdf0e10cSrcweir 
129*0deba7fbSSteve Yin IMPLEMENT_FORWARD_XTYPEPROVIDER3( ScAccessibleCell, ScAccessibleCellBase, AccessibleStaticTextBase, ScAccessibleCellAttributeImpl )
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 	//=====  XAccessibleComponent  ============================================
132cdf0e10cSrcweir 
133cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL ScAccessibleCell::getAccessibleAtPoint(
134cdf0e10cSrcweir 		const awt::Point& rPoint )
135cdf0e10cSrcweir 		throw (uno::RuntimeException)
136cdf0e10cSrcweir {
137cdf0e10cSrcweir     return AccessibleStaticTextBase::getAccessibleAtPoint(rPoint);
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir void SAL_CALL ScAccessibleCell::grabFocus(  )
141cdf0e10cSrcweir 		throw (uno::RuntimeException)
142cdf0e10cSrcweir {
143cdf0e10cSrcweir  	ScUnoGuard aGuard;
144cdf0e10cSrcweir     IsObjectValid();
145cdf0e10cSrcweir 	if (getAccessibleParent().is() && mpViewShell)
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
148cdf0e10cSrcweir 		if (xAccessibleComponent.is())
149cdf0e10cSrcweir 		{
150cdf0e10cSrcweir 			xAccessibleComponent->grabFocus();
151cdf0e10cSrcweir 			mpViewShell->SetCursor(maCellAddress.Col(), maCellAddress.Row());
152cdf0e10cSrcweir 		}
153cdf0e10cSrcweir 	}
154cdf0e10cSrcweir }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir Rectangle ScAccessibleCell::GetBoundingBoxOnScreen(void) const
157cdf0e10cSrcweir 		throw (uno::RuntimeException)
158cdf0e10cSrcweir {
159cdf0e10cSrcweir 	Rectangle aCellRect(GetBoundingBox());
160cdf0e10cSrcweir 	if (mpViewShell)
161cdf0e10cSrcweir 	{
162cdf0e10cSrcweir 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
163cdf0e10cSrcweir 		if (pWindow)
164cdf0e10cSrcweir 		{
165cdf0e10cSrcweir 			Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
166cdf0e10cSrcweir 			aCellRect.setX(aCellRect.getX() + aRect.getX());
167cdf0e10cSrcweir 			aCellRect.setY(aCellRect.getY() + aRect.getY());
168cdf0e10cSrcweir 		}
169cdf0e10cSrcweir 	}
170cdf0e10cSrcweir 	return aCellRect;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir Rectangle ScAccessibleCell::GetBoundingBox(void) const
174cdf0e10cSrcweir 		throw (uno::RuntimeException)
175cdf0e10cSrcweir {
176cdf0e10cSrcweir 	Rectangle aCellRect;
177cdf0e10cSrcweir 	if (mpViewShell)
178cdf0e10cSrcweir 	{
179cdf0e10cSrcweir 		long nSizeX, nSizeY;
180cdf0e10cSrcweir 		mpViewShell->GetViewData()->GetMergeSizePixel(
181cdf0e10cSrcweir 			maCellAddress.Col(), maCellAddress.Row(), nSizeX, nSizeY);
182cdf0e10cSrcweir 		aCellRect.SetSize(Size(nSizeX, nSizeY));
183cdf0e10cSrcweir 		aCellRect.SetPos(mpViewShell->GetViewData()->GetScrPos(maCellAddress.Col(), maCellAddress.Row(), meSplitPos, sal_True));
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 		Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
186cdf0e10cSrcweir 		if (pWindow)
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			Rectangle aRect(pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow()));
189cdf0e10cSrcweir 			aRect.Move(-aRect.Left(), -aRect.Top());
190cdf0e10cSrcweir 			aCellRect = aRect.Intersection(aCellRect);
191cdf0e10cSrcweir 		}
192cdf0e10cSrcweir 
193cdf0e10cSrcweir         /*  #i19430# Gnopernicus reads text partly if it sticks out of the cell
194cdf0e10cSrcweir             boundaries. This leads to wrong results in cases where the cell
195cdf0e10cSrcweir             text is rotated, because rotation is not taken into account when
196cdf0e10cSrcweir             calculating the visible part of the text. In these cases we will
197cdf0e10cSrcweir             simply expand the cell size to the width of the unrotated text. */
198cdf0e10cSrcweir         if (mpDoc)
199cdf0e10cSrcweir         {
200cdf0e10cSrcweir             const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >(
201cdf0e10cSrcweir                 mpDoc->GetAttr( maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_ROTATE_VALUE ) );
202cdf0e10cSrcweir             if( pItem && (pItem->GetValue() != 0) )
203cdf0e10cSrcweir             {
204cdf0e10cSrcweir                 Rectangle aParaRect = GetParagraphBoundingBox();
205cdf0e10cSrcweir                 if( !aParaRect.IsEmpty() && (aCellRect.GetWidth() < aParaRect.GetWidth()) )
206cdf0e10cSrcweir                     aCellRect.SetSize( Size( aParaRect.GetWidth(), aCellRect.GetHeight() ) );
207cdf0e10cSrcweir             }
208cdf0e10cSrcweir         }
209cdf0e10cSrcweir 	}
210cdf0e10cSrcweir     if (aCellRect.IsEmpty())
211cdf0e10cSrcweir         aCellRect.SetPos(Point(-1, -1));
212cdf0e10cSrcweir 	return aCellRect;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	//=====  XAccessibleContext  ==============================================
216cdf0e10cSrcweir 
217cdf0e10cSrcweir sal_Int32 SAL_CALL
218cdf0e10cSrcweir 	ScAccessibleCell::getAccessibleChildCount(void)
219cdf0e10cSrcweir     				throw (uno::RuntimeException)
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     return AccessibleStaticTextBase::getAccessibleChildCount();
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir uno::Reference< XAccessible > SAL_CALL
225cdf0e10cSrcweir 	ScAccessibleCell::getAccessibleChild(sal_Int32 nIndex)
226cdf0e10cSrcweir         throw (uno::RuntimeException,
227cdf0e10cSrcweir 		lang::IndexOutOfBoundsException)
228cdf0e10cSrcweir {
229cdf0e10cSrcweir     return AccessibleStaticTextBase::getAccessibleChild(nIndex);
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> SAL_CALL
233cdf0e10cSrcweir 	ScAccessibleCell::getAccessibleStateSet(void)
234cdf0e10cSrcweir     throw (uno::RuntimeException)
235cdf0e10cSrcweir {
236cdf0e10cSrcweir 	ScUnoGuard aGuard;
237cdf0e10cSrcweir 	uno::Reference<XAccessibleStateSet> xParentStates;
238cdf0e10cSrcweir 	if (getAccessibleParent().is())
239cdf0e10cSrcweir 	{
240cdf0e10cSrcweir 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
241cdf0e10cSrcweir 		xParentStates = xParentContext->getAccessibleStateSet();
242cdf0e10cSrcweir 	}
243cdf0e10cSrcweir 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
244cdf0e10cSrcweir 	if (IsDefunc(xParentStates))
245cdf0e10cSrcweir 		pStateSet->AddState(AccessibleStateType::DEFUNC);
246cdf0e10cSrcweir     else
247cdf0e10cSrcweir     {
248*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
249*0deba7fbSSteve Yin 		if (IsFormulaMode())
250*0deba7fbSSteve Yin 		{
251*0deba7fbSSteve Yin 			pStateSet->AddState(AccessibleStateType::ENABLED);
252*0deba7fbSSteve Yin 		    pStateSet->AddState(AccessibleStateType::MULTI_LINE);
253*0deba7fbSSteve Yin 			pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
254*0deba7fbSSteve Yin 			if (IsOpaque(xParentStates))
255*0deba7fbSSteve Yin 				pStateSet->AddState(AccessibleStateType::OPAQUE);
256*0deba7fbSSteve Yin 			pStateSet->AddState(AccessibleStateType::SELECTABLE);
257*0deba7fbSSteve Yin 			if (IsSelected())
258*0deba7fbSSteve Yin 				pStateSet->AddState(AccessibleStateType::SELECTED);
259*0deba7fbSSteve Yin 			if (isShowing())
260*0deba7fbSSteve Yin 				pStateSet->AddState(AccessibleStateType::SHOWING);
261*0deba7fbSSteve Yin 			pStateSet->AddState(AccessibleStateType::TRANSIENT);
262*0deba7fbSSteve Yin 			if (isVisible())
263*0deba7fbSSteve Yin 				pStateSet->AddState(AccessibleStateType::VISIBLE);
264*0deba7fbSSteve Yin 			return pStateSet;
265*0deba7fbSSteve Yin 		}
266*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
267cdf0e10cSrcweir 	    if (IsEditable(xParentStates))
268cdf0e10cSrcweir 	    {
269cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::EDITABLE);
270cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::RESIZABLE);
271cdf0e10cSrcweir 	    }
272cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::ENABLED);
273cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::MULTI_LINE);
274cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
275*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
276*0deba7fbSSteve Yin 	    pStateSet->AddState(AccessibleStateType::FOCUSABLE);
277*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
278cdf0e10cSrcweir 	    if (IsOpaque(xParentStates))
279cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::OPAQUE);
280cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::SELECTABLE);
281cdf0e10cSrcweir 	    if (IsSelected())
282cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::SELECTED);
283cdf0e10cSrcweir 	    if (isShowing())
284cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::SHOWING);
285cdf0e10cSrcweir 	    pStateSet->AddState(AccessibleStateType::TRANSIENT);
286cdf0e10cSrcweir 	    if (isVisible())
287cdf0e10cSrcweir 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
288cdf0e10cSrcweir     }
289cdf0e10cSrcweir 	return pStateSet;
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir uno::Reference<XAccessibleRelationSet> SAL_CALL
293cdf0e10cSrcweir    	ScAccessibleCell::getAccessibleRelationSet(void)
294cdf0e10cSrcweir     throw (uno::RuntimeException)
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	ScUnoGuard aGuard;
297cdf0e10cSrcweir     IsObjectValid();
298cdf0e10cSrcweir     utl::AccessibleRelationSetHelper* pRelationSet = NULL;
299cdf0e10cSrcweir     if (mpAccDoc)
300cdf0e10cSrcweir         pRelationSet = mpAccDoc->GetRelationSet(&maCellAddress);
301cdf0e10cSrcweir     if (!pRelationSet)
302cdf0e10cSrcweir 	    pRelationSet = new utl::AccessibleRelationSetHelper();
303cdf0e10cSrcweir 	FillDependends(pRelationSet);
304cdf0e10cSrcweir 	FillPrecedents(pRelationSet);
305cdf0e10cSrcweir 	return pRelationSet;
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 	//=====  XServiceInfo  ====================================================
309cdf0e10cSrcweir 
310cdf0e10cSrcweir ::rtl::OUString SAL_CALL ScAccessibleCell::getImplementationName(void)
311cdf0e10cSrcweir         throw (uno::RuntimeException)
312cdf0e10cSrcweir {
313cdf0e10cSrcweir 	return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCell"));
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> SAL_CALL
317cdf0e10cSrcweir 	ScAccessibleCell::getSupportedServiceNames(void)
318cdf0e10cSrcweir         throw (uno::RuntimeException)
319cdf0e10cSrcweir {
320cdf0e10cSrcweir 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
321cdf0e10cSrcweir     sal_Int32 nOldSize(aSequence.getLength());
322cdf0e10cSrcweir     aSequence.realloc(nOldSize + 1);
323cdf0e10cSrcweir     ::rtl::OUString* pNames = aSequence.getArray();
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessibleCell"));
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 	return aSequence;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 	//====  internal  =========================================================
331cdf0e10cSrcweir 
332cdf0e10cSrcweir sal_Bool ScAccessibleCell::IsDefunc(
333cdf0e10cSrcweir 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
334cdf0e10cSrcweir {
335cdf0e10cSrcweir 	return ScAccessibleContextBase::IsDefunc() || (mpDoc == NULL) || (mpViewShell == NULL) || !getAccessibleParent().is() ||
336cdf0e10cSrcweir 		 (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir sal_Bool ScAccessibleCell::IsEditable(
340cdf0e10cSrcweir 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
341cdf0e10cSrcweir {
342cdf0e10cSrcweir 	sal_Bool bEditable(sal_True);
343cdf0e10cSrcweir 	if (rxParentStates.is() && !rxParentStates->contains(AccessibleStateType::EDITABLE) &&
344cdf0e10cSrcweir 		mpDoc)
345cdf0e10cSrcweir 	{
346cdf0e10cSrcweir 		// here I have to test whether the protection of the table should influence this cell.
347cdf0e10cSrcweir 		const ScProtectionAttr* pItem = (const ScProtectionAttr*)mpDoc->GetAttr(
348cdf0e10cSrcweir 			maCellAddress.Col(), maCellAddress.Row(),
349cdf0e10cSrcweir 			maCellAddress.Tab(), ATTR_PROTECTION);
350cdf0e10cSrcweir 		if (pItem)
351cdf0e10cSrcweir 			bEditable = !pItem->GetProtection();
352cdf0e10cSrcweir 	}
353cdf0e10cSrcweir 	return bEditable;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir sal_Bool ScAccessibleCell::IsOpaque(
357cdf0e10cSrcweir     const uno::Reference<XAccessibleStateSet>& /* rxParentStates */)
358cdf0e10cSrcweir {
359cdf0e10cSrcweir 	// test whether there is a background color
360cdf0e10cSrcweir 	sal_Bool bOpaque(sal_True);
361cdf0e10cSrcweir 	if (mpDoc)
362cdf0e10cSrcweir 	{
363cdf0e10cSrcweir 		const SvxBrushItem* pItem = (const SvxBrushItem*)mpDoc->GetAttr(
364cdf0e10cSrcweir 			maCellAddress.Col(), maCellAddress.Row(),
365cdf0e10cSrcweir 			maCellAddress.Tab(), ATTR_BACKGROUND);
366cdf0e10cSrcweir 		if (pItem)
367cdf0e10cSrcweir 			bOpaque = pItem->GetColor() != COL_TRANSPARENT;
368cdf0e10cSrcweir 	}
369cdf0e10cSrcweir 	return bOpaque;
370cdf0e10cSrcweir }
371cdf0e10cSrcweir 
372cdf0e10cSrcweir sal_Bool ScAccessibleCell::IsSelected()
373cdf0e10cSrcweir {
374*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
375*0deba7fbSSteve Yin 	if (IsFormulaMode())
376*0deba7fbSSteve Yin 	{
377*0deba7fbSSteve Yin 		const ScAccessibleSpreadsheet *pSheet =static_cast<const ScAccessibleSpreadsheet*>(mxParent.get());
378*0deba7fbSSteve Yin 		if (pSheet)
379*0deba7fbSSteve Yin 		{
380*0deba7fbSSteve Yin 			return pSheet->IsScAddrFormulaSel(maCellAddress);
381*0deba7fbSSteve Yin 		}
382*0deba7fbSSteve Yin 		return sal_False;
383*0deba7fbSSteve Yin 	}
384*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
385cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
386cdf0e10cSrcweir 	if (mpViewShell && mpViewShell->GetViewData())
387cdf0e10cSrcweir 	{
388cdf0e10cSrcweir 		const ScMarkData& rMarkdata = mpViewShell->GetViewData()->GetMarkData();
389cdf0e10cSrcweir 		bResult = rMarkdata.IsCellMarked(maCellAddress.Col(), maCellAddress.Row());
390cdf0e10cSrcweir 	}
391cdf0e10cSrcweir 	return bResult;
392cdf0e10cSrcweir }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir ScDocument* ScAccessibleCell::GetDocument(ScTabViewShell* pViewShell)
395cdf0e10cSrcweir {
396cdf0e10cSrcweir 	ScDocument* pDoc = NULL;
397cdf0e10cSrcweir 	if (pViewShell && pViewShell->GetViewData())
398cdf0e10cSrcweir 		pDoc = pViewShell->GetViewData()->GetDocument();
399cdf0e10cSrcweir 	return pDoc;
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir ::std::auto_ptr< SvxEditSource > ScAccessibleCell::CreateEditSource(ScTabViewShell* pViewShell, ScAddress aCell, ScSplitPos eSplitPos)
403cdf0e10cSrcweir {
404*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
405*0deba7fbSSteve Yin 	if (IsFormulaMode())
406*0deba7fbSSteve Yin 	{
407*0deba7fbSSteve Yin 		return ::std::auto_ptr< SvxEditSource >();
408*0deba7fbSSteve Yin 	}
409*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
410cdf0e10cSrcweir 	::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData
411cdf0e10cSrcweir         ( new ScAccessibleCellTextData( pViewShell, aCell, eSplitPos, this ) );
412cdf0e10cSrcweir 	::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleCellTextData));
413cdf0e10cSrcweir 
414cdf0e10cSrcweir     return pEditSource;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir void ScAccessibleCell::FillDependends(utl::AccessibleRelationSetHelper* pRelationSet)
418cdf0e10cSrcweir {
419cdf0e10cSrcweir 	if (mpDoc)
420cdf0e10cSrcweir 	{
421cdf0e10cSrcweir 		ScCellIterator aCellIter( mpDoc, 0,0, maCellAddress.Tab(), MAXCOL,MAXROW, maCellAddress.Tab() );
422cdf0e10cSrcweir 		ScBaseCell* pCell = aCellIter.GetFirst();
423cdf0e10cSrcweir 		while (pCell)
424cdf0e10cSrcweir 		{
425cdf0e10cSrcweir 			if (pCell->GetCellType() == CELLTYPE_FORMULA)
426cdf0e10cSrcweir 			{
427cdf0e10cSrcweir 				sal_Bool bFound(sal_False);
428cdf0e10cSrcweir 				ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
429cdf0e10cSrcweir                 ScRange aRef;
430cdf0e10cSrcweir 				while ( !bFound && aIter.GetNextRef( aRef ) )
431cdf0e10cSrcweir 				{
432cdf0e10cSrcweir 					if (aRef.In(maCellAddress))
433cdf0e10cSrcweir 						bFound = sal_True;
434cdf0e10cSrcweir 				}
435cdf0e10cSrcweir 				if (bFound)
436cdf0e10cSrcweir 					AddRelation(ScAddress(aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab()), AccessibleRelationType::CONTROLLER_FOR, pRelationSet);
437cdf0e10cSrcweir 			}
438cdf0e10cSrcweir 			pCell = aCellIter.GetNext();
439cdf0e10cSrcweir 		}
440cdf0e10cSrcweir 	}
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir void ScAccessibleCell::FillPrecedents(utl::AccessibleRelationSetHelper* pRelationSet)
444cdf0e10cSrcweir {
445cdf0e10cSrcweir 	if (mpDoc)
446cdf0e10cSrcweir 	{
447cdf0e10cSrcweir 		ScBaseCell* pBaseCell = mpDoc->GetCell(maCellAddress);
448cdf0e10cSrcweir 		if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_FORMULA))
449cdf0e10cSrcweir 		{
450cdf0e10cSrcweir 			ScFormulaCell* pFCell = (ScFormulaCell*) pBaseCell;
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 			ScDetectiveRefIter aIter( pFCell );
453cdf0e10cSrcweir             ScRange aRef;
454cdf0e10cSrcweir 			while ( aIter.GetNextRef( aRef ) )
455cdf0e10cSrcweir 			{
456cdf0e10cSrcweir 				AddRelation( aRef, AccessibleRelationType::CONTROLLED_BY, pRelationSet);
457cdf0e10cSrcweir 			}
458cdf0e10cSrcweir 		}
459cdf0e10cSrcweir 	}
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir void ScAccessibleCell::AddRelation(const ScAddress& rCell,
463cdf0e10cSrcweir 	const sal_uInt16 aRelationType,
464cdf0e10cSrcweir 	utl::AccessibleRelationSetHelper* pRelationSet)
465cdf0e10cSrcweir {
466cdf0e10cSrcweir 	AddRelation(ScRange(rCell, rCell), aRelationType, pRelationSet);
467cdf0e10cSrcweir }
468cdf0e10cSrcweir 
469cdf0e10cSrcweir void ScAccessibleCell::AddRelation(const ScRange& rRange,
470cdf0e10cSrcweir 	const sal_uInt16 aRelationType,
471cdf0e10cSrcweir 	utl::AccessibleRelationSetHelper* pRelationSet)
472cdf0e10cSrcweir {
473cdf0e10cSrcweir 	uno::Reference < XAccessibleTable > xTable ( getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY );
474cdf0e10cSrcweir 	if (xTable.is())
475cdf0e10cSrcweir 	{
476cdf0e10cSrcweir         sal_uInt32 nCount(static_cast<sal_uInt32>(rRange.aEnd.Col() -
477cdf0e10cSrcweir                     rRange.aStart.Col() + 1) * (rRange.aEnd.Row() -
478cdf0e10cSrcweir                     rRange.aStart.Row() + 1));
479cdf0e10cSrcweir 		uno::Sequence < uno::Reference < uno::XInterface > > aTargetSet( nCount );
480cdf0e10cSrcweir 		uno::Reference < uno::XInterface >* pTargetSet = aTargetSet.getArray();
481cdf0e10cSrcweir 		if (pTargetSet)
482cdf0e10cSrcweir 		{
483cdf0e10cSrcweir 			sal_uInt32 nPos(0);
484cdf0e10cSrcweir             for (sal_uInt32 nRow = rRange.aStart.Row(); nRow <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Row()); ++nRow)
485cdf0e10cSrcweir 			{
486cdf0e10cSrcweir                 for (sal_uInt32 nCol = rRange.aStart.Col(); nCol <= sal::static_int_cast<sal_uInt32>(rRange.aEnd.Col()); ++nCol)
487cdf0e10cSrcweir 				{
488cdf0e10cSrcweir 					pTargetSet[nPos] = xTable->getAccessibleCellAt(nRow, nCol);
489cdf0e10cSrcweir 					++nPos;
490cdf0e10cSrcweir 				}
491cdf0e10cSrcweir 			}
492cdf0e10cSrcweir 			DBG_ASSERT(nCount == nPos, "something wents wrong");
493cdf0e10cSrcweir 		}
494cdf0e10cSrcweir 		AccessibleRelation aRelation;
495cdf0e10cSrcweir 		aRelation.RelationType = aRelationType;
496cdf0e10cSrcweir 		aRelation.TargetSet = aTargetSet;
497cdf0e10cSrcweir 		pRelationSet->AddRelation(aRelation);
498cdf0e10cSrcweir 	}
499cdf0e10cSrcweir }
500*0deba7fbSSteve Yin //IAccessibility2 Implementation 2009-----
501*0deba7fbSSteve Yin ::rtl::OUString ReplaceOneChar(::rtl::OUString oldOUString, ::rtl::OUString replacedChar, ::rtl::OUString replaceStr)
502*0deba7fbSSteve Yin {
503*0deba7fbSSteve Yin 	int iReplace = -1;
504*0deba7fbSSteve Yin 	iReplace = oldOUString.lastIndexOf(replacedChar);
505*0deba7fbSSteve Yin 	if (iReplace > -1)
506*0deba7fbSSteve Yin 	{
507*0deba7fbSSteve Yin 		for(;iReplace>-1;)
508*0deba7fbSSteve Yin 		{
509*0deba7fbSSteve Yin 			oldOUString = oldOUString.replaceAt(iReplace,1, replaceStr);
510*0deba7fbSSteve Yin 			iReplace=oldOUString.lastIndexOf(replacedChar,iReplace);
511*0deba7fbSSteve Yin 		}
512*0deba7fbSSteve Yin 	}
513*0deba7fbSSteve Yin 	return oldOUString;
514*0deba7fbSSteve Yin }
515*0deba7fbSSteve Yin ::rtl::OUString ReplaceFourChar(::rtl::OUString oldOUString)
516*0deba7fbSSteve Yin {
517*0deba7fbSSteve Yin 	oldOUString = ReplaceOneChar(oldOUString,::rtl::OUString::createFromAscii("\\"),::rtl::OUString::createFromAscii("\\\\"));
518*0deba7fbSSteve Yin 	oldOUString = ReplaceOneChar(oldOUString,::rtl::OUString::createFromAscii(";"),::rtl::OUString::createFromAscii("\\;"));
519*0deba7fbSSteve Yin 	oldOUString = ReplaceOneChar(oldOUString,::rtl::OUString::createFromAscii("="),::rtl::OUString::createFromAscii("\\="));
520*0deba7fbSSteve Yin 	oldOUString = ReplaceOneChar(oldOUString,::rtl::OUString::createFromAscii(","),::rtl::OUString::createFromAscii("\\,"));
521*0deba7fbSSteve Yin 	oldOUString = ReplaceOneChar(oldOUString,::rtl::OUString::createFromAscii(":"),::rtl::OUString::createFromAscii("\\:"));
522*0deba7fbSSteve Yin 	return oldOUString;
523*0deba7fbSSteve Yin }
524*0deba7fbSSteve Yin 
525*0deba7fbSSteve Yin uno::Any SAL_CALL ScAccessibleCell::getExtendedAttributes()
526*0deba7fbSSteve Yin 		throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
527*0deba7fbSSteve Yin {
528*0deba7fbSSteve Yin 	uno::Any strRet;
529*0deba7fbSSteve Yin 	if (mpViewShell)
530*0deba7fbSSteve Yin 	{
531*0deba7fbSSteve Yin 		const ::rtl::OUString strAttr(::rtl::OUString::createFromAscii(":"));
532*0deba7fbSSteve Yin 		const ::rtl::OUString strSplit(::rtl::OUString::createFromAscii(";"));
533*0deba7fbSSteve Yin 		::rtl::OUString strFor = mpViewShell->GetFormula(maCellAddress) ;
534*0deba7fbSSteve Yin 		strFor = strFor.replaceAt(0,1,::rtl::OUString::createFromAscii(""));
535*0deba7fbSSteve Yin 		strFor = ReplaceFourChar(strFor);
536*0deba7fbSSteve Yin 		strFor =::rtl::OUString::createFromAscii("Formula:") + strFor;
537*0deba7fbSSteve Yin 		strFor +=strSplit;
538*0deba7fbSSteve Yin 		strFor +=::rtl::OUString::createFromAscii("Note:");
539*0deba7fbSSteve Yin 		strFor +=ReplaceFourChar(GetAllDisplayNote());
540*0deba7fbSSteve Yin 		strFor +=strSplit;
541*0deba7fbSSteve Yin 		strFor += getShadowAttrs();//the string returned contains the spliter ";"
542*0deba7fbSSteve Yin 		strFor += getBorderAttrs();//the string returned contains the spliter ";"
543*0deba7fbSSteve Yin 		//end of cell attributes
544*0deba7fbSSteve Yin 		if( mpDoc )
545*0deba7fbSSteve Yin 		{
546*0deba7fbSSteve Yin 			strFor += ::rtl::OUString::createFromAscii("isdropdown:");
547*0deba7fbSSteve Yin 			if( IsDropdown() )
548*0deba7fbSSteve Yin 				strFor+= ::rtl::OUString::createFromAscii("true");
549*0deba7fbSSteve Yin 			else
550*0deba7fbSSteve Yin 				strFor+= ::rtl::OUString::createFromAscii("false");
551*0deba7fbSSteve Yin 			strFor += ::rtl::OUString::createFromAscii(";");
552*0deba7fbSSteve Yin 		}
553*0deba7fbSSteve Yin 		strRet <<= strFor ;
554*0deba7fbSSteve Yin 	}
555*0deba7fbSSteve Yin 	return strRet;
556*0deba7fbSSteve Yin }
557*0deba7fbSSteve Yin 
558*0deba7fbSSteve Yin // cell has its own ParaIndent property, so when calling character attributes on cell, the ParaIndent should replace the ParaLeftMargin if its value is not zero.
559*0deba7fbSSteve Yin uno::Sequence< beans::PropertyValue > SAL_CALL ScAccessibleCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
560*0deba7fbSSteve Yin {
561*0deba7fbSSteve Yin 	uno::Sequence< beans::PropertyValue > aAttribs = AccessibleStaticTextBase::getCharacterAttributes( nIndex, aRequestedAttributes );
562*0deba7fbSSteve Yin 	beans::PropertyValue *pAttribs = aAttribs.getArray();
563*0deba7fbSSteve Yin 
564*0deba7fbSSteve Yin 	sal_uInt16 nParaIndent = static_cast< const SfxUInt16Item* >( mpDoc->GetAttr( maCellAddress.Col(), maCellAddress.Row(), maCellAddress.Tab(), ATTR_INDENT ) )->GetValue();
565*0deba7fbSSteve Yin 	if (nParaIndent > 0)
566*0deba7fbSSteve Yin 	{
567*0deba7fbSSteve Yin 		::rtl::OUString sLeftMarginName (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLeftMargin")));
568*0deba7fbSSteve Yin 		for (int i = 0; i < aAttribs.getLength(); ++i)
569*0deba7fbSSteve Yin 		{
570*0deba7fbSSteve Yin 			if (sLeftMarginName == pAttribs[i].Name)
571*0deba7fbSSteve Yin 			{
572*0deba7fbSSteve Yin 				pAttribs[i].Value = uno::makeAny( nParaIndent );
573*0deba7fbSSteve Yin 				break;
574*0deba7fbSSteve Yin 			}
575*0deba7fbSSteve Yin 		}
576*0deba7fbSSteve Yin 	}
577*0deba7fbSSteve Yin 	return aAttribs;
578*0deba7fbSSteve Yin }
579*0deba7fbSSteve Yin 
580*0deba7fbSSteve Yin sal_Bool ScAccessibleCell::IsFormulaMode()
581*0deba7fbSSteve Yin {
582*0deba7fbSSteve Yin 	ScAccessibleSpreadsheet* pSheet =static_cast<ScAccessibleSpreadsheet*>(mxParent.get());
583*0deba7fbSSteve Yin 	if (pSheet)
584*0deba7fbSSteve Yin 	{
585*0deba7fbSSteve Yin 		return pSheet->IsFormulaMode();
586*0deba7fbSSteve Yin 	}
587*0deba7fbSSteve Yin 	return sal_False;
588*0deba7fbSSteve Yin }
589*0deba7fbSSteve Yin sal_Bool ScAccessibleCell::IsDropdown()
590*0deba7fbSSteve Yin {
591*0deba7fbSSteve Yin 	sal_uInt16 nPosX = maCellAddress.Col();
592*0deba7fbSSteve Yin 	sal_uInt16 nPosY = sal_uInt16(maCellAddress.Row());
593*0deba7fbSSteve Yin 	sal_uInt16 nTab = maCellAddress.Tab();
594*0deba7fbSSteve Yin 	//IAccessibility2 Implementation 2009-----
595*0deba7fbSSteve Yin 	sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( mpDoc->GetAttr( nPosX, nPosY, nTab, ATTR_VALIDDATA ) )->GetValue();
596*0deba7fbSSteve Yin     if( nValidation )
597*0deba7fbSSteve Yin     {
598*0deba7fbSSteve Yin         const ScValidationData* pData = mpDoc->GetValidationEntry( nValidation );
599*0deba7fbSSteve Yin         if( pData && pData->HasSelectionList() )
600*0deba7fbSSteve Yin             return sal_True;
601*0deba7fbSSteve Yin     }
602*0deba7fbSSteve Yin 	//-----IAccessibility2 Implementation 2009
603*0deba7fbSSteve Yin 	ScMergeFlagAttr* pAttr;
604*0deba7fbSSteve Yin 	pAttr = (ScMergeFlagAttr*)mpDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
605*0deba7fbSSteve Yin 	if( pAttr->HasAutoFilter() )
606*0deba7fbSSteve Yin 	{
607*0deba7fbSSteve Yin 		return sal_True;
608*0deba7fbSSteve Yin 	}
609*0deba7fbSSteve Yin 	else
610*0deba7fbSSteve Yin 	{
611*0deba7fbSSteve Yin 		sal_uInt16 nTabCount = mpDoc->GetTableCount();
612*0deba7fbSSteve Yin 		if ( nTab+1<nTabCount && mpDoc->IsScenario(nTab+1) && !mpDoc->IsScenario(nTab) )
613*0deba7fbSSteve Yin 		{
614*0deba7fbSSteve Yin 			sal_uInt16 i;
615*0deba7fbSSteve Yin 			ScMarkData aMarks;
616*0deba7fbSSteve Yin 			for (i=nTab+1; i<nTabCount && mpDoc->IsScenario(i); i++)
617*0deba7fbSSteve Yin 				mpDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
618*0deba7fbSSteve Yin 			ScRangeList aRanges;
619*0deba7fbSSteve Yin 			aMarks.FillRangeListWithMarks( &aRanges, sal_False );
620*0deba7fbSSteve Yin 			sal_Bool bHasScenario;
621*0deba7fbSSteve Yin 			sal_uInt16 nRangeCount = (sal_uInt16)aRanges.Count();
622*0deba7fbSSteve Yin 			for (i=0; i<nRangeCount; i++)
623*0deba7fbSSteve Yin 			{
624*0deba7fbSSteve Yin 				ScRange aRange = *aRanges.GetObject(i);
625*0deba7fbSSteve Yin 				mpDoc->ExtendTotalMerge( aRange );
626*0deba7fbSSteve Yin 				sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
627*0deba7fbSSteve Yin 				// MT IA2: Not used: sal_Bool bIsInScen = sal_False;
628*0deba7fbSSteve Yin 				if ( bTextBelow )
629*0deba7fbSSteve Yin 				{
630*0deba7fbSSteve Yin 					bHasScenario = (aRange.aStart.Col() == nPosX && aRange.aEnd.Row() == nPosY-1);
631*0deba7fbSSteve Yin 				}
632*0deba7fbSSteve Yin 				else
633*0deba7fbSSteve Yin 				{
634*0deba7fbSSteve Yin 					bHasScenario = (aRange.aStart.Col() == nPosX && aRange.aStart.Row() == nPosY+1);
635*0deba7fbSSteve Yin 				}
636*0deba7fbSSteve Yin 				if( bHasScenario ) return sal_True;
637*0deba7fbSSteve Yin 			}
638*0deba7fbSSteve Yin 		}
639*0deba7fbSSteve Yin 	}
640*0deba7fbSSteve Yin 	return sal_False;
641*0deba7fbSSteve Yin }
642*0deba7fbSSteve Yin //-----IAccessibility2 Implementation 2009
643