]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kitemlistviewaccessible.cpp
Improve drawing selected items in Compact/Details View and Places Panel
[dolphin.git] / src / kitemviews / kitemlistviewaccessible.cpp
1 /***************************************************************************
2 * Copyright (C) 2012 by Amandeep Singh <aman.dedman@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #ifndef QT_NO_ACCESSIBILITY
21
22 #include "kitemlistviewaccessible.h"
23
24 #include "kitemlistcontainer.h"
25 #include "kitemlistcontroller.h"
26 #include "kitemlistselectionmanager.h"
27 #include "kitemlistview.h"
28 #include "private/kitemlistviewlayouter.h"
29
30 #include <QtGui/qaccessible2.h>
31 #include <qgraphicsscene.h>
32 #include <qgraphicsview.h>
33
34 #include <KDebug>
35 #include <QHash>
36
37 KItemListView* KItemListViewAccessible::view() const
38 {
39 return qobject_cast<KItemListView*>(object());
40 }
41
42 KItemListViewAccessible::KItemListViewAccessible(KItemListView* view_) :
43 QAccessibleObjectEx(view_)
44 {
45 Q_ASSERT(view());
46 }
47
48 void KItemListViewAccessible::modelReset()
49 {
50 }
51
52 QAccessible::Role KItemListViewAccessible::cellRole() const
53 {
54 return QAccessible::Cell;
55 }
56
57 QAccessibleTable2CellInterface* KItemListViewAccessible::cell(int index) const
58 {
59 if (index < 0 || index >= view()->model()->count()) {
60 return 0;
61 } else {
62 return new KItemListAccessibleCell(view(), index);
63 }
64 }
65
66 QVariant KItemListViewAccessible::invokeMethodEx(Method, int, const QVariantList&)
67 {
68 return QVariant();
69 }
70
71 QAccessibleTable2CellInterface* KItemListViewAccessible::cellAt(int row, int column) const
72 {
73 return cell(columnCount() * row + column);
74 }
75
76 QAccessibleInterface* KItemListViewAccessible::caption() const
77 {
78 return 0;
79 }
80
81 QString KItemListViewAccessible::columnDescription(int) const
82 {
83 return QString();
84 }
85
86 int KItemListViewAccessible::columnCount() const
87 {
88 return view()->m_layouter->columnCount();
89 }
90
91 int KItemListViewAccessible::rowCount() const
92 {
93 if (columnCount() <= 0) {
94 return 0;
95 }
96
97 int itemCount = view()->model()->count();
98 int rowCount = itemCount / columnCount();
99
100 if (rowCount <= 0) {
101 return 0;
102 }
103
104 if (itemCount % columnCount()) {
105 ++rowCount;
106 }
107 return rowCount;
108 }
109
110 int KItemListViewAccessible::selectedCellCount() const
111 {
112 return view()->controller()->selectionManager()->selectedItems().count();
113 }
114
115 int KItemListViewAccessible::selectedColumnCount() const
116 {
117 return 0;
118 }
119
120 int KItemListViewAccessible::selectedRowCount() const
121 {
122 return 0;
123 }
124
125 QString KItemListViewAccessible::rowDescription(int) const
126 {
127 return QString();
128 }
129
130 QList<QAccessibleTable2CellInterface*> KItemListViewAccessible::selectedCells() const
131 {
132 QList<QAccessibleTable2CellInterface*> cells;
133 Q_FOREACH (int index, view()->controller()->selectionManager()->selectedItems()) {
134 cells.append(cell(index));
135 }
136 return cells;
137 }
138
139 QList<int> KItemListViewAccessible::selectedColumns() const
140 {
141 return QList<int>();
142 }
143
144 QList<int> KItemListViewAccessible::selectedRows() const
145 {
146 return QList<int>();
147 }
148
149 QAccessibleInterface* KItemListViewAccessible::summary() const
150 {
151 return 0;
152 }
153
154 bool KItemListViewAccessible::isColumnSelected(int) const
155 {
156 return false;
157 }
158
159 bool KItemListViewAccessible::isRowSelected(int) const
160 {
161 return false;
162 }
163
164 bool KItemListViewAccessible::selectRow(int)
165 {
166 return true;
167 }
168
169 bool KItemListViewAccessible::selectColumn(int)
170 {
171 return true;
172 }
173
174 bool KItemListViewAccessible::unselectRow(int)
175 {
176 return true;
177 }
178
179 bool KItemListViewAccessible::unselectColumn(int)
180 {
181 return true;
182 }
183
184 QAccessible2::TableModelChange KItemListViewAccessible::modelChange() const
185 {
186 QAccessible2::TableModelChange change;
187 change.lastRow = rowCount();
188 change.lastColumn = columnCount();
189 return change;
190 }
191
192 QAccessible::Role KItemListViewAccessible::role(int child) const
193 {
194 Q_ASSERT(child >= 0);
195
196 if (child > 0) {
197 return QAccessible::Cell;
198 } else {
199 return QAccessible::Table;
200 }
201 }
202
203 QAccessible::State KItemListViewAccessible::state(int child) const
204 {
205 if (child) {
206 QAccessibleInterface* interface = 0;
207 navigate(Child, child, &interface);
208 if (interface) {
209 return interface->state(0);
210 }
211 }
212
213 return QAccessible::Normal | QAccessible::HasInvokeExtension;
214 }
215
216 int KItemListViewAccessible::childAt(int x, int y) const
217 {
218 const QPointF point = QPointF(x,y);
219 return view()->itemAt(view()->mapFromScene(point));
220 }
221
222 int KItemListViewAccessible::childCount() const
223 {
224 return view()->model()->count();
225 }
226
227 int KItemListViewAccessible::indexOfChild(const QAccessibleInterface* interface) const
228 {
229 const KItemListAccessibleCell* widget = static_cast<const KItemListAccessibleCell*>(interface);
230 return widget->index() + 1;
231 }
232
233 QString KItemListViewAccessible::text(Text, int child) const
234 {
235 Q_ASSERT(child == 0);
236 return QString();
237 }
238
239 QRect KItemListViewAccessible::rect(int child) const
240 {
241 Q_UNUSED(child)
242 if (!view()->isVisible()) {
243 return QRect();
244 }
245
246 const QGraphicsScene* scene = view()->scene();
247 if (scene) {
248 const QPoint origin = scene->views()[0]->mapToGlobal(QPoint(0, 0));
249 const QRect viewRect = view()->geometry().toRect();
250 return viewRect.translated(origin);
251 } else {
252 return QRect();
253 }
254 }
255
256 int KItemListViewAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface** interface) const
257 {
258 *interface = 0;
259
260 switch (relation) {
261 case QAccessible::Child:
262 Q_ASSERT(index > 0);
263 *interface = cell(index - 1);
264 if (*interface) {
265 return 0;
266 }
267 break;
268
269 default:
270 break;
271 }
272
273 return -1;
274 }
275
276 QAccessible::Relation KItemListViewAccessible::relationTo(int, const QAccessibleInterface*, int) const
277 {
278 return QAccessible::Unrelated;
279 }
280
281 #ifndef QT_NO_ACTION
282
283 int KItemListViewAccessible::userActionCount(int) const
284 {
285 return 0;
286 }
287
288 QString KItemListViewAccessible::actionText(int, Text, int) const
289 {
290 return QString();
291 }
292
293 bool KItemListViewAccessible::doAction(int, int, const QVariantList&)
294 {
295 return false;
296 }
297
298 #endif
299
300 // Table Cell
301
302 KItemListAccessibleCell::KItemListAccessibleCell(KItemListView* view, int index) :
303 m_view(view),
304 m_index(index)
305 {
306 Q_ASSERT(index >= 0 && index < view->model()->count());
307 }
308
309 int KItemListAccessibleCell::columnExtent() const
310 {
311 return 1;
312 }
313
314 int KItemListAccessibleCell::rowExtent() const
315 {
316 return 1;
317 }
318
319 QList<QAccessibleInterface*> KItemListAccessibleCell::rowHeaderCells() const
320 {
321 return QList<QAccessibleInterface*>();
322 }
323
324 QList<QAccessibleInterface*> KItemListAccessibleCell::columnHeaderCells() const
325 {
326 return QList<QAccessibleInterface*>();
327 }
328
329 int KItemListAccessibleCell::columnIndex() const
330 {
331 return m_view->m_layouter->itemColumn(m_index);
332 }
333
334 int KItemListAccessibleCell::rowIndex() const
335 {
336 return m_view->m_layouter->itemRow(m_index);
337 }
338
339 bool KItemListAccessibleCell::isSelected() const
340 {
341 return m_view->controller()->selectionManager()->isSelected(m_index);
342 }
343
344 void KItemListAccessibleCell::rowColumnExtents(int* row, int* column, int* rowExtents, int* columnExtents, bool* selected) const
345 {
346 const KItemListViewLayouter* layouter = m_view->m_layouter;
347 *row = layouter->itemRow(m_index);
348 *column = layouter->itemColumn(m_index);
349 *rowExtents = 1;
350 *columnExtents = 1;
351 *selected = isSelected();
352 }
353
354 QAccessibleTable2Interface* KItemListAccessibleCell::table() const
355 {
356 return QAccessible::queryAccessibleInterface(m_view)->table2Interface();
357 }
358
359 QAccessible::Role KItemListAccessibleCell::role(int child) const
360 {
361 Q_ASSERT(child == 0);
362 return QAccessible::Cell;
363 }
364
365 QAccessible::State KItemListAccessibleCell::state(int child) const
366 {
367 Q_ASSERT(child == 0);
368 QAccessible::State state = Normal;
369
370 if (isSelected()) {
371 state |= Selected;
372 }
373
374 if (m_view->controller()->selectionManager()->currentItem() == m_index) {
375 state |= Focused;
376 }
377
378 state |= Selectable;
379 state |= Focusable;
380
381 if (m_view->controller()->selectionBehavior() == KItemListController::MultiSelection) {
382 state |= MultiSelectable;
383 }
384
385 if (m_view->model()->isExpandable(m_index)) {
386 if (m_view->model()->isExpanded(m_index)) {
387 state |= Expanded;
388 } else {
389 state |= Collapsed;
390 }
391 }
392
393 return state;
394 }
395
396 bool KItemListAccessibleCell::isExpandable() const
397 {
398 return m_view->model()->isExpandable(m_index);
399 }
400
401 QRect KItemListAccessibleCell::rect(int) const
402 {
403 QRect rect = m_view->itemRect(m_index).toRect();
404
405 if (rect.isNull()) {
406 return QRect();
407 }
408
409 rect.translate(m_view->mapToScene(QPointF(0.0, 0.0)).toPoint());
410 rect.translate(m_view->scene()->views()[0]->mapToGlobal(QPoint(0, 0)));
411 return rect;
412 }
413
414 QString KItemListAccessibleCell::text(QAccessible::Text t, int child) const
415 {
416 Q_ASSERT(child == 0);
417 Q_UNUSED(child)
418
419 switch (t) {
420 case QAccessible::Value:
421 case QAccessible::Name: {
422 const QHash<QByteArray, QVariant> data = m_view->model()->data(m_index);
423 return data["text"].toString();
424 }
425
426 default:
427 break;
428 }
429
430 return QString();
431 }
432
433 void KItemListAccessibleCell::setText(QAccessible::Text, int child, const QString&)
434 {
435 Q_ASSERT(child == 0);
436 }
437
438 bool KItemListAccessibleCell::isValid() const
439 {
440 return m_view && (m_index >= 0) && (m_index < m_view->model()->count());
441 }
442
443 int KItemListAccessibleCell::childAt(int, int) const
444 {
445 return 0;
446 }
447
448 int KItemListAccessibleCell::childCount() const
449 {
450 return 0;
451 }
452
453 int KItemListAccessibleCell::indexOfChild(const QAccessibleInterface* child) const
454 {
455 Q_UNUSED(child);
456 return -1;
457 }
458
459 int KItemListAccessibleCell::navigate(RelationFlag relation, int index, QAccessibleInterface** interface) const
460 {
461 if (relation == Ancestor && index == 1) {
462 *interface = new KItemListViewAccessible(m_view);
463 return 0;
464 }
465
466 *interface = 0;
467 return -1;
468 }
469
470 QAccessible::Relation KItemListAccessibleCell::relationTo(int child, const QAccessibleInterface* , int otherChild) const
471 {
472 Q_ASSERT(child == 0);
473 Q_ASSERT(otherChild == 0);
474 return QAccessible::Unrelated;
475 }
476
477 #ifndef QT_NO_ACTION
478
479 int KItemListAccessibleCell::userActionCount(int) const
480 {
481 return 0;
482 }
483
484 QString KItemListAccessibleCell::actionText(int, Text, int) const
485 {
486 return QString();
487 }
488
489 bool KItemListAccessibleCell::doAction(int, int, const QVariantList&)
490 {
491 return false;
492 }
493
494 #endif
495
496 int KItemListAccessibleCell::index() const
497 {
498 return m_index;
499 }
500
501 QObject* KItemListAccessibleCell::object() const
502 {
503 return 0;
504 }
505
506 // Container Interface
507 KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer* container) :
508 QAccessibleWidgetEx(container)
509 {
510 }
511
512 KItemListContainerAccessible::~KItemListContainerAccessible()
513 {
514 }
515
516 int KItemListContainerAccessible::childCount() const
517 {
518 return 1;
519 }
520
521 int KItemListContainerAccessible::indexOfChild(const QAccessibleInterface* child) const
522 {
523 if (child->object() == container()->controller()->view()) {
524 return 1;
525 } else {
526 return -1;
527 }
528 }
529
530 int KItemListContainerAccessible::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface** target) const
531 {
532 if (relation == QAccessible::Child) {
533 *target = new KItemListViewAccessible(container()->controller()->view());
534 return 0;
535 } else {
536 return QAccessibleWidgetEx::navigate(relation, index, target);
537 }
538 }
539
540 const KItemListContainer* KItemListContainerAccessible::container() const
541 {
542 return qobject_cast<KItemListContainer*>(object());
543 }
544
545 #endif // QT_NO_ACCESSIBILITY