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