accessibility/Library_acc.mk                             |    1 
 accessibility/inc/extended/AccessibleIconView.hxx        |   30 ++++++++
 accessibility/inc/extended/accessiblelistbox.hxx         |    9 +-
 accessibility/source/extended/AccessibleIconView.cxx     |   53 +++++++++++++++
 accessibility/source/extended/accessiblelistboxentry.cxx |   25 -------
 accessibility/source/helper/acc_factory.cxx              |   13 +++
 include/vcl/accessiblefactory.hxx                        |    5 +
 include/vcl/toolkit/treelistbox.hxx                      |    2 
 include/vcl/weld.hxx                                     |    5 +
 starmath/source/accessibility.cxx                        |    6 -
 vcl/inc/iconview.hxx                                     |   11 +++
 vcl/inc/salvtables.hxx                                   |    1 
 vcl/source/app/salvtables.cxx                            |   12 +++
 vcl/source/helper/svtaccessiblefactory.cxx               |    9 ++
 vcl/source/treelist/iconview.cxx                         |   25 +++++++
 vcl/source/treelist/treelistbox.cxx                      |   27 +++++++
 16 files changed, 202 insertions(+), 32 deletions(-)

New commits:
commit 2a28ebeef5ea3e2b01d836a7233d2316b765bf38
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Jun 1 11:18:26 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Jun 9 17:49:16 2022 +0200

    Accessibility for IconView
    
    Change-Id: I65ca9d43f70a50e2e95aabfc3b8ba1b15f9ff8be
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135226
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/accessibility/Library_acc.mk b/accessibility/Library_acc.mk
index 0926fee97e5d..34c4dc7eb0c5 100644
--- a/accessibility/Library_acc.mk
+++ b/accessibility/Library_acc.mk
@@ -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 \
diff --git a/accessibility/inc/extended/AccessibleIconView.hxx 
b/accessibility/inc/extended/AccessibleIconView.hxx
new file mode 100644
index 000000000000..d5ab5eafb198
--- /dev/null
+++ b/accessibility/inc/extended/AccessibleIconView.hxx
@@ -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: */
diff --git a/accessibility/inc/extended/accessiblelistbox.hxx 
b/accessibility/inc/extended/accessiblelistbox.hxx
index 4f4104701709..40b01ea180a5 100644
--- a/accessibility/inc/extended/accessiblelistbox.hxx
+++ b/accessibility/inc/extended/accessiblelistbox.hxx
@@ -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
diff --git a/accessibility/source/extended/AccessibleIconView.cxx 
b/accessibility/source/extended/AccessibleIconView.cxx
new file mode 100644
index 000000000000..6bc5c99e9243
--- /dev/null
+++ b/accessibility/source/extended/AccessibleIconView.cxx
@@ -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: */
diff --git a/accessibility/source/extended/accessiblelistboxentry.cxx 
b/accessibility/source/extended/accessiblelistboxentry.cxx
index a1e38012dfff..2fff77b03699 100644
--- a/accessibility/source/extended/accessiblelistboxentry.cxx
+++ b/accessibility/source/extended/accessiblelistboxentry.cxx
@@ -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(  )
diff --git a/accessibility/source/helper/acc_factory.cxx 
b/accessibility/source/helper/acc_factory.cxx
index 53ed173c15b2..10cc27f007c6 100644
--- a/accessibility/source/helper/acc_factory.cxx
+++ b/accessibility/source/helper/acc_factory.cxx
@@ -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
diff --git a/include/vcl/accessiblefactory.hxx 
b/include/vcl/accessiblefactory.hxx
index f0482392fb65..a13e4dabc135 100644
--- a/include/vcl/accessiblefactory.hxx
+++ b/include/vcl/accessiblefactory.hxx
@@ -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,
diff --git a/include/vcl/toolkit/treelistbox.hxx 
b/include/vcl/toolkit/treelistbox.hxx
index 7e21dfda21e7..216ffd55d83c 100644
--- a/include/vcl/toolkit/treelistbox.hxx
+++ b/include/vcl/toolkit/treelistbox.hxx
@@ -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.
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 135378ec540f..83e68002ce6c 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -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;
diff --git a/starmath/source/accessibility.cxx 
b/starmath/source/accessibility.cxx
index 25fd9532c758..591bbeafbba5 100644
--- a/starmath/source/accessibility.cxx
+++ b/starmath/source/accessibility.cxx
@@ -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) );
     }
 }
 
diff --git a/vcl/inc/iconview.hxx b/vcl/inc/iconview.hxx
index 971a638cc6ef..c5ece6d4aeb1 100644
--- a/vcl/inc/iconview.hxx
+++ b/vcl/inc/iconview.hxx
@@ -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
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 81e1d1f00d4f..4fab7dfe2bb9 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -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);
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 0a26b3ae49a4..f548fe152b4f 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -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);
diff --git a/vcl/source/helper/svtaccessiblefactory.cxx 
b/vcl/source/helper/svtaccessiblefactory.cxx
index 82845ec041d9..f6728732a2e7 100644
--- a/vcl/source/helper/svtaccessiblefactory.cxx
+++ b/vcl/source/helper/svtaccessiblefactory.cxx
@@ -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*/,
diff --git a/vcl/source/treelist/iconview.cxx b/vcl/source/treelist/iconview.cxx
index 6b8a193fde11..7814810cb7dd 100644
--- a/vcl/source/treelist/iconview.cxx
+++ b/vcl/source/treelist/iconview.cxx
@@ -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)
diff --git a/vcl/source/treelist/treelistbox.cxx 
b/vcl/source/treelist/treelistbox.cxx
index 962dd60cf53b..925900dc0e2d 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -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 );

Reply via email to