a11y: Hold list items by rtl::Reference
Use a vector of `rtl::Reference<VCLXAccessibleListItem>`
for the children instead of a vector of
`css::uno::Reference<css::accessibility::XAccessible>`
and casting in various places.
Change-Id: I1d0e72a7c844a685d762069002d747cf5e7d02dc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156525
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
diff --git a/accessibility/inc/standard/vclxaccessiblelist.hxx b/accessibility/inc/standard/vclxaccessiblelist.hxx
index eb1cdc6..f668e75 100644
--- a/accessibility/inc/standard/vclxaccessiblelist.hxx
+++ b/accessibility/inc/standard/vclxaccessiblelist.hxx
@@ -25,6 +25,8 @@
#include <cppuhelper/implbase.hxx>
#include <toolkit/awt/vclxaccessiblecomponent.hxx>
class VCLXAccessibleListItem;
namespace accessibility
{
class IComboListBoxHelper;
@@ -114,7 +116,7 @@ public:
private:
BoxType m_aBoxType;
std::unique_ptr<::accessibility::IComboListBoxHelper> m_pListBoxHelper;
std::vector<css::uno::Reference<css::accessibility::XAccessible>> m_aAccessibleChildren;
std::vector<rtl::Reference<VCLXAccessibleListItem>> m_aAccessibleChildren;
sal_Int32 m_nVisibleLineCount;
/// Index in parent. This is settable from the outside.
sal_Int32 m_nIndexInParent;
@@ -144,8 +146,7 @@ private:
/** Create the specified child and insert it into the list of children.
Sets the child's states.
*/
css::uno::Reference< css::accessibility::XAccessible >
CreateChild (sal_Int32 i);
rtl::Reference<VCLXAccessibleListItem> CreateChild (sal_Int32 i);
/** Call this method when the item list has been changed, i.e. items
have been deleted or inserted.
diff --git a/accessibility/source/standard/vclxaccessiblelist.cxx b/accessibility/source/standard/vclxaccessiblelist.cxx
index 14f6cdd..67061aa 100644
--- a/accessibility/source/standard/vclxaccessiblelist.cxx
+++ b/accessibility/source/standard/vclxaccessiblelist.cxx
@@ -108,8 +108,11 @@ void SAL_CALL VCLXAccessibleList::disposing()
VCLXAccessibleComponent::disposing();
// Dispose all items in the list.
for (Reference<XAccessible>& rxChild : m_aAccessibleChildren)
comphelper::disposeComponent(rxChild);
for (rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren)
{
if (rxChild.is())
rxChild->dispose();
}
m_aAccessibleChildren.clear();
@@ -159,18 +162,17 @@ void VCLXAccessibleList::notifyVisibleStates(bool _bSetNew )
// adjust the index inside the VCLXAccessibleListItem
for ( ; aIter != m_aAccessibleChildren.end(); )
{
Reference<XAccessible> xChild = *aIter;
rtl::Reference<VCLXAccessibleListItem> xChild = *aIter;
if (!xChild.is())
{
aIter = m_aAccessibleChildren.erase(aIter);
}
else
{
VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xChild.get());
const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
const sal_Int32 nPos = static_cast<sal_Int32>(aIter - m_aAccessibleChildren.begin());
bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
pItem->SetVisible( m_bVisible && bVisible );
xChild->SetVisible(m_bVisible && bVisible);
++aIter;
}
@@ -209,25 +211,24 @@ void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool bHasDropDownList)
{
sal_Int32 i=0;
m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
for (const Reference<XAccessible>& rxChild : m_aAccessibleChildren)
for (const rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren)
{
if (rxChild.is())
{
VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(rxChild.get() );
// Retrieve the item's index from the list entry.
bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
if (bNowSelected)
m_nCurSelectedPos = i;
if ( bNowSelected && !pItem->IsSelected() )
if (bNowSelected && !rxChild->IsSelected())
{
xNewAcc = rxChild;
aNewValue <<= xNewAcc;
}
else if ( pItem->IsSelected() )
else if (rxChild->IsSelected())
m_nLastSelectedPos = i;
pItem->SetSelected( bNowSelected );
rxChild->SetSelected(bNowSelected);
}
else
{ // it could happen that a child was not created before
@@ -332,7 +333,7 @@ void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEve
if ( nPos == LISTBOX_ENTRY_NOTFOUND )
nPos = m_pListBoxHelper->GetTopEntry();
if ( nPos != LISTBOX_ENTRY_NOTFOUND )
aNewValue <<= CreateChild(nPos);
aNewValue <<= uno::Reference<XAccessible>(CreateChild(nPos));
NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
aOldValue,
aNewValue );
@@ -401,7 +402,7 @@ void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEve
if ( nPos == LISTBOX_ENTRY_NOTFOUND )
nPos = m_pListBoxHelper->GetTopEntry();
if ( nPos != LISTBOX_ENTRY_NOTFOUND )
aNewValue <<= CreateChild(nPos);
aNewValue <<= Reference<XAccessible>(CreateChild(nPos));
NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
aOldValue,
aNewValue );
@@ -455,9 +456,9 @@ void VCLXAccessibleList::UpdateSelection (std::u16string_view sTextOfSelectedIte
}
Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 nPos)
rtl::Reference<VCLXAccessibleListItem> VCLXAccessibleList::CreateChild(sal_Int32 nPos)
{
Reference<XAccessible> xChild;
rtl::Reference<VCLXAccessibleListItem> xChild;
if ( o3tl::make_unsigned(nPos) >= m_aAccessibleChildren.size() )
{
@@ -486,14 +487,13 @@ Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 nPos)
bNowSelected = m_pListBoxHelper->IsEntryPosSelected(nPos);
if (bNowSelected)
m_nCurSelectedPos = nPos;
VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get());
pItem->SetSelected( bNowSelected );
xChild->SetSelected(bNowSelected);
// Set the child's VISIBLE state.
UpdateVisibleLineCount();
const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
pItem->SetVisible( m_bVisible && bVisible );
xChild->SetVisible(m_bVisible && bVisible);
}
return xChild;
@@ -622,14 +622,14 @@ void VCLXAccessibleList::UpdateEntryRange_Impl()
for (sal_Int32 i = nBegin; (i <= nEnd); ++i)
{
bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) );
Reference< XAccessible > xHold;
rtl::Reference<VCLXAccessibleListItem> xChild;
if ( o3tl::make_unsigned(i) < m_aAccessibleChildren.size() )
xHold = m_aAccessibleChildren[i];
xChild = m_aAccessibleChildren[i];
else if ( bVisible )
xHold = CreateChild(i);
xChild = CreateChild(i);
if ( xHold.is() )
static_cast< VCLXAccessibleListItem* >( xHold.get() )->SetVisible( m_bVisible && bVisible );
if (xChild.is())
xChild->SetVisible(m_bVisible && bVisible);
}
}
@@ -666,25 +666,24 @@ void VCLXAccessibleList::UpdateSelection_Impl(sal_Int32)
{
sal_Int32 i=0;
m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
for (const Reference<XAccessible>& rxChild : m_aAccessibleChildren )
for (const rtl::Reference<VCLXAccessibleListItem>& rxChild : m_aAccessibleChildren)
{
if (rxChild.is())
{
VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( rxChild.get() );
// Retrieve the item's index from the list entry.
bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
if (bNowSelected)
m_nCurSelectedPos = i;
if ( bNowSelected && !pItem->IsSelected() )
if (bNowSelected && !rxChild->IsSelected())
{
xNewAcc = rxChild;
aNewValue <<= xNewAcc;
}
else if ( pItem->IsSelected() )
else if (rxChild->IsSelected())
m_nLastSelectedPos = i;
pItem->SetSelected( bNowSelected );
rxChild->SetSelected(bNowSelected);
}
else
{ // it could happen that a child was not created before