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