Accessibility for IconView
Change-Id: I65ca9d43f70a50e2e95aabfc3b8ba1b15f9ff8be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135226 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
parent
2910ce0b43
commit
2a28ebeef5
16 changed files with 202 additions and 32 deletions
|
@ -62,6 +62,7 @@ $(eval $(call gb_Library_add_exception_objects,acc,\
|
|||
accessibility/source/extended/accessibleeditbrowseboxcell \
|
||||
accessibility/source/extended/accessibleiconchoicectrl \
|
||||
accessibility/source/extended/accessibleiconchoicectrlentry \
|
||||
accessibility/source/extended/AccessibleIconView \
|
||||
accessibility/source/extended/accessiblelistbox \
|
||||
accessibility/source/extended/accessiblelistboxentry \
|
||||
accessibility/source/extended/accessibletablistbox \
|
||||
|
|
30
accessibility/inc/extended/AccessibleIconView.hxx
Normal file
30
accessibility/inc/extended/AccessibleIconView.hxx
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include "accessiblelistbox.hxx"
|
||||
|
||||
namespace accessibility
|
||||
{
|
||||
class AccessibleIconView final : public AccessibleListBox
|
||||
{
|
||||
public:
|
||||
AccessibleIconView(SvTreeListBox const& _rListBox,
|
||||
const css::uno::Reference<css::accessibility::XAccessible>& _xParent);
|
||||
|
||||
protected:
|
||||
// VCLXAccessibleComponent
|
||||
virtual void ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent) override;
|
||||
};
|
||||
} // namespace accessibility
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
@ -37,7 +37,7 @@ namespace accessibility
|
|||
|
||||
/** the class OAccessibleListBoxEntry represents the base class for an accessible object of a listbox entry
|
||||
*/
|
||||
class AccessibleListBox final :
|
||||
class AccessibleListBox :
|
||||
public cppu::ImplHelper2<
|
||||
css::accessibility::XAccessible,
|
||||
css::accessibility::XAccessibleSelection>,
|
||||
|
@ -45,18 +45,17 @@ namespace accessibility
|
|||
{
|
||||
|
||||
css::uno::Reference< css::accessibility::XAccessible > m_xParent;
|
||||
|
||||
virtual ~AccessibleListBox() override;
|
||||
|
||||
// OComponentHelper overridables
|
||||
/** this function is called upon disposing the component */
|
||||
virtual void SAL_CALL disposing() override;
|
||||
|
||||
protected:
|
||||
// VCLXAccessibleComponent
|
||||
virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override;
|
||||
virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) override;
|
||||
virtual void FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) override;
|
||||
|
||||
private:
|
||||
VclPtr< SvTreeListBox > getListBox() const;
|
||||
|
||||
void RemoveChildEntries(SvTreeListEntry*);
|
||||
|
@ -73,6 +72,8 @@ namespace accessibility
|
|||
AccessibleListBox( SvTreeListBox const & _rListBox,
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& _xParent );
|
||||
|
||||
virtual ~AccessibleListBox() override;
|
||||
|
||||
rtl::Reference<AccessibleListBoxEntry> implGetAccessible(SvTreeListEntry & rEntry);
|
||||
|
||||
// XTypeProvider
|
||||
|
|
53
accessibility/source/extended/AccessibleIconView.cxx
Normal file
53
accessibility/source/extended/AccessibleIconView.cxx
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
|
||||
|
||||
#include <toolkit/helper/convert.hxx>
|
||||
#include <vcl/event.hxx>
|
||||
|
||||
#include <extended/AccessibleIconView.hxx>
|
||||
|
||||
namespace accessibility
|
||||
{
|
||||
AccessibleIconView::AccessibleIconView(
|
||||
SvTreeListBox const& _rListBox,
|
||||
const css::uno::Reference<css::accessibility::XAccessible>& _xParent)
|
||||
: AccessibleListBox(_rListBox, _xParent)
|
||||
{
|
||||
}
|
||||
|
||||
void AccessibleIconView::ProcessWindowEvent(const VclWindowEvent& rVclWindowEvent)
|
||||
{
|
||||
if (!isAlive())
|
||||
return;
|
||||
|
||||
switch (rVclWindowEvent.GetId())
|
||||
{
|
||||
case VclEventId::WindowMouseMove:
|
||||
if (MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData()))
|
||||
{
|
||||
if (auto xChild = getAccessibleAtPoint(AWTPoint(pMouseEvt->GetPosPixel())))
|
||||
{
|
||||
// Allow announcing the element on mouse hover
|
||||
css::uno::Any aNew(xChild);
|
||||
NotifyAccessibleEvent(
|
||||
css::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, {}, aNew);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AccessibleListBox::ProcessWindowEvent(rVclWindowEvent);
|
||||
}
|
||||
}
|
||||
} // namespace accessibility
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
@ -439,33 +439,12 @@ namespace accessibility
|
|||
SolarMutexGuard aSolarGuard;
|
||||
::osl::MutexGuard aGuard( m_aMutex );
|
||||
|
||||
SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
|
||||
if( getAccessibleRole() == AccessibleRole::TREE_ITEM )
|
||||
{
|
||||
return OUString();
|
||||
}
|
||||
//want to count the real column number in the list box.
|
||||
sal_uInt16 iRealItemCount = 0;
|
||||
sal_uInt16 iCount = 0;
|
||||
sal_uInt16 iTotleItemCount = pEntry->ItemCount();
|
||||
while( iCount < iTotleItemCount )
|
||||
{
|
||||
const SvLBoxItem& rItem = pEntry->GetItem( iCount );
|
||||
if ( rItem.GetType() == SvLBoxItemType::String &&
|
||||
!static_cast<const SvLBoxString&>( rItem ).GetText().isEmpty() )
|
||||
{
|
||||
iRealItemCount++;
|
||||
}
|
||||
iCount++;
|
||||
}
|
||||
if(iRealItemCount<=1 )
|
||||
{
|
||||
return OUString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return SvTreeListBox::SearchEntryTextWithHeadTitle( pEntry );
|
||||
}
|
||||
return m_pTreeListBox->GetEntryAccessibleDescription(
|
||||
m_pTreeListBox->GetEntryFromPath(m_aEntryPath));
|
||||
}
|
||||
|
||||
OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName( )
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <extended/accessibletablistbox.hxx>
|
||||
#include <extended/AccessibleBrowseBox.hxx>
|
||||
#include <extended/accessibleiconchoicectrl.hxx>
|
||||
#include <extended/AccessibleIconView.hxx>
|
||||
#include <extended/accessibletabbar.hxx>
|
||||
#include <extended/accessiblelistbox.hxx>
|
||||
#include <extended/AccessibleBrowseBoxHeaderBar.hxx>
|
||||
|
@ -155,6 +156,12 @@ public:
|
|||
const css::uno::Reference< css::accessibility::XAccessible >& _xParent
|
||||
) const override;
|
||||
|
||||
virtual css::uno::Reference< css::accessibility::XAccessible >
|
||||
createAccessibleIconView(
|
||||
SvTreeListBox& _rListBox,
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& _xParent
|
||||
) const override;
|
||||
|
||||
virtual css::uno::Reference< css::accessibility::XAccessible >
|
||||
createAccessibleBrowseBoxHeaderBar(
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& rxParent,
|
||||
|
@ -407,6 +414,12 @@ Reference< XAccessible > AccessibleFactory::createAccessibleTreeListBox(
|
|||
return new AccessibleListBox( _rListBox, _xParent );
|
||||
}
|
||||
|
||||
Reference< XAccessible > AccessibleFactory::createAccessibleIconView(
|
||||
SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) const
|
||||
{
|
||||
return new AccessibleIconView( _rListBox, _xParent );
|
||||
}
|
||||
|
||||
Reference< XAccessible > AccessibleFactory::createAccessibleBrowseBoxHeaderBar(
|
||||
const Reference< XAccessible >& rxParent, vcl::IAccessibleTableProvider& _rOwningTable,
|
||||
AccessibleBrowseBoxObjType _eObjType ) const
|
||||
|
|
|
@ -82,6 +82,11 @@ namespace vcl
|
|||
SvTreeListBox& _rListBox,
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& _xParent
|
||||
) const = 0;
|
||||
virtual css::uno::Reference< css::accessibility::XAccessible >
|
||||
createAccessibleIconView(
|
||||
SvTreeListBox& _rListBox,
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& _xParent
|
||||
) const = 0;
|
||||
virtual vcl::IAccessibleBrowseBox*
|
||||
createAccessibleBrowseBox(
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& _rxParent,
|
||||
|
|
|
@ -456,6 +456,8 @@ public:
|
|||
/** Fills the StateSet of one entry. */
|
||||
void FillAccessibleEntryStateSet( SvTreeListEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const;
|
||||
|
||||
virtual OUString GetEntryAccessibleDescription(SvTreeListEntry* pEntry) const;
|
||||
|
||||
/** Calculate and return the bounding rectangle of an entry.
|
||||
@param pEntry
|
||||
The entry.
|
||||
|
|
|
@ -1348,7 +1348,10 @@ protected:
|
|||
|
||||
void signal_selection_changed() { m_aSelectionChangeHdl.Call(*this); }
|
||||
bool signal_item_activated() { return m_aItemActivatedHdl.Call(*this); }
|
||||
OUString signal_query_tooltip(const TreeIter& rIter) { return m_aQueryTooltipHdl.Call(rIter); }
|
||||
OUString signal_query_tooltip(const TreeIter& rIter) const
|
||||
{
|
||||
return m_aQueryTooltipHdl.Call(rIter);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int get_item_width() const = 0;
|
||||
|
|
|
@ -84,8 +84,7 @@ void SmGraphicAccessible::ClearWin()
|
|||
|
||||
if ( nClientId )
|
||||
{
|
||||
comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
|
||||
nClientId = 0;
|
||||
comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( std::exchange(nClientId, 0), *this );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,8 +390,7 @@ void SAL_CALL SmGraphicAccessible::removeAccessibleEventListener(
|
|||
// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
|
||||
// and at least to us not firing any events anymore, in case somebody calls
|
||||
// NotifyAccessibleEvent, again
|
||||
comphelper::AccessibleEventNotifier::revokeClient( nClientId );
|
||||
nClientId = 0;
|
||||
comphelper::AccessibleEventNotifier::revokeClient( std::exchange(nClientId, 0) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,22 @@ public:
|
|||
void PaintEntry(SvTreeListEntry&, tools::Long nX, tools::Long nY,
|
||||
vcl::RenderContext& rRenderContext);
|
||||
|
||||
virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
|
||||
|
||||
virtual OUString GetEntryAccessibleDescription(SvTreeListEntry* pEntry) const override;
|
||||
void SetEntryAccessibleDescriptionHdl(const Link<SvTreeListEntry*, OUString>& rLink)
|
||||
{
|
||||
maEntryAccessibleDescriptionHdl = rLink;
|
||||
}
|
||||
|
||||
virtual FactoryFunction GetUITestFactory() const override;
|
||||
virtual void DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) override;
|
||||
|
||||
protected:
|
||||
virtual void CalcEntryHeight(SvTreeListEntry const* pEntry) override;
|
||||
|
||||
private:
|
||||
Link<SvTreeListEntry*, OUString> maEntryAccessibleDescriptionHdl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1759,6 +1759,7 @@ private:
|
|||
DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
|
||||
DECL_LINK(CommandHdl, const CommandEvent&, bool);
|
||||
DECL_LINK(TooltipHdl, const HelpEvent&, bool);
|
||||
DECL_LINK(EntryAccessibleDescriptionHdl, SvTreeListEntry*, OUString);
|
||||
|
||||
public:
|
||||
SalInstanceIconView(::IconView* pIconView, SalInstanceBuilder* pBuilder, bool bTakeOwnership);
|
||||
|
|
|
@ -5317,6 +5317,10 @@ SalInstanceIconView::SalInstanceIconView(::IconView* pIconView, SalInstanceBuild
|
|||
m_xIconView->SetDeselectHdl(LINK(this, SalInstanceIconView, DeSelectHdl));
|
||||
m_xIconView->SetDoubleClickHdl(LINK(this, SalInstanceIconView, DoubleClickHdl));
|
||||
m_xIconView->SetPopupMenuHdl(LINK(this, SalInstanceIconView, CommandHdl));
|
||||
|
||||
m_xIconView->SetEntryAccessibleDescriptionHdl(
|
||||
LINK(this, SalInstanceIconView, EntryAccessibleDescriptionHdl));
|
||||
m_xIconView->SetAccessible(m_xIconView->CreateAccessible());
|
||||
}
|
||||
|
||||
int SalInstanceIconView::get_item_width() const { return m_xIconView->GetEntryWidth(); }
|
||||
|
@ -5457,6 +5461,14 @@ IMPL_LINK(SalInstanceIconView, TooltipHdl, const HelpEvent&, rHEvt, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
IMPL_LINK(SalInstanceIconView, EntryAccessibleDescriptionHdl, SvTreeListEntry*, pEntry, OUString)
|
||||
{
|
||||
OUString s = SvTreeListBox::SearchEntryTextWithHeadTitle(pEntry);
|
||||
if (s.isEmpty())
|
||||
s = signal_query_tooltip(SalInstanceTreeIter(pEntry));
|
||||
return s;
|
||||
}
|
||||
|
||||
void SalInstanceIconView::connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink)
|
||||
{
|
||||
weld::IconView::connect_query_tooltip(rLink);
|
||||
|
|
|
@ -82,6 +82,15 @@ namespace vcl
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
virtual css::uno::Reference< css::accessibility::XAccessible >
|
||||
createAccessibleIconView(
|
||||
SvTreeListBox& /*_rListBox*/,
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& /*_xParent*/
|
||||
) const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual vcl::IAccessibleBrowseBox*
|
||||
createAccessibleBrowseBox(
|
||||
const css::uno::Reference< css::accessibility::XAccessible >& /*_rxParent*/,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <vcl/toolkit/viewdataentry.hxx>
|
||||
#include <iconview.hxx>
|
||||
#include "iconviewimpl.hxx"
|
||||
#include <vcl/accessiblefactory.hxx>
|
||||
#include <vcl/uitest/uiobject.hxx>
|
||||
#include <tools/json_writer.hxx>
|
||||
#include <vcl/toolkit/svlbitm.hxx>
|
||||
|
@ -231,6 +232,30 @@ void IconView::PaintEntry(SvTreeListEntry& rEntry, tools::Long nX, tools::Long n
|
|||
}
|
||||
}
|
||||
|
||||
css::uno::Reference<css::accessibility::XAccessible> IconView::CreateAccessible()
|
||||
{
|
||||
if (vcl::Window* pParent = GetAccessibleParentWindow())
|
||||
{
|
||||
if (auto xAccParent = pParent->GetAccessible())
|
||||
{
|
||||
// need to be done here to get the vclxwindow later on in the accessible
|
||||
css::uno::Reference<css::awt::XWindowPeer> xHoldAlive(GetComponentInterface());
|
||||
return pImpl->m_aFactoryAccess.getFactory().createAccessibleIconView(*this, xAccParent);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
OUString IconView::GetEntryAccessibleDescription(SvTreeListEntry* pEntry) const
|
||||
{
|
||||
assert(pEntry);
|
||||
|
||||
if (maEntryAccessibleDescriptionHdl.IsSet())
|
||||
return maEntryAccessibleDescriptionHdl.Call(pEntry);
|
||||
|
||||
return SvTreeListBox::GetEntryAccessibleDescription(pEntry);
|
||||
}
|
||||
|
||||
FactoryFunction IconView::GetUITestFactory() const { return IconViewUIObject::create; }
|
||||
|
||||
static OUString extractPngString(const SvLBoxContextBmp* pBmpItem)
|
||||
|
|
|
@ -3513,6 +3513,33 @@ void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry* pEntry, ::utl:
|
|||
}
|
||||
}
|
||||
|
||||
OUString SvTreeListBox::GetEntryAccessibleDescription(SvTreeListEntry* pEntry) const
|
||||
{
|
||||
assert(pEntry);
|
||||
|
||||
//want to count the real column number in the list box.
|
||||
sal_uInt16 iRealItemCount = 0;
|
||||
for (size_t i = 0; i < pEntry->ItemCount(); ++i)
|
||||
{
|
||||
const SvLBoxItem& rItem = pEntry->GetItem(i);
|
||||
if (rItem.GetType() == SvLBoxItemType::String &&
|
||||
!static_cast<const SvLBoxString&>(rItem).GetText().isEmpty())
|
||||
{
|
||||
iRealItemCount++;
|
||||
}
|
||||
}
|
||||
// No idea why <= 1; that was in AccessibleListBoxEntry::getAccessibleDescription
|
||||
// since the "Integrate branch of IAccessible2" commit
|
||||
if (iRealItemCount <= 1)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return SearchEntryTextWithHeadTitle(pEntry);
|
||||
}
|
||||
}
|
||||
|
||||
tools::Rectangle SvTreeListBox::GetBoundingRect(const SvTreeListEntry* pEntry)
|
||||
{
|
||||
Point aPos = GetEntryPosition( pEntry );
|
||||
|
|
Loading…
Reference in a new issue