📄 qtreewidget.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module 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 "qtreewidget.h"#ifndef QT_NO_TREEWIDGET#include <qheaderview.h>#include <qpainter.h>#include <qitemdelegate.h>#include <qstack.h>#include <qdebug.h>#include <private/qtreeview_p.h>#include <private/qwidgetitemdata_p.h>#include <private/qtreewidget_p.h>#include <private/qtreewidgetitemiterator_p.h>// workaround for VC++ 6.0 linker bug (?)typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&);class QTreeModelLessThan{public: inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const { return *i1 < *i2; }};class QTreeModelGreaterThan{public: inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const { return *i2 < *i1; }};/* \class QTreeModel \brief The QTreeModel class manages the items stored in a tree view. \ingroup model-view \mainclass*//*! \enum QTreeWidgetItem::ChildIndicatorPolicy \since 4.3 \value ShowIndicator \value DontShowIndicator \value DontShowIndicatorWhenChildless*//*! \fn void QTreeWidgetItem::setDisabled(bool disabled) \since 4.3 Disables the item if \a disabled is true; otherwise enables the item. \sa setFlags()*//*! \fn bool QTreeWidgetItem::isDisabled() const \since 4.3 Returns true if the item is disabled; otherwise returns false. \sa setFlags()*//*! \internal Constructs a tree model with a \a parent object and the given number of \a columns.*/QTreeModel::QTreeModel(int columns, QTreeWidget *parent) : QAbstractItemModel(parent), rootItem(new QTreeWidgetItem), headerItem(new QTreeWidgetItem), sortPending(false){ rootItem->view = parent; headerItem->view = parent; setColumnCount(columns);}/*! \internal*/QTreeModel::QTreeModel(QTreeModelPrivate &dd, QTreeWidget *parent) : QAbstractItemModel(dd, parent), rootItem(new QTreeWidgetItem), headerItem(new QTreeWidgetItem), sortPending(false){ rootItem->view = parent; headerItem->view = parent;}/*! \internal Destroys this tree model.*/QTreeModel::~QTreeModel(){ clear(); delete headerItem; rootItem->view = 0; delete rootItem;}/*! \internal Removes all items in the model.*/void QTreeModel::clear(){ for (int i = 0; i < rootItem->childCount(); ++i) { QTreeWidgetItem *item = rootItem->children.at(i); item->par = 0; item->view = 0; delete item; } rootItem->children.clear(); sortPending = false; reset();}/*! \internal Sets the number of \a columns in the tree model.*/void QTreeModel::setColumnCount(int columns){ if (columns < 0) return; if (!headerItem) { headerItem = new QTreeWidgetItem(); headerItem->view = view(); } int count = columnCount(); if (count == columns) return; if (columns < count) { beginRemoveColumns(QModelIndex(), columns, count - 1); headerItem->values.resize(columns); endRemoveColumns(); } else { beginInsertColumns(QModelIndex(), count, columns - 1); headerItem->values.resize(columns); for (int i = count; i < columns; ++i) {// insert data without emitting the dataChanged signal headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1))); headerItem->d->display.append(QString::number(i + 1)); } endInsertColumns(); }}/*! \internal Returns the tree view item corresponding to the \a index given. \sa QModelIndex*/QTreeWidgetItem *QTreeModel::item(const QModelIndex &index) const{ if (!index.isValid()) return 0; return static_cast<QTreeWidgetItem*>(index.internalPointer());}/*! \internal Returns the model index that refers to the tree view \a item and \a column.*/QModelIndex QTreeModel::index(const QTreeWidgetItem *item, int column) const{ if (!item || (item == rootItem)) return QModelIndex(); const QTreeWidgetItem *par = item->parent(); QTreeWidgetItem *itm = const_cast<QTreeWidgetItem*>(item); if (!par) par = rootItem; const int row = par->children.lastIndexOf(itm); return createIndex(row, column, itm);}/*! \internal \reimp Returns the model index with the given \a row, \a column and \a parent.*/QModelIndex QTreeModel::index(int row, int column, const QModelIndex &parent) const{ int c = columnCount(parent); if (row < 0 || column < 0 || column >= c) return QModelIndex(); QTreeWidgetItem *parentItem = parent.isValid() ? item(parent) : rootItem; if (parentItem && row < parentItem->childCount()) { QTreeWidgetItem *itm = parentItem->child(row); if (itm) return createIndex(row, column, itm); return QModelIndex(); } return QModelIndex();}/*! \internal \reimp Returns the parent model index of the index given as the \a child.*/QModelIndex QTreeModel::parent(const QModelIndex &child) const{ if (!child.isValid()) return QModelIndex(); QTreeWidgetItem *itm = static_cast<QTreeWidgetItem *>(child.internalPointer()); if (!itm) return QModelIndex(); QTreeWidgetItem *parent = itm->parent(); return index(parent, 0);}/*! \internal \reimp Returns the number of rows in the \a parent model index.*/int QTreeModel::rowCount(const QModelIndex &parent) const{ executePendingSort(); if (!parent.isValid()) return rootItem->childCount(); QTreeWidgetItem *parentItem = item(parent); if (parentItem) return parentItem->childCount(); return 0;}/*! \internal \reimp Returns the number of columns in the item referred to by the given \a index.*/int QTreeModel::columnCount(const QModelIndex &index) const{ Q_UNUSED(index); if (!headerItem) return 0; return headerItem->columnCount();}bool QTreeModel::hasChildren(const QModelIndex &parent) const{ executePendingSort(); if (!parent.isValid()) return (rootItem->childCount() > 0); QTreeWidgetItem *itm = item(parent); if (!itm) return false; switch (itm->d->policy) { case QTreeWidgetItem::ShowIndicator: return true; case QTreeWidgetItem::DontShowIndicator: return false; case QTreeWidgetItem::DontShowIndicatorWhenChildless: return (itm->childCount() > 0); } return false;}/*! \internal \reimp Returns the data corresponding to the given model \a index and \a role.*/QVariant QTreeModel::data(const QModelIndex &index, int role) const{ if (!index.isValid()) return QVariant(); QTreeWidgetItem *itm = item(index); if (itm) return itm->data(index.column(), role); return QVariant();}/*! \internal \reimp Sets the data for the item specified by the \a index and \a role to that referred to by the \a value. Returns true if successful; otherwise returns false.*/bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int role){ if (!index.isValid()) return false; QTreeWidgetItem *itm = item(index); if (itm) { itm->setData(index.column(), role, value); return true; } return false;}QMap<int, QVariant> QTreeModel::itemData(const QModelIndex &index) const{ QMap<int, QVariant> roles; QTreeWidgetItem *itm = item(index); if (itm) { int column = index.column(); if (column < itm->values.count()) { for (int i = 0; i < itm->values.at(column).count(); ++i) { roles.insert(itm->values.at(column).at(i).role, itm->values.at(column).at(i).value); } } // the two special cases QVariant displayValue = itm->data(column, Qt::DisplayRole); if (displayValue.isValid()) roles.insert(Qt::DisplayRole, displayValue); QVariant checkValue = itm->data(column, Qt::CheckStateRole); if (checkValue.isValid()) roles.insert(Qt::CheckStateRole, checkValue); } return roles;}/*! \internal \reimp*/bool QTreeModel::insertRows(int row, int count, const QModelIndex &parent){ if (count < 1 || row < 0 || row > rowCount(parent) || parent.column() > 0) return false; beginInsertRows(parent, row, row + count - 1); QTreeWidgetItem *par = item(parent); while (count > 0) { QTreeWidgetItem *item = new QTreeWidgetItem(); item->view = view(); item->par = par; if (par) par->children.insert(row++, item); else rootItem->children.insert(row++, item); --count; } endInsertRows(); return true;}/*! \internal \reimp*/bool QTreeModel::insertColumns(int column, int count, const QModelIndex &parent){ if (count < 1 || column < 0 || column > columnCount(parent) || parent.column() > 0 || !headerItem) return false; beginInsertColumns(parent, column, column + count - 1); int oldCount = columnCount(parent); column = qBound(0, column, oldCount); headerItem->values.resize(oldCount + count); for (int i = oldCount; i < oldCount + count; ++i) { headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1))); headerItem->d->display.append(QString::number(i + 1)); } QStack<QTreeWidgetItem*> itemstack; itemstack.push(0); while (!itemstack.isEmpty()) { QTreeWidgetItem *par = itemstack.pop(); QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children; for (int row = 0; row < children.count(); ++row) { QTreeWidgetItem *child = children.at(row); if (child->children.count()) itemstack.push(child); child->values.insert(column, count, QVector<QWidgetItemData>()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -