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