File indexing completed on 2024-04-28 05:45:09
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Amandeep Singh <aman.dedman@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef QT_NO_ACCESSIBILITY 0008 #include "kitemlistviewaccessible.h" 0009 0010 #include "kitemlistcontainer.h" 0011 #include "kitemlistcontroller.h" 0012 #include "kitemlistselectionmanager.h" 0013 #include "kitemlistview.h" 0014 #include "private/kitemlistviewlayouter.h" 0015 0016 #include <QGraphicsScene> 0017 #include <QGraphicsView> 0018 0019 KItemListView *KItemListViewAccessible::view() const 0020 { 0021 return qobject_cast<KItemListView *>(object()); 0022 } 0023 0024 KItemListViewAccessible::KItemListViewAccessible(KItemListView *view_, KItemListContainerAccessible *parent) 0025 : QAccessibleObject(view_) 0026 , m_parent(parent) 0027 { 0028 Q_ASSERT(view()); 0029 Q_CHECK_PTR(parent); 0030 m_cells.resize(childCount()); 0031 } 0032 0033 KItemListViewAccessible::~KItemListViewAccessible() 0034 { 0035 for (AccessibleIdWrapper idWrapper : std::as_const(m_cells)) { 0036 if (idWrapper.isValid) { 0037 QAccessible::deleteAccessibleInterface(idWrapper.id); 0038 } 0039 } 0040 } 0041 0042 void *KItemListViewAccessible::interface_cast(QAccessible::InterfaceType type) 0043 { 0044 if (type == QAccessible::TableInterface) { 0045 return static_cast<QAccessibleTableInterface *>(this); 0046 } 0047 return nullptr; 0048 } 0049 0050 void KItemListViewAccessible::modelReset() 0051 { 0052 } 0053 0054 QAccessibleInterface *KItemListViewAccessible::cell(int index) const 0055 { 0056 if (index < 0 || index >= view()->model()->count()) { 0057 return nullptr; 0058 } 0059 0060 if (m_cells.size() <= index) { 0061 m_cells.resize(childCount()); 0062 } 0063 Q_ASSERT(index < m_cells.size()); 0064 0065 AccessibleIdWrapper idWrapper = m_cells.at(index); 0066 if (!idWrapper.isValid) { 0067 idWrapper.id = QAccessible::registerAccessibleInterface(new KItemListAccessibleCell(view(), index)); 0068 idWrapper.isValid = true; 0069 m_cells.insert(index, idWrapper); 0070 } 0071 return QAccessible::accessibleInterface(idWrapper.id); 0072 } 0073 0074 QAccessibleInterface *KItemListViewAccessible::cellAt(int row, int column) const 0075 { 0076 return cell(columnCount() * row + column); 0077 } 0078 0079 QAccessibleInterface *KItemListViewAccessible::caption() const 0080 { 0081 return nullptr; 0082 } 0083 0084 QString KItemListViewAccessible::columnDescription(int) const 0085 { 0086 return QString(); 0087 } 0088 0089 int KItemListViewAccessible::columnCount() const 0090 { 0091 return view()->m_layouter->columnCount(); 0092 } 0093 0094 int KItemListViewAccessible::rowCount() const 0095 { 0096 if (columnCount() <= 0) { 0097 return 0; 0098 } 0099 0100 int itemCount = view()->model()->count(); 0101 int rowCount = itemCount / columnCount(); 0102 0103 if (rowCount <= 0) { 0104 return 0; 0105 } 0106 0107 if (itemCount % columnCount()) { 0108 ++rowCount; 0109 } 0110 return rowCount; 0111 } 0112 0113 int KItemListViewAccessible::selectedCellCount() const 0114 { 0115 return view()->controller()->selectionManager()->selectedItems().count(); 0116 } 0117 0118 int KItemListViewAccessible::selectedColumnCount() const 0119 { 0120 return 0; 0121 } 0122 0123 int KItemListViewAccessible::selectedRowCount() const 0124 { 0125 return 0; 0126 } 0127 0128 QString KItemListViewAccessible::rowDescription(int) const 0129 { 0130 return QString(); 0131 } 0132 0133 QList<QAccessibleInterface *> KItemListViewAccessible::selectedCells() const 0134 { 0135 QList<QAccessibleInterface *> cells; 0136 const auto items = view()->controller()->selectionManager()->selectedItems(); 0137 cells.reserve(items.count()); 0138 for (int index : items) { 0139 cells.append(cell(index)); 0140 } 0141 return cells; 0142 } 0143 0144 QList<int> KItemListViewAccessible::selectedColumns() const 0145 { 0146 return QList<int>(); 0147 } 0148 0149 QList<int> KItemListViewAccessible::selectedRows() const 0150 { 0151 return QList<int>(); 0152 } 0153 0154 QAccessibleInterface *KItemListViewAccessible::summary() const 0155 { 0156 return nullptr; 0157 } 0158 0159 bool KItemListViewAccessible::isColumnSelected(int) const 0160 { 0161 return false; 0162 } 0163 0164 bool KItemListViewAccessible::isRowSelected(int) const 0165 { 0166 return false; 0167 } 0168 0169 bool KItemListViewAccessible::selectRow(int) 0170 { 0171 return true; 0172 } 0173 0174 bool KItemListViewAccessible::selectColumn(int) 0175 { 0176 return true; 0177 } 0178 0179 bool KItemListViewAccessible::unselectRow(int) 0180 { 0181 return true; 0182 } 0183 0184 bool KItemListViewAccessible::unselectColumn(int) 0185 { 0186 return true; 0187 } 0188 0189 void KItemListViewAccessible::modelChange(QAccessibleTableModelChangeEvent * /*event*/) 0190 { 0191 } 0192 0193 QAccessible::Role KItemListViewAccessible::role() const 0194 { 0195 return QAccessible::Table; 0196 } 0197 0198 QAccessible::State KItemListViewAccessible::state() const 0199 { 0200 QAccessible::State s; 0201 return s; 0202 } 0203 0204 QAccessibleInterface *KItemListViewAccessible::childAt(int x, int y) const 0205 { 0206 const QPointF point = QPointF(x, y); 0207 const std::optional<int> itemIndex = view()->itemAt(view()->mapFromScene(point)); 0208 return child(itemIndex.value_or(-1)); 0209 } 0210 0211 QAccessibleInterface *KItemListViewAccessible::parent() const 0212 { 0213 return m_parent; 0214 } 0215 0216 int KItemListViewAccessible::childCount() const 0217 { 0218 return view()->model()->count(); 0219 } 0220 0221 int KItemListViewAccessible::indexOfChild(const QAccessibleInterface *interface) const 0222 { 0223 const KItemListAccessibleCell *widget = static_cast<const KItemListAccessibleCell *>(interface); 0224 return widget->index(); 0225 } 0226 0227 QString KItemListViewAccessible::text(QAccessible::Text) const 0228 { 0229 return QString(); 0230 } 0231 0232 QRect KItemListViewAccessible::rect() const 0233 { 0234 if (!view()->isVisible()) { 0235 return QRect(); 0236 } 0237 0238 const QGraphicsScene *scene = view()->scene(); 0239 if (scene) { 0240 const QPoint origin = scene->views().at(0)->mapToGlobal(QPoint(0, 0)); 0241 const QRect viewRect = view()->geometry().toRect(); 0242 return viewRect.translated(origin); 0243 } else { 0244 return QRect(); 0245 } 0246 } 0247 0248 QAccessibleInterface *KItemListViewAccessible::child(int index) const 0249 { 0250 if (index >= 0 && index < childCount()) { 0251 return cell(index); 0252 } 0253 return nullptr; 0254 } 0255 0256 KItemListViewAccessible::AccessibleIdWrapper::AccessibleIdWrapper() 0257 : isValid(false) 0258 , id(0) 0259 { 0260 } 0261 0262 // Table Cell 0263 0264 KItemListAccessibleCell::KItemListAccessibleCell(KItemListView *view, int index) 0265 : m_view(view) 0266 , m_index(index) 0267 { 0268 Q_ASSERT(index >= 0 && index < view->model()->count()); 0269 } 0270 0271 void *KItemListAccessibleCell::interface_cast(QAccessible::InterfaceType type) 0272 { 0273 if (type == QAccessible::TableCellInterface) { 0274 return static_cast<QAccessibleTableCellInterface *>(this); 0275 } 0276 return nullptr; 0277 } 0278 0279 int KItemListAccessibleCell::columnExtent() const 0280 { 0281 return 1; 0282 } 0283 0284 int KItemListAccessibleCell::rowExtent() const 0285 { 0286 return 1; 0287 } 0288 0289 QList<QAccessibleInterface *> KItemListAccessibleCell::rowHeaderCells() const 0290 { 0291 return QList<QAccessibleInterface *>(); 0292 } 0293 0294 QList<QAccessibleInterface *> KItemListAccessibleCell::columnHeaderCells() const 0295 { 0296 return QList<QAccessibleInterface *>(); 0297 } 0298 0299 int KItemListAccessibleCell::columnIndex() const 0300 { 0301 return m_view->m_layouter->itemColumn(m_index); 0302 } 0303 0304 int KItemListAccessibleCell::rowIndex() const 0305 { 0306 return m_view->m_layouter->itemRow(m_index); 0307 } 0308 0309 bool KItemListAccessibleCell::isSelected() const 0310 { 0311 return m_view->controller()->selectionManager()->isSelected(m_index); 0312 } 0313 0314 QAccessibleInterface *KItemListAccessibleCell::table() const 0315 { 0316 return QAccessible::queryAccessibleInterface(m_view); 0317 } 0318 0319 QAccessible::Role KItemListAccessibleCell::role() const 0320 { 0321 return QAccessible::Cell; 0322 } 0323 0324 QAccessible::State KItemListAccessibleCell::state() const 0325 { 0326 QAccessible::State state; 0327 0328 state.selectable = true; 0329 if (isSelected()) { 0330 state.selected = true; 0331 } 0332 0333 state.focusable = true; 0334 if (m_view->controller()->selectionManager()->currentItem() == m_index) { 0335 state.focused = true; 0336 } 0337 0338 if (m_view->controller()->selectionBehavior() == KItemListController::MultiSelection) { 0339 state.multiSelectable = true; 0340 } 0341 0342 if (m_view->model()->isExpandable(m_index)) { 0343 if (m_view->model()->isExpanded(m_index)) { 0344 state.expanded = true; 0345 } else { 0346 state.collapsed = true; 0347 } 0348 } 0349 0350 return state; 0351 } 0352 0353 bool KItemListAccessibleCell::isExpandable() const 0354 { 0355 return m_view->model()->isExpandable(m_index); 0356 } 0357 0358 QRect KItemListAccessibleCell::rect() const 0359 { 0360 QRect rect = m_view->itemRect(m_index).toRect(); 0361 0362 if (rect.isNull()) { 0363 return QRect(); 0364 } 0365 0366 rect.translate(m_view->mapToScene(QPointF(0.0, 0.0)).toPoint()); 0367 rect.translate(m_view->scene()->views()[0]->mapToGlobal(QPoint(0, 0))); 0368 return rect; 0369 } 0370 0371 QString KItemListAccessibleCell::text(QAccessible::Text t) const 0372 { 0373 switch (t) { 0374 case QAccessible::Name: { 0375 const QHash<QByteArray, QVariant> data = m_view->model()->data(m_index); 0376 return data["text"].toString(); 0377 } 0378 0379 default: 0380 break; 0381 } 0382 0383 return QString(); 0384 } 0385 0386 void KItemListAccessibleCell::setText(QAccessible::Text, const QString &) 0387 { 0388 } 0389 0390 QAccessibleInterface *KItemListAccessibleCell::child(int) const 0391 { 0392 return nullptr; 0393 } 0394 0395 bool KItemListAccessibleCell::isValid() const 0396 { 0397 return m_view && (m_index >= 0) && (m_index < m_view->model()->count()); 0398 } 0399 0400 QAccessibleInterface *KItemListAccessibleCell::childAt(int, int) const 0401 { 0402 return nullptr; 0403 } 0404 0405 int KItemListAccessibleCell::childCount() const 0406 { 0407 return 0; 0408 } 0409 0410 int KItemListAccessibleCell::indexOfChild(const QAccessibleInterface *child) const 0411 { 0412 Q_UNUSED(child) 0413 return -1; 0414 } 0415 0416 QAccessibleInterface *KItemListAccessibleCell::parent() const 0417 { 0418 return QAccessible::queryAccessibleInterface(m_view); 0419 } 0420 0421 int KItemListAccessibleCell::index() const 0422 { 0423 return m_index; 0424 } 0425 0426 QObject *KItemListAccessibleCell::object() const 0427 { 0428 return nullptr; 0429 } 0430 0431 // Container Interface 0432 KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer *container) 0433 : QAccessibleWidget(container) 0434 { 0435 } 0436 0437 KItemListContainerAccessible::~KItemListContainerAccessible() 0438 { 0439 } 0440 0441 int KItemListContainerAccessible::childCount() const 0442 { 0443 return 1; 0444 } 0445 0446 int KItemListContainerAccessible::indexOfChild(const QAccessibleInterface *child) const 0447 { 0448 if (child->object() == container()->controller()->view()) { 0449 return 0; 0450 } 0451 return -1; 0452 } 0453 0454 QAccessibleInterface *KItemListContainerAccessible::child(int index) const 0455 { 0456 if (index == 0) { 0457 return QAccessible::queryAccessibleInterface(container()->controller()->view()); 0458 } 0459 return nullptr; 0460 } 0461 0462 const KItemListContainer *KItemListContainerAccessible::container() const 0463 { 0464 return qobject_cast<KItemListContainer *>(object()); 0465 } 0466 0467 #endif // QT_NO_ACCESSIBILITY