diff --git a/src/kitemviews/kitemlistviewaccessible.cpp b/src/kitemviews/kitemlistviewaccessible.cpp index 4d1b28b9f..8fe8a6ef8 100644 --- a/src/kitemviews/kitemlistviewaccessible.cpp +++ b/src/kitemviews/kitemlistviewaccessible.cpp @@ -1,474 +1,479 @@ /*************************************************************************** * Copyright (C) 2012 by Amandeep Singh * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #ifndef QT_NO_ACCESSIBILITY #include "kitemlistviewaccessible.h" #include "kitemlistcontainer.h" #include "kitemlistcontroller.h" #include "kitemlistselectionmanager.h" #include "kitemlistview.h" #include "private/kitemlistviewlayouter.h" #include #include KItemListView* KItemListViewAccessible::view() const { return qobject_cast(object()); } KItemListViewAccessible::KItemListViewAccessible(KItemListView* view_) : QAccessibleObject(view_) { Q_ASSERT(view()); m_cells.resize(childCount()); } KItemListViewAccessible::~KItemListViewAccessible() { - foreach (QAccessibleInterface* child, m_cells) { - if (child) { - QAccessible::Id childId = QAccessible::uniqueId(child); - QAccessible::deleteAccessibleInterface(childId); + foreach (AccessibleIdWrapper idWrapper, m_cells) { + if (idWrapper.isValid) { + QAccessible::deleteAccessibleInterface(idWrapper.id); } } } void* KItemListViewAccessible::interface_cast(QAccessible::InterfaceType type) { if (type == QAccessible::TableInterface) { return static_cast(this); } return nullptr; } void KItemListViewAccessible::modelReset() { } QAccessibleInterface* KItemListViewAccessible::cell(int index) const { if (index < 0 || index >= view()->model()->count()) { return nullptr; } if (m_cells.size() <= index) { m_cells.resize(childCount()); } Q_ASSERT(index < m_cells.size()); - QAccessibleInterface* child = m_cells.at(index); - if (!child) { - child = new KItemListAccessibleCell(view(), index); - m_cells.insert(index, child); - QAccessible::registerAccessibleInterface(child); + AccessibleIdWrapper idWrapper = m_cells.at(index); + if (!idWrapper.isValid) { + idWrapper.id = QAccessible::registerAccessibleInterface(new KItemListAccessibleCell(view(), index)); + idWrapper.isValid = true; + m_cells.insert(index, idWrapper); } - return child; + return QAccessible::accessibleInterface(idWrapper.id); } QAccessibleInterface* KItemListViewAccessible::cellAt(int row, int column) const { return cell(columnCount() * row + column); } QAccessibleInterface* KItemListViewAccessible::caption() const { return nullptr; } QString KItemListViewAccessible::columnDescription(int) const { return QString(); } int KItemListViewAccessible::columnCount() const { return view()->m_layouter->columnCount(); } int KItemListViewAccessible::rowCount() const { if (columnCount() <= 0) { return 0; } int itemCount = view()->model()->count(); int rowCount = itemCount / columnCount(); if (rowCount <= 0) { return 0; } if (itemCount % columnCount()) { ++rowCount; } return rowCount; } int KItemListViewAccessible::selectedCellCount() const { return view()->controller()->selectionManager()->selectedItems().count(); } int KItemListViewAccessible::selectedColumnCount() const { return 0; } int KItemListViewAccessible::selectedRowCount() const { return 0; } QString KItemListViewAccessible::rowDescription(int) const { return QString(); } QList KItemListViewAccessible::selectedCells() const { QList cells; const auto items = view()->controller()->selectionManager()->selectedItems(); cells.reserve(items.count()); for (int index : items) { cells.append(cell(index)); } return cells; } QList KItemListViewAccessible::selectedColumns() const { return QList(); } QList KItemListViewAccessible::selectedRows() const { return QList(); } QAccessibleInterface* KItemListViewAccessible::summary() const { return nullptr; } bool KItemListViewAccessible::isColumnSelected(int) const { return false; } bool KItemListViewAccessible::isRowSelected(int) const { return false; } bool KItemListViewAccessible::selectRow(int) { return true; } bool KItemListViewAccessible::selectColumn(int) { return true; } bool KItemListViewAccessible::unselectRow(int) { return true; } bool KItemListViewAccessible::unselectColumn(int) { return true; } void KItemListViewAccessible::modelChange(QAccessibleTableModelChangeEvent* /*event*/) {} QAccessible::Role KItemListViewAccessible::role() const { return QAccessible::Table; } QAccessible::State KItemListViewAccessible::state() const { QAccessible::State s; return s; } QAccessibleInterface* KItemListViewAccessible::childAt(int x, int y) const { const QPointF point = QPointF(x, y); int itemIndex = view()->itemAt(view()->mapFromScene(point)); return child(itemIndex); } QAccessibleInterface* KItemListViewAccessible::parent() const { // FIXME: return KItemListContainerAccessible here return nullptr; } int KItemListViewAccessible::childCount() const { return view()->model()->count(); } int KItemListViewAccessible::indexOfChild(const QAccessibleInterface* interface) const { const KItemListAccessibleCell* widget = static_cast(interface); return widget->index(); } QString KItemListViewAccessible::text(QAccessible::Text) const { return QString(); } QRect KItemListViewAccessible::rect() const { if (!view()->isVisible()) { return QRect(); } const QGraphicsScene* scene = view()->scene(); if (scene) { const QPoint origin = scene->views().at(0)->mapToGlobal(QPoint(0, 0)); const QRect viewRect = view()->geometry().toRect(); return viewRect.translated(origin); } else { return QRect(); } } QAccessibleInterface* KItemListViewAccessible::child(int index) const { if (index >= 0 && index < childCount()) { return cell(index); } return nullptr; } +KItemListViewAccessible::AccessibleIdWrapper::AccessibleIdWrapper() : + isValid(false), + id(0) +{ +} + // Table Cell KItemListAccessibleCell::KItemListAccessibleCell(KItemListView* view, int index) : m_view(view), m_index(index) { Q_ASSERT(index >= 0 && index < view->model()->count()); } void* KItemListAccessibleCell::interface_cast(QAccessible::InterfaceType type) { if (type == QAccessible::TableCellInterface) { return static_cast(this); } return nullptr; } int KItemListAccessibleCell::columnExtent() const { return 1; } int KItemListAccessibleCell::rowExtent() const { return 1; } QList KItemListAccessibleCell::rowHeaderCells() const { return QList(); } QList KItemListAccessibleCell::columnHeaderCells() const { return QList(); } int KItemListAccessibleCell::columnIndex() const { return m_view->m_layouter->itemColumn(m_index); } int KItemListAccessibleCell::rowIndex() const { return m_view->m_layouter->itemRow(m_index); } bool KItemListAccessibleCell::isSelected() const { return m_view->controller()->selectionManager()->isSelected(m_index); } QAccessibleInterface* KItemListAccessibleCell::table() const { return QAccessible::queryAccessibleInterface(m_view); } QAccessible::Role KItemListAccessibleCell::role() const { return QAccessible::Cell; } QAccessible::State KItemListAccessibleCell::state() const { QAccessible::State state; state.selectable = true; if (isSelected()) { state.selected = true; } state.focusable = true; if (m_view->controller()->selectionManager()->currentItem() == m_index) { state.focused = true; } if (m_view->controller()->selectionBehavior() == KItemListController::MultiSelection) { state.multiSelectable = true; } if (m_view->model()->isExpandable(m_index)) { if (m_view->model()->isExpanded(m_index)) { state.expanded = true; } else { state.collapsed = true; } } return state; } bool KItemListAccessibleCell::isExpandable() const { return m_view->model()->isExpandable(m_index); } QRect KItemListAccessibleCell::rect() const { QRect rect = m_view->itemRect(m_index).toRect(); if (rect.isNull()) { return QRect(); } rect.translate(m_view->mapToScene(QPointF(0.0, 0.0)).toPoint()); rect.translate(m_view->scene()->views()[0]->mapToGlobal(QPoint(0, 0))); return rect; } QString KItemListAccessibleCell::text(QAccessible::Text t) const { switch (t) { case QAccessible::Name: { const QHash data = m_view->model()->data(m_index); return data["text"].toString(); } default: break; } return QString(); } void KItemListAccessibleCell::setText(QAccessible::Text, const QString&) { } QAccessibleInterface* KItemListAccessibleCell::child(int) const { return nullptr; } bool KItemListAccessibleCell::isValid() const { return m_view && (m_index >= 0) && (m_index < m_view->model()->count()); } QAccessibleInterface* KItemListAccessibleCell::childAt(int, int) const { return nullptr; } int KItemListAccessibleCell::childCount() const { return 0; } int KItemListAccessibleCell::indexOfChild(const QAccessibleInterface* child) const { Q_UNUSED(child); return -1; } QAccessibleInterface* KItemListAccessibleCell::parent() const { return QAccessible::queryAccessibleInterface(m_view); } int KItemListAccessibleCell::index() const { return m_index; } QObject* KItemListAccessibleCell::object() const { return nullptr; } // Container Interface KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer* container) : QAccessibleWidget(container) { } KItemListContainerAccessible::~KItemListContainerAccessible() { } int KItemListContainerAccessible::childCount() const { return 1; } int KItemListContainerAccessible::indexOfChild(const QAccessibleInterface* child) const { if (child->object() == container()->controller()->view()) { return 0; } return -1; } QAccessibleInterface* KItemListContainerAccessible::child(int index) const { if (index == 0) { return QAccessible::queryAccessibleInterface(container()->controller()->view()); } return nullptr; } const KItemListContainer* KItemListContainerAccessible::container() const { return qobject_cast(object()); } #endif // QT_NO_ACCESSIBILITY diff --git a/src/kitemviews/kitemlistviewaccessible.h b/src/kitemviews/kitemlistviewaccessible.h index fdc3ff1a3..3e39e2399 100644 --- a/src/kitemviews/kitemlistviewaccessible.h +++ b/src/kitemviews/kitemlistviewaccessible.h @@ -1,147 +1,153 @@ /*************************************************************************** * Copyright (C) 2012 by Amandeep Singh * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #ifndef KITEMLISTVIEWACCESSIBLE_H #define KITEMLISTVIEWACCESSIBLE_H #ifndef QT_NO_ACCESSIBILITY #include "dolphin_export.h" #include #include #include #include class KItemListView; class KItemListContainer; class DOLPHIN_EXPORT KItemListViewAccessible: public QAccessibleObject, public QAccessibleTableInterface { public: explicit KItemListViewAccessible(KItemListView* view); ~KItemListViewAccessible() override; void* interface_cast(QAccessible::InterfaceType type) override; QAccessible::Role role() const override; QAccessible::State state() const override; QString text(QAccessible::Text t) const override; QRect rect() const override; QAccessibleInterface* child(int index) const override; int childCount() const override; int indexOfChild(const QAccessibleInterface*) const override; QAccessibleInterface* childAt(int x, int y) const override; QAccessibleInterface* parent() const override; // Table interface QAccessibleInterface* cellAt(int row, int column) const override; QAccessibleInterface* caption() const override; QAccessibleInterface* summary() const override; QString columnDescription(int column) const override; QString rowDescription(int row) const override; int columnCount() const override; int rowCount() const override; // Selection int selectedCellCount() const override; int selectedColumnCount() const override; int selectedRowCount() const override; QList selectedCells() const override; QList selectedColumns() const override; QList selectedRows() const override; bool isColumnSelected(int column) const override; bool isRowSelected(int row) const override; bool selectRow(int row) override; bool selectColumn(int column) override; bool unselectRow(int row) override; bool unselectColumn(int column) override; void modelChange(QAccessibleTableModelChangeEvent*) override; KItemListView* view() const; protected: virtual void modelReset(); /** * Create an QAccessibleTableCellInterface representing the table * cell at the @index. Index is 0-based. */ inline QAccessibleInterface* cell(int index) const; private: - mutable QVector m_cells; + class AccessibleIdWrapper { + public: + AccessibleIdWrapper(); + bool isValid; + QAccessible::Id id; + }; + mutable QVector m_cells; }; class DOLPHIN_EXPORT KItemListAccessibleCell: public QAccessibleInterface, public QAccessibleTableCellInterface { public: KItemListAccessibleCell(KItemListView* view, int m_index); void* interface_cast(QAccessible::InterfaceType type) override; QObject* object() const override; bool isValid() const override; QAccessible::Role role() const override; QAccessible::State state() const override; QRect rect() const override; QString text(QAccessible::Text t) const override; void setText(QAccessible::Text t, const QString& text) override; QAccessibleInterface* child(int index) const override; int childCount() const override; QAccessibleInterface* childAt(int x, int y) const override; int indexOfChild(const QAccessibleInterface*) const override; QAccessibleInterface* parent() const override; bool isExpandable() const; // Cell Interface int columnExtent() const override; QList columnHeaderCells() const override; int columnIndex() const override; int rowExtent() const override; QList rowHeaderCells() const override; int rowIndex() const override; bool isSelected() const override; QAccessibleInterface* table() const override; inline int index() const; private: QPointer m_view; int m_index; }; class DOLPHIN_EXPORT KItemListContainerAccessible : public QAccessibleWidget { public: explicit KItemListContainerAccessible(KItemListContainer* container); ~KItemListContainerAccessible() override; QAccessibleInterface* child(int index) const override; int childCount() const override; int indexOfChild(const QAccessibleInterface* child) const override; private: const KItemListContainer* container() const; }; #endif // QT_NO_ACCESSIBILITY #endif