]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kitemlistviewaccessible.cpp
Renaming the a11y classes and adding implementation
[dolphin.git] / src / kitemviews / kitemlistviewaccessible.cpp
1 #include "kitemlistviewaccessible.h"
2 #include "kitemlistcontroller.h"
3 #include "kitemlistselectionmanager.h"
4 #include "private/kitemlistviewlayouter.h"
5
6 #include <QtGui/qtableview.h>
7 #include <QtGui/qaccessible2.h>
8 #include <KDebug>
9 #include <QHash>
10
11 #ifndef QT_NO_ACCESSIBILITY
12
13 #ifndef QT_NO_ITEMVIEWS
14
15 KItemListView *KItemListViewAccessible::view() const
16 {
17 return qobject_cast<KItemListView*>(object());
18 }
19
20 KItemListViewAccessible::KItemListViewAccessible(KItemListView *view_)
21 : QAccessibleObjectEx(view_)
22 {
23 Q_ASSERT(view());
24
25 /*if (qobject_cast<const QTableView*>(view())) {
26 m_role = QAccessible::Table;
27 } else if (qobject_cast<const QTreeView*>(view())) {
28 m_role = QAccessible::Tree;
29 } else if (qobject_cast<const QListView*>(view())) {
30 m_role = QAccessible::List;
31 } else {
32 // is this our best guess?
33 m_role = QAccessible::Table;
34 }*/
35 }
36
37 KItemListViewAccessible::~KItemListViewAccessible()
38 {
39 }
40
41 void KItemListViewAccessible::modelReset()
42 {}
43
44 QAccessibleTable2CellInterface *KItemListViewAccessible::cell(int index) const
45 {
46 if (index > 0)
47 return new KItemListAccessibleCell(view(), index);
48 return 0;
49 }
50
51 QAccessibleTable2CellInterface *KItemListViewAccessible::cellAt(int row, int column) const
52 {
53 /*Q_ASSERT(role(0) != QAccessible::Tree);
54 QModelIndex index = view()->model()->index(row, column);
55 //Q_ASSERT(index.isValid());
56 if (!index.isValid()) {
57 qWarning() << "QAccessibleTable2::cellAt: invalid index: " << index << " for " << view();
58 return 0;
59 }
60 return cell(index);*/
61 Q_UNUSED(row)
62 Q_UNUSED(column)
63 return cell(1);
64
65 }
66
67 QAccessibleInterface *KItemListViewAccessible::caption() const
68 {
69 return 0;
70 }
71
72 QString KItemListViewAccessible::columnDescription(int) const
73 {
74 // FIXME: no i18n
75 return QObject::tr("No Column Description");
76 }
77
78 int KItemListViewAccessible::columnCount() const
79 {
80 return view()->layouter()->columnCount();
81 }
82
83 int KItemListViewAccessible::rowCount() const
84 {
85 int itemCount = view()->model()->count();
86 int rowCount = itemCount / columnCount();
87 if (itemCount % rowCount)
88 ++rowCount;
89 return rowCount;
90 }
91
92 int KItemListViewAccessible::selectedCellCount() const
93 {
94 return view()->controller()->selectionManager()->selectedItems().size();
95 }
96
97 int KItemListViewAccessible::selectedColumnCount() const
98 {
99 return 0;
100 }
101
102 int KItemListViewAccessible::selectedRowCount() const
103 {
104 return 0;
105 }
106
107 QString KItemListViewAccessible::rowDescription(int) const
108 {
109 return "No Row Description";
110 }
111
112 QList<QAccessibleTable2CellInterface*> KItemListViewAccessible::selectedCells() const
113 {
114 QList<QAccessibleTable2CellInterface*> cells;
115 Q_FOREACH (int index, view()->controller()->selectionManager()->selectedItems()) {
116 cells.append(cell(index));
117 }
118 return cells;
119 }
120
121 QList<int> KItemListViewAccessible::selectedColumns() const
122 {
123 QList<int> columns;
124 /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) {
125 columns.append(index.column());
126 }*/
127 return columns;
128 }
129
130 QList<int> KItemListViewAccessible::selectedRows() const
131 {
132 QList<int> rows;
133 /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) {
134 rows.append(index.row());
135 }*/
136 return rows;
137 }
138
139 QAccessibleInterface *KItemListViewAccessible::summary() const
140 {
141 return 0;
142 }
143
144 bool KItemListViewAccessible::isColumnSelected(int) const
145 {
146 return false; //view()->selectionModel()->isColumnSelected(column, QModelIndex());
147 }
148
149 bool KItemListViewAccessible::isRowSelected(int) const
150 {
151 return false; //view()->selectionModel()->isRowSelected(row, QModelIndex());
152 }
153
154 bool KItemListViewAccessible::selectRow(int)
155 {
156 /*QModelIndex index = view()->model()->index(row, 0);
157 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
158 return false;
159 view()->selectionModel()->select(index, QItemSelectionModel::Select);*/
160 return true;
161 }
162
163 bool KItemListViewAccessible::selectColumn(int)
164 {
165 /*QModelIndex index = view()->model()->index(0, column);
166 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
167 return false;
168 view()->selectionModel()->select(index, QItemSelectionModel::Select);*/
169 return true;
170 }
171
172 bool KItemListViewAccessible::unselectRow(int)
173 {
174 /*QModelIndex index = view()->model()->index(row, 0);
175 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
176 return false;
177 view()->selectionModel()->select(index, QItemSelectionModel::Deselect);*/
178 return true;
179 }
180
181 bool KItemListViewAccessible::unselectColumn(int)
182 {
183 /*QModelIndex index = view()->model()->index(0, column);
184 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
185 return false;
186 view()->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect);*/
187 return true;
188 }
189
190 QAccessible2::TableModelChange KItemListViewAccessible::modelChange() const
191 {
192 QAccessible2::TableModelChange change;
193 // FIXME
194 return change;
195 }
196
197 QAccessible::Role KItemListViewAccessible::role(int child) const
198 {
199 Q_ASSERT(child >= 0);
200 if (child > 0)
201 return QAccessible::Cell;
202 return QAccessible::Table;
203 }
204
205 QAccessible::State KItemListViewAccessible::state(int child) const
206 {
207 Q_ASSERT(child == 0);
208 return QAccessible::Normal;
209 }
210
211 int KItemListViewAccessible::childAt(int x, int y) const
212 {
213 QPointF point = QPointF(x,y);
214 return view()->itemAt(view()->mapFromScene(point));
215 }
216
217 int KItemListViewAccessible::childCount() const
218 {
219 return rowCount() * columnCount();
220 }
221
222 int KItemListViewAccessible::indexOfChild(const QAccessibleInterface *iface) const
223 {
224 /*Q_ASSERT(iface->role(0) != QAccessible::TreeItem); // should be handled by tree class
225 if (iface->role(0) == QAccessible::Cell || iface->role(0) == QAccessible::ListItem) {
226 const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface);
227 return logicalIndex(cell->m_index);
228 } else if (iface->role(0) == QAccessible::ColumnHeader){
229 const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
230 return cell->index + (verticalHeader() ? 1 : 0) + 1;
231 } else if (iface->role(0) == QAccessible::RowHeader){
232 const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
233 return (cell->index+1) * (view()->model()->rowCount()+1) + 1;
234 } else if (iface->role(0) == QAccessible::Pane) {
235 return 1; // corner button
236 } else {
237 qWarning() << "WARNING QAccessibleTable2::indexOfChild Fix my children..."
238 << iface->role(0) << iface->text(QAccessible::Name, 0);
239 }
240 // FIXME: we are in denial of our children. this should stop.
241 return -1;*/
242
243 const KItemListAccessibleCell *widget = static_cast<const KItemListAccessibleCell*>(iface);
244 return widget->getIndex();
245 }
246
247 QString KItemListViewAccessible::text(Text t, int child) const
248 {
249 Q_ASSERT(child == 0);
250 // FIXME: I don't think this is needed, but if at all it needs i18n
251 if (t == QAccessible::Description)
252 return QObject::tr("List of files present in the current directory");
253 return QObject::tr("File List");
254 }
255
256 QRect KItemListViewAccessible::rect(int child) const
257 {
258 Q_UNUSED(child)
259 if (!view()->isVisible())
260 return QRect();
261 // FIXME: map to global
262 return view()->rect().toRect();
263 }
264
265 int KItemListViewAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
266 {
267 *iface = 0;
268 switch (relation) {
269 /*case Ancestor: {
270 if (index == 1 && view()->parent()) {
271 *iface = QAccessible::queryAccessibleInterface(view()->parent());
272 if (*iface)
273 return 0;
274 }
275 break;
276 }*/
277 case QAccessible::Child: {
278 Q_ASSERT(index > 0);
279 *iface = cell(index);
280 if (*iface) {
281 return 0;
282 }
283 break;
284 }
285 default:
286 break;
287 }
288 return -1;
289 }
290
291 QAccessible::Relation KItemListViewAccessible::relationTo(int, const QAccessibleInterface *, int) const
292 {
293 return QAccessible::Unrelated;
294 }
295
296 #ifndef QT_NO_ACTION
297 int KItemListViewAccessible::userActionCount(int) const
298 {
299 return 0;
300 }
301 QString KItemListViewAccessible::actionText(int, Text, int) const
302 {
303 return QString();
304 }
305 bool KItemListViewAccessible::doAction(int, int, const QVariantList &)
306 {
307 return false;
308 }
309 #endif
310
311 // TABLE CELL
312
313 KItemListAccessibleCell::KItemListAccessibleCell(KItemListView *view_, int index_)
314 : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_)
315 , index(index_)
316 {
317 Q_ASSERT(index_ > 0);
318 }
319
320 int KItemListAccessibleCell::columnExtent() const
321 {
322 return 1;
323 }
324
325 int KItemListAccessibleCell::rowExtent() const
326 {
327 return 1;
328 }
329
330 QList<QAccessibleInterface*> KItemListAccessibleCell::rowHeaderCells() const
331 {
332 QList<QAccessibleInterface*> headerCell;
333 /*if (verticalHeader()) {
334 headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.row(), Qt::Vertical));
335 }*/
336 return headerCell;
337 }
338
339 QList<QAccessibleInterface*> KItemListAccessibleCell::columnHeaderCells() const
340 {
341 QList<QAccessibleInterface*> headerCell;
342 /*if (horizontalHeader()) {
343 headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.column(), Qt::Horizontal));
344 }*/
345 return headerCell;
346 }
347
348 int KItemListAccessibleCell::columnIndex() const
349 {
350 return view->layouter()->itemColumn(index);
351 }
352
353 int KItemListAccessibleCell::rowIndex() const
354 {
355 /*if (role(0) == QAccessible::TreeItem) {
356 const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
357 Q_ASSERT(treeView);
358 int row = treeView->d_func()->viewIndex(m_index);
359 return row;
360 }*/
361 return view->layouter()->itemRow(index);
362 }
363
364 //Done
365 bool KItemListAccessibleCell::isSelected() const
366 {
367 //return widget->isSelected();
368 // FIXME
369 return false;
370 }
371
372 void KItemListAccessibleCell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const
373 {
374 KItemListViewLayouter* layouter = view->layouter();
375 *row = layouter->itemRow(index);
376 *column = layouter->itemColumn(index);
377 *rowExtents = 1;
378 *columnExtents = 1;
379 *selected = isSelected();
380 }
381
382 QAccessibleTable2Interface* KItemListAccessibleCell::table() const
383 {
384 return QAccessible::queryAccessibleInterface(view)->table2Interface();
385 }
386
387 QAccessible::Role KItemListAccessibleCell::role(int child) const
388 {
389 Q_ASSERT(child == 0);
390 return QAccessible::Cell;
391 }
392
393 QAccessible::State KItemListAccessibleCell::state(int child) const
394 {
395 Q_ASSERT(child == 0);
396 QAccessible::State st = Normal;
397
398 //QRect globalRect = view->rect();
399 //globalRect.translate(view->mapToGlobal(QPoint(0,0)));
400 //if (!globalRect.intersects(rect(0)))
401 // st |= Invisible;
402
403 // if (widget->isSelected())
404 // st |= Selected;
405 if (view->controller()->selectionManager()->currentItem() == index)
406 st |= Focused;
407
408 //if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked)
409 // st |= Checked;
410 //if (flags & Qt::ItemIsSelectable) {
411 st |= Selectable;
412 st |= Focusable;
413 if (view->controller()->selectionBehavior() == KItemListController::MultiSelection)
414 st |= MultiSelectable;
415
416 //if (view->selectionMode() == QAbstractItemView::ExtendedSelection)
417 //st |= ExtSelectable;
418 //}
419 //if (m_role == QAccessible::TreeItem) {
420 // const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
421 // if (treeView->isExpanded(m_index))
422 // st |= Expanded;
423 //}
424
425 return st;
426 }
427
428 //Done
429 bool KItemListAccessibleCell::isExpandable() const
430 {
431 return false; //view->model()->hasChildren(m_index);
432 }
433
434 //Done
435 QRect KItemListAccessibleCell::rect(int child) const
436 {
437 // Q_ASSERT(child == 0);
438 return QRect();
439
440 // FIXME
441
442 //QRect r;
443 //r = view->visualRect(m_index);
444
445 //if (!r.isNull())
446 // r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
447 // r.translate(view->mapToGlobal(QPoint(0, 0)));
448 //return widget->textRect().toRect();
449 }
450
451 QString KItemListAccessibleCell::text(QAccessible::Text t, int child) const
452 {
453 //Q_ASSERT(child == 0)
454 Q_UNUSED(child)
455 QHash<QByteArray, QVariant> data = view->model()->data(index);
456 switch (t) {
457 case QAccessible::Value:
458 case QAccessible::Name:
459 return data["text"].toString();
460 case QAccessible::Description:
461 return data["text"].toString() + " : " + data["group"].toString();
462 default:
463 break;
464 }
465 return QString();
466 }
467
468 void KItemListAccessibleCell::setText(QAccessible::Text /*t*/, int child, const QString &text)
469 {
470 Q_ASSERT(child == 0);
471 // FIXME - is this even allowed on the KItemListWidget?
472 }
473
474 bool KItemListAccessibleCell::isValid() const
475 {
476 if (index <= 0) {
477 kDebug() << "Interface is not valid";
478 }
479
480 return index > 0;
481 }
482
483 int KItemListAccessibleCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
484 {
485 if (relation == Ancestor && index == 1) {
486 //if (m_role == QAccessible::TreeItem) {
487 // *iface = new QAccessibleTree(view);
488 //} else {
489 *iface = new KItemListViewAccessible(view);
490 return 0;
491 }
492
493 *iface = 0;
494 if (!view)
495 return -1;
496
497 switch (relation) {
498
499 case Child: {
500 return -1;
501 }
502 case Sibling:
503 if (index > 0) {
504 QAccessibleInterface *parent = queryAccessibleInterface(view);
505 int ret = parent->navigate(QAccessible::Child, index, iface);
506 delete parent;
507 if (*iface)
508 return ret;
509 }
510 return -1;
511
512 // From table1 implementation:
513 // case Up:
514 // case Down:
515 // case Left:
516 // case Right: {
517 // // This is in the "not so nice" category. In order to find out which item
518 // // is geometrically around, we have to set the current index, navigate
519 // // and restore the index as well as the old selection
520 // view()->setUpdatesEnabled(false);
521 // const QModelIndex oldIdx = view()->currentIndex();
522 // QList<QModelIndex> kids = children();
523 // const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row);
524 // const QItemSelection oldSelection = view()->selectionModel()->selection();
525 // view()->setCurrentIndex(currentIndex);
526 // const QModelIndex idx = view()->moveCursor(toCursorAction(relation), Qt::NoModifier);
527 // view()->setCurrentIndex(oldIdx);
528 // view()->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
529 // view()->setUpdatesEnabled(true);
530 // if (!idx.isValid())
531 // return -1;
532
533 // if (idx.parent() != row.parent() || idx.row() != row.row())
534 // *iface = cell(idx);
535 // return index ? kids.indexOf(idx) + 1 : 0; }
536 default:
537 break;
538 }
539
540 return -1;
541 }
542
543 QAccessible::Relation KItemListAccessibleCell::relationTo(int child, const QAccessibleInterface *, int otherChild) const
544 {
545 Q_ASSERT(child == 0);
546 Q_ASSERT(otherChild == 0);
547 /* we only check for parent-child relationships in trees
548 if (m_role == QAccessible::TreeItem && other->role(0) == QAccessible::TreeItem) {
549 QModelIndex otherIndex = static_cast<const QAccessibleTable2Cell*>(other)->m_index;
550 // is the other our parent?
551 if (otherIndex.parent() == m_index)
552 return QAccessible::Ancestor;
553 // are we the other's child?
554 if (m_index.parent() == otherIndex)
555 return QAccessible::Child;
556 }*/
557 return QAccessible::Unrelated;
558 }
559
560 #ifndef QT_NO_ACTION
561 int KItemListAccessibleCell::userActionCount(int) const
562 {
563 return 0;
564 }
565
566 QString KItemListAccessibleCell::actionText(int, Text, int) const
567 {
568 return QString();
569 }
570
571 bool KItemListAccessibleCell::doAction(int, int, const QVariantList &)
572 {
573 return false;
574 }
575
576 #endif
577
578 KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer *container)
579 : QAccessibleWidgetEx(container)
580 {}
581
582 KItemListContainerAccessible::~KItemListContainerAccessible ()
583 {}
584
585 int KItemListContainerAccessible::childCount () const
586 {
587 return 1;
588 }
589
590 int KItemListContainerAccessible::indexOfChild ( const QAccessibleInterface * child ) const
591 {
592 if(child == QAccessible::queryAccessibleInterface(container()->controller()->view()))
593 return 1;
594 return -1;
595 }
596
597 int KItemListContainerAccessible::navigate ( QAccessible::RelationFlag relation, int index, QAccessibleInterface ** target ) const
598 {
599 if (relation == QAccessible::Child) {
600 *target = new KItemListViewAccessible(container()->controller()->view());
601 return 0;
602 }
603 return QAccessibleWidgetEx::navigate(relation, index, target);
604 }
605
606 #endif // QT_NO_ITEMVIEWS
607
608 #endif // QT_NO_ACCESSIBILITY