📄 complexwidgets.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the plugins of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "complexwidgets.h"#include <qapplication.h>#include <qabstractbutton.h>#include <qevent.h>#include <qheaderview.h>#include <qtabbar.h>#include <qcombobox.h>#include <qlistview.h>#include <qtableview.h>#include <qlineedit.h>#include <qstyle.h>#include <qstyleoption.h>#include <qtooltip.h>#include <qwhatsthis.h>#include <qtreeview.h>#include <private/qtabbar_p.h>#include <QAbstractScrollArea>#include <QScrollArea>#include <QScrollBar>#include <QDebug>#ifndef QT_NO_ACCESSIBILITYQString Q_GUI_EXPORT qt_accStripAmp(const QString &text);#ifndef QT_NO_ITEMVIEWSQAccessibleItemRow::QAccessibleItemRow(QAbstractItemView *aView, const QModelIndex &index) : row(index), view(aView){}QRect QAccessibleItemRow::rect(int child) const{ if (!row.isValid() || !view || !view->isVisible()) return QRect(); QRect r; if (child) { r = view->visualRect(childIndex(child)); } else { QModelIndex parent = row.parent(); const int colCount = row.model()->columnCount(parent); for (int i = 0; i < colCount; ++i) r |= view->visualRect(row.model()->index(row.row(), i, parent)); } return r.translated(view->viewport()->mapToGlobal(QPoint(0, 0)));}int QAccessibleItemRow::treeLevel() const{ int level = 0; QModelIndex idx = row; while (idx.isValid()) { idx = idx.parent(); ++level; } return level;}QString QAccessibleItemRow::text(Text t, int child) const{ QString value; if (t == Name) { if (!child) { if (children().count() >= 1) child = 1; else return QString(); } QModelIndex idx = childIndex(child); if (!idx.isValid()) return QString(); value = idx.model()->data(idx, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) value = idx.model()->data(idx, Qt::DisplayRole).toString(); } else if (t == Value) {#ifndef QT_NO_TREEVIEW if (qobject_cast<const QTreeView*>(view)) { if (child == 0) value = QString::number(treeLevel()); } else#endif { if (!child && children().count() >= 1) child = 1; if (child) { QModelIndex idx = childIndex(child); if (!idx.isValid()) return QString(); value = idx.model()->data(idx, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) value = idx.model()->data(idx, Qt::DisplayRole).toString(); } } } else if (t == Description) {#ifndef QT_NO_TREEVIEW if (child == 0 && qobject_cast<const QTreeView*>(view)) { // We store the tree coordinates of the current item in the description. // This enables some screen readers to report where the focus is // in a tree view. (works in JAWS). Also, Firefox does the same thing. // For instance the description "L2, 4 of 25 with 24" means // "L2": Tree Level 2 // "4 of 25": We are item 4 out of in total 25 other siblings // "with 24": We have 24 children. (JAWS does not read this number) // level int level = treeLevel(); QAbstractItemModel *m = view->model(); // totalSiblings and itemIndex QModelIndex parent = row.parent(); int rowCount = m->rowCount(parent); int itemIndex = -1; int totalSiblings = 0; for (int i = 0 ; i < rowCount; ++i) { QModelIndex sibling = row.sibling(i, 0); if (!view->isIndexHidden(sibling)) ++totalSiblings; if (row == sibling) itemIndex = totalSiblings; } int totalChildren = m->rowCount(row); // JAWS does not report child count, so we do // this simple and efficient. // (don't check if they are all visible). value = QString::fromAscii("L%1, %2 of %3 with %4").arg(level).arg(itemIndex).arg(totalSiblings).arg(totalChildren); } else#endif // QT_NO_TREEVIEW { if (child == 0 && children().count() >= 1) child = 1; QModelIndex idx = childIndex(child); value = idx.model()->data(idx, Qt::AccessibleDescriptionRole).toString(); } } return value;}void QAccessibleItemRow::setText(Text t, int child, const QString &text){ if (!child) { if (children().count() == 1) child = 1; else return; } QModelIndex idx = childIndex(child); if (!idx.isValid()) return; switch (t) { case Description: const_cast<QAbstractItemModel *>(idx.model())->setData(idx, text, Qt::AccessibleDescriptionRole); break; case Value: const_cast<QAbstractItemModel *>(idx.model())->setData(idx, text, Qt::EditRole); break; default: break; }}QModelIndex QAccessibleItemRow::childIndex(int child) const{ QList<QModelIndex> kids = children(); Q_ASSERT(child >= 1 && child <= kids.count()); return kids.at(child - 1);}QList<QModelIndex> QAccessibleItemRow::children() const{ QList<QModelIndex> kids; for (int i = 0; i < row.model()->columnCount(row.parent()); ++i) { QModelIndex idx = row.model()->index(row.row(), i, row.parent()); if (!view->isIndexHidden(idx)) { kids << idx; } } return kids;}bool QAccessibleItemRow::isValid() const{ return row.isValid();}QObject *QAccessibleItemRow::object() const{ return 0;}int QAccessibleItemRow::childCount() const{ return children().count();}int QAccessibleItemRow::indexOfChild(const QAccessibleInterface *iface) const{ if (!iface || iface->role(0) != Row) return -1; QList<QModelIndex> kids = children(); QModelIndex idx = static_cast<const QAccessibleItemRow *>(iface)->row; if (!idx.isValid()) return -1; return kids.indexOf(idx) + 1;}QAccessible::Relation QAccessibleItemRow::relationTo(int child, const QAccessibleInterface *other, int otherChild) const{ if (!child && !otherChild && other->object() == view) return Child; if (!child && !otherChild && other == this) return Self; if (!child && otherChild && other == this) return Ancestor; if (child && otherChild && other == this) return Sibling; return Unrelated;}int QAccessibleItemRow::childAt(int x, int y) const{ if (!view || !view->isVisible()) return -1; QModelIndex idx = view->indexAt(view->viewport()->mapFromGlobal(QPoint(x, y))); if (idx.isValid() && idx.parent() == row.parent() && idx.row() == row.row()) { QList<QModelIndex> kids = children(); return kids.indexOf(idx) + 1; } return -1;}QAbstractItemView::CursorAction QAccessibleItemRow::toCursorAction( QAccessible::Relation rel){ switch (rel) { case QAccessible::Up: return QAbstractItemView::MoveUp; case QAccessible::Down: return QAbstractItemView::MoveDown; case QAccessible::Left: return QAbstractItemView::MoveLeft; case QAccessible::Right: return QAbstractItemView::MoveRight; default: Q_ASSERT(false); } // should never be reached. return QAbstractItemView::MoveRight;}int QAccessibleItemRow::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const{ *iface = 0; if (!view) return -1; switch (relation) { case Ancestor: { if (!index) return -1; QAccessibleItemView *ancestor = new QAccessibleItemView(view->viewport()); if (index == 1) { *iface = ancestor; return 0; } else if (index > 1) { int ret = ancestor->navigate(Ancestor, index - 1, iface); delete ancestor; return ret; } } case Child: { if (!index) return -1; QList<QModelIndex> kids = children(); if (index < 1 && index > kids.count()) return -1; return index;} case Sibling: if (index) { QAccessibleInterface *ifaceParent = 0; navigate(Ancestor, 1, &ifaceParent); if (ifaceParent) { int entry = ifaceParent->navigate(Child, index, iface); delete ifaceParent; return entry; } } return -1; case Up: case Down: case Left: case Right: { // This is in the "not so nice" category. In order to find out which item // is geometrically around, we have to set the current index, navigate // and restore the index as well as the old selection view->setUpdatesEnabled(false); const QModelIndex oldIdx = view->currentIndex(); QList<QModelIndex> kids = children(); const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row); const QItemSelection oldSelection = view->selectionModel()->selection(); view->setCurrentIndex(currentIndex); const QModelIndex idx = view->moveCursor(toCursorAction(relation), Qt::NoModifier); view->setCurrentIndex(oldIdx); view->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); view->setUpdatesEnabled(true); if (!idx.isValid()) return -1; if (idx.parent() != row.parent() || idx.row() != row.row()) *iface = new QAccessibleItemRow(view, idx); return index ? kids.indexOf(idx) + 1 : 0; } default: break; } return -1;}QAccessible::Role QAccessibleItemRow::role(int child) const{ if (false) {#ifndef QT_NO_TREEVIEW } else if (qobject_cast<const QTreeView*>(view)) { return TreeItem;#endif#ifndef QT_NO_LISTVIEW } else if (qobject_cast<const QListView*>(view)) { return ListItem;#endif } // TableView if (!child) return Row; return Cell;}QAccessible::State QAccessibleItemRow::state(int child) const{ State st = Normal; if (!view) return st; QRect globalRect = view->viewport()->rect().translated(view->viewport()->mapToGlobal(QPoint(0,0))); if (!globalRect.intersects(rect(child))) { st |= Invisible; } else { if (child) { QModelIndex idx = childIndex(child); if (!idx.isValid()) return st; if (view->selectionModel()->isSelected(idx)) st |= Selected; if (idx.model()->data(idx, Qt::CheckStateRole).toInt() == Qt::Checked) st |= Checked; Qt::ItemFlags flags = idx.flags(); if (flags & Qt::ItemIsSelectable) { st |= Selectable; if (view->selectionMode() == QAbstractItemView::MultiSelection) st |= MultiSelectable; if (view->selectionMode() == QAbstractItemView::ExtendedSelection) st |= ExtSelectable; } } else { Qt::ItemFlags flags = row.flags(); if (flags & Qt::ItemIsSelectable) { st |= Selectable; st |= Focusable; } if (view->selectionModel()->isRowSelected(row.row(), row.parent())) st |= Selected; } } return st;}int QAccessibleItemRow::userActionCount(int) const{ return 0;}QString QAccessibleItemRow::actionText(int, Text, int) const{ return QString();}static QItemSelection rowAt(const QModelIndex &idx){ return QItemSelection(idx.sibling(idx.row(), 0), idx.sibling(idx.row(), idx.model()->columnCount(idx.parent())));}bool QAccessibleItemRow::doAction(int action, int child, const QVariantList & /*params*/){ if (!view) return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -