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