tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleCellBase.cxx
blobebff91c101e263978d98898da9ca68cde3c0a7c0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
23 #include <docsh.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>
40 #include <float.h>
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,
51 ScDocument* pDoc,
52 const ScAddress& rCellAddress,
53 sal_Int64 nIndex)
55 ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
56 maCellAddress(rCellAddress),
57 mpDoc(pDoc),
58 mnIndex(nIndex)
62 ScAccessibleCellBase::~ScAccessibleCellBase()
66 //===== XAccessibleComponent ============================================
68 bool ScAccessibleCellBase::isVisible()
70 SolarMutexGuard aGuard;
71 IsObjectValid();
72 // test whether the cell is hidden (column/row - hidden/filtered)
73 bool bVisible(true);
74 if (mpDoc)
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)
82 bVisible = false;
84 return bVisible;
87 sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
89 SolarMutexGuard aGuard;
90 IsObjectValid();
91 sal_Int32 nColor(0);
92 if (mpDoc)
94 ScDocShell* pObjSh = mpDoc->GetDocumentShell();
95 if ( pObjSh )
97 ScModelObj* pSpreadDoc = pObjSh->GetModel();
98 if ( pSpreadDoc )
100 uno::Reference<sheet::XSpreadsheets> xSheets = pSpreadDoc->getSheets();
101 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
102 if ( xIndex.is() )
104 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
105 uno::Reference<sheet::XSpreadsheet> xTable;
106 if (aTable>>=xTable)
108 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
109 if (xCell.is())
111 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
112 if (xCellProps.is())
114 uno::Any aAny = xCellProps->getPropertyValue(SC_UNONAME_CCOLOR);
115 aAny >>= nColor;
123 return nColor;
126 sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
128 SolarMutexGuard aGuard;
129 IsObjectValid();
130 sal_Int32 nColor(0);
132 if (mpDoc)
134 ScDocShell* pObjSh = mpDoc->GetDocumentShell();
135 if ( pObjSh )
137 ScModelObj* pSpreadDoc = pObjSh->GetModel();
138 if ( pSpreadDoc )
140 uno::Reference<sheet::XSpreadsheets> xSheets = pSpreadDoc->getSheets();
141 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
142 if ( xIndex.is() )
144 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
145 uno::Reference<sheet::XSpreadsheet> xTable;
146 if (aTable>>=xTable)
148 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
149 if (xCell.is())
151 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
152 if (xCellProps.is())
154 uno::Any aAny = xCellProps->getPropertyValue(SC_UNONAME_CELLBACK);
155 aAny >>= nColor;
164 return nColor;
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()
176 noexcept
178 ScAccessibleContextBase::acquire();
181 void SAL_CALL ScAccessibleCellBase::release()
182 noexcept
184 ScAccessibleContextBase::release();
187 //===== XAccessibleContext ==============================================
189 sal_Int64
190 ScAccessibleCellBase::getAccessibleIndexInParent()
192 SolarMutexGuard aGuard;
193 IsObjectValid();
194 return mnIndex;
197 OUString
198 ScAccessibleCellBase::createAccessibleDescription()
200 return STR_ACC_CELL_DESCR;
203 OUString
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 ================================================
213 uno::Any SAL_CALL
214 ScAccessibleCellBase::getCurrentValue()
216 SolarMutexGuard aGuard;
217 IsObjectValid();
218 uno::Any aAny;
219 if (mpDoc)
221 aAny <<= mpDoc->GetValue(maCellAddress);
223 return aAny;
226 sal_Bool SAL_CALL
227 ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
229 SolarMutexGuard aGuard;
230 IsObjectValid();
231 double fValue = 0;
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);
247 return bResult;
250 uno::Any SAL_CALL
251 ScAccessibleCellBase::getMaximumValue( )
253 return uno::Any(DBL_MAX);
256 uno::Any SAL_CALL
257 ScAccessibleCellBase::getMinimumValue( )
259 return uno::Any(-DBL_MAX);
262 uno::Any SAL_CALL
263 ScAccessibleCellBase::getMinimumIncrement( )
265 return uno::Any();
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;
291 return bEditable;
294 OUString ScAccessibleCellBase::GetNote() const
296 SolarMutexGuard aGuard;
297 IsObjectValid();
298 OUString sNote;
299 if (mpDoc)
301 ScDocShell* pObjSh = mpDoc->GetDocumentShell();
302 if ( pObjSh )
304 ScModelObj* pSpreadDoc = pObjSh->GetModel();
305 if ( pSpreadDoc )
307 uno::Reference<sheet::XSpreadsheets> xSheets = pSpreadDoc->getSheets();
308 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
309 if ( xIndex.is() )
311 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
312 uno::Reference<sheet::XSpreadsheet> xTable;
313 if (aTable>>=xTable)
315 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
316 if (xCell.is())
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);
325 if (xText.is())
327 sNote = xText->getString();
337 return sNote;
340 OUString ScAccessibleCellBase::getShadowAttrs() const
342 SolarMutexGuard aGuard;
343 IsObjectValid();
344 table::ShadowFormat aShadowFmt;
345 if (mpDoc)
347 ScDocShell* pObjSh = mpDoc->GetDocumentShell();
348 if ( pObjSh )
350 ScModelObj* pSpreadDoc = pObjSh->GetModel();
351 if ( pSpreadDoc )
353 uno::Reference<sheet::XSpreadsheets> xSheets = pSpreadDoc->getSheets();
354 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
355 if ( xIndex.is() )
357 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
358 uno::Reference<sheet::XSpreadsheet> xTable;
359 if (aTable>>=xTable)
361 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
362 if (xCell.is())
364 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
365 if (xCellProps.is())
367 uno::Any aAny = xCellProps->getPropertyValue(SC_UNONAME_SHADOW);
368 aAny >>= aShadowFmt;
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:
384 nLocationVal = 1;
385 break;
386 case table::ShadowLocation_TOP_RIGHT:
387 nLocationVal = 2;
388 break;
389 case table::ShadowLocation_BOTTOM_LEFT:
390 nLocationVal = 3;
391 break;
392 case table::ShadowLocation_BOTTOM_RIGHT:
393 nLocationVal = 4;
394 break;
395 default:
396 break;
398 //if there is no shadow property for the cell
399 if ( nLocationVal == 0 )
401 sShadowAttrs += sOuterSplit;
402 return sShadowAttrs;
404 //else return all the shadow properties
405 sShadowAttrs += "Location=" +
406 OUString::number( nLocationVal ) +
407 sInnerSplit +
408 "ShadowWidth=" +
409 OUString::number( static_cast<sal_Int32>(aShadowFmt.ShadowWidth) ) +
410 sInnerSplit +
411 "IsTransparent=" +
412 OUString::number( static_cast<int>(aShadowFmt.IsTransparent) ) +
413 sInnerSplit +
414 "Color=" +
415 OUString::number( aShadowFmt.Color ) +
416 sOuterSplit;
417 return sShadowAttrs;
420 OUString ScAccessibleCellBase::getBorderAttrs()
422 SolarMutexGuard aGuard;
423 IsObjectValid();
424 table::BorderLine aTopBorder;
425 table::BorderLine aBottomBorder;
426 table::BorderLine aLeftBorder;
427 table::BorderLine aRightBorder;
428 if (mpDoc)
430 ScDocShell* pObjSh = mpDoc->GetDocumentShell();
431 if ( pObjSh )
433 ScModelObj* pSpreadDoc = pObjSh->GetModel();
434 if ( pSpreadDoc )
436 uno::Reference<sheet::XSpreadsheets> xSheets = pSpreadDoc->getSheets();
437 uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
438 if ( xIndex.is() )
440 uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
441 uno::Reference<sheet::XSpreadsheet> xTable;
442 if (aTable>>=xTable)
444 uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
445 if (xCell.is())
447 uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
448 if (xCellProps.is())
450 uno::Any aAny = xCellProps->getPropertyValue(SC_UNONAME_TOPBORDER);
451 aAny >>= aTopBorder;
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;
466 Color aColor;
467 bool bIn = mpDoc && mpDoc->IsCellInChangeTrack(maCellAddress,&aColor);
468 if (bIn)
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);
484 //top border
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 ) +
494 sInnerSplit +
495 "InnerLineWidth=" +
496 OUString::number( static_cast<sal_Int32>(aTopBorder.InnerLineWidth) ) +
497 sInnerSplit +
498 "OuterLineWidth=" +
499 OUString::number( static_cast<sal_Int32>(aTopBorder.OuterLineWidth) ) +
500 sInnerSplit +
501 "LineDistance=" +
502 OUString::number( static_cast<sal_Int32>(aTopBorder.LineDistance) ) +
503 sOuterSplit;
505 //bottom border
506 if ( aBottomBorder.InnerLineWidth == 0 && aBottomBorder.OuterLineWidth == 0 )
508 sBorderAttrs += "BottomBorder:;";
510 else
512 sBorderAttrs += "BottomBorder:Color=" +
513 OUString::number( aBottomBorder.Color ) +
514 sInnerSplit +
515 "InnerLineWidth=" +
516 OUString::number( static_cast<sal_Int32>(aBottomBorder.InnerLineWidth) ) +
517 sInnerSplit +
518 "OuterLineWidth=" +
519 OUString::number( static_cast<sal_Int32>(aBottomBorder.OuterLineWidth) ) +
520 sInnerSplit +
521 "LineDistance=" +
522 OUString::number( static_cast<sal_Int32>(aBottomBorder.LineDistance) ) +
523 sOuterSplit;
525 //left border
526 if ( aLeftBorder.InnerLineWidth == 0 && aLeftBorder.OuterLineWidth == 0 )
528 sBorderAttrs += "LeftBorder:;";
530 else
532 sBorderAttrs += "LeftBorder:Color=" +
533 OUString::number( aLeftBorder.Color ) +
534 sInnerSplit +
535 "InnerLineWidth=" +
536 OUString::number( static_cast<sal_Int32>(aLeftBorder.InnerLineWidth) ) +
537 sInnerSplit +
538 "OuterLineWidth=" +
539 OUString::number( static_cast<sal_Int32>(aLeftBorder.OuterLineWidth) ) +
540 sInnerSplit +
541 "LineDistance=" +
542 OUString::number( static_cast<sal_Int32>(aLeftBorder.LineDistance) ) +
543 sOuterSplit;
545 //right border
546 if ( aRightBorder.InnerLineWidth == 0 && aRightBorder.OuterLineWidth == 0 )
548 sBorderAttrs += "RightBorder:;";
550 else
552 sBorderAttrs += "RightBorder:Color=" +
553 OUString::number( aRightBorder.Color ) +
554 sInnerSplit +
555 "InnerLineWidth=" +
556 OUString::number( static_cast<sal_Int32>(aRightBorder.InnerLineWidth) ) +
557 sInnerSplit +
558 "OuterLineWidth=" +
559 OUString::number( static_cast<sal_Int32>(aRightBorder.OuterLineWidth) ) +
560 sInnerSplit +
561 "LineDistance=" +
562 OUString::number( static_cast<sal_Int32>(aRightBorder.LineDistance) ) +
563 sOuterSplit;
565 return sBorderAttrs;
567 //end of cell attributes
569 OUString ScAccessibleCellBase::GetAllDisplayNote() const
571 OUString strNote;
572 OUString strTrackText;
573 if (mpDoc)
575 bool bLeftedge = false;
576 mpDoc->GetCellChangeTrackNote(maCellAddress,strTrackText,bLeftedge);
578 if (!strTrackText.isEmpty())
580 ScDetectiveFunc::AppendChangTrackNoteSeparator(strTrackText);
581 strNote = strTrackText;
583 strNote += GetNote();
584 return strNote;
587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */