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