diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index afc190f832..1a0460e873 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(dolphinprivate_LIB_SRCS kitemviews/kitemlistselectionmanager.cpp kitemviews/kitemliststyleoption.cpp kitemviews/kitemlistview.cpp + kitemviews/kitemlistviewaccessible.cpp kitemviews/kitemlistwidget.cpp kitemviews/kitemmodelbase.cpp kitemviews/kstandarditem.cpp diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp index 5500851c8c..6e25402601 100644 --- a/src/kitemviews/kitemlistcontainer.cpp +++ b/src/kitemviews/kitemlistcontainer.cpp @@ -38,6 +38,8 @@ #include +#include "kitemlistviewaccessible.h" + /** * Replaces the default viewport of KItemListContainer by a * non-scrollable viewport. The scrolling is done in an optimized @@ -67,6 +69,14 @@ void KItemListContainerViewport::wheelEvent(QWheelEvent* event) event->ignore(); } +QAccessibleInterface* accessibleContainerFactory(const QString &key, QObject *object) +{ + Q_UNUSED(key) + if (KItemListView *view = qobject_cast(object)) + return new KItemListViewAccessible(view); + return 0; +} + KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* parent) : QAbstractScrollArea(parent), m_controller(controller), @@ -93,6 +103,8 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*))); connect(controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)), this, SLOT(slotViewChanged(KItemListView*,KItemListView*))); + + QAccessible::installFactory(accessibleContainerFactory); } KItemListContainer::~KItemListContainer() @@ -101,6 +113,8 @@ KItemListContainer::~KItemListContainer() // the QGraphicsScene might get deleted before the view. delete m_controller; m_controller = 0; + + QAccessible::removeFactory(accessibleContainerFactory); } KItemListController* KItemListContainer::controller() const diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 72b3fd8fcb..11dad52094 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -43,6 +43,8 @@ #include #include +#include "kitemlistviewaccessible.h" + namespace { // Time in ms until reaching the autoscroll margin triggers // an initial autoscrolling @@ -52,6 +54,14 @@ namespace { const int RepeatingAutoScrollDelay = 1000 / 60; } +QAccessibleInterface* accessibleViewFactory(const QString &key, QObject *object) +{ + Q_UNUSED(key) + if (KItemListView *view = qobject_cast(object)) + return new KItemListViewAccessible(view); + return 0; +} + KItemListView::KItemListView(QGraphicsWidget* parent) : QGraphicsWidget(parent), m_enabledSelectionToggles(false), @@ -110,6 +120,8 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : m_headerWidget->setVisible(false); m_header = new KItemListHeader(this); + + QAccessible::installFactory(accessibleViewFactory); } KItemListView::~KItemListView() @@ -125,6 +137,8 @@ KItemListView::~KItemListView() delete m_sizeHintResolver; m_sizeHintResolver = 0; + + QAccessible::removeFactory(accessibleViewFactory); } void KItemListView::setScrollOffset(qreal offset) diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 5723b9aaab..d4602d7297 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -275,6 +275,14 @@ public: */ virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + /** + * @return The Layouter for the view + */ + inline KItemListViewLayouter *layouter() const + { + return m_layouter; + } + signals: void scrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous); void scrollOffsetChanged(qreal current, qreal previous); diff --git a/src/kitemviews/kitemlistviewaccessible.cpp b/src/kitemviews/kitemlistviewaccessible.cpp new file mode 100644 index 0000000000..fc7cb7bfe1 --- /dev/null +++ b/src/kitemviews/kitemlistviewaccessible.cpp @@ -0,0 +1,658 @@ +#include "kitemlistviewaccessible.h" +#include "kitemlistcontroller.h" +#include "kitemlistselectionmanager.h" +#include "private/kitemlistviewlayouter.h" + +#include +#include +#include + +#ifndef QT_NO_ACCESSIBILITY + +#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 + ... +*/ + +KItemListView *KItemListViewAccessible::view() const +{ + return qobject_cast(object()); +} + +KItemListViewAccessible::KItemListViewAccessible(KItemListView *view_) + : QAccessibleObjectEx(view_) +{ + 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; + }*/ +} + +KItemListViewAccessible::~KItemListViewAccessible() +{ +} + +void KItemListViewAccessible::modelReset() +{} + +QAccessibleTable2CellInterface *KItemListViewAccessible::cell(int index) const +{ + if (index > 0) + return new KItemListWidgetAccessible(view(), index); + return 0; +} + +QAccessibleTable2CellInterface *KItemListViewAccessible::cellAt(int row, int column) const +{ + /*Q_ASSERT(role(0) != QAccessible::Tree); + QModelIndex index = view()->model()->index(row, column); + //Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning() << "QAccessibleTable2::cellAt: invalid index: " << index << " for " << view(); + return 0; + } + return cell(index);*/ + Q_UNUSED(row) + Q_UNUSED(column) + return cell(1); + +} + +QAccessibleInterface *KItemListViewAccessible::caption() const +{ + return 0; +} + +QString KItemListViewAccessible::columnDescription(int) const +{ + return "No Column Description"; +} + +int KItemListViewAccessible::columnCount() const +{ + return view()->layouter()->columnCount(); +} + +int KItemListViewAccessible::rowCount() const +{ + int itemCount = view()->model()->count(); + int rowCount = itemCount / columnCount(); + if (itemCount % rowCount) + ++rowCount; + return rowCount; +} + +int KItemListViewAccessible::selectedCellCount() const +{ + return view()->controller()->selectionManager()->selectedItems().size(); +} + +int KItemListViewAccessible::selectedColumnCount() const +{ + return 0; +} + +int KItemListViewAccessible::selectedRowCount() const +{ + return 0; +} + +QString KItemListViewAccessible::rowDescription(int) const +{ + return "No Row Description"; +} + +QList KItemListViewAccessible::selectedCells() const +{ + QList cells; + Q_FOREACH (int index, view()->controller()->selectionManager()->selectedItems()) { + cells.append(cell(index)); + } + return cells; +} + +QList KItemListViewAccessible::selectedColumns() const +{ + QList columns; + /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) { + columns.append(index.column()); + }*/ + return columns; +} + +QList KItemListViewAccessible::selectedRows() const +{ + QList rows; + /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) { + rows.append(index.row()); + }*/ + return rows; +} + +QAccessibleInterface *KItemListViewAccessible::summary() const +{ + return 0; +} + +bool KItemListViewAccessible::isColumnSelected(int) const +{ + return false; //view()->selectionModel()->isColumnSelected(column, QModelIndex()); +} + +bool KItemListViewAccessible::isRowSelected(int) const +{ + return false; //view()->selectionModel()->isRowSelected(row, QModelIndex()); +} + +bool KItemListViewAccessible::selectRow(int) +{ + /*QModelIndex index = view()->model()->index(row, 0); + if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + return false; + view()->selectionModel()->select(index, QItemSelectionModel::Select);*/ + return true; +} + +bool KItemListViewAccessible::selectColumn(int) +{ + /*QModelIndex index = view()->model()->index(0, column); + if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + return false; + view()->selectionModel()->select(index, QItemSelectionModel::Select);*/ + return true; +} + +bool KItemListViewAccessible::unselectRow(int) +{ + /*QModelIndex index = view()->model()->index(row, 0); + if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + return false; + view()->selectionModel()->select(index, QItemSelectionModel::Deselect);*/ + return true; +} + +bool KItemListViewAccessible::unselectColumn(int) +{ + /*QModelIndex index = view()->model()->index(0, column); + if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + return false; + view()->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect);*/ + return true; +} + +QAccessible2::TableModelChange KItemListViewAccessible::modelChange() const +{ + QAccessible2::TableModelChange change; + // FIXME + return change; +} + +QAccessible::Role KItemListViewAccessible::role(int child) const +{ + Q_ASSERT(child >= 0); + if (child > 0) + return QAccessible::Cell; + return QAccessible::Table; +} + +QAccessible::State KItemListViewAccessible::state(int child) const +{ + Q_ASSERT(child == 0); + return QAccessible::Normal | HasInvokeExtension; +} + +int KItemListViewAccessible::childAt(int x, int y) const +{ + QPointF point = QPointF(x,y); + return view()->itemAt(view()->mapFromScene(point)); +} + +int KItemListViewAccessible::childCount() const +{ + return rowCount() * columnCount(); +} + +int KItemListViewAccessible::indexOfChild(const QAccessibleInterface *iface) const +{ + /*Q_ASSERT(iface->role(0) != QAccessible::TreeItem); // should be handled by tree class + if (iface->role(0) == QAccessible::Cell || iface->role(0) == QAccessible::ListItem) { + const QAccessibleTable2Cell* cell = static_cast(iface); + return logicalIndex(cell->m_index); + } else if (iface->role(0) == QAccessible::ColumnHeader){ + const QAccessibleTable2HeaderCell* cell = static_cast(iface); + return cell->index + (verticalHeader() ? 1 : 0) + 1; + } else if (iface->role(0) == QAccessible::RowHeader){ + const QAccessibleTable2HeaderCell* cell = static_cast(iface); + return (cell->index+1) * (view()->model()->rowCount()+1) + 1; + } else if (iface->role(0) == QAccessible::Pane) { + return 1; // corner button + } else { + qWarning() << "WARNING QAccessibleTable2::indexOfChild Fix my children..." + << iface->role(0) << iface->text(QAccessible::Name, 0); + } + // FIXME: we are in denial of our children. this should stop. + return -1;*/ + + const KItemListWidgetAccessible *widget = static_cast(iface); + return widget->getIndex(); +} + +QString KItemListViewAccessible::text(Text t, int child) const +{ + Q_ASSERT(child == 0); + if (t == QAccessible::Description) + return "List of files present in the current directory"; + return "File List"; +} + +QRect KItemListViewAccessible::rect(int child) const +{ + Q_UNUSED(child) + if (!view()->isVisible()) + return QRect(); + return view()->geometry().toRect(); +} + +int KItemListViewAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + *iface = 0; + switch (relation) { + /*case Ancestor: { + if (index == 1 && view()->parent()) { + *iface = QAccessible::queryAccessibleInterface(view()->parent()); + if (*iface) + return 0; + } + break; + }*/ + case QAccessible::Child: { + Q_ASSERT(index > 0); + *iface = cell(index); + if (*iface) { + return 0; + } + break; + } + default: + break; + } + return -1; +} + +QAccessible::Relation KItemListViewAccessible::relationTo(int, const QAccessibleInterface *, int) const +{ + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION +int KItemListViewAccessible::userActionCount(int) const +{ + return 0; +} +QString KItemListViewAccessible::actionText(int, Text, int) const +{ + return QString(); +} +bool KItemListViewAccessible::doAction(int, int, const QVariantList &) +{ + return false; +} +#endif + +// TABLE CELL + +KItemListWidgetAccessible::KItemListWidgetAccessible(KItemListView *view_, int index_) + : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), index(index_) +{ + Q_ASSERT(index_>0); +} + +int KItemListWidgetAccessible::columnExtent() const { return 1; } +int KItemListWidgetAccessible::rowExtent() const { return 1; } + +QList KItemListWidgetAccessible::rowHeaderCells() const +{ + QList headerCell; + /*if (verticalHeader()) { + headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.row(), Qt::Vertical)); + }*/ + return headerCell; +} + +QList KItemListWidgetAccessible::columnHeaderCells() const +{ + QList headerCell; + /*if (horizontalHeader()) { + headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.column(), Qt::Horizontal)); + }*/ + return headerCell; +} + +int KItemListWidgetAccessible::columnIndex() const +{ + return view->layouter()->itemColumn(index); +} + +int KItemListWidgetAccessible::rowIndex() const +{ + /*if (role(0) == QAccessible::TreeItem) { + const QTreeView *treeView = qobject_cast(view); + Q_ASSERT(treeView); + int row = treeView->d_func()->viewIndex(m_index); + return row; + }*/ + return view->layouter()->itemRow(index); +} + +//Done +bool KItemListWidgetAccessible::isSelected() const +{ + return widget->isSelected(); +} + +void KItemListWidgetAccessible::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const +{ + KItemListViewLayouter* layouter = view->layouter(); + *row = layouter->itemRow(index); + *column = layouter->itemColumn(index); + *rowExtents = 1; + *columnExtents = 1; + *selected = isSelected(); +} + +QAccessibleTable2Interface* KItemListWidgetAccessible::table() const +{ + return QAccessible::queryAccessibleInterface(view)->table2Interface(); +} + +QAccessible::Role KItemListWidgetAccessible::role(int child) const +{ + Q_ASSERT(child == 0); + return QAccessible::Cell; +} + +QAccessible::State KItemListWidgetAccessible::state(int child) const +{ + Q_ASSERT(child == 0); + QAccessible::State st = Normal; + + //QRect globalRect = view->rect(); + //globalRect.translate(view->mapToGlobal(QPoint(0,0))); + //if (!globalRect.intersects(rect(0))) + // st |= Invisible; + + if (widget->isSelected()) + st |= Selected; + if (view->controller()->selectionManager()->currentItem() == index) + st |= Focused; + + //if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) + // st |= Checked; + //if (flags & Qt::ItemIsSelectable) { + st |= Selectable; + st |= Focusable; + if (view->controller()->selectionBehavior() == KItemListController::MultiSelection) + st |= MultiSelectable; + + //if (view->selectionMode() == QAbstractItemView::ExtendedSelection) + //st |= ExtSelectable; + //} + //if (m_role == QAccessible::TreeItem) { + // const QTreeView *treeView = qobject_cast(view); + // if (treeView->isExpanded(m_index)) + // st |= Expanded; + //} + + st |= HasInvokeExtension; + return st; +} + +//Done +bool KItemListWidgetAccessible::isExpandable() const +{ + return false; //view->model()->hasChildren(m_index); +} + +//Done +QRect KItemListWidgetAccessible::rect(int child) const +{ + Q_ASSERT(child == 0); + + //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 widget->textRect().toRect(); +} + +//Done +QString KItemListWidgetAccessible::text(Text t, int child) const +{ + Q_ASSERT(child == 0); + + QHash data = widget->data(); + switch (t) { + case QAccessible::Value: + case QAccessible::Name: + return data["text"].toString(); + case QAccessible::Description: + return data["text"].toString() + " : " + data["group"].toString(); + default: + break; + } + return ""; +} + +//Done +void KItemListWidgetAccessible::setText(QAccessible::Text /*t*/, int child, const QString &text) +{ + Q_ASSERT(child == 0); + (widget->data())["text"]=QVariant(text); +} + +//Done +bool KItemListWidgetAccessible::isValid() const +{ + if (index <= 0) { + qDebug() << "Interface is not valid"; + } + + return index > 0; +} + +int KItemListWidgetAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + if (relation == Ancestor && index == 1) { + //if (m_role == QAccessible::TreeItem) { + // *iface = new QAccessibleTree(view); + //} else { + *iface = new KItemListViewAccessible(view); + return 0; + } + + *iface = 0; + if (!view) + return -1; + + switch (relation) { + + case Child: { + return -1; + } + case Sibling: + if (index > 0) { + QAccessibleInterface *parent = queryAccessibleInterface(view); + int ret = parent->navigate(QAccessible::Child, index, iface); + delete parent; + if (*iface) + return ret; + } + return -1; + +// From table1 implementation: +// case Up: +// case Down: +// case Left: +// case Right: { +// // This is in the "not so nice" category. In order to find out which item +// // is geometrically around, we have to set the current index, navigate +// // and restore the index as well as the old selection +// view()->setUpdatesEnabled(false); +// const QModelIndex oldIdx = view()->currentIndex(); +// QList kids = children(); +// const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row); +// const QItemSelection oldSelection = view()->selectionModel()->selection(); +// view()->setCurrentIndex(currentIndex); +// const QModelIndex idx = view()->moveCursor(toCursorAction(relation), Qt::NoModifier); +// view()->setCurrentIndex(oldIdx); +// view()->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); +// view()->setUpdatesEnabled(true); +// if (!idx.isValid()) +// return -1; + +// if (idx.parent() != row.parent() || idx.row() != row.row()) +// *iface = cell(idx); +// return index ? kids.indexOf(idx) + 1 : 0; } + default: + break; + } + + return -1; +} + +QAccessible::Relation KItemListWidgetAccessible::relationTo(int child, const QAccessibleInterface *, int otherChild) const +{ + Q_ASSERT(child == 0); + Q_ASSERT(otherChild == 0); + /* we only check for parent-child relationships in trees + if (m_role == QAccessible::TreeItem && other->role(0) == QAccessible::TreeItem) { + QModelIndex otherIndex = static_cast(other)->m_index; + // is the other our parent? + if (otherIndex.parent() == m_index) + return QAccessible::Ancestor; + // are we the other's child? + if (m_index.parent() == otherIndex) + return QAccessible::Child; + }*/ + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION +int KItemListWidgetAccessible::userActionCount(int) const +{ + return 0; +} + +QString KItemListWidgetAccessible::actionText(int, Text, int) const +{ + return QString(); +} + +bool KItemListWidgetAccessible::doAction(int, int, const QVariantList &) +{ + return false; +} + +#endif + +KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer *container) + : QAccessibleWidgetEx(container) + , m_container(container) +{} + +KItemListContainerAccessible::~KItemListContainerAccessible () +{} + +int KItemListContainerAccessible::childCount () const +{ + return 1; +} + +int KItemListContainerAccessible::indexOfChild ( const QAccessibleInterface * child ) const +{ + if(child == QAccessible::queryAccessibleInterface(m_container->controller()->view())) + return 1; + return -1; +} + +bool KItemListContainerAccessible::isValid () const +{ + return true; +} + +int KItemListContainerAccessible::navigate ( QAccessible::RelationFlag relation, int , QAccessibleInterface ** target ) const +{ + *target=0; + switch(relation){ + case QAccessible::Child : + *target = new KItemListViewAccessible(m_container->controller()->view()); + return 1; + case QAccessible::Ancestor : + //FIXME + *target = 0; + return -1; + case QAccessible::Self : + *target = static_cast(const_cast(this)); + return 0; + default: + *target=0; + } + return -1; +} + +QObject *KItemListContainerAccessible::object() const +{ + return m_container; +} + +QRect KItemListContainerAccessible::rect ( int child ) const +{ + if(child){ + KItemListViewAccessible *iface = static_cast(QAccessible::queryAccessibleInterface(m_container->controller()->view())); + return iface->rect(0); + } + return m_container->frameRect(); +} + +QAccessible::Relation KItemListContainerAccessible::relationTo ( int , const QAccessibleInterface *, int ) const +{ + return QAccessible::Unrelated; +} + +QAccessible::Role KItemListContainerAccessible::role ( int child ) const +{ + if(child) + return QAccessible::Table; + return QAccessible::Pane; +} + +QAccessible::State KItemListContainerAccessible::state ( int child ) const +{ + return Normal | HasInvokeExtension; +} + +QString KItemListContainerAccessible::text ( QAccessible::Text, int ) const +{ + return ""; +} + +#endif // QT_NO_ITEMVIEWS + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/kitemviews/kitemlistviewaccessible.h b/src/kitemviews/kitemlistviewaccessible.h new file mode 100644 index 0000000000..e34acb6200 --- /dev/null +++ b/src/kitemviews/kitemlistviewaccessible.h @@ -0,0 +1,187 @@ +#ifndef ACCESSIBLE_ITEMVIEWS_H +#define ACCESSIBLE_ITEMVIEWS_H + +#include "QtCore/qpointer.h" +#include +#include +#include +#include +#include + +#include "kitemlistview.h" +#include "kitemlistcontainer.h" + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_ITEMVIEWS + +class KItemListWidgetAccessible; + +class KItemListViewAccessible: public QAccessibleTable2Interface, public QAccessibleObjectEx +{ + Q_ACCESSIBLE_OBJECT +public: + explicit KItemListViewAccessible(KItemListView *view); + + virtual ~KItemListViewAccessible(); + + Role role(int child) const; + State state(int child) const; + QString text(Text t, int child) const; + QRect rect(int child) const; + + int childAt(int x, int y) const; + int childCount() const; + int indexOfChild(const QAccessibleInterface *) const; + + int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList ¶ms); +#endif + QVariant invokeMethodEx(Method, int, const QVariantList &) { return QVariant(); } + + // table2 interface + virtual QAccessibleTable2CellInterface *cellAt(int row, int column) const; + virtual QAccessibleInterface *caption() const; + virtual QAccessibleInterface *summary() const; + virtual QString columnDescription(int column) const; + virtual QString rowDescription(int row) const; + virtual int columnCount() const; + virtual int rowCount() const; + virtual QAccessible2::TableModelChange modelChange() const; + + //Table + virtual void rowsInserted(const QModelIndex&, int, int) {} + virtual void rowsRemoved(const QModelIndex&, int, int) {} + virtual void columnsInserted(const QModelIndex&, int, int) {} + virtual void columnsRemoved(const QModelIndex&, int, int) {} + virtual void rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int) {} + virtual void columnsMoved(const QModelIndex&, int, int, const QModelIndex&, int) {} + + // selection + virtual int selectedCellCount() const; + virtual int selectedColumnCount() const; + virtual int selectedRowCount() const; + virtual QList selectedCells() const; + virtual QList selectedColumns() const; + virtual QList selectedRows() const; + virtual bool isColumnSelected(int column) const; + virtual bool isRowSelected(int row) const; + virtual bool selectRow(int row); + virtual bool selectColumn(int column); + virtual bool unselectRow(int row); + virtual bool unselectColumn(int column); + + KItemListView *view() const; + +protected: + virtual void modelReset(); + +protected: + inline QAccessibleTable2CellInterface *cell(int index) const; + inline QAccessible::Role cellRole() const { + /* + switch (m_role) { + case QAccessible::List: + return QAccessible::ListItem; + case QAccessible::Table: + return QAccessible::Cell; + case QAccessible::Tree: + return QAccessible::TreeItem; + default: + Q_ASSERT(0); + } + return QAccessible::NoRole; + */ + return QAccessible::Cell; + } + +private: + //QAccessible::Role m_role; + // the child index for a model index + //inline int logicalIndex(const QModelIndex &index) const; + // the model index from the child index + //QAccessibleInterface *childFromLogical(int logicalIndex) const; +}; + +class KItemListWidgetAccessible: public QAccessibleTable2CellInterface +{ +public: + KItemListWidgetAccessible(KItemListView *view, int m_index); + + QObject *object() const { return 0; } + Role role(int child) const; + State state(int child) const; + QRect rect(int child) const; + bool isValid() const; + + int childAt(int, int) const { return 0; } + int childCount() const { return 0; } + int indexOfChild(const QAccessibleInterface *) const { return -1; } + + QString text(Text t, int child) const; + void setText(Text t, int child, const QString &text); + + int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + + bool isExpandable() const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList ¶ms); +#endif + + // cell interface + virtual int columnExtent() const; + virtual QList columnHeaderCells() const; + virtual int columnIndex() const; + virtual int rowExtent() const; + virtual QList rowHeaderCells() const; + virtual int rowIndex() const; + virtual bool isSelected() const; + virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const; + virtual QAccessibleTable2Interface* table() const; + + inline int getIndex() const + { return index; } + +private: + QPointer view; + int index; + KItemListWidget *widget; + +friend class KItemListViewAccessible; +//friend class QAccessibleTree; +}; + +class KItemListContainerAccessible : public QAccessibleWidgetEx +{ + Q_ACCESSIBLE_OBJECT +public: + explicit KItemListContainerAccessible(KItemListContainer*); + virtual ~KItemListContainerAccessible (); + int childCount () const ; + int indexOfChild ( const QAccessibleInterface * child ) const ; + bool isValid () const ; + int navigate ( RelationFlag relation, int entry, QAccessibleInterface ** target ) const ; + QObject * object () const ; + QRect rect ( int child ) const ; + QAccessible::Relation relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const ; + QAccessible::Role role ( int child ) const ; + QAccessible::State state ( int child ) const ; + QString text ( QAccessible::Text, int ) const ; +private: + KItemListContainer *m_container ; +}; + +#endif // QT_NO_ITEMVIEWS + +#endif // QT_NO_ACCESSIBILITY + +#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/kitemviews/private/kitemlistviewlayouter.h b/src/kitemviews/private/kitemlistviewlayouter.h index da5bd1d7d9..5ca73e1ada 100644 --- a/src/kitemviews/private/kitemlistviewlayouter.h +++ b/src/kitemviews/private/kitemlistviewlayouter.h @@ -164,6 +164,11 @@ public: */ void markAsDirty(); + inline int columnCount() const + { + return m_columnCount; + } + #ifndef QT_NO_DEBUG /** * @return True if the layouter has been marked as dirty and hence has diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 3f906d1876..e1202ec121 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -20,6 +20,7 @@ set(kitemlistcontrollertest_SRCS ../kitemviews/kfileitemlistview.cpp ../kitemviews/kitemmodelbase.cpp ../kitemviews/kitemlistview.cpp + ../kitemviews/kitemlistviewaccessible.cpp ) kde4_add_unit_test(kitemlistcontrollertest TEST ${kitemlistcontrollertest_SRCS}) target_link_libraries(kitemlistcontrollertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) @@ -32,6 +33,7 @@ set(kfileitemlistviewtest_SRCS ../kitemviews/kfileitemlistview.cpp ../kitemviews/kitemmodelbase.cpp ../kitemviews/kitemlistview.cpp + ../kitemviews/kitemlistviewaccessible.cpp ) kde4_add_unit_test(kfileitemlistviewtest TEST ${kfileitemlistviewtest_SRCS}) target_link_libraries(kfileitemlistviewtest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY})