offapi/com/sun/star/accessibility/AccessibleTableModelChange.idl | 4 offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl | 64 +++++++++- vcl/osx/a11ylistener.cxx | 6 vcl/unx/gtk3/a11y/atklistener.cxx | 17 ++ 4 files changed, 81 insertions(+), 10 deletions(-)
New commits: commit 5371eef48a34acd06307a7b2bf898586938e27ff Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Mon Mar 28 08:40:59 2022 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Mar 29 06:48:25 2022 +0200 a11y: Add new table model change types for row/col insertion/del So far, there were two types/constants to use in an `AcessibleTableModelChange` event to indicate the insertion or deletion of rows and/or columns. From `offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl`: > /** One or more rows and/or columns have been inserted. > > <p>Use the fields of the AccessibleTableModelChange > structure to determine the indices of the rows and/or columns that > have been inserted.</p> > */ > const short INSERT = 1; > > /** One or more rows and/or columns have been deleted. > > <p>The affected area of the table is stored in the fields of the > AccessibleTableModelChange structure.</p> > */ > const short DELETE = 2; From the documentation, it would be possible to indicate an insertion or deletion of both, rows and columns in a single event. However, there is no single instance where this is actually used to indicate the deletion/insertion of both, whole rows and whole columns at the same time. The way that indices are currently used is rather confusing and results in incorrect a11y events being sent on maOS as well as the gtk3 VCL plugin: When only rows are inserted, row indices are set as expected (index of the first and last inserted row), but the column indices are set to the first and last column in the table; i.e. the indices actually give the range of the newly inserted cell range, rather than just the indices of the rows that have been inserted. (The same applies the other way around when only columns are inserted.) That's not what I would have expected when reading the documentation. ("Use the fields of the AccessibleTableModelChange structure to determine the indices of the rows and/or columns that have been inserted.") In the same way, the range of deleted cells is set when emitting `AccessibleTableModelChangeType::DELETE` events. In this case, this can be seen as matching what the documentation says. ("The affected area of the table is stored in the fields of the AccessibleTableModelChange structure.") In any case, the way that the events are handled in the gtk3 VCL plugin and for macOS results in the emission of incorrect events, since those are handling such indices as if both, rows and columns had been inserted/deleted. Example for the gtk3 VCL plugin: Row with index 1 has been deleted from a table. -> an AccessibleTableModelChange event is sent with Type=AccessibleTableModelChangeType::DELETE FirstRow=1 LastRow=1 FirstColumn=0 LastColumn=<index of last column> This would then result in 2 AT-SPI events being emitted by the gtk3 VCL plugin: * one that indicates that row 1 has been deleted (OK) * another event that indicates that all columns have been deleted (NOT OK) Instead of changing the handling of the existing `AccessibleTableModelChangeType`s, introduce 4 new types to replace the existing ones that don't mix handling of rows and columns at the same time: one for row insertion, one for column insertion, one for row deletion, one for column deletion. This commit also adds handling for the newly added change types for macOS and the gtk3 VCL plugin on Linux. winaccessibility is unaffected because it doesn't have any handling specific to the change type. The qt5/qt6 VCL plugins don't yet have any handling for the `AcessibleTableModelChange` event yet (but that will be added in a follow-up commit). Existing uses of `AccessibleTableModelChangeType::INSERT` and `AccessibleTableModelChangeType::DELETE` will be migrated to use the new types in follow-up commits. From a UNO API perspective, this change and the final removal of the `AccessibleTableModelChangeType::DELETE` and `AccessibleTableModelChangeType::INSERT` constants in a follow-up commit should be unproblematic, because the corresponding APIs have been unpublished in commit 70626249cd247d9acdad417b8eaf252bae22c059 Date: Thu Nov 29 00:27:03 2012 +0100 API CHANGE a11y unpublishing and add/removeListener rename. The following Python script was used in follow-up commits to check that AT-SPI events with the expected indices are retrieved with the gtk3 VCL plugin after porting existing uses of `AccessibleTableModelChangeType::INSERT` and `AccessibleTableModelChangeType::DELETE`. #!/usr/bin/python3 import pyatspi def listener(e): try: if e.host_application.name != 'soffice': return except: return print(e) pyatspi.Registry.registerEventListener(listener, "object:row-inserted", "object:column-inserted", "object:column-deleted", "object:row-deleted") pyatspi.Registry.start() Change-Id: I30821a5acafa4f3d1dafdfc219f3b4568d9a6e89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132217 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/offapi/com/sun/star/accessibility/AccessibleTableModelChange.idl b/offapi/com/sun/star/accessibility/AccessibleTableModelChange.idl index ae49447cecb6..236c4401423d 100644 --- a/offapi/com/sun/star/accessibility/AccessibleTableModelChange.idl +++ b/offapi/com/sun/star/accessibility/AccessibleTableModelChange.idl @@ -39,8 +39,8 @@ struct AccessibleTableModelChange /** The type of the event as defined in AccessibleTableModelChangeType. - <p>The model change either inserted or deleted one or more rows - and/or columns or modified the content of a number of cells. See + <p>The model change either inserted or removed one or more rows + or columns or modified the content of a number of cells. See AccessibleTableModelChangeType for details of the type of the model change.</p> */ diff --git a/offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl b/offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl index 88729f6a46f1..69669eb11eda 100644 --- a/offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl +++ b/offapi/com/sun/star/accessibility/AccessibleTableModelChangeType.idl @@ -30,11 +30,13 @@ module com { module sun { module star { module accessibility { AccessibleTableModelChange structure to specify the type of change that has been made to a table model.</p> - <p>Two of the constants, - AccessibleTableModelChangeType::INSERT and - AccessibleTableModelChangeType::DELETE describe - changes to the table's geometry. One or more rows and/or columns have - been inserted or deleted. In contrast, the remaining constant + <p>Four of the constants, + AccessibleTableModelChangeType::ROWS_INSERTED, + AccessibleTableModelChangeType::COLUMNS_INSERTED, + AccessibleTableModelChangeType::ROWS_REMOVED and + AccessibleTableModelChangeType::COLUMNS_REMOVED describe + changes to the table's geometry. One or more rows or columns have + been inserted or removed. In contrast, the remaining constant AccessibleTabelModelChangeType::UPDATE specifies a change of the table's content.</p> @@ -47,6 +49,10 @@ constants AccessibleTableModelChangeType <p>Use the fields of the AccessibleTableModelChange structure to determine the indices of the rows and/or columns that have been inserted.</p> + + @deprecated: use ROWS_INSERTED/COLUMNS_INSERTED instead. + This constant will be removed once all remaining uses have been + ported. */ const short INSERT = 1; @@ -54,6 +60,10 @@ constants AccessibleTableModelChangeType <p>The affected area of the table is stored in the fields of the AccessibleTableModelChange structure.</p> + + @deprecated: use ROWS_REMOVED/COLUMNS_REMOVED instead. + This constant will be removed once all remaining uses have been + ported. */ const short DELETE = 2; @@ -65,6 +75,50 @@ constants AccessibleTableModelChangeType been changed.</p> */ const short UPDATE = 3; + + /** One or more rows have been inserted. + + <p>Use the fields of the AccessibleTableModelChange + structure to determine the indices of the rows that + have been inserted. + Column indices should be set to -1.</p> + + @since LibreOffice 7.4 + */ + const short ROWS_INSERTED = 4; + + /** One or more columns have been inserted. + + <p>Use the fields of the AccessibleTableModelChange + structure to determine the indices of the columns that + have been inserted. + Row indices should be set to -1.</p> + + @since LibreOffice 7.4 + */ + const short COLUMNS_INSERTED = 5; + + /** One or more rows have been removed. + + <p>Use the fields of the AccessibleTableModelChange + structure to determine the indices of the rows that + have been removed. + Column indices should be set to -1.</p> + + @since LibreOffice 7.4 + */ + const short ROWS_REMOVED = 6; + + /** One or more columns have been removed. + + <p>Use the fields of the AccessibleTableModelChange + structure to determine the indices of the columns that + have been removed. + Row indices should be set to -1.</p> + + @since LibreOffice 7.4 + */ + const short COLUMNS_REMOVED = 7; }; }; }; }; }; diff --git a/vcl/osx/a11ylistener.cxx b/vcl/osx/a11ylistener.cxx index b34d047b3b7b..fd275dab3079 100644 --- a/vcl/osx/a11ylistener.cxx +++ b/vcl/osx/a11ylistener.cxx @@ -41,8 +41,10 @@ static NSString * getTableNotification( const AccessibleEventObject& aEvent ) NSString * notification = nil; if( (aEvent.NewValue >>= aChange) && - ( AccessibleTableModelChangeType::INSERT == aChange.Type || AccessibleTableModelChangeType::DELETE == aChange.Type ) && - aChange.FirstRow != aChange.LastRow ) + (aChange.Type == AccessibleTableModelChangeType::ROWS_INSERTED || + aChange.Type == AccessibleTableModelChangeType::ROWS_REMOVED || + (( AccessibleTableModelChangeType::INSERT == aChange.Type || AccessibleTableModelChangeType::DELETE == aChange.Type ) && + aChange.FirstRow != aChange.LastRow ))) { notification = NSAccessibilityRowCountChangedNotification; } diff --git a/vcl/unx/gtk3/a11y/atklistener.cxx b/vcl/unx/gtk3/a11y/atklistener.cxx index 6d81a9a60531..d73c2f753b3b 100644 --- a/vcl/unx/gtk3/a11y/atklistener.cxx +++ b/vcl/unx/gtk3/a11y/atklistener.cxx @@ -647,7 +647,22 @@ void AtkListener::notifyEvent( const accessibility::AccessibleEventObject& aEven aSignalNames[aChange.Type].col, aChange.FirstColumn, nColumnsChanged ); break; - + case accessibility::AccessibleTableModelChangeType::COLUMNS_INSERTED: + g_signal_emit_by_name(G_OBJECT(atk_obj), "column-inserted", + aChange.FirstColumn, nColumnsChanged); + break; + case accessibility::AccessibleTableModelChangeType::COLUMNS_REMOVED: + g_signal_emit_by_name(G_OBJECT(atk_obj), "column-deleted", + aChange.FirstColumn, nColumnsChanged); + break; + case accessibility::AccessibleTableModelChangeType::ROWS_INSERTED: + g_signal_emit_by_name(G_OBJECT(atk_obj), "row-inserted", + aChange.FirstRow, nRowsChanged); + break; + case accessibility::AccessibleTableModelChangeType::ROWS_REMOVED: + g_signal_emit_by_name(G_OBJECT(atk_obj), "row-deleted", + aChange.FirstRow, nRowsChanged); + break; case accessibility::AccessibleTableModelChangeType::UPDATE: // This is not really a model change, is it ? break;