sc/source/ui/Accessibility/AccessibleCell.cxx | 27 ++-- sc/source/ui/Accessibility/AccessibleCellBase.cxx | 128 ++++++++-------------- sc/source/ui/Accessibility/AccessibleDocument.cxx | 14 +- sc/source/ui/inc/AccessibleCell.hxx | 4 sc/source/ui/inc/AccessibleCellBase.hxx | 7 - sc/source/ui/inc/AccessibleDocument.hxx | 3 6 files changed, 74 insertions(+), 109 deletions(-)
New commits: commit 6147a4ca97c55bd3c6c8fb4ce42105649f7eab48 Author: Michael Weghorn <[email protected]> AuthorDate: Thu Mar 5 13:30:30 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Fri Mar 6 07:16:17 2026 +0100 sc a11y: Switch to override new extended attr helper for doc Override the OAccessible::implGetExtendedAttributes base class method newly introduced in Change-Id: Ie66f135fbf6cdc98c7cdca27fa3f5fe7db7f9a74 Author: Michael Weghorn <[email protected]> Date: Thu Mar 5 12:12:45 2026 +0100 a11y: Introduce helper to implement XAccessibleExtendedAttributes logic instead of manually implementing XAccessibleExtendedAttributes::getExtendedAttributes, to unify/deduplicate the string concatenation and locking logic by having it implemented (only) in the base class implementation. Change-Id: I791a26e50dc00d4330e92f913b32d0de919ff9de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201038 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx index 5ff99a1cf36a..c7b98ae1a354 100644 --- a/sc/source/ui/Accessibility/AccessibleDocument.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx @@ -2084,20 +2084,18 @@ ScAddress ScAccessibleDocument::GetCurCellAddress() const return mpViewShell ? mpViewShell->GetViewData().GetCurPos() : ScAddress(); } -OUString SAL_CALL ScAccessibleDocument::getExtendedAttributes() +std::unordered_map<OUString, OUString> ScAccessibleDocument::implGetExtendedAttributes() { - SolarMutexGuard g; - sal_uInt16 sheetIndex; OUString sSheetName; sheetIndex = getVisibleTable(); if(GetDocument()==nullptr) - return OUString(); + return {}; + GetDocument()->GetName(sheetIndex,sSheetName); - OUString sValue = "page-name:" + sSheetName + - ";page-number:" + OUString::number(sheetIndex+1) + - ";total-pages:" + OUString::number(GetDocument()->GetTableCount()) + ";"; - return sValue; + return { { u"page-name"_ustr, sSheetName }, + { u"page-number"_ustr, OUString::number(sheetIndex + 1) }, + { u"total-pages"_ustr, OUString::number(GetDocument()->GetTableCount()) } }; } sal_Int32 SAL_CALL ScAccessibleDocument::getForeground( ) diff --git a/sc/source/ui/inc/AccessibleDocument.hxx b/sc/source/ui/inc/AccessibleDocument.hxx index 90fedc526559..c95257070ea1 100644 --- a/sc/source/ui/inc/AccessibleDocument.hxx +++ b/sc/source/ui/inc/AccessibleDocument.hxx @@ -92,7 +92,6 @@ public: virtual OUString SAL_CALL getAccessibleName() override; - virtual OUString SAL_CALL getExtendedAttributes() override ; ///===== XAccessibleSelection =========================================== virtual void SAL_CALL @@ -165,6 +164,8 @@ public: GetAccessibleSpreadsheet(); protected: + virtual std::unordered_map<OUString, OUString> implGetExtendedAttributes() override; + /// Return this object's description. virtual OUString createAccessibleDescription() override; commit bbd64edb27c3ed01ca451f2ab23d055f93c98b80 Author: Michael Weghorn <[email protected]> AuthorDate: Thu Mar 5 13:15:44 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Fri Mar 6 07:16:10 2026 +0100 sc a11y: Switch to override new extended attr helper for cell Override the OAccessible::implGetExtendedAttributes base class method newly introduced in Change-Id: Ie66f135fbf6cdc98c7cdca27fa3f5fe7db7f9a74 Author: Michael Weghorn <[email protected]> Date: Thu Mar 5 12:12:45 2026 +0100 a11y: Introduce helper to implement XAccessibleExtendedAttributes logic instead of manually implementing XAccessibleExtendedAttributes::getExtendedAttributes, to unify/deduplicate the string concatenation and locking logic by having it implemented (only) in the base class implementation. Switch the helper methods accordingly and drop custom mutex locking and checking that the object is still alive, as the base class takes care of this now in OAccessible::getExtendedAttributes. Change-Id: I740d7968ed732b092604a69b5c8a1b2709caa4f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201037 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx index 8344029c3f83..340fe5a0ba43 100644 --- a/sc/source/ui/Accessibility/AccessibleCell.cxx +++ b/sc/source/ui/Accessibility/AccessibleCell.cxx @@ -463,9 +463,9 @@ static OUString ReplaceFourChar(const OUString& oldOUString) .replaceAll(u":", u"\:"); } -OUString SAL_CALL ScAccessibleCell::getExtendedAttributes() +std::unordered_map<OUString, OUString> ScAccessibleCell::implGetExtendedAttributes() { - SolarMutexGuard aGuard; + std::unordered_map<OUString, OUString> aAttributes; // report row and column index text via attributes as specified in ARIA which map // to attributes of the same name for AT-SPI2, IAccessible2, UIA @@ -473,30 +473,29 @@ OUString SAL_CALL ScAccessibleCell::getExtendedAttributes() // https://www.w3.org/TR/core-aam-1.2/#ariaColIndexText const OUString sRowIndexText = maCellAddress.Format(ScRefFlags::ROW_VALID); const OUString sColIndexText = maCellAddress.Format(ScRefFlags::COL_VALID); - OUString sAttributes = "rowindextext:" + sRowIndexText + ";colindextext:" + sColIndexText + ";"; + aAttributes.emplace(u"rowindextext"_ustr, sRowIndexText); + aAttributes.emplace(u"colindextext"_ustr, sColIndexText); if (mpViewShell) { const OUString sFormula = mpViewShell->GetFormula(maCellAddress) ; if (!sFormula.isEmpty()) - sAttributes += u"Formula:" + ReplaceFourChar(sFormula.copy(1)) + u";"; + aAttributes.emplace(u"Formula"_ustr, ReplaceFourChar(sFormula.copy(1))); - sAttributes += "Note:" + ReplaceFourChar(GetAllDisplayNote()) + ";" + - getShadowAttrs() + //the string returned contains the spliter ";" - getBorderAttrs();//the string returned contains the spliter ";" + aAttributes.emplace(u"Note"_ustr, ReplaceFourChar(GetAllDisplayNote())); + for (const auto& rAttr : getShadowAttrs()) + aAttributes.insert(rAttr); + for (const auto& rAttr : getBorderAttrs()) + aAttributes.insert(rAttr); //end of cell attributes if( mpDoc ) { - sAttributes += "isdropdown:"; - if( IsDropdown() ) - sAttributes += "true"; - else - sAttributes += "false"; - sAttributes += ";"; + const OUString sDropDownValue = IsDropdown() ? u"true"_ustr : u"false"_ustr; + aAttributes.emplace(u"isdropdown"_ustr, sDropDownValue); } } - return sAttributes; + return aAttributes; } // 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. diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx index dce3ff27ab62..588a7e0459d1 100644 --- a/sc/source/ui/Accessibility/AccessibleCellBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx @@ -292,10 +292,8 @@ OUString ScAccessibleCellBase::GetNote() const return sNote; } -OUString ScAccessibleCellBase::getShadowAttrs() const +std::unordered_map<OUString, OUString> ScAccessibleCellBase::getShadowAttrs() const { - SolarMutexGuard aGuard; - ensureAlive(); table::ShadowFormat aShadowFmt; if (mpDoc) { @@ -328,10 +326,8 @@ OUString ScAccessibleCellBase::getShadowAttrs() const } } } - //construct shadow attributes string - OUString sShadowAttrs(u"Shadow:"_ustr); + const OUString sShadowAttrName(u"Shadow"_ustr); OUString sInnerSplit(u","_ustr); - OUString sOuterSplit(u";"_ustr); sal_Int32 nLocationVal = 0; switch( aShadowFmt.Location ) { @@ -353,29 +349,19 @@ OUString ScAccessibleCellBase::getShadowAttrs() const //if there is no shadow property for the cell if ( nLocationVal == 0 ) { - sShadowAttrs += sOuterSplit; - return sShadowAttrs; + return { { sShadowAttrName, u""_ustr } }; } //else return all the shadow properties - sShadowAttrs += "Location=" + - OUString::number( nLocationVal ) + - sInnerSplit + - "ShadowWidth=" + - OUString::number( static_cast<sal_Int32>(aShadowFmt.ShadowWidth) ) + - sInnerSplit + - "IsTransparent=" + - OUString::number( static_cast<int>(aShadowFmt.IsTransparent) ) + - sInnerSplit + - "Color=" + - OUString::number( aShadowFmt.Color ) + - sOuterSplit; - return sShadowAttrs; + const OUString sAttrValue + = "Location=" + OUString::number(nLocationVal) + sInnerSplit + "ShadowWidth=" + + OUString::number(static_cast<sal_Int32>(aShadowFmt.ShadowWidth)) + sInnerSplit + + "IsTransparent=" + OUString::number(static_cast<int>(aShadowFmt.IsTransparent)) + + sInnerSplit + "Color=" + OUString::number(aShadowFmt.Color); + return { { sShadowAttrName, sAttrValue } }; } -OUString ScAccessibleCellBase::getBorderAttrs() +std::unordered_map<OUString, OUString> ScAccessibleCellBase::getBorderAttrs() { - SolarMutexGuard aGuard; - ensureAlive(); table::BorderLine aTopBorder; table::BorderLine aBottomBorder; table::BorderLine aLeftBorder; @@ -432,92 +418,74 @@ OUString ScAccessibleCellBase::getBorderAttrs() aRightBorder.OuterLineWidth = DEFAULT_LINE_WIDTH; } - //construct border attributes string - OUString sBorderAttrs; + std::unordered_map<OUString, OUString> aBorderAttrs; OUString sInnerSplit(u","_ustr); - OUString sOuterSplit(u";"_ustr); //top border //if top of the cell has no border if ( aTopBorder.InnerLineWidth == 0 && aTopBorder.OuterLineWidth == 0 ) { - sBorderAttrs += "TopBorder:;"; + aBorderAttrs.emplace(u"TopBorder"_ustr, u""_ustr); } else//add all the border properties to the return string. { - sBorderAttrs += "TopBorder:Color=" + - OUString::number( aTopBorder.Color ) + - sInnerSplit + - "InnerLineWidth=" + - OUString::number( static_cast<sal_Int32>(aTopBorder.InnerLineWidth) ) + - sInnerSplit + - "OuterLineWidth=" + - OUString::number( static_cast<sal_Int32>(aTopBorder.OuterLineWidth) ) + - sInnerSplit + - "LineDistance=" + - OUString::number( static_cast<sal_Int32>(aTopBorder.LineDistance) ) + - sOuterSplit; + aBorderAttrs.emplace( + u"TopBorder"_ustr, + u"Color=" + OUString::number(aTopBorder.Color) + sInnerSplit + "InnerLineWidth=" + + OUString::number(static_cast<sal_Int32>(aTopBorder.InnerLineWidth)) + sInnerSplit + + "OuterLineWidth=" + + OUString::number(static_cast<sal_Int32>(aTopBorder.OuterLineWidth)) + sInnerSplit + + "LineDistance=" + + OUString::number(static_cast<sal_Int32>(aTopBorder.LineDistance))); } //bottom border if ( aBottomBorder.InnerLineWidth == 0 && aBottomBorder.OuterLineWidth == 0 ) { - sBorderAttrs += "BottomBorder:;"; + aBorderAttrs.emplace(u"BottomBorder"_ustr, u""_ustr); } else { - sBorderAttrs += "BottomBorder:Color=" + - OUString::number( aBottomBorder.Color ) + - sInnerSplit + - "InnerLineWidth=" + - OUString::number( static_cast<sal_Int32>(aBottomBorder.InnerLineWidth) ) + - sInnerSplit + - "OuterLineWidth=" + - OUString::number( static_cast<sal_Int32>(aBottomBorder.OuterLineWidth) ) + - sInnerSplit + - "LineDistance=" + - OUString::number( static_cast<sal_Int32>(aBottomBorder.LineDistance) ) + - sOuterSplit; + aBorderAttrs.emplace( + u"BottomBorder"_ustr, + u"Color" + OUString::number(aBottomBorder.Color) + sInnerSplit + "InnerLineWidth=" + + OUString::number(static_cast<sal_Int32>(aBottomBorder.InnerLineWidth)) + + sInnerSplit + "OuterLineWidth=" + + OUString::number(static_cast<sal_Int32>(aBottomBorder.OuterLineWidth)) + + sInnerSplit + "LineDistance=" + + OUString::number(static_cast<sal_Int32>(aBottomBorder.LineDistance))); } //left border if ( aLeftBorder.InnerLineWidth == 0 && aLeftBorder.OuterLineWidth == 0 ) { - sBorderAttrs += "LeftBorder:;"; + aBorderAttrs.emplace(u"LeftBorder"_ustr, u""_ustr); } else { - sBorderAttrs += "LeftBorder:Color=" + - OUString::number( aLeftBorder.Color ) + - sInnerSplit + - "InnerLineWidth=" + - OUString::number( static_cast<sal_Int32>(aLeftBorder.InnerLineWidth) ) + - sInnerSplit + - "OuterLineWidth=" + - OUString::number( static_cast<sal_Int32>(aLeftBorder.OuterLineWidth) ) + - sInnerSplit + - "LineDistance=" + - OUString::number( static_cast<sal_Int32>(aLeftBorder.LineDistance) ) + - sOuterSplit; + aBorderAttrs.emplace( + u"LeftBorder"_ustr, + u"Color=" + OUString::number(aLeftBorder.Color) + sInnerSplit + "InnerLineWidth=" + + OUString::number(static_cast<sal_Int32>(aLeftBorder.InnerLineWidth)) + sInnerSplit + + "OuterLineWidth=" + + OUString::number(static_cast<sal_Int32>(aLeftBorder.OuterLineWidth)) + sInnerSplit + + "LineDistance=" + + OUString::number(static_cast<sal_Int32>(aLeftBorder.LineDistance))); } //right border if ( aRightBorder.InnerLineWidth == 0 && aRightBorder.OuterLineWidth == 0 ) { - sBorderAttrs += "RightBorder:;"; + aBorderAttrs.emplace(u"RightBorder"_ustr, u""_ustr); } else { - sBorderAttrs += "RightBorder:Color=" + - OUString::number( aRightBorder.Color ) + - sInnerSplit + - "InnerLineWidth=" + - OUString::number( static_cast<sal_Int32>(aRightBorder.InnerLineWidth) ) + - sInnerSplit + - "OuterLineWidth=" + - OUString::number( static_cast<sal_Int32>(aRightBorder.OuterLineWidth) ) + - sInnerSplit + - "LineDistance=" + - OUString::number( static_cast<sal_Int32>(aRightBorder.LineDistance) ) + - sOuterSplit; + aBorderAttrs.emplace( + u"RightBorder"_ustr, + u"Color=" + OUString::number(aRightBorder.Color) + sInnerSplit + "InnerLineWidth=" + + OUString::number(static_cast<sal_Int32>(aRightBorder.InnerLineWidth)) + + sInnerSplit + "OuterLineWidth=" + + OUString::number(static_cast<sal_Int32>(aRightBorder.OuterLineWidth)) + + sInnerSplit + "LineDistance=" + + OUString::number(static_cast<sal_Int32>(aRightBorder.LineDistance))); } - return sBorderAttrs; + return aBorderAttrs; } //end of cell attributes diff --git a/sc/source/ui/inc/AccessibleCell.hxx b/sc/source/ui/inc/AccessibleCell.hxx index 6e6135495e45..410de8bb7969 100644 --- a/sc/source/ui/inc/AccessibleCell.hxx +++ b/sc/source/ui/inc/AccessibleCell.hxx @@ -84,6 +84,8 @@ public: virtual void SAL_CALL grabFocus( ) override; protected: + virtual std::unordered_map<OUString, OUString> implGetExtendedAttributes() override; + /// Return the object's current bounding box relative to the desktop. virtual AbsoluteScreenPixelRectangle GetBoundingBoxOnScreen() override; @@ -111,8 +113,6 @@ public: css::accessibility::XAccessibleRelationSet> SAL_CALL getAccessibleRelationSet() override; - virtual OUString SAL_CALL getExtendedAttributes() override; - // Override this method to handle cell's ParaIndent attribute specially. virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; private: diff --git a/sc/source/ui/inc/AccessibleCellBase.hxx b/sc/source/ui/inc/AccessibleCellBase.hxx index c14d3f644d89..8f641f879bce 100644 --- a/sc/source/ui/inc/AccessibleCellBase.hxx +++ b/sc/source/ui/inc/AccessibleCellBase.hxx @@ -93,10 +93,9 @@ protected: /// @throw css::uno::RuntimeException OUString GetAllDisplayNote() const; - /// @throw css::uno::RuntimeException - OUString getShadowAttrs() const; - /// @throw css::uno::RuntimeException - OUString getBorderAttrs(); + std::unordered_map<OUString, OUString> getShadowAttrs() const; + std::unordered_map<OUString, OUString> getBorderAttrs(); + public: const ScAddress& GetCellAddress() const { return maCellAddress; } };
