1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <AccessibleCellBase.hxx>
21 #include <document.hxx>
22 #include <docfunc.hxx>
24 #include <strings.hxx>
25 #include <unonames.hxx>
26 #include <detfunc.hxx>
28 #include <com/sun/star/accessibility/AccessibleRole.hpp>
29 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
30 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
31 #include <com/sun/star/sheet/XSpreadsheet.hpp>
32 #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
33 #include <com/sun/star/text/XSimpleText.hpp>
34 #include <com/sun/star/table/BorderLine.hpp>
35 #include <com/sun/star/table/ShadowFormat.hpp>
36 #include <comphelper/sequence.hxx>
37 #include <sfx2/objsh.hxx>
38 #include <vcl/svapp.hxx>
42 using namespace ::com::sun::star
;
43 using namespace ::com::sun::star::accessibility
;
45 #define DEFAULT_LINE_WIDTH 2
47 //===== internal ============================================================
49 ScAccessibleCellBase::ScAccessibleCellBase(
50 const uno::Reference
<XAccessible
>& rxParent
,
52 const ScAddress
& rCellAddress
,
55 ScAccessibleContextBase(rxParent
, AccessibleRole::TABLE_CELL
),
56 maCellAddress(rCellAddress
),
62 ScAccessibleCellBase::~ScAccessibleCellBase()
66 //===== XAccessibleComponent ============================================
68 bool ScAccessibleCellBase::isVisible()
70 SolarMutexGuard aGuard
;
72 // test whether the cell is hidden (column/row - hidden/filtered)
76 bool bColHidden
= mpDoc
->ColHidden(maCellAddress
.Col(), maCellAddress
.Tab());
77 bool bRowHidden
= mpDoc
->RowHidden(maCellAddress
.Row(), maCellAddress
.Tab());
78 bool bColFiltered
= mpDoc
->ColFiltered(maCellAddress
.Col(), maCellAddress
.Tab());
79 bool bRowFiltered
= mpDoc
->RowFiltered(maCellAddress
.Row(), maCellAddress
.Tab());
81 if (bColHidden
|| bColFiltered
|| bRowHidden
|| bRowFiltered
)
87 sal_Int32 SAL_CALL
ScAccessibleCellBase::getForeground()
89 SolarMutexGuard aGuard
;
94 ScDocShell
* pObjSh
= mpDoc
->GetDocumentShell();
97 ScModelObj
* pSpreadDoc
= pObjSh
->GetModel();
100 uno::Reference
<sheet::XSpreadsheets
> xSheets
= pSpreadDoc
->getSheets();
101 uno::Reference
<container::XIndexAccess
> xIndex( xSheets
, uno::UNO_QUERY
);
104 uno::Any aTable
= xIndex
->getByIndex(maCellAddress
.Tab());
105 uno::Reference
<sheet::XSpreadsheet
> xTable
;
108 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByPosition(maCellAddress
.Col(), maCellAddress
.Row());
111 uno::Reference
<beans::XPropertySet
> xCellProps(xCell
, uno::UNO_QUERY
);
114 uno::Any aAny
= xCellProps
->getPropertyValue(SC_UNONAME_CCOLOR
);
126 sal_Int32 SAL_CALL
ScAccessibleCellBase::getBackground()
128 SolarMutexGuard aGuard
;
134 ScDocShell
* pObjSh
= mpDoc
->GetDocumentShell();
137 ScModelObj
* pSpreadDoc
= pObjSh
->GetModel();
140 uno::Reference
<sheet::XSpreadsheets
> xSheets
= pSpreadDoc
->getSheets();
141 uno::Reference
<container::XIndexAccess
> xIndex( xSheets
, uno::UNO_QUERY
);
144 uno::Any aTable
= xIndex
->getByIndex(maCellAddress
.Tab());
145 uno::Reference
<sheet::XSpreadsheet
> xTable
;
148 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByPosition(maCellAddress
.Col(), maCellAddress
.Row());
151 uno::Reference
<beans::XPropertySet
> xCellProps(xCell
, uno::UNO_QUERY
);
154 uno::Any aAny
= xCellProps
->getPropertyValue(SC_UNONAME_CELLBACK
);
167 //===== XInterface =====================================================
169 uno::Any SAL_CALL
ScAccessibleCellBase::queryInterface( uno::Type
const & rType
)
171 uno::Any
aAny (ScAccessibleCellBaseImpl::queryInterface(rType
));
172 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
175 void SAL_CALL
ScAccessibleCellBase::acquire()
178 ScAccessibleContextBase::acquire();
181 void SAL_CALL
ScAccessibleCellBase::release()
184 ScAccessibleContextBase::release();
187 //===== XAccessibleContext ==============================================
190 ScAccessibleCellBase::getAccessibleIndexInParent()
192 SolarMutexGuard aGuard
;
198 ScAccessibleCellBase::createAccessibleDescription()
200 return STR_ACC_CELL_DESCR
;
204 ScAccessibleCellBase::createAccessibleName()
206 // Document not needed, because only the cell address, but not the tablename is needed
207 // always us OOO notation
208 return maCellAddress
.Format(ScRefFlags::VALID
);
211 //===== XAccessibleValue ================================================
214 ScAccessibleCellBase::getCurrentValue()
216 SolarMutexGuard aGuard
;
221 aAny
<<= mpDoc
->GetValue(maCellAddress
);
227 ScAccessibleCellBase::setCurrentValue( const uno::Any
& aNumber
)
229 SolarMutexGuard aGuard
;
232 bool bResult
= false;
233 if((aNumber
>>= fValue
) && mpDoc
&& mpDoc
->GetDocumentShell())
235 sal_Int64 nParentStates
= 0;
236 if (getAccessibleParent().is())
238 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
239 nParentStates
= xParentContext
->getAccessibleStateSet();
241 if (IsEditable(nParentStates
))
243 ScDocShell
* pDocShell
= mpDoc
->GetDocumentShell();
244 bResult
= pDocShell
->GetDocFunc().SetValueCell(maCellAddress
, fValue
, false);
251 ScAccessibleCellBase::getMaximumValue( )
253 return uno::Any(DBL_MAX
);
257 ScAccessibleCellBase::getMinimumValue( )
259 return uno::Any(-DBL_MAX
);
263 ScAccessibleCellBase::getMinimumIncrement( )
268 //===== XServiceInfo ====================================================
270 OUString SAL_CALL
ScAccessibleCellBase::getImplementationName()
272 return u
"ScAccessibleCellBase"_ustr
;
275 //===== XTypeProvider ===================================================
277 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleCellBase::getTypes()
279 return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
282 uno::Sequence
<sal_Int8
> SAL_CALL
283 ScAccessibleCellBase::getImplementationId()
285 return css::uno::Sequence
<sal_Int8
>();
288 bool ScAccessibleCellBase::IsEditable(sal_Int64 nParentStates
)
290 bool bEditable
= nParentStates
& AccessibleStateType::EDITABLE
;
294 OUString
ScAccessibleCellBase::GetNote() const
296 SolarMutexGuard aGuard
;
301 ScDocShell
* pObjSh
= mpDoc
->GetDocumentShell();
304 ScModelObj
* pSpreadDoc
= pObjSh
->GetModel();
307 uno::Reference
<sheet::XSpreadsheets
> xSheets
= pSpreadDoc
->getSheets();
308 uno::Reference
<container::XIndexAccess
> xIndex( xSheets
, uno::UNO_QUERY
);
311 uno::Any aTable
= xIndex
->getByIndex(maCellAddress
.Tab());
312 uno::Reference
<sheet::XSpreadsheet
> xTable
;
315 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByPosition(maCellAddress
.Col(), maCellAddress
.Row());
318 uno::Reference
<sheet::XSheetAnnotationAnchor
> xAnnotationAnchor ( xCell
, uno::UNO_QUERY
);
319 if(xAnnotationAnchor
.is())
321 uno::Reference
<sheet::XSheetAnnotation
> xSheetAnnotation
= xAnnotationAnchor
->getAnnotation();
322 if (xSheetAnnotation
.is())
324 uno::Reference
<text::XSimpleText
> xText (xSheetAnnotation
, uno::UNO_QUERY
);
327 sNote
= xText
->getString();
340 OUString
ScAccessibleCellBase::getShadowAttrs() const
342 SolarMutexGuard aGuard
;
344 table::ShadowFormat aShadowFmt
;
347 ScDocShell
* pObjSh
= mpDoc
->GetDocumentShell();
350 ScModelObj
* pSpreadDoc
= pObjSh
->GetModel();
353 uno::Reference
<sheet::XSpreadsheets
> xSheets
= pSpreadDoc
->getSheets();
354 uno::Reference
<container::XIndexAccess
> xIndex( xSheets
, uno::UNO_QUERY
);
357 uno::Any aTable
= xIndex
->getByIndex(maCellAddress
.Tab());
358 uno::Reference
<sheet::XSpreadsheet
> xTable
;
361 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByPosition(maCellAddress
.Col(), maCellAddress
.Row());
364 uno::Reference
<beans::XPropertySet
> xCellProps(xCell
, uno::UNO_QUERY
);
367 uno::Any aAny
= xCellProps
->getPropertyValue(SC_UNONAME_SHADOW
);
376 //construct shadow attributes string
377 OUString
sShadowAttrs(u
"Shadow:"_ustr
);
378 OUString
sInnerSplit(u
","_ustr
);
379 OUString
sOuterSplit(u
";"_ustr
);
380 sal_Int32 nLocationVal
= 0;
381 switch( aShadowFmt
.Location
)
383 case table::ShadowLocation_TOP_LEFT
:
386 case table::ShadowLocation_TOP_RIGHT
:
389 case table::ShadowLocation_BOTTOM_LEFT
:
392 case table::ShadowLocation_BOTTOM_RIGHT
:
398 //if there is no shadow property for the cell
399 if ( nLocationVal
== 0 )
401 sShadowAttrs
+= sOuterSplit
;
404 //else return all the shadow properties
405 sShadowAttrs
+= "Location=" +
406 OUString::number( nLocationVal
) +
409 OUString::number( static_cast<sal_Int32
>(aShadowFmt
.ShadowWidth
) ) +
412 OUString::number( static_cast<int>(aShadowFmt
.IsTransparent
) ) +
415 OUString::number( aShadowFmt
.Color
) +
420 OUString
ScAccessibleCellBase::getBorderAttrs()
422 SolarMutexGuard aGuard
;
424 table::BorderLine aTopBorder
;
425 table::BorderLine aBottomBorder
;
426 table::BorderLine aLeftBorder
;
427 table::BorderLine aRightBorder
;
430 ScDocShell
* pObjSh
= mpDoc
->GetDocumentShell();
433 ScModelObj
* pSpreadDoc
= pObjSh
->GetModel();
436 uno::Reference
<sheet::XSpreadsheets
> xSheets
= pSpreadDoc
->getSheets();
437 uno::Reference
<container::XIndexAccess
> xIndex( xSheets
, uno::UNO_QUERY
);
440 uno::Any aTable
= xIndex
->getByIndex(maCellAddress
.Tab());
441 uno::Reference
<sheet::XSpreadsheet
> xTable
;
444 uno::Reference
<table::XCell
> xCell
= xTable
->getCellByPosition(maCellAddress
.Col(), maCellAddress
.Row());
447 uno::Reference
<beans::XPropertySet
> xCellProps(xCell
, uno::UNO_QUERY
);
450 uno::Any aAny
= xCellProps
->getPropertyValue(SC_UNONAME_TOPBORDER
);
452 aAny
= xCellProps
->getPropertyValue(SC_UNONAME_BOTTBORDER
);
453 aAny
>>= aBottomBorder
;
454 aAny
= xCellProps
->getPropertyValue(SC_UNONAME_LEFTBORDER
);
455 aAny
>>= aLeftBorder
;
456 aAny
= xCellProps
->getPropertyValue(SC_UNONAME_RIGHTBORDER
);
457 aAny
>>= aRightBorder
;
467 bool bIn
= mpDoc
&& mpDoc
->IsCellInChangeTrack(maCellAddress
,&aColor
);
470 aTopBorder
.Color
= sal_Int32(aColor
);
471 aBottomBorder
.Color
= sal_Int32(aColor
);
472 aLeftBorder
.Color
= sal_Int32(aColor
);
473 aRightBorder
.Color
= sal_Int32(aColor
);
474 aTopBorder
.OuterLineWidth
= DEFAULT_LINE_WIDTH
;
475 aBottomBorder
.OuterLineWidth
= DEFAULT_LINE_WIDTH
;
476 aLeftBorder
.OuterLineWidth
= DEFAULT_LINE_WIDTH
;
477 aRightBorder
.OuterLineWidth
= DEFAULT_LINE_WIDTH
;
480 //construct border attributes string
481 OUString sBorderAttrs
;
482 OUString
sInnerSplit(u
","_ustr
);
483 OUString
sOuterSplit(u
";"_ustr
);
485 //if top of the cell has no border
486 if ( aTopBorder
.InnerLineWidth
== 0 && aTopBorder
.OuterLineWidth
== 0 )
488 sBorderAttrs
+= "TopBorder:;";
490 else//add all the border properties to the return string.
492 sBorderAttrs
+= "TopBorder:Color=" +
493 OUString::number( aTopBorder
.Color
) +
496 OUString::number( static_cast<sal_Int32
>(aTopBorder
.InnerLineWidth
) ) +
499 OUString::number( static_cast<sal_Int32
>(aTopBorder
.OuterLineWidth
) ) +
502 OUString::number( static_cast<sal_Int32
>(aTopBorder
.LineDistance
) ) +
506 if ( aBottomBorder
.InnerLineWidth
== 0 && aBottomBorder
.OuterLineWidth
== 0 )
508 sBorderAttrs
+= "BottomBorder:;";
512 sBorderAttrs
+= "BottomBorder:Color=" +
513 OUString::number( aBottomBorder
.Color
) +
516 OUString::number( static_cast<sal_Int32
>(aBottomBorder
.InnerLineWidth
) ) +
519 OUString::number( static_cast<sal_Int32
>(aBottomBorder
.OuterLineWidth
) ) +
522 OUString::number( static_cast<sal_Int32
>(aBottomBorder
.LineDistance
) ) +
526 if ( aLeftBorder
.InnerLineWidth
== 0 && aLeftBorder
.OuterLineWidth
== 0 )
528 sBorderAttrs
+= "LeftBorder:;";
532 sBorderAttrs
+= "LeftBorder:Color=" +
533 OUString::number( aLeftBorder
.Color
) +
536 OUString::number( static_cast<sal_Int32
>(aLeftBorder
.InnerLineWidth
) ) +
539 OUString::number( static_cast<sal_Int32
>(aLeftBorder
.OuterLineWidth
) ) +
542 OUString::number( static_cast<sal_Int32
>(aLeftBorder
.LineDistance
) ) +
546 if ( aRightBorder
.InnerLineWidth
== 0 && aRightBorder
.OuterLineWidth
== 0 )
548 sBorderAttrs
+= "RightBorder:;";
552 sBorderAttrs
+= "RightBorder:Color=" +
553 OUString::number( aRightBorder
.Color
) +
556 OUString::number( static_cast<sal_Int32
>(aRightBorder
.InnerLineWidth
) ) +
559 OUString::number( static_cast<sal_Int32
>(aRightBorder
.OuterLineWidth
) ) +
562 OUString::number( static_cast<sal_Int32
>(aRightBorder
.LineDistance
) ) +
567 //end of cell attributes
569 OUString
ScAccessibleCellBase::GetAllDisplayNote() const
572 OUString strTrackText
;
575 bool bLeftedge
= false;
576 mpDoc
->GetCellChangeTrackNote(maCellAddress
,strTrackText
,bLeftedge
);
578 if (!strTrackText
.isEmpty())
580 ScDetectiveFunc::AppendChangTrackNoteSeparator(strTrackText
);
581 strNote
= strTrackText
;
583 strNote
+= GetNote();
587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */