]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kitemlistviewaccessible.cpp
Add some fixmes, comment out broken rect()
[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
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 // FIXME: no i18n
84 return "No Column Description";
85 }
86
87 int KItemListViewAccessible::columnCount() const
88 {
89 return view()->layouter()->columnCount();
90 }
91
92 int KItemListViewAccessible::rowCount() const
93 {
94 int itemCount = view()->model()->count();
95 int rowCount = itemCount / columnCount();
96 if (itemCount % rowCount)
97 ++rowCount;
98 return rowCount;
99 }
100
101 int KItemListViewAccessible::selectedCellCount() const
102 {
103 return view()->controller()->selectionManager()->selectedItems().size();
104 }
105
106 int KItemListViewAccessible::selectedColumnCount() const
107 {
108 return 0;
109 }
110
111 int KItemListViewAccessible::selectedRowCount() const
112 {
113 return 0;
114 }
115
116 QString KItemListViewAccessible::rowDescription(int) const
117 {
118 return "No Row Description";
119 }
120
121 QList<QAccessibleTable2CellInterface*> KItemListViewAccessible::selectedCells() const
122 {
123 QList<QAccessibleTable2CellInterface*> cells;
124 Q_FOREACH (int index, view()->controller()->selectionManager()->selectedItems()) {
125 cells.append(cell(index));
126 }
127 return cells;
128 }
129
130 QList<int> KItemListViewAccessible::selectedColumns() const
131 {
132 QList<int> columns;
133 /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) {
134 columns.append(index.column());
135 }*/
136 return columns;
137 }
138
139 QList<int> KItemListViewAccessible::selectedRows() const
140 {
141 QList<int> rows;
142 /*Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) {
143 rows.append(index.row());
144 }*/
145 return rows;
146 }
147
148 QAccessibleInterface *KItemListViewAccessible::summary() const
149 {
150 return 0;
151 }
152
153 bool KItemListViewAccessible::isColumnSelected(int) const
154 {
155 return false; //view()->selectionModel()->isColumnSelected(column, QModelIndex());
156 }
157
158 bool KItemListViewAccessible::isRowSelected(int) const
159 {
160 return false; //view()->selectionModel()->isRowSelected(row, QModelIndex());
161 }
162
163 bool KItemListViewAccessible::selectRow(int)
164 {
165 /*QModelIndex index = view()->model()->index(row, 0);
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::selectColumn(int)
173 {
174 /*QModelIndex index = view()->model()->index(0, column);
175 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
176 return false;
177 view()->selectionModel()->select(index, QItemSelectionModel::Select);*/
178 return true;
179 }
180
181 bool KItemListViewAccessible::unselectRow(int)
182 {
183 /*QModelIndex index = view()->model()->index(row, 0);
184 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
185 return false;
186 view()->selectionModel()->select(index, QItemSelectionModel::Deselect);*/
187 return true;
188 }
189
190 bool KItemListViewAccessible::unselectColumn(int)
191 {
192 /*QModelIndex index = view()->model()->index(0, column);
193 if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection)
194 return false;
195 view()->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect);*/
196 return true;
197 }
198
199 QAccessible2::TableModelChange KItemListViewAccessible::modelChange() const
200 {
201 QAccessible2::TableModelChange change;
202 // FIXME
203 return change;
204 }
205
206 QAccessible::Role KItemListViewAccessible::role(int child) const
207 {
208 Q_ASSERT(child >= 0);
209 if (child > 0)
210 return QAccessible::Cell;
211 return QAccessible::Table;
212 }
213
214 QAccessible::State KItemListViewAccessible::state(int child) const
215 {
216 Q_ASSERT(child == 0);
217 return QAccessible::Normal | HasInvokeExtension;
218 }
219
220 int KItemListViewAccessible::childAt(int x, int y) const
221 {
222 QPointF point = QPointF(x,y);
223 return view()->itemAt(view()->mapFromScene(point));
224 }
225
226 int KItemListViewAccessible::childCount() const
227 {
228 return rowCount() * columnCount();
229 }
230
231 int KItemListViewAccessible::indexOfChild(const QAccessibleInterface *iface) const
232 {
233 /*Q_ASSERT(iface->role(0) != QAccessible::TreeItem); // should be handled by tree class
234 if (iface->role(0) == QAccessible::Cell || iface->role(0) == QAccessible::ListItem) {
235 const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface);
236 return logicalIndex(cell->m_index);
237 } else if (iface->role(0) == QAccessible::ColumnHeader){
238 const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
239 return cell->index + (verticalHeader() ? 1 : 0) + 1;
240 } else if (iface->role(0) == QAccessible::RowHeader){
241 const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
242 return (cell->index+1) * (view()->model()->rowCount()+1) + 1;
243 } else if (iface->role(0) == QAccessible::Pane) {
244 return 1; // corner button
245 } else {
246 qWarning() << "WARNING QAccessibleTable2::indexOfChild Fix my children..."
247 << iface->role(0) << iface->text(QAccessible::Name, 0);
248 }
249 // FIXME: we are in denial of our children. this should stop.
250 return -1;*/
251
252 const KItemListWidgetAccessible *widget = static_cast<const KItemListWidgetAccessible*>(iface);
253 return widget->getIndex();
254 }
255
256 QString KItemListViewAccessible::text(Text t, int child) const
257 {
258 Q_ASSERT(child == 0);
259 // FIXME: I don't think this is needed, but if at all it needs i18n
260 if (t == QAccessible::Description)
261 return "List of files present in the current directory";
262 return "File List";
263 }
264
265 QRect KItemListViewAccessible::rect(int child) const
266 {
267 Q_UNUSED(child)
268 if (!view()->isVisible())
269 return QRect();
270
271 // FIXME: map to global
272 return view()->geometry().toRect();
273 }
274
275 int KItemListViewAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
276 {
277 *iface = 0;
278 switch (relation) {
279 /*case Ancestor: {
280 if (index == 1 && view()->parent()) {
281 *iface = QAccessible::queryAccessibleInterface(view()->parent());
282 if (*iface)
283 return 0;
284 }
285 break;
286 }*/
287 case QAccessible::Child: {
288 Q_ASSERT(index > 0);
289 *iface = cell(index);
290 if (*iface) {
291 return 0;
292 }
293 break;
294 }
295 default:
296 break;
297 }
298 return -1;
299 }
300
301 QAccessible::Relation KItemListViewAccessible::relationTo(int, const QAccessibleInterface *, int) const
302 {
303 return QAccessible::Unrelated;
304 }
305
306 #ifndef QT_NO_ACTION
307 int KItemListViewAccessible::userActionCount(int) const
308 {
309 return 0;
310 }
311 QString KItemListViewAccessible::actionText(int, Text, int) const
312 {
313 return QString();
314 }
315 bool KItemListViewAccessible::doAction(int, int, const QVariantList &)
316 {
317 return false;
318 }
319 #endif
320
321 // TABLE CELL
322
323 KItemListWidgetAccessible::KItemListWidgetAccessible(KItemListView *view_, int index_)
324 : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), index(index_)
325 {
326 Q_ASSERT(index_>0);
327 }
328
329 int KItemListWidgetAccessible::columnExtent() const { return 1; }
330 int KItemListWidgetAccessible::rowExtent() const { return 1; }
331
332 QList<QAccessibleInterface*> KItemListWidgetAccessible::rowHeaderCells() const
333 {
334 QList<QAccessibleInterface*> headerCell;
335 /*if (verticalHeader()) {
336 headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.row(), Qt::Vertical));
337 }*/
338 return headerCell;
339 }
340
341 QList<QAccessibleInterface*> KItemListWidgetAccessible::columnHeaderCells() const
342 {
343 QList<QAccessibleInterface*> headerCell;
344 /*if (horizontalHeader()) {
345 headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.column(), Qt::Horizontal));
346 }*/
347 return headerCell;
348 }
349
350 int KItemListWidgetAccessible::columnIndex() const
351 {
352 return view->layouter()->itemColumn(index);
353 }
354
355 int KItemListWidgetAccessible::rowIndex() const
356 {
357 /*if (role(0) == QAccessible::TreeItem) {
358 const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
359 Q_ASSERT(treeView);
360 int row = treeView->d_func()->viewIndex(m_index);
361 return row;
362 }*/
363 return view->layouter()->itemRow(index);
364 }
365
366 //Done
367 bool KItemListWidgetAccessible::isSelected() const
368 {
369 return widget->isSelected();
370 }
371
372 void KItemListWidgetAccessible::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* KItemListWidgetAccessible::table() const
383 {
384 return QAccessible::queryAccessibleInterface(view)->table2Interface();
385 }
386
387 QAccessible::Role KItemListWidgetAccessible::role(int child) const
388 {
389 Q_ASSERT(child == 0);
390 return QAccessible::Cell;
391 }
392
393 QAccessible::State KItemListWidgetAccessible::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 st |= HasInvokeExtension;
426 return st;
427 }
428
429 //Done
430 bool KItemListWidgetAccessible::isExpandable() const
431 {
432 return false; //view->model()->hasChildren(m_index);
433 }
434
435 //Done
436 QRect KItemListWidgetAccessible::rect(int child) const
437 {
438 // Q_ASSERT(child == 0);
439 return QRect();
440
441 // FIXME
442
443 //QRect r;
444 //r = view->visualRect(m_index);
445
446 //if (!r.isNull())
447 // r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
448 // r.translate(view->mapToGlobal(QPoint(0, 0)));
449 //return widget->textRect().toRect();
450 }
451
452 //Done
453 QString KItemListWidgetAccessible::text(Text t, int child) const
454 {
455 Q_ASSERT(child == 0);
456
457 QHash<QByteArray, QVariant> data = widget->data();
458 switch (t) {
459 case QAccessible::Value:
460 case QAccessible::Name:
461 return data["text"].toString();
462 case QAccessible::Description:
463 return data["text"].toString() + " : " + data["group"].toString();
464 default:
465 break;
466 }
467 return "";
468 }
469
470 //Done
471 void KItemListWidgetAccessible::setText(QAccessible::Text /*t*/, int child, const QString &text)
472 {
473 Q_ASSERT(child == 0);
474 (widget->data())["text"]=QVariant(text);
475 }
476
477 //Done
478 bool KItemListWidgetAccessible::isValid() const
479 {
480 if (index <= 0) {
481 kDebug() << "Interface is not valid";
482 }
483
484 return index > 0;
485 }
486
487 int KItemListWidgetAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
488 {
489 if (relation == Ancestor && index == 1) {
490 //if (m_role == QAccessible::TreeItem) {
491 // *iface = new QAccessibleTree(view);
492 //} else {
493 *iface = new KItemListViewAccessible(view);
494 return 0;
495 }
496
497 *iface = 0;
498 if (!view)
499 return -1;
500
501 switch (relation) {
502
503 case Child: {
504 return -1;
505 }
506 case Sibling:
507 if (index > 0) {
508 QAccessibleInterface *parent = queryAccessibleInterface(view);
509 int ret = parent->navigate(QAccessible::Child, index, iface);
510 delete parent;
511 if (*iface)
512 return ret;
513 }
514 return -1;
515
516 // From table1 implementation:
517 // case Up:
518 // case Down:
519 // case Left:
520 // case Right: {
521 // // This is in the "not so nice" category. In order to find out which item
522 // // is geometrically around, we have to set the current index, navigate
523 // // and restore the index as well as the old selection
524 // view()->setUpdatesEnabled(false);
525 // const QModelIndex oldIdx = view()->currentIndex();
526 // QList<QModelIndex> kids = children();
527 // const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row);
528 // const QItemSelection oldSelection = view()->selectionModel()->selection();
529 // view()->setCurrentIndex(currentIndex);
530 // const QModelIndex idx = view()->moveCursor(toCursorAction(relation), Qt::NoModifier);
531 // view()->setCurrentIndex(oldIdx);
532 // view()->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
533 // view()->setUpdatesEnabled(true);
534 // if (!idx.isValid())
535 // return -1;
536
537 // if (idx.parent() != row.parent() || idx.row() != row.row())
538 // *iface = cell(idx);
539 // return index ? kids.indexOf(idx) + 1 : 0; }
540 default:
541 break;
542 }
543
544 return -1;
545 }
546
547 QAccessible::Relation KItemListWidgetAccessible::relationTo(int child, const QAccessibleInterface *, int otherChild) const
548 {
549 Q_ASSERT(child == 0);
550 Q_ASSERT(otherChild == 0);
551 /* we only check for parent-child relationships in trees
552 if (m_role == QAccessible::TreeItem && other->role(0) == QAccessible::TreeItem) {
553 QModelIndex otherIndex = static_cast<const QAccessibleTable2Cell*>(other)->m_index;
554 // is the other our parent?
555 if (otherIndex.parent() == m_index)
556 return QAccessible::Ancestor;
557 // are we the other's child?
558 if (m_index.parent() == otherIndex)
559 return QAccessible::Child;
560 }*/
561 return QAccessible::Unrelated;
562 }
563
564 #ifndef QT_NO_ACTION
565 int KItemListWidgetAccessible::userActionCount(int) const
566 {
567 return 0;
568 }
569
570 QString KItemListWidgetAccessible::actionText(int, Text, int) const
571 {
572 return QString();
573 }
574
575 bool KItemListWidgetAccessible::doAction(int, int, const QVariantList &)
576 {
577 return false;
578 }
579
580 #endif
581
582 KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer *container)
583 : QAccessibleWidgetEx(container)
584 {}
585
586 KItemListContainerAccessible::~KItemListContainerAccessible ()
587 {}
588
589 int KItemListContainerAccessible::childCount () const
590 {
591 return 1;
592 }
593
594 int KItemListContainerAccessible::indexOfChild ( const QAccessibleInterface * child ) const
595 {
596 if(child == QAccessible::queryAccessibleInterface(container()->controller()->view()))
597 return 1;
598 return -1;
599 }
600
601 int KItemListContainerAccessible::navigate ( QAccessible::RelationFlag relation, int index, QAccessibleInterface ** target ) const
602 {
603 if (relation == QAccessible::Child) {
604 *target = new KItemListViewAccessible(container()->controller()->view());
605 return 0;
606 }
607 return QAccessibleWidgetEx::navigate(relation, index, target);
608 }
609
610 #endif // QT_NO_ITEMVIEWS
611
612 #endif // QT_NO_ACCESSIBILITY