/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef IACCESSIBLE2_H #define IACCESSIBLE2_H #include #ifndef QT_NO_ACCESSIBILITY #include "qwindowscombase.h" #include "qwindowsmsaaaccessible.h" #include "comutils.h" #include "ia2_api_all.h" #include QT_BEGIN_NAMESPACE #ifdef Q_CC_MINGW QT_WARNING_DISABLE_GCC("-Wunused-function") // MinGW 7.X claims it is unused // MinGW's __uuidof operator does not work for the Accessible2 interfaces template <> IID qUuidOf() { return IID_IAccessibleComponent; } #endif // Q_CC_MINGW class QWindowsIA2Accessible : public QWindowsMsaaAccessible, public IAccessibleAction, public IAccessibleComponent, public IAccessibleEditableText, public IAccessibleTable2, public IAccessibleTableCell, public IAccessibleText, public IAccessibleValue, public IServiceProvider { public: QWindowsIA2Accessible(QAccessibleInterface *a) : QWindowsMsaaAccessible(a) {} /* IUnknown */ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); /* IAccessible2 */ HRESULT STDMETHODCALLTYPE get_nRelations(long *nRelations); HRESULT STDMETHODCALLTYPE get_relation(long relationIndex, IAccessibleRelation **relation); HRESULT STDMETHODCALLTYPE get_relations(long maxRelations, IAccessibleRelation **relations, long *nRelations); HRESULT STDMETHODCALLTYPE role(long *role); HRESULT STDMETHODCALLTYPE scrollTo(enum IA2ScrollType scrollType); HRESULT STDMETHODCALLTYPE scrollToPoint(enum IA2CoordinateType coordinateType, long x, long y); HRESULT STDMETHODCALLTYPE get_groupPosition(long *groupLevel, long *similarItemsInGroup, long *positionInGroup); HRESULT STDMETHODCALLTYPE get_states(AccessibleStates *states); HRESULT STDMETHODCALLTYPE get_extendedRole(BSTR *extendedRole); HRESULT STDMETHODCALLTYPE get_localizedExtendedRole(BSTR *localizedExtendedRole); HRESULT STDMETHODCALLTYPE get_nExtendedStates(long *nExtendedStates); HRESULT STDMETHODCALLTYPE get_extendedStates(long maxExtendedStates, BSTR **extendedStates, long *nExtendedStates); HRESULT STDMETHODCALLTYPE get_localizedExtendedStates(long maxLocalizedExtendedStates, BSTR **localizedExtendedStates, long *nLocalizedExtendedStates); HRESULT STDMETHODCALLTYPE get_uniqueID(long *uniqueID); HRESULT STDMETHODCALLTYPE get_windowHandle(HWND *windowHandle); HRESULT STDMETHODCALLTYPE get_indexInParent(long *indexInParent); HRESULT STDMETHODCALLTYPE get_locale(IA2Locale *locale); HRESULT STDMETHODCALLTYPE get_attributes(BSTR *attributes); /* IAccessibleAction */ HRESULT STDMETHODCALLTYPE nActions(long *nActions); HRESULT STDMETHODCALLTYPE doAction(long actionIndex); HRESULT STDMETHODCALLTYPE get_description(long actionIndex, BSTR *description); HRESULT STDMETHODCALLTYPE get_keyBinding(long actionIndex, long nMaxBindings, BSTR **keyBindings, long *nBindings); HRESULT STDMETHODCALLTYPE get_name(long actionIndex, BSTR *name); HRESULT STDMETHODCALLTYPE get_localizedName(long actionIndex, BSTR *localizedName); /* IAccessibleComponent */ HRESULT STDMETHODCALLTYPE get_locationInParent(long *x,long *y); HRESULT STDMETHODCALLTYPE get_foreground(IA2Color *foreground); HRESULT STDMETHODCALLTYPE get_background(IA2Color *background); /* IAccessibleEditableText */ HRESULT STDMETHODCALLTYPE copyText(long startOffset, long endOffset); HRESULT STDMETHODCALLTYPE deleteText(long startOffset, long endOffset); HRESULT STDMETHODCALLTYPE insertText(long offset, BSTR *text); HRESULT STDMETHODCALLTYPE cutText(long startOffset, long endOffset); HRESULT STDMETHODCALLTYPE pasteText(long offset); HRESULT STDMETHODCALLTYPE replaceText(long startOffset, long endOffset, BSTR *text); HRESULT STDMETHODCALLTYPE setAttributes(long startOffset, long endOffset, BSTR *attributes); /* IAccessibleTable2 */ HRESULT STDMETHODCALLTYPE get_cellAt( long row, long column, IUnknown **cell); HRESULT STDMETHODCALLTYPE get_caption( IUnknown **accessibleInterface); HRESULT STDMETHODCALLTYPE get_columnDescription( long column, BSTR *description); HRESULT STDMETHODCALLTYPE get_nColumns( long *columnCount); HRESULT STDMETHODCALLTYPE get_nRows( long *rowCount); HRESULT STDMETHODCALLTYPE get_nSelectedCells( long *cellCount); HRESULT STDMETHODCALLTYPE get_nSelectedColumns( long *columnCount); HRESULT STDMETHODCALLTYPE get_nSelectedRows( long *rowCount); HRESULT STDMETHODCALLTYPE get_rowDescription( long row, BSTR *description); HRESULT STDMETHODCALLTYPE get_selectedCells( IUnknown ***cells, long *nSelectedCells); HRESULT STDMETHODCALLTYPE get_selectedColumns( long **selectedColumns, long *nColumns); HRESULT STDMETHODCALLTYPE get_selectedRows( long **selectedRows, long *nRows); HRESULT STDMETHODCALLTYPE get_summary( IUnknown **accessibleInterface); HRESULT STDMETHODCALLTYPE get_isColumnSelected( long column, boolean *isSelected); HRESULT STDMETHODCALLTYPE get_isRowSelected( long row, boolean *isSelected); HRESULT STDMETHODCALLTYPE selectRow( long row); HRESULT STDMETHODCALLTYPE selectColumn( long column); HRESULT STDMETHODCALLTYPE unselectRow( long row); HRESULT STDMETHODCALLTYPE unselectColumn( long column); HRESULT STDMETHODCALLTYPE get_modelChange( IA2TableModelChange *modelChange); /* IAccessibleTableCell */ HRESULT STDMETHODCALLTYPE get_columnExtent(long *nColumnsSpanned); HRESULT STDMETHODCALLTYPE get_columnHeaderCells(IUnknown ***cellAccessibles, long *nColumnHeaderCells); HRESULT STDMETHODCALLTYPE get_columnIndex(long *columnIndex); HRESULT STDMETHODCALLTYPE get_rowExtent(long *nRowsSpanned); HRESULT STDMETHODCALLTYPE get_rowHeaderCells(IUnknown ***cellAccessibles, long *nRowHeaderCells); HRESULT STDMETHODCALLTYPE get_rowIndex(long *rowIndex); HRESULT STDMETHODCALLTYPE get_isSelected( boolean *isSelected); HRESULT STDMETHODCALLTYPE get_rowColumnExtents(long *row, long *column, long *rowExtents, long *columnExtents, boolean *isSelected); HRESULT STDMETHODCALLTYPE get_table(IUnknown **table); /* IAccessibleText */ HRESULT STDMETHODCALLTYPE addSelection(long startOffset, long endOffset); HRESULT STDMETHODCALLTYPE get_attributes(long offset, long *startOffset, long *endOffset, BSTR *textAttributes); HRESULT STDMETHODCALLTYPE get_caretOffset(long *offset); HRESULT STDMETHODCALLTYPE get_characterExtents(long offset, enum IA2CoordinateType coordType, long *x, long *y, long *width, long *height); HRESULT STDMETHODCALLTYPE get_nSelections(long *nSelections); HRESULT STDMETHODCALLTYPE get_offsetAtPoint(long x, long y, enum IA2CoordinateType coordType, long *offset); HRESULT STDMETHODCALLTYPE get_selection(long selectionIndex, long *startOffset, long *endOffset); HRESULT STDMETHODCALLTYPE get_text(long startOffset, long endOffset, BSTR *text); HRESULT STDMETHODCALLTYPE get_textBeforeOffset(long offset, enum IA2TextBoundaryType boundaryType, long *startOffset, long *endOffset, BSTR *text); HRESULT STDMETHODCALLTYPE get_textAfterOffset(long offset, enum IA2TextBoundaryType boundaryType, long *startOffset, long *endOffset, BSTR *text); HRESULT STDMETHODCALLTYPE get_textAtOffset(long offset, enum IA2TextBoundaryType boundaryType, long *startOffset, long *endOffset, BSTR *text); HRESULT STDMETHODCALLTYPE removeSelection(long selectionIndex); HRESULT STDMETHODCALLTYPE setCaretOffset(long offset); HRESULT STDMETHODCALLTYPE setSelection(long selectionIndex, long startOffset, long endOffset); HRESULT STDMETHODCALLTYPE get_nCharacters(long *nCharacters); HRESULT STDMETHODCALLTYPE scrollSubstringTo(long startIndex, long endIndex, enum IA2ScrollType scrollType); HRESULT STDMETHODCALLTYPE scrollSubstringToPoint(long startIndex, long endIndex, enum IA2CoordinateType coordinateType, long x, long y); HRESULT STDMETHODCALLTYPE get_newText(IA2TextSegment *newText); HRESULT STDMETHODCALLTYPE get_oldText(IA2TextSegment *oldText); /* IAccessibleValue */ HRESULT STDMETHODCALLTYPE get_currentValue(VARIANT *currentValue); HRESULT STDMETHODCALLTYPE setCurrentValue(VARIANT value); HRESULT STDMETHODCALLTYPE get_maximumValue(VARIANT *maximumValue); HRESULT STDMETHODCALLTYPE get_minimumValue(VARIANT *minimumValue); /* IServiceProvider */ HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppv); /* private helper functions */ private: inline QAccessibleTextInterface *textInterface() const { QAccessibleInterface *accessible = accessibleInterface(); return accessible ? accessible->textInterface() : static_cast(0); } inline QAccessibleActionInterface *actionInterface() const { QAccessibleInterface *accessible = accessibleInterface(); return accessible->actionInterface(); } inline QAccessibleValueInterface *valueInterface() const { QAccessibleInterface *accessible = accessibleInterface(); return accessible->valueInterface(); } inline QAccessibleTableInterface *tableInterface() const { QAccessibleInterface *accessible = accessibleInterface(); return accessible->tableInterface(); } inline QAccessibleTableCellInterface *tableCellInterface() const { QAccessibleInterface *accessible = accessibleInterface(); return accessible->tableCellInterface(); } /*! \internal \a screenPos is in screen relative position \a x and \y (out) is in parent relative position if coordType == IA2_COORDTYPE_PARENT_RELATIVE */ void mapFromScreenPos(enum IA2CoordinateType coordType, const QPoint &screenPos, long *x, long *y) const { QAccessibleInterface *accessible = accessibleInterface(); if (coordType == IA2_COORDTYPE_PARENT_RELATIVE) { // caller wants relative to parent if (QAccessibleInterface *parent = accessible->parent()) { const QRect parentScreenRect = parent->rect(); *x = parentScreenRect.x() - screenPos.x(); *y = parentScreenRect.y() - screenPos.y(); return; } } *x = screenPos.x(); *y = screenPos.y(); } /*! \internal \a x and \y is in parent relative position if coordType == IA2_COORDTYPE_PARENT_RELATIVE \return a screen relative position */ QPoint mapToScreenPos(enum IA2CoordinateType coordType, long x, long y) const { QAccessibleInterface *accessible = accessibleInterface(); if (coordType == IA2_COORDTYPE_PARENT_RELATIVE) { if (QAccessibleInterface *parent = accessible->parent()) { const QRect parentScreenRect = parent->rect(); return QPoint(parentScreenRect.x() + x, parentScreenRect.y() + y); } } return QPoint(x,y); } HRESULT getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations = 0); HRESULT wrapListOfCells(const QList &inputCells, IUnknown ***outputAccessibles, long *nCellCount); QString textForRange(int startOffset, int endOffset) const; void replaceTextFallback(long startOffset, long endOffset, const QString &txt); }; /**************************************************************\ * AccessibleApplication * **************************************************************/ #ifdef Q_CC_MINGW // MinGW's __uuidof operator does not work for the IAccessible2 interfaces template <> IID qUuidOf() { return IID_IAccessibleApplication; } template <> IID qUuidOf() { return IID_IAccessible2; } template <> IID qUuidOf() { return IID_IAccessibleRelation; } #endif // Q_CC_MINGW class AccessibleApplication : public QWindowsComBase { public: AccessibleApplication() {} virtual ~AccessibleApplication() {} /* IAccessibleApplication */ HRESULT STDMETHODCALLTYPE get_appName(/* [retval][out] */ BSTR *name); HRESULT STDMETHODCALLTYPE get_appVersion(/* [retval][out] */ BSTR *version); HRESULT STDMETHODCALLTYPE get_toolkitName(/* [retval][out] */ BSTR *name); HRESULT STDMETHODCALLTYPE get_toolkitVersion(/* [retval][out] */ BSTR *version); }; /**************************************************************\ * AccessibleRelation * **************************************************************/ class AccessibleRelation : public QWindowsComBase { public: AccessibleRelation(const QList &targets, QAccessible::Relation relation); virtual ~AccessibleRelation() {} /* IAccessibleRelation */ HRESULT STDMETHODCALLTYPE get_relationType(BSTR *relationType); HRESULT STDMETHODCALLTYPE get_localizedRelationType(BSTR *localizedRelationType); HRESULT STDMETHODCALLTYPE get_nTargets(long *nTargets); HRESULT STDMETHODCALLTYPE get_target(long targetIndex, IUnknown **target); HRESULT STDMETHODCALLTYPE get_targets(long maxTargets, IUnknown **targets, long *nTargets); private: static BSTR relationToBSTR(QAccessible::Relation relation) { const wchar_t *constRelationString = 0; switch (relation) { case QAccessible::Label: constRelationString = IA2_RELATION_LABEL_FOR; break; case QAccessible::Labelled: constRelationString = IA2_RELATION_LABELLED_BY; break; case QAccessible::Controller: constRelationString = IA2_RELATION_CONTROLLER_FOR; break; case QAccessible::Controlled: constRelationString = IA2_RELATION_CONTROLLED_BY; break; case QAccessible::AllRelations: constRelationString = ( L"AllRelations" ); break; } if (constRelationString) { BSTR bstrVal; const UINT wlen = (UINT)wcslen(constRelationString); bstrVal = ::SysAllocStringLen(constRelationString, wlen); return bstrVal; } return 0; } QList m_targets; QAccessible::Relation m_relation; }; QT_END_NAMESPACE #endif //QT_NO_ACCESSIBILITY #endif // IACCESSIBLE2_H