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