winaccessibility/source/UAccCOM/AccTableCell.cxx |   82 +++++++++++++++++++++++
 winaccessibility/source/UAccCOM/AccTableCell.h   |    4 -
 2 files changed, 84 insertions(+), 2 deletions(-)

New commits:
commit 8a4271e168f70f9147b567189c1770a243e7fcb1
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Fri Aug 5 09:49:02 2022 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Aug 5 13:22:45 2022 +0200

    wina11y: Implement IAccessibleTableCell::get{column,row}HeaderCells
    
    This is essentially the Windows version of
    
        commit 12f96c3d0f61018cfa83c940765311aa9015f60a
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Thu Aug 4 13:27:32 2022 +0200
    
            qt a11y: implement QtAccessibleWidget::{row,column}HeaderCells
    
    Tested using NVDA's Python Console as follows:
    
    1) start LO Writer, "Table" -> "Insert Table"
    2) select to create table with  2 rows, 2 columns
    3) make sure "Heading" is checked, "Heading rows": 1
    4) "Insert"
    5) in the first row, type "First heading" into first column,
       "Second heading" into second column
    5) start NVDA
    6) move cursor to the table cell in second row first column
       (i.e. the cell below "Heading 1")
    7) press KP_Insert+Ctrl+Z to start NVDA's Python console
    8) Use NVDA's Python console to call corresponding IAccessible2
        methods and check the result:
    
        >>> from IAccessibleHandler import IA2
        >>> cell = 
focus.parent.IAccessibleObject.QueryInterface(IA2.IAccessibleTableCell)
        >>> cell.columnHeaderCells
        (<comtypes.LP_POINTER(IUnknown) object at 0x010528A0>, 2)
        >>> header_cell = cell.columnHeaderCells[0].contents
        >>> header_cell.QueryInterface(IA2.IAccessibleTableCell).columnIndex
        0
        >>> header_cell.QueryInterface(IA2.IAccessibleTableCell).rowIndex
        0
    
    9) Repeat steps 6-8, but now with the cursor in cell in
       second row, second column (i.e. the cell below "Heading 2") instead,
       which correctly returns the cell with row index 0 and column index 1 as 
header cell:
    
        >>> from IAccessibleHandler import IA2
        >>> cell = 
focus.parent.IAccessibleObject.QueryInterface(IA2.IAccessibleTableCell)
        >>> cell.columnHeaderCells
        (<comtypes.LP_POINTER(IUnknown) object at 0x01024B70>, 2)
        >>> header_cell = cell.columnHeaderCells[0].contents
        >>> header_cell.QueryInterface(IA2.IAccessibleTableCell).columnIndex
        1
        >>> header_cell.QueryInterface(IA2.IAccessibleTableCell).rowIndex
        0
    
    Without this commit, this would fail like this:
    
        >>> from IAccessibleHandler import IA2
        >>> cell = 
focus.parent.IAccessibleObject.QueryInterface(IA2.IAccessibleTableCell)
        >>> cell.columnHeaderCells
        Traceback (most recent call last):
          File "<console>", line 1, in <module>
          File "monkeyPatches\comtypesMonkeyPatches.pyc", line 32, in __call__
        _ctypes.COMError: (-2147467259, 'Unspecified error', (None, None, None, 
0, None))
    
    Change-Id: I8de495ad28b2bece971fe4462e539bcc242ed440
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137847
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/winaccessibility/source/UAccCOM/AccTableCell.cxx 
b/winaccessibility/source/UAccCOM/AccTableCell.cxx
index 5e793af9ec96..1b126404456a 100644
--- a/winaccessibility/source/UAccCOM/AccTableCell.cxx
+++ b/winaccessibility/source/UAccCOM/AccTableCell.cxx
@@ -91,6 +91,47 @@ COM_DECLSPEC_NOTHROW STDMETHODIMP 
CAccTableCell::get_columnExtent(long* pColumns
     }
 }
 
+COM_DECLSPEC_NOTHROW STDMETHODIMP 
CAccTableCell::get_columnHeaderCells(IUnknown*** cellAccessibles,
+                                                                       long* 
pColumnHeaderCellCount)
+{
+    SolarMutexGuard g;
+
+    if (!cellAccessibles || !pColumnHeaderCellCount)
+        return E_INVALIDARG;
+
+    if (!m_xTable.is())
+        return E_FAIL;
+
+    Reference<XAccessibleTable> xHeaders = 
m_xTable->getAccessibleColumnHeaders();
+    if (!xHeaders.is())
+        return E_FAIL;
+
+    const sal_Int32 nCount = xHeaders->getAccessibleRowCount();
+    *pColumnHeaderCellCount = nCount;
+    *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * 
sizeof(IUnknown*)));
+    sal_Int32 nCol = 0;
+    get_columnIndex(&nCol);
+    for (sal_Int32 nRow = 0; nRow < nCount; nRow++)
+    {
+        Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, 
nCol);
+        assert(xCell.is());
+
+        IAccessible* pIAccessible;
+        bool bOK = CMAccessible::get_IAccessibleFromXAccessible(xCell.get(), 
&pIAccessible);
+        if (!bOK)
+        {
+            Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
+            CMAccessible::g_pAgent->InsertAccObj(xCell.get(), xTableAcc.get());
+            bOK = CMAccessible::get_IAccessibleFromXAccessible(xCell.get(), 
&pIAccessible);
+        }
+        assert(bOK && "Couldn't retrieve IAccessible object for cell.");
+
+        pIAccessible->AddRef();
+        (*cellAccessibles)[nRow] = pIAccessible;
+    }
+    return S_OK;
+}
+
 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnIndex(long* 
pColumnIndex)
 {
     SolarMutexGuard g;
@@ -138,6 +179,47 @@ COM_DECLSPEC_NOTHROW STDMETHODIMP 
CAccTableCell::get_rowExtent(long* pRowsSpanne
     }
 }
 
+COM_DECLSPEC_NOTHROW STDMETHODIMP 
CAccTableCell::get_rowHeaderCells(IUnknown*** cellAccessibles,
+                                                                    long* 
pRowHeaderCellCount)
+{
+    SolarMutexGuard g;
+
+    if (!cellAccessibles || !pRowHeaderCellCount)
+        return E_INVALIDARG;
+
+    if (!m_xTable.is())
+        return E_FAIL;
+
+    Reference<XAccessibleTable> xHeaders = m_xTable->getAccessibleRowHeaders();
+    if (!xHeaders.is())
+        return E_FAIL;
+
+    const sal_Int32 nCount = xHeaders->getAccessibleColumnCount();
+    *pRowHeaderCellCount = nCount;
+    *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * 
sizeof(IUnknown*)));
+    sal_Int32 nRow = 0;
+    get_rowIndex(&nRow);
+    for (sal_Int32 nCol = 0; nCol < nCount; nCol++)
+    {
+        Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, 
nCol);
+        assert(xCell.is());
+
+        IAccessible* pIAccessible;
+        bool bOK = CMAccessible::get_IAccessibleFromXAccessible(xCell.get(), 
&pIAccessible);
+        if (!bOK)
+        {
+            Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
+            CMAccessible::g_pAgent->InsertAccObj(xCell.get(), xTableAcc.get());
+            bOK = CMAccessible::get_IAccessibleFromXAccessible(xCell.get(), 
&pIAccessible);
+        }
+        assert(bOK && "Couldn't retrieve IAccessible object for cell.");
+
+        pIAccessible->AddRef();
+        (*cellAccessibles)[nRow] = pIAccessible;
+    }
+    return S_OK;
+}
+
 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowIndex(long* pRowIndex)
 {
     SolarMutexGuard g;
diff --git a/winaccessibility/source/UAccCOM/AccTableCell.h 
b/winaccessibility/source/UAccCOM/AccTableCell.h
index 0b85a6c245d1..ee1649ea7115 100644
--- a/winaccessibility/source/UAccCOM/AccTableCell.h
+++ b/winaccessibility/source/UAccCOM/AccTableCell.h
@@ -70,10 +70,10 @@ public:
 
     // IAccessibleTableCell interfaces
     STDMETHOD(get_columnExtent)(long*) override;
-    STDMETHOD(get_columnHeaderCells)(IUnknown***, long*) override { return 
E_FAIL; }
+    STDMETHOD(get_columnHeaderCells)(IUnknown***, long*) override;
     STDMETHOD(get_columnIndex)(long*) override;
     STDMETHOD(get_rowExtent)(long*) override;
-    STDMETHOD(get_rowHeaderCells)(IUnknown***, long*) override { return 
E_FAIL; }
+    STDMETHOD(get_rowHeaderCells)(IUnknown***, long*) override;
     STDMETHOD(get_rowIndex)(long*) override;
     STDMETHOD(get_isSelected)(boolean*) override;
     STDMETHOD(get_rowColumnExtents)(long*, long*, long*, long*, boolean*) 
override;

Reply via email to