VirtualBox

Changeset 105517 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Jul 26, 2024 10:04:07 AM (6 months ago)
Author:
vboxsync
Message:

FE/Qt: bugref:10681: QITreeView: Reworking accessibility interface to support proxy-models; This is just a first step, cause the question is more complex than similar for QITableView in r163682.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QITreeView.cpp

    r104513 r105517  
    265265int QIAccessibilityInterfaceForQITreeView::childCount() const
    266266{
    267     /* Sanity check: */
     267    /* Make sure tree still alive: */
    268268    AssertPtrReturn(tree(), 0);
     269    /* Make sure model still alive: */
    269270    AssertPtrReturn(tree()->model(), 0);
    270271
    271     /* Acquire root model-index: */
     272    /* Acquire required model-index, that can be root-index if specified
     273     * or null index otherwise, in that case we return the amount of top-level children: */
    272274    const QModelIndex rootIndex = tree()->rootIndex();
     275    const QModelIndex requiredIndex = rootIndex.isValid() ? rootIndex : QModelIndex();
    273276
    274277    /* Return the number of children: */
    275     return tree()->model()->rowCount(rootIndex);
     278    return tree()->model()->rowCount(requiredIndex);
    276279}
    277280
    278281QAccessibleInterface *QIAccessibilityInterfaceForQITreeView::child(int iIndex) const
    279282{
    280     /* Sanity check: */
    281     AssertPtrReturn(tree(), 0);
    282     AssertPtrReturn(tree()->model(), 0);
     283    /* Make sure table still alive: */
     284    QITreeView *pTree = tree();
     285    AssertPtrReturn(pTree, 0);
     286    /* Make sure model still alive: */
     287    QAbstractItemModel *pModel = pTree->model();
     288    AssertPtrReturn(pModel, 0);
     289    /* Make sure index is valid: */
    283290    AssertReturn(iIndex >= 0, 0);
    284     if (iIndex >= childCount())
     291
     292    /* Real index might be different: */
     293    int iRealIndex = iIndex;
     294
     295    // WORKAROUND:
     296    // For a tree-views Qt accessibility code has a hard-coded architecture which we do not like
     297    // but have to live with, this architecture enumerates children of all levels as children of level 0,
     298    // so Qt can try to address our interface with index which surely out of bounds by our laws.
     299    // Let's assume that's exactly the case and try to enumerate children like they are a part of the list, not tree.
     300    if (iRealIndex >= childCount())
    285301    {
    286         // WORKAROUND:
    287         // Normally I would assert here, but Qt5 accessibility code has
    288         // a hard-coded architecture for a tree-views which we do not like
    289         // but have to live with and this architecture enumerates children
    290         // of all levels as children of level 0, so Qt5 can try to address
    291         // our interface with index which surely out of bounds by our laws.
    292         // So let's assume that's exactly such case and try to enumerate
    293         // visible children like they are a part of the list, not tree.
    294         // printf("Invalid index: %d\n", iIndex);
    295 
    296         // Take into account we also have header with 'column count' indexes,
    297         // so we should start enumerating tree indexes since 'column count'.
    298         const int iColumnCount = tree()->model()->columnCount();
    299         int iCurrentIndex = iColumnCount;
    300 
    301         // Set iterator to root model-index initially:
    302         QModelIndex index = tree()->rootIndex();
    303         // But if it has child, go deeper:
    304         if (tree()->model()->index(0, 0, index).isValid())
    305             index = tree()->model()->index(0, 0, index);
    306 
    307         // Search for sibling with corresponding index:
    308         while (index.isValid() && iCurrentIndex < iIndex)
    309         {
    310             ++iCurrentIndex;
    311             if (iCurrentIndex % iColumnCount == 0)
    312                 index = tree()->indexBelow(index);
    313         }
    314 
    315         // Check whether we have proxy model set or source one otherwise:
    316         const QSortFilterProxyModel *pProxyModel = qobject_cast<const QSortFilterProxyModel*>(tree()->model());
    317         // Acquire source model-index, which can be the same as model-index:
    318         const QModelIndex sourceIndex = pProxyModel ? pProxyModel->mapToSource(index) : index;
    319 
    320         // Return what we found:
    321         // if (sourceIndex.isValid())
    322         //     printf("Item found: [%s]\n", ((QITreeViewItem*)sourceIndex.internalPointer())->text().toUtf8().constData());
    323         // else
    324         //     printf("Item not found\n");
    325         return sourceIndex.isValid() ? QAccessible::queryAccessibleInterface((QITreeViewItem*)sourceIndex.internalPointer()) : 0;
     302        // Split delimeter is overall column count:
     303        const int iColumnCount = pModel->columnCount();
     304
     305        // Real row index:
     306        iRealIndex = iRealIndex / iColumnCount;
    326307    }
    327308
    328     /* Acquire root model-index: */
     309    /* Make sure index fits the bounds finally: */
     310    if (iRealIndex >= childCount())
     311        return 0;
     312
     313    /* Acquire parent model-index, that can be root-index if specified
     314     * or null index otherwise, in that case we will return one of top-level children: */
    329315    const QModelIndex rootIndex = tree()->rootIndex();
    330     /* Acquire child model-index: */
    331     const QModelIndex childIndex = tree()->model()->index(iIndex, 0, rootIndex);
    332 
     316    const QModelIndex parentIndex = rootIndex.isValid() ? rootIndex : QModelIndex();
     317
     318    /* Acquire child-index: */
     319    const QModelIndex childIndex = pModel->index(iRealIndex, 0, parentIndex);
    333320    /* Check whether we have proxy model set or source one otherwise: */
    334     const QSortFilterProxyModel *pProxyModel = qobject_cast<const QSortFilterProxyModel*>(tree()->model());
    335     /* Acquire source child model-index, which can be the same as child model-index: */
     321    const QSortFilterProxyModel *pProxyModel = qobject_cast<const QSortFilterProxyModel*>(pModel);
     322    /* Acquire source-model child-index (can be the same as original if there is no proxy model): */
    336323    const QModelIndex sourceChildIndex = pProxyModel ? pProxyModel->mapToSource(childIndex) : childIndex;
    337     /* Acquire source child item: */
     324
     325    /* Acquire child item: */
    338326    QITreeViewItem *pItem = reinterpret_cast<QITreeViewItem*>(sourceChildIndex.internalPointer());
    339     /* Return the child with the passed iIndex: */
     327    /* Return child item's accessibility interface: */
    340328    return QAccessible::queryAccessibleInterface(pItem);
    341329}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette