/**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "itemviews.h" #include #include #include #include #include #include #include #ifndef QT_NO_ACCESSIBILITY QT_BEGIN_NAMESPACE QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); #ifndef QT_NO_ITEMVIEWS /* Implementation of the IAccessible2 table2 interface. Much simpler than the other table interfaces since there is only the main table and cells: TABLE/LIST/TREE |- HEADER CELL |- CELL |- CELL ... */ QAbstractItemView *QAccessibleTable::view() const { return qobject_cast(object()); } int QAccessibleTable::logicalIndex(const QModelIndex &index) const { if (!view()->model() || !index.isValid()) return -1; int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader); } QAccessibleInterface *QAccessibleTable::childFromLogical(int logicalIndex) const { if (!view()->model()) return 0; int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; int columns = view()->model()->columnCount() + vHeader; int row = logicalIndex / columns; int column = logicalIndex % columns; if (vHeader) { if (column == 0) { if (row == 0) { return new QAccessibleTableCornerButton(view()); } return new QAccessibleTableHeaderCell(view(), row-1, Qt::Vertical); } --column; } if (hHeader) { if (row == 0) { return new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal); } --row; } QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); if (!index.isValid()) { qWarning() << "QAccessibleTable::childFromLogical: Invalid index at: " << row << column; return 0; } return new QAccessibleTableCell(view(), index, cellRole()); } QAccessibleTable::QAccessibleTable(QWidget *w) : QAccessibleObject(w) { Q_ASSERT(view()); if (qobject_cast(view())) { m_role = QAccessible::Table; } else if (qobject_cast(view())) { m_role = QAccessible::Tree; } else if (qobject_cast(view())) { m_role = QAccessible::List; } else { // is this our best guess? m_role = QAccessible::Table; } } QAccessibleTable::~QAccessibleTable() { } QHeaderView *QAccessibleTable::horizontalHeader() const { QHeaderView *header = 0; if (false) { #ifndef QT_NO_TABLEVIEW } else if (const QTableView *tv = qobject_cast(view())) { header = tv->horizontalHeader(); #endif #ifndef QT_NO_TREEVIEW } else if (const QTreeView *tv = qobject_cast(view())) { header = tv->header(); #endif } return header; } QHeaderView *QAccessibleTable::verticalHeader() const { QHeaderView *header = 0; if (false) { #ifndef QT_NO_TABLEVIEW } else if (const QTableView *tv = qobject_cast(view())) { header = tv->verticalHeader(); #endif } return header; } QAccessibleTableCell *QAccessibleTable::cell(const QModelIndex &index) const { if (index.isValid()) return new QAccessibleTableCell(view(), index, cellRole()); return 0; } QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const { if (!view()->model()) return 0; Q_ASSERT(role() != QAccessible::Tree); QModelIndex index = view()->model()->index(row, column, view()->rootIndex()); if (!index.isValid()) { qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view(); return 0; } return cell(index); } QAccessibleInterface *QAccessibleTable::caption() const { return 0; } QString QAccessibleTable::columnDescription(int column) const { if (!view()->model()) return QString(); return view()->model()->headerData(column, Qt::Horizontal).toString(); } int QAccessibleTable::columnCount() const { if (!view()->model()) return 0; return view()->model()->columnCount(); } int QAccessibleTable::rowCount() const { if (!view()->model()) return 0; return view()->model()->rowCount(); } int QAccessibleTable::selectedCellCount() const { if (!view()->selectionModel()) return 0; return view()->selectionModel()->selectedIndexes().count(); } int QAccessibleTable::selectedColumnCount() const { if (!view()->selectionModel()) return 0; return view()->selectionModel()->selectedColumns().count(); } int QAccessibleTable::selectedRowCount() const { if (!view()->selectionModel()) return 0; return view()->selectionModel()->selectedRows().count(); } QString QAccessibleTable::rowDescription(int row) const { if (!view()->model()) return QString(); return view()->model()->headerData(row, Qt::Vertical).toString(); } QList QAccessibleTable::selectedCells() const { QList cells; if (!view()->selectionModel()) return cells; Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes()) { cells.append(cell(index)); } return cells; } QList QAccessibleTable::selectedColumns() const { if (!view()->selectionModel()) return QList(); QList columns; Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) { columns.append(index.column()); } return columns; } QList QAccessibleTable::selectedRows() const { if (!view()->selectionModel()) return QList(); QList rows; Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) { rows.append(index.row()); } return rows; } QAccessibleInterface *QAccessibleTable::summary() const { return 0; } bool QAccessibleTable::isColumnSelected(int column) const { if (!view()->selectionModel()) return false; return view()->selectionModel()->isColumnSelected(column, QModelIndex()); } bool QAccessibleTable::isRowSelected(int row) const { if (!view()->selectionModel()) return false; return view()->selectionModel()->isRowSelected(row, QModelIndex()); } bool QAccessibleTable::selectRow(int row) { if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) return false; switch (view()->selectionMode()) { case QAbstractItemView::NoSelection: return false; case QAbstractItemView::SingleSelection: if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 ) return false; view()->clearSelection(); break; case QAbstractItemView::ContiguousSelection: if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) view()->clearSelection(); break; default: break; } view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); return true; } bool QAccessibleTable::selectColumn(int column) { if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows) return false; switch (view()->selectionMode()) { case QAbstractItemView::NoSelection: return false; case QAbstractItemView::SingleSelection: if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) return false; case QAbstractItemView::ContiguousSelection: if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) view()->clearSelection(); break; default: break; } view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns); return true; } bool QAccessibleTable::unselectRow(int row) { if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); if (!index.isValid()) return false; QItemSelection selection(index, index); switch (view()->selectionMode()) { case QAbstractItemView::SingleSelection: //In SingleSelection and ContiguousSelection once an item //is selected, there's no way for the user to unselect all items if (selectedRowCount() == 1) return false; break; case QAbstractItemView::ContiguousSelection: if (selectedRowCount() == 1) return false; if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { //If there are rows selected both up the current row and down the current rown, //the ones which are down the current row will be deselected selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); } default: break; } view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); return true; } bool QAccessibleTable::unselectColumn(int column) { if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); if (!index.isValid()) return false; QItemSelection selection(index, index); switch (view()->selectionMode()) { case QAbstractItemView::SingleSelection: //In SingleSelection and ContiguousSelection once an item //is selected, there's no way for the user to unselect all items if (selectedColumnCount() == 1) return false; break; case QAbstractItemView::ContiguousSelection: if (selectedColumnCount() == 1) return false; if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { //If there are columns selected both at the left of the current row and at the right //of the current rown, the ones which are at the right will be deselected selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex())); } default: break; } view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns); return true; } QAccessible::Role QAccessibleTable::role() const { return m_role; } QAccessible::State QAccessibleTable::state() const { return QAccessible::State(); } QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const { QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); // FIXME: if indexPosition < 0 in one coordinate, return header QModelIndex index = view()->indexAt(indexPosition); if (index.isValid()) { return childFromLogical(logicalIndex(index)); } return 0; } int QAccessibleTable::childCount() const { if (!view()->model()) return 0; int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; return (view()->model()->rowCount()+hHeader) * (view()->model()->columnCount()+vHeader); } int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const { if (!view()->model()) return -1; QSharedPointer parent(iface->parent()); if (parent->object() != view()) return -1; Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { const QAccessibleTableCell* cell = static_cast(iface); return logicalIndex(cell->m_index); } else if (iface->role() == QAccessible::ColumnHeader){ const QAccessibleTableHeaderCell* cell = static_cast(iface); return cell->index + (verticalHeader() ? 1 : 0); } else if (iface->role() == QAccessible::RowHeader){ const QAccessibleTableHeaderCell* cell = static_cast(iface); return (cell->index + 1) * (view()->model()->rowCount() + 1); } else if (iface->role() == QAccessible::Pane) { return 0; // corner button } else { qWarning() << "WARNING QAccessibleTable::indexOfChild Fix my children..." << iface->role() << iface->text(QAccessible::Name); } // FIXME: we are in denial of our children. this should stop. return -1; } QString QAccessibleTable::text(QAccessible::Text t) const { if (t == QAccessible::Description) return view()->accessibleDescription(); return view()->accessibleName(); } QRect QAccessibleTable::rect() const { if (!view()->isVisible()) return QRect(); QPoint pos = view()->mapToGlobal(QPoint(0, 0)); return QRect(pos.x(), pos.y(), view()->width(), view()->height()); } QAccessibleInterface *QAccessibleTable::parent() const { if (view()->parent()) { if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) { return QAccessible::queryAccessibleInterface(view()->parent()->parent()); } return QAccessible::queryAccessibleInterface(view()->parent()); } return 0; } QAccessibleInterface *QAccessibleTable::child(int index) const { return childFromLogical(index); } void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableInterface) return static_cast(this); return 0; } // TREE VIEW QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const { if (!isValid() || !view()->model()) return QModelIndex(); const QTreeView *treeView = qobject_cast(view()); if ((row < 0) || (column < 0) || (treeView->d_func()->viewItems.count() <= row)) { qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView; return QModelIndex(); } QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index; if (modelIndex.isValid() && column > 0) { modelIndex = view()->model()->index(modelIndex.row(), column, modelIndex.parent()); } return modelIndex; } QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const { if (!view()->model()) return 0; QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0)); QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset); QModelIndex index = view()->indexAt(indexPosition); if (!index.isValid()) return 0; const QTreeView *treeView = qobject_cast(view()); int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); int column = index.column(); int i = row * view()->model()->columnCount() + column; return child(i); } int QAccessibleTree::childCount() const { const QTreeView *treeView = qobject_cast(view()); Q_ASSERT(treeView); if (!view()->model()) return 0; int hHeader = horizontalHeader() ? 1 : 0; return (treeView->d_func()->viewItems.count() + hHeader)* view()->model()->columnCount(); } QAccessibleInterface *QAccessibleTree::child(int index) const { if ((index < 0) || (!view()->model())) return 0; int hHeader = horizontalHeader() ? 1 : 0; if (hHeader) { if (index < view()->model()->columnCount()) { return new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal); } else { index -= view()->model()->columnCount(); } } int row = index / view()->model()->columnCount(); int column = index % view()->model()->columnCount(); QModelIndex modelIndex = indexFromLogical(row, column); if (modelIndex.isValid()) { return cell(modelIndex); } return 0; } int QAccessibleTree::rowCount() const { const QTreeView *treeView = qobject_cast(view()); Q_ASSERT(treeView); return treeView->d_func()->viewItems.count(); } int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const { if (!view()->model()) return -1; QSharedPointer parent(iface->parent()); if (parent->object() != view()) return -1; if (iface->role() == QAccessible::TreeItem) { const QAccessibleTableCell* cell = static_cast(iface); const QTreeView *treeView = qobject_cast(view()); Q_ASSERT(treeView); int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0); int column = cell->m_index.column(); int index = row * view()->model()->columnCount() + column; //qDebug() << "QAccessibleTree::indexOfChild r " << row << " c " << column << "index " << index; Q_ASSERT(index >= treeView->model()->columnCount()); return index; } else if (iface->role() == QAccessible::ColumnHeader){ const QAccessibleTableHeaderCell* cell = static_cast(iface); //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index; return cell->index; } else { qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child" << iface->role() << iface->text(QAccessible::Name); } // FIXME: add scrollbars and don't just ignore them return -1; } QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const { QModelIndex index = indexFromLogical(row, column); if (!index.isValid()) { qWarning() << "Requested invalid tree cell: " << row << column; return 0; } return new QAccessibleTableCell(view(), index, cellRole()); } QString QAccessibleTree::rowDescription(int) const { return QString(); // no headers for rows in trees } bool QAccessibleTree::isRowSelected(int row) const { if (!view()->selectionModel()) return false; QModelIndex index = indexFromLogical(row); return view()->selectionModel()->isRowSelected(index.row(), index.parent()); } bool QAccessibleTree::selectRow(int row) { if (!view()->selectionModel()) return false; QModelIndex index = indexFromLogical(row); if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) return false; switch (view()->selectionMode()) { case QAbstractItemView::NoSelection: return false; case QAbstractItemView::SingleSelection: if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1)) return false; view()->clearSelection(); break; case QAbstractItemView::ContiguousSelection: if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) view()->clearSelection(); break; default: break; } view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); return true; } // TABLE CELL QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_) : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_) { if (!index_.isValid()) qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_; } void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableCellInterface) return static_cast(this); return 0; } int QAccessibleTableCell::columnExtent() const { return 1; } int QAccessibleTableCell::rowExtent() const { return 1; } QList QAccessibleTableCell::rowHeaderCells() const { QList headerCell; if (verticalHeader()) { headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical)); } return headerCell; } QList QAccessibleTableCell::columnHeaderCells() const { QList headerCell; if (horizontalHeader()) { headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal)); } return headerCell; } QHeaderView *QAccessibleTableCell::horizontalHeader() const { QHeaderView *header = 0; if (false) { #ifndef QT_NO_TABLEVIEW } else if (const QTableView *tv = qobject_cast(view)) { header = tv->horizontalHeader(); #endif #ifndef QT_NO_TREEVIEW } else if (const QTreeView *tv = qobject_cast(view)) { header = tv->header(); #endif } return header; } QHeaderView *QAccessibleTableCell::verticalHeader() const { QHeaderView *header = 0; #ifndef QT_NO_TABLEVIEW if (const QTableView *tv = qobject_cast(view)) header = tv->verticalHeader(); #endif return header; } int QAccessibleTableCell::columnIndex() const { return m_index.column(); } int QAccessibleTableCell::rowIndex() const { if (role() == QAccessible::TreeItem) { const QTreeView *treeView = qobject_cast(view); Q_ASSERT(treeView); int row = treeView->d_func()->viewIndex(m_index); return row; } return m_index.row(); } bool QAccessibleTableCell::isSelected() const { return view->selectionModel()->isSelected(m_index); } void QAccessibleTableCell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const { *row = m_index.row(); *column = m_index.column(); *rowExtents = 1; *columnExtents = 1; *selected = isSelected(); } QAccessibleInterface *QAccessibleTableCell::table() const { return QAccessible::queryAccessibleInterface(view); } QAccessible::Role QAccessibleTableCell::role() const { return m_role; } QAccessible::State QAccessibleTableCell::state() const { QAccessible::State st; QRect globalRect = view->rect(); globalRect.translate(view->mapToGlobal(QPoint(0,0))); if (!globalRect.intersects(rect())) st.invisible = true; if (view->selectionModel()->isSelected(m_index)) st.selected = true; if (view->selectionModel()->currentIndex() == m_index) st.focused = true; if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) st.checked = true; Qt::ItemFlags flags = m_index.flags(); if (flags & Qt::ItemIsSelectable) { st.selectable = true; st.focusable = true; if (view->selectionMode() == QAbstractItemView::MultiSelection) st.multiSelectable = true; if (view->selectionMode() == QAbstractItemView::ExtendedSelection) st.extSelectable = true; } if (m_role == QAccessible::TreeItem) { const QTreeView *treeView = qobject_cast(view); if (treeView->model()->hasChildren(m_index)) st.expandable = true; if (treeView->isExpanded(m_index)) st.expanded = true; } return st; } QRect QAccessibleTableCell::rect() const { QRect r; r = view->visualRect(m_index); if (!r.isNull()) r.translate(view->viewport()->mapTo(view, QPoint(0,0))); r.translate(view->mapToGlobal(QPoint(0, 0))); return r; } QString QAccessibleTableCell::text(QAccessible::Text t) const { QAbstractItemModel *model = view->model(); QString value; switch (t) { case QAccessible::Value: case QAccessible::Name: value = model->data(m_index, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) value = model->data(m_index, Qt::DisplayRole).toString(); break; case QAccessible::Description: value = model->data(m_index, Qt::AccessibleDescriptionRole).toString(); break; default: break; } return value; } void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text) { if (!(m_index.flags() & Qt::ItemIsEditable)) return; view->model()->setData(m_index, text); } bool QAccessibleTableCell::isValid() const { return view && view->model() && m_index.isValid(); } QAccessibleInterface *QAccessibleTableCell::parent() const { if (m_role == QAccessible::TreeItem) return new QAccessibleTree(view); return new QAccessibleTable(view); } QAccessibleInterface *QAccessibleTableCell::child(int) const { return 0; } QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_) : view(view_), index(index_), orientation(orientation_) { Q_ASSERT(index_ >= 0); } QAccessible::Role QAccessibleTableHeaderCell::role() const { if (orientation == Qt::Horizontal) return QAccessible::ColumnHeader; return QAccessible::RowHeader; } QAccessible::State QAccessibleTableHeaderCell::state() const { return QAccessible::State(); } QRect QAccessibleTableHeaderCell::rect() const { QHeaderView *header = 0; if (false) { #ifndef QT_NO_TABLEVIEW } else if (const QTableView *tv = qobject_cast(view)) { if (orientation == Qt::Horizontal) { header = tv->horizontalHeader(); } else { header = tv->verticalHeader(); } #endif #ifndef QT_NO_TREEVIEW } else if (const QTreeView *tv = qobject_cast(view)) { header = tv->header(); #endif } if (!header) return QRect(); QPoint zero = header->mapToGlobal(QPoint(0, 0)); int sectionSize = header->sectionSize(index); int sectionPos = header->sectionPosition(index); return orientation == Qt::Horizontal ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height()) : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize); } QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const { QAbstractItemModel *model = view->model(); QString value; switch (t) { case QAccessible::Value: case QAccessible::Name: value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) value = model->headerData(index, orientation, Qt::DisplayRole).toString(); break; case QAccessible::Description: value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString(); break; default: break; } return value; } void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &) { return; } bool QAccessibleTableHeaderCell::isValid() const { return view && view->model() && (index >= 0) && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount())); } QAccessibleInterface *QAccessibleTableHeaderCell::parent() const { if (false) { #ifndef QT_NO_TREEVIEW } else if (qobject_cast(view)) { return new QAccessibleTree(view); #endif } else { return new QAccessibleTable(view); } } QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const { return 0; } #endif // QT_NO_ITEMVIEWS QT_END_NAMESPACE #endif // QT_NO_ACCESSIBILITY