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