📄 qtreewidget.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 <qapplication.h>#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 QTreeWidgetMimeData : public QMimeData{ Q_OBJECTpublic: QList<QTreeWidgetItem*> items;};#include "qtreewidget.moc"/* \class QTreeModel \brief The QTreeModel class manages the items stored in a tree view. \ingroup model-view \mainclass*//*! \internal Constructs a tree model with a \a parent object and the given number of \a columns.*/QTreeModel::QTreeModel(int columns, QObject *parent) : QAbstractItemModel(parent), header(new QTreeWidgetItem), sorting(Qt::AscendingOrder){ setColumnCount(columns);}/*! \internal Destroys this tree model.*/QTreeModel::~QTreeModel(){ clear(); delete header;}/*! \internal Removes all items in the model.*/void QTreeModel::clear(){ for (int i = 0; i < tree.count(); ++i) { QTreeWidgetItem *item = tree.at(i); item->par = 0; item->view = 0; item->model = 0; delete item; } tree.clear(); reset();}/*! \internal Sets the number of \a columns in the tree model.*/void QTreeModel::setColumnCount(int columns){ Q_ASSERT(columns >= 0); if (!header) header = new QTreeWidgetItem(); int count = header->columnCount(); if (count == columns) return; if (columns < count) { beginRemoveColumns(QModelIndex(), columns, count - 1); header->values.resize(columns); endRemoveColumns(); } else { beginInsertColumns(QModelIndex(), count, columns - 1); header->values.resize(columns); for (int i = count; i < columns; ++i) // insert data without emitting the dataChanged signal header->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i))); 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(QTreeWidgetItem *item, int column) const{ if (!item) return QModelIndex(); const QTreeWidgetItem *par = item->parent(); if (par) return createIndex(par->children.lastIndexOf(item), column, item); return createIndex(tree.lastIndexOf(item), column, item);}/*! \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(); // toplevel items if (!parent.isValid()) { if (row >= tree.count()) return QModelIndex(); QTreeWidgetItem *itm = tree.at(row); if (itm) return createIndex(row, column, itm); return QModelIndex(); } // children QTreeWidgetItem *parentItem = item(parent); if (parentItem && row < parentItem->childCount()) { QTreeWidgetItem *itm = static_cast<QTreeWidgetItem*>(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 = reinterpret_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{ if (parent.isValid()) { QTreeWidgetItem *parentItem = item(parent); if (parentItem) return parentItem->childCount(); } return tree.count();}/*! \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 (!header) return 0; return header->columnCount();}bool QTreeModel::hasChildren(const QModelIndex &parent) const{ if (!parent.isValid()) return tree.count() > 0; QTreeWidgetItem *itm = item(parent); if (!itm) return false; return itm->children.count() > 0;}/*! \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;}/*! \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); while (count > 0) { QTreeWidgetItem *par = item(parent); QTreeWidgetItem *item = new QTreeWidgetItem(); item->view = qobject_cast<QTreeWidget*>(QObject::parent()); item->model = this; item->par = par; if (par) par->children.insert(row++, item); else tree.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) return false; beginInsertColumns(parent, column, column + count - 1); int oldCount = columnCount(parent); column = qBound(0, column, oldCount); header->values.resize(oldCount + count); for (int i = oldCount; i < oldCount + count; ++i) header->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i))); QStack<QTreeWidgetItem*> itemstack; itemstack.push(0); while (!itemstack.isEmpty()) { QTreeWidgetItem *par = itemstack.pop(); QList<QTreeWidgetItem*> children = par ? par->children : tree; 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>()); } } endInsertColumns(); return true;}/*! \internal \reimp Returns the header data corresponding to the given header \a section, \a orientation and data \a role.*/QVariant QTreeModel::headerData(int section, Qt::Orientation orientation, int role) const{ if (!header) return section; if (orientation == Qt::Horizontal) { if (header) return header->data(section, role); if (role == Qt::DisplayRole) return section + 1; } return QVariant();}/*! \internal \reimp Sets the header data for the item specified by the header \a section, \a orientation and data \a role to the given \a value. Returns true if successful; otherwise returns false.*/bool QTreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role){ if (section < 0 || (orientation == Qt::Horizontal && header->columnCount() <= section)) return false; if (orientation == Qt::Horizontal && header) { header->setData(section, role, value); emit headerDataChanged(orientation, section, section); return true; } return false;}/*! \reimp Returns the flags for the item refered to the given \a index.*/Qt::ItemFlags QTreeModel::flags(const QModelIndex &index) const{ if (!index.isValid()) return Qt::ItemIsDropEnabled; // can drop on the viewport QTreeWidgetItem *itm = item(index); Q_ASSERT(itm); return itm->flags();}/*! \internal Sorts the entire tree in the model in the given \a order, by the values in the given \a column.*/void QTreeModel::sort(int column, Qt::SortOrder order){ if (header && (column < 0 || column >= header->columnCount())) return; // sort top level sortItems(&tree, column, order); // sort the children QList<QTreeWidgetItem*>::iterator it = tree.begin(); for (; it != tree.end(); ++it) (*it)->sortChildren(column, order, true); emit layoutChanged();}/*! \internal Returns true if the value of the \a left item is less than the value of the \a right item. Used by the sorting functions.*/bool QTreeModel::itemLessThan(const QPair<QTreeWidgetItem*,int> &left, const QPair<QTreeWidgetItem*,int> &right){ return *(left.first) < *(right.first);}/*! \internal Returns true if the value of the \a left item is greater than the value of the \a right item. Used by the sorting functions.*/bool QTreeModel::itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left, const QPair<QTreeWidgetItem*,int> &right){ return !(*(left .first) < *(right.first));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -