itemviews.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/accessible/itemviews.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the plugins of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "itemviews_p.h"-
41-
42#include <qheaderview.h>-
43#include <qtableview.h>-
44#include <qlistview.h>-
45#include <qtreeview.h>-
46#include <private/qtreewidget_p.h>-
47-
48#ifndef QT_NO_ACCESSIBILITY-
49-
50QT_BEGIN_NAMESPACE-
51-
52#ifndef QT_NO_ITEMVIEWS-
53/*-
54Implementation of the IAccessible2 table2 interface. Much simpler than-
55the other table interfaces since there is only the main table and cells:-
56-
57TABLE/LIST/TREE-
58 |- HEADER CELL-
59 |- CELL-
60 |- CELL-
61 ...-
62*/-
63-
64-
65QAbstractItemView *QAccessibleTable::view() const-
66{-
67 return qobject_cast<QAbstractItemView*>(object());-
68}-
69-
70int QAccessibleTable::logicalIndex(const QModelIndex &index) const-
71{-
72 if (!view()->model() || !index.isValid())-
73 return -1;-
74 int vHeader = verticalHeader() ? 1 : 0;-
75 int hHeader = horizontalHeader() ? 1 : 0;-
76 return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader);-
77}-
78-
79QAccessibleTable::QAccessibleTable(QWidget *w)-
80 : QAccessibleObject(w)-
81{-
82 Q_ASSERT(view());-
83-
84 if (qobject_cast<const QTableView*>(view())) {-
85 m_role = QAccessible::Table;-
86 } else if (qobject_cast<const QTreeView*>(view())) {-
87 m_role = QAccessible::Tree;-
88 } else if (qobject_cast<const QListView*>(view())) {-
89 m_role = QAccessible::List;-
90 } else {-
91 // is this our best guess?-
92 m_role = QAccessible::Table;-
93 }-
94}-
95-
96bool QAccessibleTable::isValid() const-
97{-
98 return (view() && !qobject_cast<QWidget*>(view())->d_func()->data.in_destructor);-
99}-
100-
101QAccessibleTable::~QAccessibleTable()-
102{-
103 Q_FOREACH (QAccessible::Id id, childToId)-
104 QAccessible::deleteAccessibleInterface(id);-
105}-
106-
107QHeaderView *QAccessibleTable::horizontalHeader() const-
108{-
109 QHeaderView *header = 0;-
110 if (false) {
dead code: { }
-
111#ifndef QT_NO_TABLEVIEW
dead code: { }
-
112 } else if (const QTableView *tv = qobject_cast<const QTableView*>(view())) {
dead code: { }
-
113 header = tv->horizontalHeader();-
114#endif-
115#ifndef QT_NO_TREEVIEW-
116 } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view())) {-
117 header = tv->header();-
118#endif-
119 }-
120 return header;-
121}-
122-
123QHeaderView *QAccessibleTable::verticalHeader() const-
124{-
125 QHeaderView *header = 0;-
126 if (false) {
dead code: { }
-
127#ifndef QT_NO_TABLEVIEW
dead code: { }
-
128 } else if (const QTableView *tv = qobject_cast<const QTableView*>(view())) {
dead code: { }
-
129 header = tv->verticalHeader();-
130#endif-
131 }-
132 return header;-
133}-
134-
135QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const-
136{-
137 if (!view()->model())
!view()->model()Description
TRUEnever evaluated
FALSEnever evaluated
0
138 return 0;
never executed: return 0;
0
139 Q_ASSERT(role() != QAccessible::Tree);-
140 QModelIndex index = view()->model()->index(row, column, view()->rootIndex());-
141 if (Q_UNLIKELY(!index.isValid())())) {
__builtin_expe...lid()), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
142 qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view();-
143 return 0;
never executed: return 0;
0
144 }-
145 return child(logicalIndex(index));
never executed: return child(logicalIndex(index));
0
146}-
147-
148QAccessibleInterface *QAccessibleTable::caption() const-
149{-
150 return 0;-
151}-
152-
153QString QAccessibleTable::columnDescription(int column) const-
154{-
155 if (!view()->model())-
156 return QString();-
157 return view()->model()->headerData(column, Qt::Horizontal).toString();-
158}-
159-
160int QAccessibleTable::columnCount() const-
161{-
162 if (!view()->model())-
163 return 0;-
164 return view()->model()->columnCount();-
165}-
166-
167int QAccessibleTable::rowCount() const-
168{-
169 if (!view()->model())-
170 return 0;-
171 return view()->model()->rowCount();-
172}-
173-
174int QAccessibleTable::selectedCellCount() const-
175{-
176 if (!view()->selectionModel())-
177 return 0;-
178 return view()->selectionModel()->selectedIndexes().count();-
179}-
180-
181int QAccessibleTable::selectedColumnCount() const-
182{-
183 if (!view()->selectionModel())-
184 return 0;-
185 return view()->selectionModel()->selectedColumns().count();-
186}-
187-
188int QAccessibleTable::selectedRowCount() const-
189{-
190 if (!view()->selectionModel())-
191 return 0;-
192 return view()->selectionModel()->selectedRows().count();-
193}-
194-
195QString QAccessibleTable::rowDescription(int row) const-
196{-
197 if (!view()->model())-
198 return QString();-
199 return view()->model()->headerData(row, Qt::Vertical).toString();-
200}-
201-
202QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const-
203{-
204 QList<QAccessibleInterface*> cells;-
205 if (!view()->selectionModel())-
206 return cells;-
207 const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes();-
208 cells.reserve(selectedIndexes.size());-
209 Q_FOREACH (const QModelIndex &index, selectedIndexes)-
210 cells.append(child(logicalIndex(index)));-
211 return cells;-
212}-
213-
214QList<int> QAccessibleTable::selectedColumns() const-
215{-
216 if (!view()->selectionModel())-
217 return QList<int>();-
218 QList<int> columns;-
219 const QModelIndexList selectedColumns = view()->selectionModel()->selectedColumns();-
220 columns.reserve(selectedColumns.size());-
221 Q_FOREACH (const QModelIndex &index, selectedColumns)-
222 columns.append(index.column());-
223-
224 return columns;-
225}-
226-
227QList<int> QAccessibleTable::selectedRows() const-
228{-
229 if (!view()->selectionModel())-
230 return QList<int>();-
231 QList<int> rows;-
232 const QModelIndexList selectedRows = view()->selectionModel()->selectedRows();-
233 rows.reserve(selectedRows.size());-
234 Q_FOREACH (const QModelIndex &index, selectedRows)-
235 rows.append(index.row());-
236-
237 return rows;-
238}-
239-
240QAccessibleInterface *QAccessibleTable::summary() const-
241{-
242 return 0;-
243}-
244-
245bool QAccessibleTable::isColumnSelected(int column) const-
246{-
247 if (!view()->selectionModel())-
248 return false;-
249 return view()->selectionModel()->isColumnSelected(column, QModelIndex());-
250}-
251-
252bool QAccessibleTable::isRowSelected(int row) const-
253{-
254 if (!view()->selectionModel())-
255 return false;-
256 return view()->selectionModel()->isRowSelected(row, QModelIndex());-
257}-
258-
259bool QAccessibleTable::selectRow(int row)-
260{-
261 if (!view()->model() || !view()->selectionModel())-
262 return false;-
263 QModelIndex index = view()->model()->index(row, 0, view()->rootIndex());-
264-
265 if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns)-
266 return false;-
267-
268 switch (view()->selectionMode()) {-
269 case QAbstractItemView::NoSelection:-
270 return false;-
271 case QAbstractItemView::SingleSelection:-
272 if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 )-
273 return false;-
274 view()->clearSelection();-
275 break;-
276 case QAbstractItemView::ContiguousSelection:-
277 if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))-
278 && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex()))-
279 view()->clearSelection();-
280 break;-
281 default:-
282 break;-
283 }-
284-
285 view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);-
286 return true;-
287}-
288-
289bool QAccessibleTable::selectColumn(int column)-
290{-
291 if (!view()->model() || !view()->selectionModel())-
292 return false;-
293 QModelIndex index = view()->model()->index(0, column, view()->rootIndex());-
294-
295 if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows)-
296 return false;-
297-
298 switch (view()->selectionMode()) {-
299 case QAbstractItemView::NoSelection:-
300 return false;-
301 case QAbstractItemView::SingleSelection:-
302 if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1)-
303 return false;-
304 case QAbstractItemView::ContiguousSelection:-
305 if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex()))-
306 && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex()))-
307 view()->clearSelection();-
308 break;-
309 default:-
310 break;-
311 }-
312-
313 view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns);-
314 return true;-
315}-
316-
317bool QAccessibleTable::unselectRow(int row)-
318{-
319 if (!view()->model() || !view()->selectionModel())-
320 return false;-
321-
322 QModelIndex index = view()->model()->index(row, 0, view()->rootIndex());-
323 if (!index.isValid())-
324 return false;-
325-
326 QItemSelection selection(index, index);-
327-
328 switch (view()->selectionMode()) {-
329 case QAbstractItemView::SingleSelection:-
330 //In SingleSelection and ContiguousSelection once an item-
331 //is selected, there's no way for the user to unselect all items-
332 if (selectedRowCount() == 1)-
333 return false;-
334 break;-
335 case QAbstractItemView::ContiguousSelection:-
336 if (selectedRowCount() == 1)-
337 return false;-
338-
339 if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))-
340 && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) {-
341 //If there are rows selected both up the current row and down the current rown,-
342 //the ones which are down the current row will be deselected-
343 selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex()));-
344 }-
345 default:-
346 break;-
347 }-
348-
349 view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows);-
350 return true;-
351}-
352-
353bool QAccessibleTable::unselectColumn(int column)-
354{-
355 if (!view()->model() || !view()->selectionModel())-
356 return false;-
357-
358 QModelIndex index = view()->model()->index(0, column, view()->rootIndex());-
359 if (!index.isValid())-
360 return false;-
361-
362 QItemSelection selection(index, index);-
363-
364 switch (view()->selectionMode()) {-
365 case QAbstractItemView::SingleSelection:-
366 //In SingleSelection and ContiguousSelection once an item-
367 //is selected, there's no way for the user to unselect all items-
368 if (selectedColumnCount() == 1)-
369 return false;-
370 break;-
371 case QAbstractItemView::ContiguousSelection:-
372 if (selectedColumnCount() == 1)-
373 return false;-
374-
375 if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex()))-
376 && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {-
377 //If there are columns selected both at the left of the current row and at the right-
378 //of the current rown, the ones which are at the right will be deselected-
379 selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex()));-
380 }-
381 default:-
382 break;-
383 }-
384-
385 view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns);-
386 return true;-
387}-
388-
389QAccessible::Role QAccessibleTable::role() const-
390{-
391 return m_role;-
392}-
393-
394QAccessible::State QAccessibleTable::state() const-
395{-
396 return QAccessible::State();-
397}-
398-
399QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const-
400{-
401 QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0));-
402 QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset);-
403 // FIXME: if indexPosition < 0 in one coordinate, return header-
404-
405 QModelIndex index = view()->indexAt(indexPosition);-
406 if (index.isValid()) {-
407 return child(logicalIndex(index));-
408 }-
409 return 0;-
410}-
411-
412int QAccessibleTable::childCount() const-
413{-
414 if (!view()->model())-
415 return 0;-
416 int vHeader = verticalHeader() ? 1 : 0;-
417 int hHeader = horizontalHeader() ? 1 : 0;-
418 return (view()->model()->rowCount()+hHeader) * (view()->model()->columnCount()+vHeader);-
419}-
420-
421int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const-
422{-
423 if (!view()->model())-
424 return -1;-
425 QAccessibleInterface *parent = iface->parent();-
426 if (parent->object() != view())-
427 return -1;-
428-
429 Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class-
430 if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {-
431 const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface);-
432 return logicalIndex(cell->m_index);-
433 } else if (iface->role() == QAccessible::ColumnHeader){-
434 const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);-
435 return cell->index + (verticalHeader() ? 1 : 0);-
436 } else if (iface->role() == QAccessible::RowHeader){-
437 const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);-
438 return (cell->index + 1) * (view()->model()->columnCount() + 1);-
439 } else if (iface->role() == QAccessible::Pane) {-
440 return 0; // corner button-
441 } else {-
442 qWarning() << "WARNING QAccessibleTable::indexOfChild Fix my children..."-
443 << iface->role() << iface->text(QAccessible::Name);-
444 }-
445 // FIXME: we are in denial of our children. this should stop.-
446 return -1;-
447}-
448-
449QString QAccessibleTable::text(QAccessible::Text t) const-
450{-
451 if (t == QAccessible::Description)-
452 return view()->accessibleDescription();-
453 return view()->accessibleName();-
454}-
455-
456QRect QAccessibleTable::rect() const-
457{-
458 if (!view()->isVisible())-
459 return QRect();-
460 QPoint pos = view()->mapToGlobal(QPoint(0, 0));-
461 return QRect(pos.x(), pos.y(), view()->width(), view()->height());-
462}-
463-
464QAccessibleInterface *QAccessibleTable::parent() const-
465{-
466 if (view() && view()->parent()) {-
467 if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) {-
468 return QAccessible::queryAccessibleInterface(view()->parent()->parent());-
469 }-
470 return QAccessible::queryAccessibleInterface(view()->parent());-
471 }-
472 return 0;-
473}-
474-
475QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const-
476{-
477 if (!view()->model())
!view()->model()Description
TRUEnever evaluated
FALSEnever evaluated
0
478 return 0;
never executed: return 0;
0
479-
480 if (childToId.contains(logicalIndex)) {
childToId.cont...(logicalIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
481 QAccessible::Id id = childToId.value(logicalIndex);-
482 return QAccessible::accessibleInterface(id);
never executed: return QAccessible::accessibleInterface(id);
0
483 }-
484-
485 int vHeader = verticalHeader() ? 1 : 0;
verticalHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
486 int hHeader = horizontalHeader() ? 1 : 0;
horizontalHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
487-
488 int columns = view()->model()->columnCount() + vHeader;-
489-
490 int row = logicalIndex / columns;-
491 int column = logicalIndex % columns;-
492-
493 QAccessibleInterface *iface = 0;-
494-
495 if (vHeader) {
vHeaderDescription
TRUEnever evaluated
FALSEnever evaluated
0
496 if (column == 0) {
column == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
497 if (hHeader && row == 0) {
hHeaderDescription
TRUEnever evaluated
FALSEnever evaluated
row == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
498 iface = new QAccessibleTableCornerButton(view());-
499 } else {
never executed: end of block
0
500 iface = new QAccessibleTableHeaderCell(view(), row - hHeader, Qt::Vertical);-
501 }
never executed: end of block
0
502 }-
503 --column;-
504 }
never executed: end of block
0
505 if (!iface && hHeader) {
!ifaceDescription
TRUEnever evaluated
FALSEnever evaluated
hHeaderDescription
TRUEnever evaluated
FALSEnever evaluated
0
506 if (row == 0) {
row == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
507 iface = new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal);-
508 }
never executed: end of block
0
509 --row;-
510 }
never executed: end of block
0
511-
512 if (!iface) {
!ifaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
513 QModelIndex index = view()->model()->index(row, column, view()->rootIndex());-
514 if (Q_UNLIKELY(!index.isValid())())) {
__builtin_expe...lid()), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
515 qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column;-
516 return 0;
never executed: return 0;
0
517 }-
518 iface = new QAccessibleTableCell(view(), index, cellRole());-
519 }
never executed: end of block
0
520-
521 QAccessible::registerAccessibleInterface(iface);-
522 childToId.insert(logicalIndex, QAccessible::uniqueId(iface));-
523 return iface;
never executed: return iface;
0
524}-
525-
526void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t)-
527{-
528 if (t == QAccessible::TableInterface)-
529 return static_cast<QAccessibleTableInterface*>(this);-
530 return 0;-
531}-
532-
533void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)-
534{-
535 // if there is no cache yet, we don't update anything-
536 if (childToId.isEmpty())-
537 return;-
538-
539 switch (event->modelChangeType()) {-
540 case QAccessibleTableModelChangeEvent::ModelReset:-
541 Q_FOREACH (QAccessible::Id id, childToId)-
542 QAccessible::deleteAccessibleInterface(id);-
543 childToId.clear();-
544 break;-
545-
546 // rows are inserted: move every row after that-
547 case QAccessibleTableModelChangeEvent::RowsInserted:-
548 case QAccessibleTableModelChangeEvent::ColumnsInserted: {-
549 int newRows = event->lastRow() - event->firstRow() + 1;-
550 int newColumns = event->lastColumn() - event->firstColumn() + 1;-
551-
552 ChildCache newCache;-
553 ChildCache::ConstIterator iter = childToId.constBegin();-
554-
555 while (iter != childToId.constEnd()) {-
556 QAccessible::Id id = iter.value();-
557 QAccessibleInterface *iface = QAccessible::accessibleInterface(id);-
558 Q_ASSERT(iface);-
559 if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted-
560 && iface->role() == QAccessible::RowHeader) {-
561 QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);-
562 if (cell->index >= event->firstRow()) {-
563 cell->index += newRows;-
564 }-
565 } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted-
566 && iface->role() == QAccessible::ColumnHeader) {-
567 QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);-
568 if (cell->index >= event->firstColumn()) {-
569 cell->index += newColumns;-
570 }-
571 }-
572 if (indexOfChild(iface) >= 0) {-
573 newCache.insert(indexOfChild(iface), id);-
574 } else {-
575 // ### This should really not happen,-
576 // but it might if the view has a root index set.-
577 // This needs to be fixed.-
578 QAccessible::deleteAccessibleInterface(id);-
579 }-
580 ++iter;-
581 }-
582 childToId = newCache;-
583 break;-
584 }-
585-
586 case QAccessibleTableModelChangeEvent::ColumnsRemoved:-
587 case QAccessibleTableModelChangeEvent::RowsRemoved: {-
588 int deletedColumns = event->lastColumn() - event->firstColumn() + 1;-
589 int deletedRows = event->lastRow() - event->firstRow() + 1;-
590 ChildCache newCache;-
591 ChildCache::ConstIterator iter = childToId.constBegin();-
592 while (iter != childToId.constEnd()) {-
593 QAccessible::Id id = iter.value();-
594 QAccessibleInterface *iface = QAccessible::accessibleInterface(id);-
595 Q_ASSERT(iface);-
596 if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {-
597 Q_ASSERT(iface->tableCellInterface());-
598 QAccessibleTableCell *cell = static_cast<QAccessibleTableCell*>(iface->tableCellInterface());-
599 // Since it is a QPersistentModelIndex, we only need to check if it is valid-
600 if (cell->m_index.isValid())-
601 newCache.insert(indexOfChild(cell), id);-
602 else-
603 QAccessible::deleteAccessibleInterface(id);-
604 } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved-
605 && iface->role() == QAccessible::RowHeader) {-
606 QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);-
607 if (cell->index < event->firstRow()) {-
608 newCache.insert(indexOfChild(cell), id);-
609 } else if (cell->index > event->lastRow()) {-
610 cell->index -= deletedRows;-
611 newCache.insert(indexOfChild(cell), id);-
612 } else {-
613 QAccessible::deleteAccessibleInterface(id);-
614 }-
615 } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved-
616 && iface->role() == QAccessible::ColumnHeader) {-
617 QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);-
618 if (cell->index < event->firstColumn()) {-
619 newCache.insert(indexOfChild(cell), id);-
620 } else if (cell->index > event->lastColumn()) {-
621 cell->index -= deletedColumns;-
622 newCache.insert(indexOfChild(cell), id);-
623 } else {-
624 QAccessible::deleteAccessibleInterface(id);-
625 }-
626 }-
627 ++iter;-
628 }-
629 childToId = newCache;-
630 break;-
631 }-
632-
633 case QAccessibleTableModelChangeEvent::DataChanged:-
634 // nothing to do in this case-
635 break;-
636 }-
637}-
638-
639// TREE VIEW-
640-
641QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const-
642{-
643 if (!isValid() || !view()->model())
!isValid()Description
TRUEnever evaluated
FALSEnever evaluated
!view()->model()Description
TRUEnever evaluated
FALSEnever evaluated
0
644 return QModelIndex();
never executed: return QModelIndex();
0
645-
646 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
647 if (((Q_UNLIKELY(row < 0 )|| (column < 0 )|| (treeView->d_func()->viewItems.count() <= row)) {
__builtin_expe...= row), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
648 qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView;-
649 return QModelIndex();
never executed: return QModelIndex();
0
650 }-
651 QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index;-
652-
653 if (modelIndex.isValid() && column > 0) {
modelIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
column > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
654 modelIndex = view()->model()->index(modelIndex.row(), column, modelIndex.parent());-
655 }
never executed: end of block
0
656 return modelIndex;
never executed: return modelIndex;
0
657}-
658-
659QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const-
660{-
661 if (!view()->model())-
662 return 0;-
663 QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0));-
664 QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset);-
665-
666 QModelIndex index = view()->indexAt(indexPosition);-
667 if (!index.isValid())-
668 return 0;-
669-
670 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
671 int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0);-
672 int column = index.column();-
673-
674 int i = row * view()->model()->columnCount() + column;-
675 return child(i);-
676}-
677-
678int QAccessibleTree::childCount() const-
679{-
680 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
681 Q_ASSERT(treeView);-
682 if (!view()->model())-
683 return 0;-
684-
685 int hHeader = horizontalHeader() ? 1 : 0;-
686 return (treeView->d_func()->viewItems.count() + hHeader)* view()->model()->columnCount();-
687}-
688-
689-
690QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const-
691{-
692 if (logicalIndex < 0 || !view()->model() || !view()->model()->columnCount())-
693 return 0;-
694-
695 QAccessibleInterface *iface = 0;-
696 int index = logicalIndex;-
697-
698 if (horizontalHeader()) {-
699 if (index < view()->model()->columnCount()) {-
700 iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal);-
701 } else {-
702 index -= view()->model()->columnCount();-
703 }-
704 }-
705-
706 if (!iface) {-
707 int row = index / view()->model()->columnCount();-
708 int column = index % view()->model()->columnCount();-
709 QModelIndex modelIndex = indexFromLogical(row, column);-
710 if (!modelIndex.isValid())-
711 return 0;-
712 iface = new QAccessibleTableCell(view(), modelIndex, cellRole());-
713 }-
714 QAccessible::registerAccessibleInterface(iface);-
715 // ### FIXME: get interfaces from the cache instead of re-creating them-
716 return iface;-
717}-
718-
719int QAccessibleTree::rowCount() const-
720{-
721 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
722 Q_ASSERT(treeView);-
723 return treeView->d_func()->viewItems.count();-
724}-
725-
726int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const-
727{-
728 if (!view()->model())-
729 return -1;-
730 QAccessibleInterface *parent = iface->parent();-
731 if (parent->object() != view())-
732 return -1;-
733-
734 if (iface->role() == QAccessible::TreeItem) {-
735 const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface);-
736 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
737 Q_ASSERT(treeView);-
738 int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0);-
739 int column = cell->m_index.column();-
740-
741 int index = row * view()->model()->columnCount() + column;-
742 return index;-
743 } else if (iface->role() == QAccessible::ColumnHeader){-
744 const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);-
745 return cell->index;-
746 } else {-
747 qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child"-
748 << iface->role() << iface->text(QAccessible::Name);-
749 }-
750 // FIXME: add scrollbars and don't just ignore them-
751 return -1;-
752}-
753-
754QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const-
755{-
756 QModelIndex index = indexFromLogical(row, column);-
757 if (Q_UNLIKELY(!index.isValid())())) {
__builtin_expe...lid()), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
758 qWarning() << "Requested invalid tree cell: " << row << column;-
759 return 0;
never executed: return 0;
0
760 }-
761 const QTreeView *treeView = qobject_cast<const QTreeView*>(view());-
762 Q_ASSERT(treeView);-
763 int logicalIndex = treeView->d_func()->accessibleTable2Index(index);-
764-
765 return child(logicalIndex); // FIXME ### new QAccessibleTableCell(view(), index, cellRole());
never executed: return child(logicalIndex);
0
766}-
767-
768QString QAccessibleTree::rowDescription(int) const-
769{-
770 return QString(); // no headers for rows in trees-
771}-
772-
773bool QAccessibleTree::isRowSelected(int row) const-
774{-
775 if (!view()->selectionModel())-
776 return false;-
777 QModelIndex index = indexFromLogical(row);-
778 return view()->selectionModel()->isRowSelected(index.row(), index.parent());-
779}-
780-
781bool QAccessibleTree::selectRow(int row)-
782{-
783 if (!view()->selectionModel())-
784 return false;-
785 QModelIndex index = indexFromLogical(row);-
786-
787 if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns)-
788 return false;-
789-
790 switch (view()->selectionMode()) {-
791 case QAbstractItemView::NoSelection:-
792 return false;-
793 case QAbstractItemView::SingleSelection:-
794 if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1))-
795 return false;-
796 view()->clearSelection();-
797 break;-
798 case QAbstractItemView::ContiguousSelection:-
799 if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))-
800 && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex()))-
801 view()->clearSelection();-
802 break;-
803 default:-
804 break;-
805 }-
806-
807 view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);-
808 return true;-
809}-
810-
811// TABLE CELL-
812-
813QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_)-
814 : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_)-
815{-
816 if (Q_UNLIKELY(!index_.isValid())()))
__builtin_expe...lid()), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
817 qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_;
never executed: QMessageLogger(__FILE__, 817, __PRETTY_FUNCTION__).warning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_;
0
818}
never executed: end of block
0
819-
820void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t)-
821{-
822 if (t == QAccessible::TableCellInterface)-
823 return static_cast<QAccessibleTableCellInterface*>(this);-
824 if (t == QAccessible::ActionInterface)-
825 return static_cast<QAccessibleActionInterface*>(this);-
826 return 0;-
827}-
828-
829int QAccessibleTableCell::columnExtent() const { return 1; }-
830int QAccessibleTableCell::rowExtent() const { return 1; }-
831-
832QList<QAccessibleInterface*> QAccessibleTableCell::rowHeaderCells() const-
833{-
834 QList<QAccessibleInterface*> headerCell;-
835 if (verticalHeader()) {-
836 // FIXME-
837 headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical));-
838 }-
839 return headerCell;-
840}-
841-
842QList<QAccessibleInterface*> QAccessibleTableCell::columnHeaderCells() const-
843{-
844 QList<QAccessibleInterface*> headerCell;-
845 if (horizontalHeader()) {-
846 // FIXME-
847 headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal));-
848 }-
849 return headerCell;-
850}-
851-
852QHeaderView *QAccessibleTableCell::horizontalHeader() const-
853{-
854 QHeaderView *header = 0;-
855-
856 if (false) {
dead code: { }
-
857#ifndef QT_NO_TABLEVIEW
dead code: { }
-
858 } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
dead code: { }
-
859 header = tv->horizontalHeader();-
860#endif-
861#ifndef QT_NO_TREEVIEW-
862 } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {-
863 header = tv->header();-
864#endif-
865 }-
866-
867 return header;-
868}-
869-
870QHeaderView *QAccessibleTableCell::verticalHeader() const-
871{-
872 QHeaderView *header = 0;-
873#ifndef QT_NO_TABLEVIEW-
874 if (const QTableView *tv = qobject_cast<const QTableView*>(view))-
875 header = tv->verticalHeader();-
876#endif-
877 return header;-
878}-
879-
880int QAccessibleTableCell::columnIndex() const-
881{-
882 return m_index.column();-
883}-
884-
885int QAccessibleTableCell::rowIndex() const-
886{-
887 if (role() == QAccessible::TreeItem) {-
888 const QTreeView *treeView = qobject_cast<const QTreeView*>(view);-
889 Q_ASSERT(treeView);-
890 int row = treeView->d_func()->viewIndex(m_index);-
891 return row;-
892 }-
893 return m_index.row();-
894}-
895-
896bool QAccessibleTableCell::isSelected() const-
897{-
898 return view->selectionModel()->isSelected(m_index);-
899}-
900-
901QStringList QAccessibleTableCell::actionNames() const-
902{-
903 QStringList names;-
904 names << toggleAction();-
905 return names;-
906}-
907-
908void QAccessibleTableCell::doAction(const QString& actionName)-
909{-
910 if (actionName == toggleAction()) {-
911 if (isSelected())-
912 unselectCell();-
913 else-
914 selectCell();-
915 }-
916}-
917-
918QStringList QAccessibleTableCell::keyBindingsForAction(const QString &) const-
919{-
920 return QStringList();-
921}-
922-
923-
924void QAccessibleTableCell::selectCell()-
925{-
926 QAbstractItemView::SelectionMode selectionMode = view->selectionMode();-
927 if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection))-
928 return;-
929 Q_ASSERT(table());-
930 QAccessibleTableInterface *cellTable = table()->tableInterface();-
931-
932 switch (view->selectionBehavior()) {-
933 case QAbstractItemView::SelectItems:-
934 break;-
935 case QAbstractItemView::SelectColumns:-
936 if (cellTable)-
937 cellTable->selectColumn(m_index.column());-
938 return;-
939 case QAbstractItemView::SelectRows:-
940 if (cellTable)-
941 cellTable->selectRow(m_index.row());-
942 return;-
943 }-
944-
945 if (selectionMode == QAbstractItemView::SingleSelection) {-
946 view->clearSelection();-
947 }-
948-
949 view->selectionModel()->select(m_index, QItemSelectionModel::Select);-
950}-
951-
952void QAccessibleTableCell::unselectCell()-
953{-
954-
955 QAbstractItemView::SelectionMode selectionMode = view->selectionMode();-
956 if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection))-
957 return;-
958-
959 QAccessibleTableInterface *cellTable = table()->tableInterface();-
960-
961 switch (view->selectionBehavior()) {-
962 case QAbstractItemView::SelectItems:-
963 break;-
964 case QAbstractItemView::SelectColumns:-
965 if (cellTable)-
966 cellTable->unselectColumn(m_index.column());-
967 return;-
968 case QAbstractItemView::SelectRows:-
969 if (cellTable)-
970 cellTable->unselectRow(m_index.row());-
971 return;-
972 }-
973-
974 //If the mode is not MultiSelection or ExtendedSelection and only-
975 //one cell is selected it cannot be unselected by the user-
976 if ((selectionMode != QAbstractItemView::MultiSelection)-
977 && (selectionMode != QAbstractItemView::ExtendedSelection)-
978 && (view->selectionModel()->selectedIndexes().count() <= 1))-
979 return;-
980-
981 view->selectionModel()->select(m_index, QItemSelectionModel::Deselect);-
982}-
983-
984QAccessibleInterface *QAccessibleTableCell::table() const-
985{-
986 return QAccessible::queryAccessibleInterface(view);-
987}-
988-
989QAccessible::Role QAccessibleTableCell::role() const-
990{-
991 return m_role;-
992}-
993-
994QAccessible::State QAccessibleTableCell::state() const-
995{-
996 QAccessible::State st;-
997 if (!view)-
998 return st;-
999-
1000 QRect globalRect = view->rect();-
1001 globalRect.translate(view->mapToGlobal(QPoint(0,0)));-
1002 if (!globalRect.intersects(rect()))-
1003 st.invisible = true;-
1004-
1005 if (view->selectionModel()->isSelected(m_index))-
1006 st.selected = true;-
1007 if (view->selectionModel()->currentIndex() == m_index)-
1008 st.focused = true;-
1009 if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked)-
1010 st.checked = true;-
1011-
1012 Qt::ItemFlags flags = m_index.flags();-
1013 if (flags & Qt::ItemIsSelectable) {-
1014 st.selectable = true;-
1015 st.focusable = true;-
1016 if (view->selectionMode() == QAbstractItemView::MultiSelection)-
1017 st.multiSelectable = true;-
1018 if (view->selectionMode() == QAbstractItemView::ExtendedSelection)-
1019 st.extSelectable = true;-
1020 }-
1021 if (m_role == QAccessible::TreeItem) {-
1022 const QTreeView *treeView = qobject_cast<const QTreeView*>(view);-
1023 if (treeView->model()->hasChildren(m_index))-
1024 st.expandable = true;-
1025 if (treeView->isExpanded(m_index))-
1026 st.expanded = true;-
1027 }-
1028 return st;-
1029}-
1030-
1031-
1032QRect QAccessibleTableCell::rect() const-
1033{-
1034 QRect r;-
1035 r = view->visualRect(m_index);-
1036-
1037 if (!r.isNull()) {-
1038 r.translate(view->viewport()->mapTo(view, QPoint(0,0)));-
1039 r.translate(view->mapToGlobal(QPoint(0, 0)));-
1040 }-
1041 return r;-
1042}-
1043-
1044QString QAccessibleTableCell::text(QAccessible::Text t) const-
1045{-
1046 QAbstractItemModel *model = view->model();-
1047 QString value;-
1048 switch (t) {-
1049 case QAccessible::Name:-
1050 value = model->data(m_index, Qt::AccessibleTextRole).toString();-
1051 if (value.isEmpty())-
1052 value = model->data(m_index, Qt::DisplayRole).toString();-
1053 break;-
1054 case QAccessible::Description:-
1055 value = model->data(m_index, Qt::AccessibleDescriptionRole).toString();-
1056 break;-
1057 default:-
1058 break;-
1059 }-
1060 return value;-
1061}-
1062-
1063void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text)-
1064{-
1065 if (!(m_index.flags() & Qt::ItemIsEditable))-
1066 return;-
1067 view->model()->setData(m_index, text);-
1068}-
1069-
1070bool QAccessibleTableCell::isValid() const-
1071{-
1072 return view && view->model() && m_index.isValid();-
1073}-
1074-
1075QAccessibleInterface *QAccessibleTableCell::parent() const-
1076{-
1077 return QAccessible::queryAccessibleInterface(view);-
1078}-
1079-
1080QAccessibleInterface *QAccessibleTableCell::child(int) const-
1081{-
1082 return 0;-
1083}-
1084-
1085QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_)-
1086 : view(view_), index(index_), orientation(orientation_)-
1087{-
1088 Q_ASSERT(index_ >= 0);-
1089}-
1090-
1091QAccessible::Role QAccessibleTableHeaderCell::role() const-
1092{-
1093 if (orientation == Qt::Horizontal)-
1094 return QAccessible::ColumnHeader;-
1095 return QAccessible::RowHeader;-
1096}-
1097-
1098QAccessible::State QAccessibleTableHeaderCell::state() const-
1099{-
1100 QAccessible::State s;-
1101 if (QHeaderView *h = headerView()) {-
1102 s.invisible = !h->testAttribute(Qt::WA_WState_Visible);-
1103 s.disabled = !h->isEnabled();-
1104 }-
1105 return s;-
1106}-
1107-
1108QRect QAccessibleTableHeaderCell::rect() const-
1109{-
1110 QHeaderView *header = 0;-
1111 if (false) {
dead code: { }
-
1112#ifndef QT_NO_TABLEVIEW
dead code: { }
-
1113 } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
dead code: { }
-
1114 if (orientation == Qt::Horizontal) {-
1115 header = tv->horizontalHeader();-
1116 } else {-
1117 header = tv->verticalHeader();-
1118 }-
1119#endif-
1120#ifndef QT_NO_TREEVIEW-
1121 } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {-
1122 header = tv->header();-
1123#endif-
1124 }-
1125 if (!header)-
1126 return QRect();-
1127 QPoint zero = header->mapToGlobal(QPoint(0, 0));-
1128 int sectionSize = header->sectionSize(index);-
1129 int sectionPos = header->sectionPosition(index);-
1130 return orientation == Qt::Horizontal-
1131 ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height())-
1132 : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize);-
1133}-
1134-
1135QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const-
1136{-
1137 QAbstractItemModel *model = view->model();-
1138 QString value;-
1139 switch (t) {-
1140 case QAccessible::Name:-
1141 value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString();-
1142 if (value.isEmpty())-
1143 value = model->headerData(index, orientation, Qt::DisplayRole).toString();-
1144 break;-
1145 case QAccessible::Description:-
1146 value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString();-
1147 break;-
1148 default:-
1149 break;-
1150 }-
1151 return value;-
1152}-
1153-
1154void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &)-
1155{-
1156 return;-
1157}-
1158-
1159bool QAccessibleTableHeaderCell::isValid() const-
1160{-
1161 return view && view->model() && (index >= 0)-
1162 && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount()));-
1163}-
1164-
1165QAccessibleInterface *QAccessibleTableHeaderCell::parent() const-
1166{-
1167 return QAccessible::queryAccessibleInterface(view);-
1168}-
1169-
1170QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const-
1171{-
1172 return 0;-
1173}-
1174-
1175QHeaderView *QAccessibleTableHeaderCell::headerView() const-
1176{-
1177 QHeaderView *header = 0;-
1178 if (false) {
dead code: { }
-
1179#ifndef QT_NO_TABLEVIEW
dead code: { }
-
1180 } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
dead code: { }
-
1181 if (orientation == Qt::Horizontal) {-
1182 header = tv->horizontalHeader();-
1183 } else {-
1184 header = tv->verticalHeader();-
1185 }-
1186#endif-
1187#ifndef QT_NO_TREEVIEW-
1188 } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {-
1189 header = tv->header();-
1190#endif-
1191 }-
1192 return header;-
1193}-
1194-
1195#endif // QT_NO_ITEMVIEWS-
1196-
1197QT_END_NAMESPACE-
1198-
1199#endif // QT_NO_ACCESSIBILITY-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9