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 "AccessibleCellBase.hxx"
29 #include "attrib.hxx"
30 #include "scitems.hxx"
31 #include "miscuno.hxx"
32 #include "document.hxx"
33 #include "docfunc.hxx"
34 #include "cell.hxx"
35 #include "unoguard.hxx"
36 #include "scresid.hxx"
37 #ifndef SC_SC_HRC
38 #include "sc.hrc"
39 #endif
40 #include "unonames.hxx"
41 //IAccessibility2 Implementation 2009-----
42 #include "detfunc.hxx"
43 #include "chgtrack.hxx"
44 //-----IAccessibility2 Implementation 2009
45 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
46 #include <com/sun/star/accessibility/AccessibleRole.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
49 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
50 #endif
51 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
52 #include <com/sun/star/sheet/XSpreadsheet.hpp>
53 #include <tools/debug.hxx>
54 #include <editeng/brshitem.hxx>
55 #include <rtl/uuid.h>
56 #include <comphelper/sequence.hxx>
57 #include <sfx2/objsh.hxx>
58 //IAccessibility2 Implementation 2009-----
59 #include <com/sun/star/sheet/XSheetAnnotation.hpp>
60 #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
61 #include <com/sun/star/text/XSimpleText.hpp>
62 //-----IAccessibility2 Implementation 2009
63 
64 #include <float.h>
65 
66 using namespace	::com::sun::star;
67 using namespace	::com::sun::star::accessibility;
68 
69 //=====  internal  ============================================================
70 
71 ScAccessibleCellBase::ScAccessibleCellBase(
72         const uno::Reference<XAccessible>& rxParent,
73 		ScDocument* pDoc,
74 		const ScAddress& rCellAddress,
75 		sal_Int32 nIndex)
76 	:
77 	ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
78 	maCellAddress(rCellAddress),
79 	mpDoc(pDoc),
80 	mnIndex(nIndex)
81 {
82 }
83 
84 ScAccessibleCellBase::~ScAccessibleCellBase()
85 {
86 }
87 
88 	//=====  XAccessibleComponent  ============================================
89 
90 sal_Bool SAL_CALL ScAccessibleCellBase::isVisible(  )
91 		throw (uno::RuntimeException)
92 {
93  	ScUnoGuard aGuard;
94     IsObjectValid();
95 	// test whether the cell is hidden (column/row - hidden/filtered)
96 	sal_Bool bVisible(sal_True);
97 	if (mpDoc)
98 	{
99         bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab());
100         bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab());
101         bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab());
102         bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab());
103 
104         if (bColHidden || bColFiltered || bRowHidden || bRowFiltered)
105 			bVisible = sal_False;
106 	}
107 	return bVisible;
108 }
109 
110 sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
111     throw (uno::RuntimeException)
112 {
113     ScUnoGuard aGuard;
114     IsObjectValid();
115     sal_Int32 nColor(0);
116     if (mpDoc)
117     {
118         SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
119         if ( pObjSh )
120         {
121             uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
122             if ( xSpreadDoc.is() )
123             {
124                 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
125                 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
126                 if ( xIndex.is() )
127                 {
128                     uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
129                     uno::Reference<sheet::XSpreadsheet> xTable;
130                     if (aTable>>=xTable)
131                     {
132                         uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
133                         if (xCell.is())
134                         {
135                             uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
136                             if (xCellProps.is())
137                             {
138                                 uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR)));
139                                 aAny >>= nColor;
140                             }
141                         }
142                     }
143                 }
144             }
145         }
146     }
147     return nColor;
148 }
149 
150 sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
151     throw (uno::RuntimeException)
152 {
153     ScUnoGuard aGuard;
154     IsObjectValid();
155     sal_Int32 nColor(0);
156 
157     if (mpDoc)
158     {
159         SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
160         if ( pObjSh )
161         {
162             uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
163             if ( xSpreadDoc.is() )
164             {
165                 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
166                 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
167                 if ( xIndex.is() )
168                 {
169                     uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
170                     uno::Reference<sheet::XSpreadsheet> xTable;
171                     if (aTable>>=xTable)
172                     {
173                         uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
174                         if (xCell.is())
175                         {
176                             uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
177                             if (xCellProps.is())
178                             {
179                                 uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK)));
180                                 aAny >>= nColor;
181                             }
182                         }
183                     }
184                 }
185             }
186         }
187     }
188 
189     return nColor;
190 }
191 
192 	//=====  XInterface  =====================================================
193 
194 uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType )
195 	throw (uno::RuntimeException)
196 {
197 	uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType));
198 	return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
199 }
200 
201 void SAL_CALL ScAccessibleCellBase::acquire()
202 	throw ()
203 {
204 	ScAccessibleContextBase::acquire();
205 }
206 
207 void SAL_CALL ScAccessibleCellBase::release()
208 	throw ()
209 {
210 	ScAccessibleContextBase::release();
211 }
212 
213 	//=====  XAccessibleContext  ==============================================
214 
215 sal_Int32
216 	ScAccessibleCellBase::getAccessibleIndexInParent(void)
217         throw (uno::RuntimeException)
218 {
219 	ScUnoGuard aGuard;
220     IsObjectValid();
221 	return mnIndex;
222 }
223 
224 ::rtl::OUString SAL_CALL
225     ScAccessibleCellBase::createAccessibleDescription(void)
226     throw (uno::RuntimeException)
227 {
228 	rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR));
229 
230 	return sDescription;
231 }
232 
233 ::rtl::OUString SAL_CALL
234     ScAccessibleCellBase::createAccessibleName(void)
235     throw (uno::RuntimeException)
236 {
237 //IAccessibility2 Implementation 2009-----
238 	//String sName( ScResId(STR_ACC_CELL_NAME) );
239 	String sAddress;
240 	// Document not needed, because only the cell address, but not the tablename is needed
241 	// always us OOO notation
242 	maCellAddress.Format( sAddress, SCA_VALID, NULL );
243 	//sName.SearchAndReplaceAscii("%1", sAddress);
244     /*  #i65103# ZoomText merges cell address and contents, e.g. if value 2 is
245         contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2".
246         Simple solution: Append a space character to the cell address. */
247     //sName.Append( ' ' );
248     //return rtl::OUString(sName);
249     return rtl::OUString(sAddress);
250 //-----IAccessibility2 Implementation 2009
251 }
252 
253 	//=====  XAccessibleValue  ================================================
254 
255 uno::Any SAL_CALL
256 	ScAccessibleCellBase::getCurrentValue(  )
257 	throw (uno::RuntimeException)
258 {
259  	ScUnoGuard aGuard;
260     IsObjectValid();
261 	uno::Any aAny;
262 	if (mpDoc)
263 //IAccessibility2 Implementation 2009-----
264 		//aAny <<= mpDoc->GetValue(maCellAddress);
265 	{
266 		String valStr;
267 		mpDoc->GetString(maCellAddress.Col(),maCellAddress.Row(),maCellAddress.Tab(), valStr);
268 		aAny <<= rtl::OUString(valStr);
269 	}
270 //-----IAccessibility2 Implementation 2009
271 	return aAny;
272 }
273 
274 sal_Bool SAL_CALL
275 	ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
276 	throw (uno::RuntimeException)
277 {
278  	ScUnoGuard aGuard;
279     IsObjectValid();
280 	double fValue = 0;
281 	sal_Bool bResult(sal_False);
282 	if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell())
283 	{
284 		uno::Reference<XAccessibleStateSet> xParentStates;
285 		if (getAccessibleParent().is())
286 		{
287 			uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
288 			xParentStates = xParentContext->getAccessibleStateSet();
289 		}
290 		if (IsEditable(xParentStates))
291 		{
292 			ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell();
293 			ScDocFunc aFunc(*pDocShell);
294 			bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), sal_True );
295 		}
296 	}
297 	return bResult;
298 }
299 
300 uno::Any SAL_CALL
301 	ScAccessibleCellBase::getMaximumValue(  )
302 	throw (uno::RuntimeException)
303 {
304 	uno::Any aAny;
305 	aAny <<= DBL_MAX;
306 
307 	return aAny;
308 }
309 
310 uno::Any SAL_CALL
311 	ScAccessibleCellBase::getMinimumValue(  )
312 	throw (uno::RuntimeException)
313 {
314 	uno::Any aAny;
315 	aAny <<= -DBL_MAX;
316 
317 	return aAny;
318 }
319 
320 	//=====  XServiceInfo  ====================================================
321 
322 ::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void)
323         throw (uno::RuntimeException)
324 {
325 	return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase"));
326 }
327 
328 	//=====  XTypeProvider  ===================================================
329 
330 uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes()
331 		throw (uno::RuntimeException)
332 {
333 	return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
334 }
335 
336 uno::Sequence<sal_Int8> SAL_CALL
337 	ScAccessibleCellBase::getImplementationId(void)
338     throw (uno::RuntimeException)
339 {
340     ScUnoGuard aGuard;
341     IsObjectValid();
342 	static uno::Sequence<sal_Int8> aId;
343 	if (aId.getLength() == 0)
344 	{
345 		aId.realloc (16);
346 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
347 	}
348 	return aId;
349 }
350 
351 sal_Bool ScAccessibleCellBase::IsEditable(
352 	const uno::Reference<XAccessibleStateSet>& rxParentStates)
353 {
354 	sal_Bool bEditable(sal_False);
355 	if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE))
356 		bEditable = sal_True;
357 	return bEditable;
358 }
359 //IAccessibility2 Implementation 2009-----
360 ::rtl::OUString SAL_CALL ScAccessibleCellBase::GetNote(void)
361 								throw (::com::sun::star::uno::RuntimeException)
362 {
363 	ScUnoGuard aGuard;
364     IsObjectValid();
365     rtl::OUString msNote;
366     if (mpDoc)
367     {
368         SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
369         if ( pObjSh )
370         {
371             uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
372             if ( xSpreadDoc.is() )
373             {
374                 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
375                 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
376                 if ( xIndex.is() )
377                 {
378                     uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
379                     uno::Reference<sheet::XSpreadsheet> xTable;
380                     if (aTable>>=xTable)
381                     {
382                         uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
383                         if (xCell.is())
384                         {
385 							uno::Reference <sheet::XSheetAnnotationAnchor> xAnnotationAnchor ( xCell, uno::UNO_QUERY);
386 							if(xAnnotationAnchor.is())
387 							{
388 								uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation = xAnnotationAnchor->getAnnotation();
389 								if (xSheetAnnotation.is())
390 								{
391 									uno::Reference <text::XSimpleText> xText (xSheetAnnotation, uno::UNO_QUERY);
392 									if (xText.is())
393 									{
394 										msNote = xText->getString();
395 									}
396 								}
397 							}
398                         }
399                     }
400                 }
401             }
402         }
403     }
404 	return msNote;
405 }
406 #ifndef _COM_SUN_STAR_TABLE_SHADOWFORMAT_HPP_
407 #include <com/sun/star/table/ShadowFormat.hpp>
408 #endif
409 ::rtl::OUString SAL_CALL ScAccessibleCellBase::getShadowAttrs(void)
410 										throw (::com::sun::star::uno::RuntimeException)
411 {
412 	ScUnoGuard aGuard;
413 	IsObjectValid();
414 	table::ShadowFormat aShadowFmt;
415 	if (mpDoc)
416 	{
417 		SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
418 		if ( pObjSh )
419 		{
420 			uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
421 			if ( xSpreadDoc.is() )
422 			{
423 				uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
424 				uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
425 				if ( xIndex.is() )
426 				{
427 					uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
428 					uno::Reference<sheet::XSpreadsheet> xTable;
429 					if (aTable>>=xTable)
430 					{
431 						uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
432 						if (xCell.is())
433 						{
434 							uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
435 							if (xCellProps.is())
436 							{
437 								uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHADOW)));
438 								aAny >>= aShadowFmt;
439 							}
440 						}
441 					}
442 				}
443 			}
444 		}
445 	}
446 	//construct shadow attributes string
447 	rtl::OUString sShadowAttrs( RTL_CONSTASCII_USTRINGPARAM("Shadow:") );
448 	rtl::OUString sInnerSplit( RTL_CONSTASCII_USTRINGPARAM(",") );
449 	rtl::OUString sOuterSplit( RTL_CONSTASCII_USTRINGPARAM(";") );
450 	sal_Int32 nLocationVal = 0;
451 	switch( aShadowFmt.Location )
452 	{
453 	case table::ShadowLocation_TOP_LEFT:
454 		nLocationVal = 1;
455 		break;
456 	case table::ShadowLocation_TOP_RIGHT:
457 		nLocationVal = 2;
458 		break;
459 	case table::ShadowLocation_BOTTOM_LEFT:
460 		nLocationVal = 3;
461 		break;
462 	case table::ShadowLocation_BOTTOM_RIGHT:
463 		nLocationVal = 4;
464 		break;
465 	default:
466 		break;
467 	}
468 	//if there is no shadow property for the cell
469 	if ( nLocationVal == 0 )
470 	{
471 		sShadowAttrs += sOuterSplit;
472 		return sShadowAttrs;
473 	}
474 	//else return all the shadow properties
475 	sShadowAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Location=") );
476 	sShadowAttrs += rtl::OUString::valueOf( (sal_Int32)nLocationVal );
477 	sShadowAttrs += sInnerSplit;
478 	sShadowAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ShadowWidth=") );
479 	sShadowAttrs += rtl::OUString::valueOf( (sal_Int32)aShadowFmt.ShadowWidth ) ;
480 	sShadowAttrs += sInnerSplit;
481 	sShadowAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IsTransparent=") );
482 	sShadowAttrs += rtl::OUString::valueOf( (sal_Bool)aShadowFmt.IsTransparent ) ;
483 	sShadowAttrs += sInnerSplit;
484 	sShadowAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Color=") );
485 	sShadowAttrs += rtl::OUString::valueOf( (sal_Int32)aShadowFmt.Color );
486 	sShadowAttrs += sOuterSplit;
487 	return sShadowAttrs;
488 }
489 #ifndef _COM_SUN_STAR_TABLE_BORDERLINE_HPP_
490 #include <com/sun/star/table/BorderLine.hpp>
491 #endif
492 ::rtl::OUString SAL_CALL ScAccessibleCellBase::getBorderAttrs(void)
493 										throw (::com::sun::star::uno::RuntimeException)
494 {
495 	ScUnoGuard aGuard;
496 	IsObjectValid();
497 	table::BorderLine aTopBorder;
498 	table::BorderLine aBottomBorder;
499 	table::BorderLine aLeftBorder;
500 	table::BorderLine aRightBorder;
501 	if (mpDoc)
502 	{
503 		SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
504 		if ( pObjSh )
505 		{
506 			uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
507 			if ( xSpreadDoc.is() )
508 			{
509 				uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
510 				uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
511 				if ( xIndex.is() )
512 				{
513 					uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
514 					uno::Reference<sheet::XSpreadsheet> xTable;
515 					if (aTable>>=xTable)
516 					{
517 						uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
518 						if (xCell.is())
519 						{
520 							uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
521 							if (xCellProps.is())
522 							{
523 								uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TOPBORDER)));
524 								aAny >>= aTopBorder;
525 								aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BOTTBORDER)));
526 								aAny >>= aBottomBorder;
527 								aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LEFTBORDER)));
528 								aAny >>= aLeftBorder;
529 								aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_RIGHTBORDER)));
530 								aAny >>= aRightBorder;
531 							}
532 						}
533 					}
534 				}
535 			}
536 		}
537 	}
538 
539 	Color aColor;
540 	sal_Bool bIn = mpDoc ? mpDoc->IsCellInChangeTrack(maCellAddress,&aColor) : sal_False;
541 	if (bIn)
542 	{
543 		aTopBorder.Color = aColor.GetColor();
544 		aBottomBorder.Color = aColor.GetColor();
545 		aLeftBorder.Color = aColor.GetColor();
546 		aRightBorder.Color = aColor.GetColor();
547 		aTopBorder.OuterLineWidth =2;
548 		aBottomBorder.OuterLineWidth =2;
549 		aLeftBorder.OuterLineWidth =2;
550 		aRightBorder.OuterLineWidth =2;
551 	}
552 
553 	//construct border attributes string
554 	rtl::OUString sBorderAttrs;
555 	rtl::OUString sInnerSplit( RTL_CONSTASCII_USTRINGPARAM(",") );
556 	rtl::OUString sOuterSplit( RTL_CONSTASCII_USTRINGPARAM(";") );
557 	//top border
558 	//if top of the cell has no border
559 	if ( aTopBorder.InnerLineWidth == 0 && aTopBorder.OuterLineWidth == 0 )
560 	{
561 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TopBorder:;") );
562 	}
563 	else//add all the border properties to the return string.
564 	{
565 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("TopBorder:Color=") );
566 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aTopBorder.Color );
567 		sBorderAttrs += sInnerSplit;
568 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("InnerLineWidth=") );
569 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aTopBorder.InnerLineWidth );
570 		sBorderAttrs += sInnerSplit;
571 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OuterLineWidth=") );
572 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aTopBorder.OuterLineWidth );
573 		sBorderAttrs += sInnerSplit;
574 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineDistance=") );
575 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aTopBorder.LineDistance );
576 		sBorderAttrs += sOuterSplit;
577 	}
578 	//bottom border
579 	if ( aBottomBorder.InnerLineWidth == 0 && aBottomBorder.OuterLineWidth == 0 )
580 	{
581 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BottomBorde:;") );
582 	}
583 	else
584 	{
585 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BottomBorder:Color=") );
586 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aBottomBorder.Color );
587 		sBorderAttrs += sInnerSplit;
588 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("InnerLineWidth=") );
589 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aBottomBorder.InnerLineWidth );
590 		sBorderAttrs += sInnerSplit;
591 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OuterLineWidth=") );
592 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aBottomBorder.OuterLineWidth );
593 		sBorderAttrs += sInnerSplit;
594 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineDistance=") );
595 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aBottomBorder.LineDistance );
596 		sBorderAttrs += sOuterSplit;
597 	}
598 	//left border
599 	if ( aLeftBorder.InnerLineWidth == 0 && aLeftBorder.OuterLineWidth == 0 )
600 	{
601 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LeftBorder:;") );
602 	}
603 	else
604 	{
605 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LeftBorder:Color=") );
606 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aLeftBorder.Color );
607 		sBorderAttrs += sInnerSplit;
608 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("InnerLineWidth=") );
609 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aLeftBorder.InnerLineWidth );
610 		sBorderAttrs += sInnerSplit;
611 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OuterLineWidth=") );
612 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aLeftBorder.OuterLineWidth );
613 		sBorderAttrs += sInnerSplit;
614 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineDistance=") );
615 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aLeftBorder.LineDistance );
616 		sBorderAttrs += sOuterSplit;
617 	}
618 	//right border
619 	if ( aRightBorder.InnerLineWidth == 0 && aRightBorder.OuterLineWidth == 0 )
620 	{
621 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightBorder:;") );
622 	}
623 	else
624 	{
625 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("RightBorder:Color=") );
626 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aRightBorder.Color );
627 		sBorderAttrs += sInnerSplit;
628 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("InnerLineWidth=") );
629 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aRightBorder.InnerLineWidth );
630 		sBorderAttrs += sInnerSplit;
631 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OuterLineWidth=") );
632 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aRightBorder.OuterLineWidth );
633 		sBorderAttrs += sInnerSplit;
634 		sBorderAttrs += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineDistance=") );
635 		sBorderAttrs += rtl::OUString::valueOf( (sal_Int32)aRightBorder.LineDistance );
636 		sBorderAttrs += sOuterSplit;
637 	}
638 	return sBorderAttrs;
639 }
640 //end of cell attributes
641 
642 ::rtl::OUString SAL_CALL ScAccessibleCellBase::GetAllDisplayNote(void)
643 	throw (::com::sun::star::uno::RuntimeException)
644 {
645 	::rtl::OUString strNote;
646 	String strTrackText;
647 	if (mpDoc)
648 	{
649 		sal_Bool bLeftedge=sal_False;
650 		mpDoc->GetCellChangeTrackNote(maCellAddress,strTrackText,bLeftedge);
651 	}
652 	if (strTrackText.Len() > 0 )
653 	{
654 		ScDetectiveFunc::AppendChangTrackNoteSeparator(strTrackText);
655 		strNote = strTrackText;
656 	}
657 	strNote += GetNote();
658 	return strNote;
659 }
660 //-----IAccessibility2 Implementation 2009
661