00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qtreewidget.h"
00025
00026 #ifndef QT_NO_TREEWIDGET
00027 #include <qheaderview.h>
00028 #include <qpainter.h>
00029 #include <qitemdelegate.h>
00030 #include <qstack.h>
00031 #include <qdebug.h>
00032 #include <private/qtreeview_p.h>
00033 #include <private/qwidgetitemdata_p.h>
00034 #include <private/qtreewidget_p.h>
00035 #include <private/qtreewidgetitemiterator_p.h>
00036
00037
00038 typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&);
00039
00040 class QTreeWidgetMimeData : public QMimeData
00041 {
00042 Q_OBJECT
00043 public:
00044 QList<QTreeWidgetItem*> items;
00045 };
00046
00047 class QTreeModelLessThan
00048 {
00049 public:
00050 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
00051 { return *i1 < *i2; }
00052 };
00053
00054 class QTreeModelGreaterThan
00055 {
00056 public:
00057 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
00058 { return *i2 < *i1; }
00059 };
00060
00061 #include "qtreewidget.moc"
00062
00063
00064
00065
00066
00067
00068
00069
00070
00078 QTreeModel::QTreeModel(int columns, QTreeWidget *parent)
00079 : QAbstractItemModel(parent), rootItem(new QTreeWidgetItem),
00080 headerItem(new QTreeWidgetItem), sortPending(false)
00081 {
00082 rootItem->view = parent;
00083 headerItem->view = parent;
00084 setColumnCount(columns);
00085 }
00086
00092 QTreeModel::QTreeModel(QTreeModelPrivate &dd, QTreeWidget *parent)
00093 : QAbstractItemModel(dd, parent), rootItem(new QTreeWidgetItem),
00094 headerItem(new QTreeWidgetItem), sortPending(false)
00095 {
00096 rootItem->view = parent;
00097 headerItem->view = parent;
00098 }
00099
00106 QTreeModel::~QTreeModel()
00107 {
00108 clear();
00109 delete headerItem;
00110 rootItem->view = 0;
00111 delete rootItem;
00112 }
00113
00120 void QTreeModel::clear()
00121 {
00122 for (int i = 0; i < rootItem->childCount(); ++i) {
00123 QTreeWidgetItem *item = rootItem->children.at(i);
00124 item->par = 0;
00125 item->view = 0;
00126 delete item;
00127 }
00128 rootItem->children.clear();
00129 sortPending = false;
00130 reset();
00131 }
00132
00139 void QTreeModel::setColumnCount(int columns)
00140 {
00141 if (columns < 0)
00142 return;
00143 if (!headerItem) {
00144 headerItem = new QTreeWidgetItem();
00145 headerItem->view = view();
00146 }
00147 int count = columnCount();
00148 if (count == columns)
00149 return;
00150
00151 if (columns < count) {
00152 beginRemoveColumns(QModelIndex(), columns, count - 1);
00153 headerItem->values.resize(columns);
00154 endRemoveColumns();
00155 } else {
00156 beginInsertColumns(QModelIndex(), count, columns - 1);
00157 headerItem->values.resize(columns);
00158 for (int i = count; i < columns; ++i) {
00159 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
00160 headerItem->display.append(QString::number(i + 1));
00161 }
00162 endInsertColumns();
00163 }
00164 }
00165
00174 QTreeWidgetItem *QTreeModel::item(const QModelIndex &index) const
00175 {
00176 if (!index.isValid())
00177 return 0;
00178 return static_cast<QTreeWidgetItem*>(index.internalPointer());
00179 }
00180
00188 QModelIndex QTreeModel::index(const QTreeWidgetItem *item, int column) const
00189 {
00190 if (!item || (item == rootItem))
00191 return QModelIndex();
00192 const QTreeWidgetItem *par = item->parent();
00193 QTreeWidgetItem *itm = const_cast<QTreeWidgetItem*>(item);
00194 if (!par)
00195 par = rootItem;
00196 return createIndex(par->children.lastIndexOf(itm), column, itm);
00197 }
00198
00207 QModelIndex QTreeModel::index(int row, int column, const QModelIndex &parent) const
00208 {
00209 int c = columnCount(parent);
00210
00211 if (row < 0 || column < 0 || column >= c)
00212 return QModelIndex();
00213
00214 QTreeWidgetItem *parentItem = parent.isValid() ? item(parent) : rootItem;
00215 if (parentItem && row < parentItem->childCount()) {
00216 QTreeWidgetItem *itm = parentItem->child(row);
00217 if (itm)
00218 return createIndex(row, column, itm);
00219 return QModelIndex();
00220 }
00221
00222 return QModelIndex();
00223 }
00224
00233 QModelIndex QTreeModel::parent(const QModelIndex &child) const
00234 {
00235 if (!child.isValid())
00236 return QModelIndex();
00237 QTreeWidgetItem *itm = static_cast<QTreeWidgetItem *>(child.internalPointer());
00238 if (!itm)
00239 return QModelIndex();
00240 QTreeWidgetItem *parent = itm->parent();
00241 return index(parent, 0);
00242 }
00243
00251 int QTreeModel::rowCount(const QModelIndex &parent) const
00252 {
00253 executePendingSort();
00254
00255 if (!parent.isValid())
00256 return rootItem->childCount();
00257
00258 QTreeWidgetItem *parentItem = item(parent);
00259 if (parentItem)
00260 return parentItem->childCount();
00261 return 0;
00262 }
00263
00272 int QTreeModel::columnCount(const QModelIndex &index) const
00273 {
00274 Q_UNUSED(index);
00275 if (!headerItem)
00276 return 0;
00277 return headerItem->columnCount();
00278 }
00279
00280 bool QTreeModel::hasChildren(const QModelIndex &parent) const
00281 {
00282 executePendingSort();
00283
00284 if (!parent.isValid())
00285 return (rootItem->childCount() > 0);
00286
00287 QTreeWidgetItem *itm = item(parent);
00288 if (!itm)
00289 return false;
00290 return (itm->childCount() > 0);
00291 }
00292
00301 QVariant QTreeModel::data(const QModelIndex &index, int role) const
00302 {
00303 if (!index.isValid())
00304 return QVariant();
00305 QTreeWidgetItem *itm = item(index);
00306 if (itm)
00307 return itm->data(index.column(), role);
00308 return QVariant();
00309 }
00310
00321 bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
00322 {
00323 if (!index.isValid())
00324 return false;
00325 QTreeWidgetItem *itm = item(index);
00326 if (itm) {
00327 itm->setData(index.column(), role, value);
00328 return true;
00329 }
00330 return false;
00331 }
00332
00337 bool QTreeModel::insertRows(int row, int count, const QModelIndex &parent)
00338 {
00339 if (count < 1 || row < 0 || row > rowCount(parent) || parent.column() > 0)
00340 return false;
00341
00342 beginInsertRows(parent, row, row + count - 1);
00343 QTreeWidgetItem *par = item(parent);
00344 while (count > 0) {
00345 QTreeWidgetItem *item = new QTreeWidgetItem();
00346 item->view = view();
00347 item->par = par;
00348 if (par)
00349 par->children.insert(row++, item);
00350 else
00351 rootItem->children.insert(row++, item);
00352 --count;
00353 }
00354 endInsertRows();
00355 return true;
00356 }
00357
00362 bool QTreeModel::insertColumns(int column, int count, const QModelIndex &parent)
00363 {
00364 if (count < 1 || column < 0 || column > columnCount(parent) || parent.column() > 0 || !headerItem)
00365 return false;
00366
00367 beginInsertColumns(parent, column, column + count - 1);
00368
00369 int oldCount = columnCount(parent);
00370 column = qBound(0, column, oldCount);
00371 headerItem->values.resize(oldCount + count);
00372 for (int i = oldCount; i < oldCount + count; ++i) {
00373 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
00374 headerItem->display.append(QString::number(i + 1));
00375 }
00376
00377 QStack<QTreeWidgetItem*> itemstack;
00378 itemstack.push(0);
00379 while (!itemstack.isEmpty()) {
00380 QTreeWidgetItem *par = itemstack.pop();
00381 QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children;
00382 for (int row = 0; row < children.count(); ++row) {
00383 QTreeWidgetItem *child = children.at(row);
00384 if (child->children.count())
00385 itemstack.push(child);
00386 child->values.insert(column, count, QVector<QWidgetItemData>());
00387 }
00388 }
00389
00390 endInsertColumns();
00391 return true;
00392 }
00393
00398 bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) {
00399 if (count < 1 || row < 0 || (row + count) > rowCount(parent))
00400 return false;
00401
00402 beginRemoveRows(parent, row, row + count - 1);
00403
00404 bool blockSignal = signalsBlocked();
00405 blockSignals(true);
00406
00407 QTreeWidgetItem *itm = item(parent);
00408 for (int i = row + count - 1; i >= row; --i) {
00409 QTreeWidgetItem *child = itm ? itm->takeChild(i) : rootItem->children.takeAt(i);
00410 Q_ASSERT(child);
00411 child->view = 0;
00412 delete child;
00413 child = 0;
00414 }
00415 blockSignals(blockSignal);
00416
00417 endRemoveRows();
00418 return true;
00419 }
00420
00429 QVariant QTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
00430 {
00431 if (orientation != Qt::Horizontal)
00432 return QVariant();
00433
00434 if (headerItem)
00435 return headerItem->data(section, role);
00436 if (role == Qt::DisplayRole)
00437 return QString::number(section + 1);
00438 return QVariant();
00439 }
00440
00451 bool QTreeModel::setHeaderData(int section, Qt::Orientation orientation,
00452 const QVariant &value, int role)
00453 {
00454 if (section < 0 || orientation != Qt::Horizontal || !headerItem)
00455 return false;
00456
00457 headerItem->setData(section, role, value);
00458 return true;
00459 }
00460
00468 Qt::ItemFlags QTreeModel::flags(const QModelIndex &index) const
00469 {
00470 if (!index.isValid())
00471 return Qt::ItemIsDropEnabled;
00472 QTreeWidgetItem *itm = item(index);
00473 Q_ASSERT(itm);
00474 return itm->flags();
00475 }
00476
00484 void QTreeModel::sort(int column, Qt::SortOrder order)
00485 {
00486 sortPending = false;
00487
00488 if (column < 0 || column >= columnCount())
00489 return;
00490
00491 emit layoutAboutToBeChanged();
00492 rootItem->sortChildren(column, order, true);
00493 emit layoutChanged();
00494 }
00495
00499 void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
00500 int start, int end, const QModelIndex &parent)
00501 {
00502 sortPending = false;
00503
00504 if (column < 0 || column >= columnCount())
00505 return;
00506
00507 QTreeWidgetItem *itm = item(parent);
00508 if (!itm)
00509 itm = rootItem;
00510 QList<QTreeWidgetItem*> lst = itm->children;
00511
00512 int count = end - start + 1;
00513 QVector < QPair<QTreeWidgetItem*,int> > sorting(count);
00514 for (int i = 0; i < count; ++i) {
00515 sorting[i].first = lst.at(start + i);
00516 sorting[i].second = start + i;
00517 }
00518
00519 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
00520 qStableSort(sorting.begin(), sorting.end(), compare);
00521
00522 QModelIndexList oldPersistentIndexes = persistentIndexList();
00523 QModelIndexList newPersistentIndexes = oldPersistentIndexes;
00524 QList<QTreeWidgetItem*>::iterator lit = lst.begin();
00525 bool changed = false;
00526 for (int i = 0; i < count; ++i) {
00527 int oldRow = sorting.at(i).second;
00528 QTreeWidgetItem *item = lst.takeAt(oldRow);
00529 lit = sortedInsertionIterator(lit, lst.end(), order, item);
00530 int newRow = qMax(lit - lst.begin(), 0);
00531 lit = lst.insert(lit, item);
00532 if (newRow != oldRow) {
00533 changed = true;
00534 for (int j = i + 1; j < count; ++j) {
00535 int otherRow = sorting.at(j).second;
00536 if (oldRow < otherRow && newRow >= otherRow)
00537 --sorting[j].second;
00538 else if (oldRow > otherRow && newRow <= otherRow)
00539 ++sorting[j].second;
00540 }
00541 for (int k = 0; k < newPersistentIndexes.count(); ++k) {
00542 QModelIndex pi = newPersistentIndexes.at(k);
00543 if (pi.parent() != parent)
00544 continue;
00545 int oldPersistentRow = pi.row();
00546 int newPersistentRow = oldPersistentRow;
00547 if (oldPersistentRow == oldRow)
00548 newPersistentRow = newRow;
00549 else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
00550 newPersistentRow = oldPersistentRow - 1;
00551 else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
00552 newPersistentRow = oldPersistentRow + 1;
00553 if (newPersistentRow != oldPersistentRow)
00554 newPersistentIndexes[k] = createIndex(newPersistentRow,
00555 pi.column(), pi.internalPointer());
00556 }
00557 }
00558 }
00559
00560 if (changed) {
00561 emit layoutAboutToBeChanged();
00562 itm->children = lst;
00563 changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
00564 emit layoutChanged();
00565 }
00566 }
00567
00577 bool QTreeModel::itemLessThan(const QPair<QTreeWidgetItem*,int> &left,
00578 const QPair<QTreeWidgetItem*,int> &right)
00579 {
00580 return *(left.first) < *(right.first);
00581 }
00582
00592 bool QTreeModel::itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
00593 const QPair<QTreeWidgetItem*,int> &right)
00594 {
00595 return !(*(left .first) < *(right.first));
00596 }
00597
00601 QList<QTreeWidgetItem*>::iterator QTreeModel::sortedInsertionIterator(
00602 const QList<QTreeWidgetItem*>::iterator &begin,
00603 const QList<QTreeWidgetItem*>::iterator &end,
00604 Qt::SortOrder order, QTreeWidgetItem *item)
00605 {
00606 if (order == Qt::AscendingOrder)
00607 return qLowerBound(begin, end, item, QTreeModelLessThan());
00608 return qLowerBound(begin, end, item, QTreeModelGreaterThan());
00609 }
00610
00611 QStringList QTreeModel::mimeTypes() const
00612 {
00613 return view()->mimeTypes();
00614 }
00615
00616 QMimeData *QTreeModel::internalMimeData() const
00617 {
00618 return QAbstractItemModel::mimeData(cachedIndexes);
00619 }
00620
00621 QMimeData *QTreeModel::mimeData(const QModelIndexList &indexes) const
00622 {
00623 QList<QTreeWidgetItem*> items;
00624 for (int i = 0; i < indexes.count(); ++i) {
00625 if (indexes.at(i).column() == 0)
00626 items << item(indexes.at(i));
00627 }
00628
00629
00630
00631 cachedIndexes = indexes;
00632 QMimeData *mimeData = view()->mimeData(items);
00633 cachedIndexes.clear();
00634 return mimeData;
00635 }
00636
00637 bool QTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
00638 int row, int column, const QModelIndex &parent)
00639 {
00640 if (row == -1 && column == -1)
00641 row = rowCount(parent);
00642 return view()->dropMimeData(item(parent), row, data, action);
00643 }
00644
00645 Qt::DropActions QTreeModel::supportedDropActions() const
00646 {
00647 return view()->supportedDropActions();
00648 }
00649
00650 void QTreeModel::itemChanged(QTreeWidgetItem *item)
00651 {
00652 QModelIndex left = index(item, 0);
00653 QModelIndex right = index(item, item->columnCount() - 1);
00654 emit dataChanged(left, right);
00655 }
00656
00657 bool QTreeModel::executePendingSort() const
00658 {
00659 if (sortPending) {
00660 sortPending = false;
00661 int column = view()->header()->sortIndicatorSection();
00662 Qt::SortOrder order = view()->header()->sortIndicatorOrder();
00663 QTreeModel *that = const_cast<QTreeModel*>(this);
00664 const bool blocked = that->signalsBlocked();
00665 that->blockSignals(true);
00666 that->sort(column, order);
00667 that->blockSignals(blocked);
00668 return true;
00669 }
00670 return false;
00671 }
00672
00679 void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
00680 {
00681 if (signalsBlocked())
00682 return;
00683
00684 if (headerItem == item && column < item->columnCount()) {
00685 if (column == -1)
00686 emit headerDataChanged(Qt::Horizontal, 0, columnCount() - 1);
00687 else
00688 emit headerDataChanged(Qt::Horizontal, column, column);
00689 return;
00690 }
00691
00692 QModelIndex bottomRight, topLeft;
00693 if (column == -1) {
00694 topLeft = index(item, 0);
00695 bottomRight = createIndex(topLeft.row(), columnCount() - 1, item);
00696 } else {
00697 topLeft = index(item, column);
00698 bottomRight = topLeft;
00699 }
00700 emit dataChanged(topLeft, bottomRight);
00701 }
00702
00703 void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count)
00704 {
00705 beginInsertRows(index(parent, 0), row, row + count - 1);
00706 }
00707
00708 void QTreeModel::endInsertItems()
00709 {
00710 endInsertRows();
00711 }
00712
00713 void QTreeModel::beginRemoveItems(QTreeWidgetItem *parent, int row, int count)
00714 {
00715 Q_ASSERT(row >= 0);
00716 Q_ASSERT(count > 0);
00717 beginRemoveRows(index(parent, 0), row, row + count - 1);
00718 if (!parent)
00719 parent = rootItem;
00720
00721 for (int i = 0; i < iterators.count(); ++i) {
00722 for (int j = 0; j < count; j++) {
00723 QTreeWidgetItem *c = parent->child(row + j);
00724 iterators[i]->d_func()->ensureValidIterator(c);
00725 }
00726 }
00727 }
00728
00729 void QTreeModel::endRemoveItems()
00730 {
00731 endRemoveRows();
00732 }
00733
00734 void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortOrder order)
00735 {
00736 Q_UNUSED(column);
00737
00738 QVector< QPair<QTreeWidgetItem*,int> > sorting(items->count());
00739 for (int i = 0; i < sorting.count(); ++i) {
00740 sorting[i].first = items->at(i);
00741 sorting[i].second = i;
00742 }
00743
00744
00745 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
00746 qStableSort(sorting.begin(), sorting.end(), compare);
00747
00748 int colCount = columnCount();
00749 for (int r = 0; r < sorting.count(); ++r) {
00750 QTreeWidgetItem *item = sorting.at(r).first;
00751 items->replace(r, item);
00752 int oldRow = sorting.at(r).second;
00753 for (int c = 0; c < colCount; ++c) {
00754 QModelIndex from = createIndex(oldRow, c, item);
00755 QModelIndex to = createIndex(r, c, item);
00756 changePersistentIndex(from, to);
00757 }
00758 }
00759 }
00760
01188 QTreeWidgetItem::QTreeWidgetItem(int type)
01189 : rtti(type), view(0), par(0),
01190 itemFlags(Qt::ItemIsSelectable
01191 |Qt::ItemIsUserCheckable
01192 |Qt::ItemIsEnabled
01193 |Qt::ItemIsDragEnabled
01194 |Qt::ItemIsDropEnabled)
01195 {
01196 }
01197
01198
01207 QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type)
01208 : rtti(type), view(0), par(0),
01209 itemFlags(Qt::ItemIsSelectable
01210 |Qt::ItemIsUserCheckable
01211 |Qt::ItemIsEnabled
01212 |Qt::ItemIsDragEnabled
01213 |Qt::ItemIsDropEnabled)
01214 {
01215 for (int i = 0; i < strings.count(); ++i)
01216 setText(i, strings.at(i));
01217 }
01218
01228 QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type)
01229 : rtti(type), view(0), par(0),
01230 itemFlags(Qt::ItemIsSelectable
01231 |Qt::ItemIsUserCheckable
01232 |Qt::ItemIsEnabled
01233 |Qt::ItemIsDragEnabled
01234 |Qt::ItemIsDropEnabled)
01235 {
01236 if (view && view->model()) {
01237 QTreeModel *model = ::qobject_cast<QTreeModel*>(view->model());
01238 model->rootItem->addChild(this);
01239 values.reserve(model->headerItem->columnCount());
01240 }
01241 }
01242
01253 QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type)
01254 : rtti(type), view(0), par(0),
01255 itemFlags(Qt::ItemIsSelectable
01256 |Qt::ItemIsUserCheckable
01257 |Qt::ItemIsEnabled
01258 |Qt::ItemIsDragEnabled
01259 |Qt::ItemIsDropEnabled)
01260 {
01261 for (int i = 0; i < strings.count(); ++i)
01262 setText(i, strings.at(i));
01263 if (view && view->model()) {
01264 QTreeModel *model = ::qobject_cast<QTreeModel*>(view->model());
01265 model->rootItem->addChild(this);
01266 values.reserve(model->headerItem->columnCount());
01267 }
01268 }
01269
01278 QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type)
01279 : rtti(type), view(0), par(0),
01280 itemFlags(Qt::ItemIsSelectable
01281 |Qt::ItemIsUserCheckable
01282 |Qt::ItemIsEnabled
01283 |Qt::ItemIsDragEnabled
01284 |Qt::ItemIsDropEnabled)
01285 {
01286 if (view) {
01287 QTreeModel *model = ::qobject_cast<QTreeModel*>(view->model());
01288 if (model) {
01289 int i = model->rootItem->indexOfChild(after) + 1;
01290 model->rootItem->insertChild(i, this);
01291 values.reserve(model->headerItem->columnCount());
01292 }
01293 }
01294 }
01295
01301 QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type)
01302 : rtti(type), view(0), par(0),
01303 itemFlags(Qt::ItemIsSelectable
01304 |Qt::ItemIsUserCheckable
01305 |Qt::ItemIsEnabled
01306 |Qt::ItemIsDragEnabled
01307 |Qt::ItemIsDropEnabled)
01308 {
01309 if (parent)
01310 parent->addChild(this);
01311 }
01312
01319 QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type)
01320 : rtti(type), view(0), par(0),
01321 itemFlags(Qt::ItemIsSelectable
01322 |Qt::ItemIsUserCheckable
01323 |Qt::ItemIsEnabled
01324 |Qt::ItemIsDragEnabled
01325 |Qt::ItemIsDropEnabled)
01326 {
01327 for (int i = 0; i < strings.count(); ++i)
01328 setText(i, strings.at(i));
01329 if (parent)
01330 parent->addChild(this);
01331
01332 }
01333
01342 QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type)
01343 : rtti(type), view(0), par(0),
01344 itemFlags(Qt::ItemIsSelectable
01345 |Qt::ItemIsUserCheckable
01346 |Qt::ItemIsEnabled
01347 |Qt::ItemIsDragEnabled
01348 |Qt::ItemIsDropEnabled)
01349 {
01350 if (parent) {
01351 int i = parent->indexOfChild(after) + 1;
01352 parent->insertChild(i, this);
01353 }
01354 }
01355
01360 QTreeWidgetItem::~QTreeWidgetItem()
01361 {
01362 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01363 if (par) {
01364 int i = par->children.indexOf(this);
01365 if (model) model->beginRemoveItems(par, i, 1);
01366 par->children.takeAt(i);
01367 if (model) model->endRemoveItems();
01368 } else if (model) {
01369 if (this == model->headerItem) {
01370 model->headerItem = 0;
01371 } else {
01372 int i = model->rootItem->children.indexOf(this);
01373 model->beginRemoveItems(0, i, 1);
01374 model->rootItem->children.takeAt(i);
01375 model->endRemoveItems();
01376 }
01377 }
01378
01379
01380 for (int i = 0; i < children.count(); ++i) {
01381 QTreeWidgetItem *child = children.at(i);
01382
01383 child->par = 0;
01384
01385 child->view = 0;
01386 delete child;
01387 }
01388
01389 children.clear();
01390 }
01391
01395 QTreeWidgetItem *QTreeWidgetItem::clone() const
01396 {
01397 QTreeWidgetItem *copy = 0;
01398
01399 QStack<const QTreeWidgetItem*> stack;
01400 QStack<QTreeWidgetItem*> parentStack;
01401 stack.push(this);
01402 parentStack.push(0);
01403
01404 QTreeWidgetItem *root = 0;
01405 const QTreeWidgetItem *item = 0;
01406 QTreeWidgetItem *parent = 0;
01407 while (!stack.isEmpty()) {
01408
01409 item = stack.pop();
01410 parent = parentStack.pop();
01411
01412
01413 copy = new QTreeWidgetItem(*item);
01414 if (!root)
01415 root = copy;
01416
01417
01418 if (parent) {
01419 copy->par = parent;
01420 parent->children.append(copy);
01421 }
01422
01423 for (int i=0; i<item->childCount(); ++i) {
01424 stack.push(item->child(i));
01425 parentStack.push(copy);
01426 }
01427 }
01428 return root;
01429 }
01430
01438 void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
01439 {
01440 if (column < 0)
01441 return;
01442
01443 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01444 switch (role) {
01445 case Qt::EditRole:
01446 case Qt::DisplayRole: {
01447 if (values.count() <= column) {
01448 if (model && this == model->headerItem)
01449 model->setColumnCount(column + 1);
01450 else
01451 values.resize(column + 1);
01452 }
01453 if (display.count() <= column) {
01454 for (int i = display.count() - 1; i < column - 1; ++i)
01455 display.append(QVariant());
01456 display.append(value);
01457 } else if (display[column] != value) {
01458 display[column] = value;
01459 } else {
01460 return;
01461 }
01462 } break;
01463 case Qt::CheckStateRole:
01464 if (itemFlags & Qt::ItemIsTristate) {
01465 for (int i = 0; i < children.count(); ++i) {
01466 QTreeWidgetItem *child = children.at(i);
01467 if (child->data(column, role).isValid()) {
01468 Qt::ItemFlags f = itemFlags;
01469 itemFlags &= ~Qt::ItemIsTristate;
01470 child->setData(column, role, value);
01471 itemFlags = f;
01472 }
01473 }
01474 }
01475
01476 default:
01477 if (column < values.count()) {
01478 bool found = false;
01479 QVector<QWidgetItemData> column_values = values.at(column);
01480 for (int i = 0; i < column_values.count(); ++i) {
01481 if (column_values.at(i).role == role) {
01482 if (column_values.at(i).value == value)
01483 return;
01484 values[column][i].value = value;
01485 found = true;
01486 break;
01487 }
01488 }
01489 if (!found)
01490 values[column].append(QWidgetItemData(role, value));
01491 } else {
01492 if (model && this == model->headerItem)
01493 model->setColumnCount(column + 1);
01494 else
01495 values.resize(column + 1);
01496 values[column].append(QWidgetItemData(role, value));
01497 }
01498 }
01499
01500 if (model) {
01501 model->emitDataChanged(this, column);
01502 if (role == Qt::CheckStateRole) {
01503 QTreeWidgetItem *p;
01504 for (p = par; p && (p->itemFlags & Qt::ItemIsTristate); p = p->par)
01505 model->emitDataChanged(p, column);
01506 }
01507 }
01508 }
01509
01513 QVariant QTreeWidgetItem::data(int column, int role) const
01514 {
01515 switch (role) {
01516 case Qt::EditRole:
01517 case Qt::DisplayRole:
01518 if (column >= 0 && column < display.count())
01519 return display.at(column);
01520 break;
01521 case Qt::CheckStateRole:
01522
01523 if (children.count() && (itemFlags & Qt::ItemIsTristate))
01524 return childrenCheckState(column);
01525 default:
01526 if (column >= 0 && column < values.size()) {
01527 const QVector<QWidgetItemData> &column_values = values.at(column);
01528 for (int i = 0; i < column_values.count(); ++i)
01529 if (column_values.at(i).role == role)
01530 return column_values.at(i).value;
01531 }
01532 }
01533 return QVariant();
01534 }
01535
01541 bool QTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
01542 {
01543 int column = view ? view->sortColumn() : 0;
01544 return text(column) < other.text(column);
01545 }
01546
01547 #ifndef QT_NO_DATASTREAM
01548
01554 void QTreeWidgetItem::read(QDataStream &in)
01555 {
01556
01557 if (in.version() < QDataStream::Qt_4_2) {
01558 display.clear();
01559 in >> values;
01560
01561 for (int column = 0; column < values.count(); ++column) {
01562 display << QVariant();
01563 for (int i = 0; i < values.at(column).count(); ++i) {
01564 if (values.at(column).at(i).role == Qt::DisplayRole) {
01565 display[column] = values.at(column).at(i).value;
01566 values[column].remove(i--);
01567 }
01568 }
01569 }
01570 } else {
01571 in >> values >> display;
01572 }
01573 }
01574
01580 void QTreeWidgetItem::write(QDataStream &out) const
01581 {
01582 out << values << display;
01583 }
01584
01595 QTreeWidgetItem::QTreeWidgetItem(const QTreeWidgetItem &other)
01596 : rtti(Type), values(other.values), view(0), display(other.display),
01597 par(0), itemFlags(other.itemFlags)
01598 {
01599 }
01600
01609 QTreeWidgetItem &QTreeWidgetItem::operator=(const QTreeWidgetItem &other)
01610 {
01611 values = other.values;
01612 display = other.display;
01613 itemFlags = other.itemFlags;
01614 return *this;
01615 }
01616
01617 #endif // QT_NO_DATASTREAM
01618
01624 void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
01625 {
01626 insertChild(children.count(), child);
01627 }
01628
01634 void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
01635 {
01636 if (index < 0 || index > children.count() || child == 0 || child->view != 0 || child->par != 0)
01637 return;
01638
01639 if (QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0)) {
01640 if (model->rootItem == this)
01641 child->par = 0;
01642 else
01643 child->par = this;
01644 if (view->isSortingEnabled()) {
01645 #if 0
01646 Qt::SortOrder order = view->header()->sortIndicatorOrder();
01647 QList<QTreeWidgetItem*>::iterator it;
01648 it = model->sortedInsertionIterator(children.begin(), children.end(),
01649 order, child);
01650 index = qMax(it - children.begin(), 0);
01651 #else
01652
01653 index = children.count();
01654 model->sortPending = true;
01655 #endif
01656 }
01657 model->beginInsertItems(this, index, 1);
01658 int cols = model->columnCount();
01659 QStack<QTreeWidgetItem*> stack;
01660 stack.push(child);
01661 while (!stack.isEmpty()) {
01662 QTreeWidgetItem *i = stack.pop();
01663 i->view = view;
01664 i->values.reserve(cols);
01665 for (int c = 0; c < i->children.count(); ++c)
01666 stack.push(i->children.at(c));
01667 }
01668 children.insert(index, child);
01669 model->endInsertItems();
01670 } else {
01671 child->par = this;
01672 children.insert(index, child);
01673 }
01674 }
01675
01679 QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
01680 {
01681 if (index >= 0 && index < children.count()) {
01682 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01683 if (model && model->executePendingSort())
01684 model = 0;
01685 if (model) model->beginRemoveItems(this, index, 1);
01686 QTreeWidgetItem *item = children.takeAt(index);
01687 item->par = 0;
01688 QStack<QTreeWidgetItem*> stack;
01689 stack.push(item);
01690 while (!stack.isEmpty()) {
01691 QTreeWidgetItem *i = stack.pop();
01692 i->view = 0;
01693 for (int c = 0; c < i->children.count(); ++c)
01694 stack.push(i->children.at(c));
01695 }
01696 if (model) model->endRemoveRows();
01697 return item;
01698 }
01699 return 0;
01700 }
01701
01709 void QTreeWidgetItem::addChildren(const QList<QTreeWidgetItem*> &children)
01710 {
01711 insertChildren(this->children.count(), children);
01712 }
01713
01721 void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &children)
01722 {
01723 if (view && view->isSortingEnabled()) {
01724 for (int n = 0; n < children.count(); ++n)
01725 insertChild(index, children.at(n));
01726 return;
01727 }
01728 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01729 QStack<QTreeWidgetItem*> stack;
01730 QList<QTreeWidgetItem*> itemsToInsert;
01731 for (int n = 0; n < children.count(); ++n) {
01732 QTreeWidgetItem *child = children.at(n);
01733 if (child->view || child->par)
01734 continue;
01735 itemsToInsert.append(child);
01736 if (view && model) {
01737 if (child->childCount() == 0)
01738 child->view = view;
01739 else
01740 stack.push(child);
01741 }
01742 if (model && (model->rootItem == this))
01743 child->par = 0;
01744 else
01745 child->par = this;
01746 }
01747 if (!itemsToInsert.isEmpty()) {
01748 while (!stack.isEmpty()) {
01749 QTreeWidgetItem *i = stack.pop();
01750 i->view = view;
01751 for (int c = 0; c < i->children.count(); ++c)
01752 stack.push(i->children.at(c));
01753 }
01754 if (model) model->beginInsertItems(this, index, itemsToInsert.count());
01755 for (int n = 0; n < itemsToInsert.count(); ++n)
01756 this->children.insert(index + n, itemsToInsert.at(n));
01757 if (model) model->endInsertItems();
01758 }
01759 }
01760
01766 QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
01767 {
01768 QList<QTreeWidgetItem*> removed;
01769 if (children.count() > 0) {
01770 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01771 if (model && model->executePendingSort())
01772 model = 0;
01773 if (model) model->beginRemoveItems(this, 0, children.count());
01774 for (int n = 0; n < children.count(); ++n) {
01775 QTreeWidgetItem *item = children.at(n);
01776 item->par = 0;
01777 QStack<QTreeWidgetItem*> stack;
01778 stack.push(item);
01779 while (!stack.isEmpty()) {
01780 QTreeWidgetItem *i = stack.pop();
01781 i->view = 0;
01782 for (int c = 0; c < i->children.count(); ++c)
01783 stack.push(i->children.at(c));
01784 }
01785 }
01786 removed = children;
01787 children.clear();
01788 if (model) model->endRemoveItems();
01789 }
01790 return removed;
01791 }
01792
01800 void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb)
01801 {
01802 QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0);
01803 if (!model)
01804 return;
01805 model->sortItems(&children, column, order);
01806 if (climb) {
01807 QList<QTreeWidgetItem*>::iterator it = children.begin();
01808 for (; it != children.end(); ++it)
01809 (*it)->sortChildren(column, order, climb);
01810 }
01811 }
01812
01821 QVariant QTreeWidgetItem::childrenCheckState(int column) const
01822 {
01823 if (column < 0)
01824 return QVariant();
01825 int checkedChildrenCount = 0;
01826 int uncheckedChildrenCount = 0;
01827 int validChildrenCount = 0;
01828 for (int i = 0; i < children.count(); ++i) {
01829 QVariant value = children.at(i)->data(column, Qt::CheckStateRole);
01830 if (!value.isValid())
01831 continue;
01832 Qt::CheckState checkState = static_cast<Qt::CheckState>(value.toInt());
01833 if (checkState == Qt::Unchecked)
01834 ++uncheckedChildrenCount;
01835 else
01836 ++checkedChildrenCount;
01837 ++validChildrenCount;
01838 }
01839 if (checkedChildrenCount + uncheckedChildrenCount == 0)
01840 return QVariant();
01841 if (checkedChildrenCount == validChildrenCount)
01842 return Qt::Checked;
01843 if (uncheckedChildrenCount == validChildrenCount)
01844 return Qt::Unchecked;
01845 return Qt::PartiallyChecked;
01846 }
01847
01851 void QTreeWidgetItem::itemChanged()
01852 {
01853 if (QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0))
01854 model->itemChanged(this);
01855 }
01856
01860 void QTreeWidgetItem::executePendingSort() const
01861 {
01862 if (QTreeModel *model = (view ? ::qobject_cast<QTreeModel*>(view->model()) : 0))
01863 model->executePendingSort();
01864 }
01865
01866
01867 #ifndef QT_NO_DATASTREAM
01868
01877 QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item)
01878 {
01879 item.write(out);
01880 return out;
01881 }
01882
01892 QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item)
01893 {
01894 item.read(in);
01895 return in;
01896 }
01897 #endif // QT_NO_DATASTREAM
01898
01899 class QTreeWidgetPrivate : public QTreeViewPrivate
01900 {
01901 Q_DECLARE_PUBLIC(QTreeWidget)
01902 public:
01903 QTreeWidgetPrivate() : QTreeViewPrivate() {}
01904 inline QTreeModel *model() const
01905 { return ::qobject_cast<QTreeModel*>(q_func()->model()); }
01906 inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
01907 { return model()->index(item, column); }
01908 inline QTreeWidgetItem *item(const QModelIndex &index) const
01909 { return model()->item(index); }
01910 void _q_emitItemPressed(const QModelIndex &index);
01911 void _q_emitItemClicked(const QModelIndex &index);
01912 void _q_emitItemDoubleClicked(const QModelIndex &index);
01913 void _q_emitItemActivated(const QModelIndex &index);
01914 void _q_emitItemEntered(const QModelIndex &index);
01915 void _q_emitItemChanged(const QModelIndex &index);
01916 void _q_emitItemExpanded(const QModelIndex &index);
01917 void _q_emitItemCollapsed(const QModelIndex &index);
01918 void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
01919 void _q_sort();
01920 void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
01921 };
01922
01923 void QTreeWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
01924 {
01925 Q_Q(QTreeWidget);
01926 emit q->itemPressed(item(index), index.column());
01927 }
01928
01929 void QTreeWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
01930 {
01931 Q_Q(QTreeWidget);
01932 emit q->itemClicked(item(index), index.column());
01933 }
01934
01935 void QTreeWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
01936 {
01937 Q_Q(QTreeWidget);
01938 emit q->itemDoubleClicked(item(index), index.column());
01939 }
01940
01941 void QTreeWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
01942 {
01943 Q_Q(QTreeWidget);
01944 emit q->itemActivated(item(index), index.column());
01945 }
01946
01947 void QTreeWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
01948 {
01949 Q_Q(QTreeWidget);
01950 emit q->itemEntered(item(index), index.column());
01951 }
01952
01953 void QTreeWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
01954 {
01955 Q_Q(QTreeWidget);
01956 emit q->itemChanged(item(index), index.column());
01957 }
01958
01959 void QTreeWidgetPrivate::_q_emitItemExpanded(const QModelIndex &index)
01960 {
01961 Q_Q(QTreeWidget);
01962 emit q->itemExpanded(item(index));
01963 }
01964
01965 void QTreeWidgetPrivate::_q_emitItemCollapsed(const QModelIndex &index)
01966 {
01967 Q_Q(QTreeWidget);
01968 emit q->itemCollapsed(item(index));
01969 }
01970
01971 void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t,
01972 const QModelIndex &previous)
01973 {
01974 Q_Q(QTreeWidget);
01975 QTreeWidgetItem *currentItem = model()->item(current);
01976 QTreeWidgetItem *previousItem = model()->item(previous);
01977 emit q->currentItemChanged(currentItem, previousItem);
01978 }
01979
01980 void QTreeWidgetPrivate::_q_sort()
01981 {
01982 Q_Q(QTreeWidget);
01983 if (sortingEnabled) {
01984 int column = q->header()->sortIndicatorSection();
01985 Qt::SortOrder order = q->header()->sortIndicatorOrder();
01986 model()->sort(column, order);
01987 }
01988 }
01989
01990 void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
01991 const QModelIndex &bottomRight)
01992 {
01993 Q_Q(QTreeWidget);
01994 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
01995 && !model()->sortPending) {
01996 int column = q->header()->sortIndicatorSection();
01997 if (column >= topLeft.column() && column <= bottomRight.column()) {
01998 Qt::SortOrder order = q->header()->sortIndicatorOrder();
01999 model()->ensureSorted(column, order, topLeft.row(),
02000 bottomRight.row(), topLeft.parent());
02001 }
02002 }
02003 }
02004
02169 QTreeWidget::QTreeWidget(QWidget *parent)
02170 : QTreeView(*new QTreeWidgetPrivate(), parent)
02171 {
02172 QTreeView::setModel(new QTreeModel(1, this));
02173 connect(this, SIGNAL(pressed(QModelIndex)),
02174 SLOT(_q_emitItemPressed(QModelIndex)));
02175 connect(this, SIGNAL(clicked(QModelIndex)),
02176 SLOT(_q_emitItemClicked(QModelIndex)));
02177 connect(this, SIGNAL(doubleClicked(QModelIndex)),
02178 SLOT(_q_emitItemDoubleClicked(QModelIndex)));
02179 connect(this, SIGNAL(activated(QModelIndex)),
02180 SLOT(_q_emitItemActivated(QModelIndex)));
02181 connect(this, SIGNAL(entered(QModelIndex)),
02182 SLOT(_q_emitItemEntered(QModelIndex)));
02183 connect(this, SIGNAL(expanded(QModelIndex)),
02184 SLOT(_q_emitItemExpanded(QModelIndex)));
02185 connect(this, SIGNAL(collapsed(QModelIndex)),
02186 SLOT(_q_emitItemCollapsed(QModelIndex)));
02187 connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
02188 this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
02189 connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
02190 this, SIGNAL(itemSelectionChanged()));
02191 connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
02192 this, SLOT(_q_emitItemChanged(QModelIndex)));
02193 QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
02194 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
02195 QObject::connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
02196 this, SLOT(_q_sort()));
02197
02198 header()->setClickable(false);
02199 }
02200
02205 QTreeWidget::~QTreeWidget()
02206 {
02207 }
02208
02209
02210
02211
02212
02213
02214
02215 int QTreeWidget::columnCount() const
02216 {
02217 Q_D(const QTreeWidget);
02218 return d->model()->columnCount();
02219 }
02220
02221
02222
02223
02224
02225 void QTreeWidget::setColumnCount(int columns)
02226 {
02227 Q_D(QTreeWidget);
02228 if (columns < 0)
02229 return;
02230 d->model()->setColumnCount(columns);
02231 }
02232
02244 QTreeWidgetItem *QTreeWidget::invisibleRootItem() const
02245 {
02246 Q_D(const QTreeWidget);
02247 return d->model()->rootItem;
02248 }
02249
02257 QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const
02258 {
02259 Q_D(const QTreeWidget);
02260 d->model()->executePendingSort();
02261 return d->model()->rootItem->child(index);
02262 }
02263
02270 int QTreeWidget::topLevelItemCount() const
02271 {
02272 Q_D(const QTreeWidget);
02273 return d->model()->rootItem->childCount();
02274 }
02275
02284 void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem *item)
02285 {
02286 Q_D(QTreeWidget);
02287 d->model()->rootItem->insertChild(index, item);
02288 }
02289
02297 void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item)
02298 {
02299 insertTopLevelItem(topLevelItemCount(), item);
02300 }
02301
02309 QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index)
02310 {
02311 Q_D(QTreeWidget);
02312 return d->model()->rootItem->takeChild(index);
02313 }
02314
02318 int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item)
02319 {
02320 Q_D(QTreeWidget);
02321 d->model()->executePendingSort();
02322 return d->model()->rootItem->indexOfChild(item);
02323 }
02324
02331 int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) const
02332 {
02333 Q_D(const QTreeWidget);
02334 d->model()->executePendingSort();
02335 return d->model()->rootItem->indexOfChild(item);
02336 }
02337
02347 void QTreeWidget::insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items)
02348 {
02349 Q_D(QTreeWidget);
02350 d->model()->rootItem->insertChildren(index, items);
02351 }
02352
02358 void QTreeWidget::addTopLevelItems(const QList<QTreeWidgetItem*> &items)
02359 {
02360 insertTopLevelItems(topLevelItemCount(), items);
02361 }
02362
02369 QTreeWidgetItem *QTreeWidget::headerItem() const
02370 {
02371 Q_D(const QTreeWidget);
02372 return d->model()->headerItem;
02373 }
02374
02384 void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)
02385 {
02386 Q_D(QTreeWidget);
02387 if (!item)
02388 return;
02389 item->view = this;
02390
02391 int oldCount = columnCount();
02392 if (oldCount < item->columnCount())
02393 d->model()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());
02394 else
02395 d->model()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);
02396 delete d->model()->headerItem;
02397 d->model()->headerItem = item;
02398 if (oldCount < item->columnCount())
02399 d->model()->endInsertColumns();
02400 else
02401 d->model()->endRemoveColumns();
02402 d->model()->headerDataChanged(Qt::Horizontal, 0, oldCount);
02403 }
02404
02405
02414 void QTreeWidget::setHeaderLabels(const QStringList &labels)
02415 {
02416 Q_D(QTreeWidget);
02417 if (columnCount() < labels.count())
02418 setColumnCount(labels.count());
02419 QTreeModel *model = d->model();
02420 QTreeWidgetItem *item = model->headerItem;
02421 for (int i = 0; i < labels.count(); ++i)
02422 item->setText(i, labels.at(i));
02423 }
02424
02437 QTreeWidgetItem *QTreeWidget::currentItem() const
02438 {
02439 Q_D(const QTreeWidget);
02440 return d->item(currentIndex());
02441 }
02442
02449 int QTreeWidget::currentColumn() const
02450 {
02451 return currentIndex().column();
02452 }
02453
02461 void QTreeWidget::setCurrentItem(QTreeWidgetItem *item)
02462 {
02463 setCurrentItem(item, 0);
02464 }
02465
02472 void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column)
02473 {
02474 Q_D(const QTreeWidget);
02475 setCurrentIndex(d->index(item, column));
02476 }
02477
02483 QTreeWidgetItem *QTreeWidget::itemAt(const QPoint &p) const
02484 {
02485 Q_D(const QTreeWidget);
02486 return d->item(indexAt(p));
02487 }
02488
02501 QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const
02502 {
02503 Q_D(const QTreeWidget);
02504 return visualRect(d->index(item));
02505 }
02506
02514 int QTreeWidget::sortColumn() const
02515 {
02516 return header()->sortIndicatorSection();
02517 }
02518
02526 void QTreeWidget::sortItems(int column, Qt::SortOrder order)
02527 {
02528 Q_D(QTreeWidget);
02529 header()->setSortIndicator(column, order);
02530 d->model()->sort(column, order);
02531 }
02532
02538 void QTreeWidget::setSortingEnabled(bool enable)
02539 {
02540 QTreeView::setSortingEnabled(enable);
02541 }
02542
02548 bool QTreeWidget::isSortingEnabled() const
02549 {
02550 return QTreeView::isSortingEnabled();
02551 }
02552
02557 void QTreeWidget::editItem(QTreeWidgetItem *item, int column)
02558 {
02559 Q_D(QTreeWidget);
02560 edit(d->index(item, column));
02561 }
02562
02569 void QTreeWidget::openPersistentEditor(QTreeWidgetItem *item, int column)
02570 {
02571 Q_D(QTreeWidget);
02572 QAbstractItemView::openPersistentEditor(d->index(item, column));
02573 }
02574
02584 void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column)
02585 {
02586 Q_D(QTreeWidget);
02587 QAbstractItemView::closePersistentEditor(d->index(item, column));
02588 }
02589
02595 QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const
02596 {
02597 Q_D(const QTreeWidget);
02598 return QAbstractItemView::indexWidget(d->index(item, column));
02599 }
02600
02619 void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
02620 {
02621 Q_D(QTreeWidget);
02622 QAbstractItemView::setIndexWidget(d->index(item, column), widget);
02623 }
02624
02634 bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const
02635 {
02636 Q_D(const QTreeWidget);
02637 return selectionModel()->isSelected(d->index(item));
02638
02639 }
02640
02651 void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select)
02652 {
02653 Q_D(QTreeWidget);
02654 selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select
02655 : QItemSelectionModel::Deselect)
02656 |QItemSelectionModel::Rows);
02657 }
02658
02664 QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
02665 {
02666 Q_D(const QTreeWidget);
02667 QModelIndexList indexes = selectionModel()->selectedIndexes();
02668 QList<QTreeWidgetItem*> items;
02669 for (int i = 0; i < indexes.count(); ++i) {
02670 QTreeWidgetItem *item = d->item(indexes.at(i));
02671 if (!items.contains(item))
02672 items.append(item);
02673 }
02674 return items;
02675 }
02676
02680 QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFlags flags, int column) const
02681 {
02682 Q_D(const QTreeWidget);
02683 QModelIndexList indexes = d->model()->match(model()->index(0, column, QModelIndex()),
02684 Qt::DisplayRole, text, -1, flags);
02685 QList<QTreeWidgetItem*> items;
02686 for (int i = 0; i < indexes.size(); ++i)
02687 items.append(d->item(indexes.at(i)));
02688 return items;
02689 }
02690
02698 bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
02699 {
02700 Q_D(const QTreeWidget);
02701 if (item == d->model()->headerItem)
02702 return header()->isHidden();
02703 const QModelIndex index = d->index(item);
02704 return isRowHidden(index.row(), index.parent());
02705 }
02706
02716 void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
02717 {
02718 Q_D(QTreeWidget);
02719 if (item == d->model()->headerItem) {
02720 header()->setHidden(hide);
02721 } else {
02722 const QModelIndex index = d->index(item);
02723 setRowHidden(index.row(), index.parent(), hide);
02724 }
02725 }
02726
02736 bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const
02737 {
02738 Q_D(const QTreeWidget);
02739 return isExpanded(d->index(item));
02740 }
02741
02752 void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
02753 {
02754 Q_D(QTreeWidget);
02755 setExpanded(d->index(item), expand);
02756 }
02757
02764 void QTreeWidget::scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint)
02765 {
02766 Q_D(QTreeWidget);
02767 QTreeView::scrollTo(d->index(item), hint);
02768 }
02769
02776 void QTreeWidget::expandItem(const QTreeWidgetItem *item)
02777 {
02778 Q_D(QTreeWidget);
02779 expand(d->index(item));
02780 }
02781
02788 void QTreeWidget::collapseItem(const QTreeWidgetItem *item)
02789 {
02790 Q_D(QTreeWidget);
02791 collapse(d->index(item));
02792 }
02793
02803 void QTreeWidget::clear()
02804 {
02805 Q_D(QTreeWidget);
02806 selectionModel()->clear();
02807 d->model()->clear();
02808 }
02809
02816 QStringList QTreeWidget::mimeTypes() const
02817 {
02818 return model()->QAbstractItemModel::mimeTypes();
02819 }
02820
02829 QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*>) const
02830 {
02831 return d_func()->model()->internalMimeData();
02832 }
02833
02844 bool QTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index,
02845 const QMimeData *data, Qt::DropAction action)
02846 {
02847 QModelIndex idx;
02848 if (parent) idx = indexFromItem(parent);
02849 return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
02850 }
02851
02857 Qt::DropActions QTreeWidget::supportedDropActions() const
02858 {
02859 return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
02860 }
02861
02868 QList<QTreeWidgetItem*> QTreeWidget::items(const QMimeData *data) const
02869 {
02870 const QTreeWidgetMimeData *twd = qobject_cast<const QTreeWidgetMimeData*>(data);
02871 if (twd)
02872 return twd->items;
02873 return QList<QTreeWidgetItem*>();
02874 }
02875
02881 QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const
02882 {
02883 Q_D(const QTreeWidget);
02884 return d->index(item, column);
02885 }
02886
02892 QTreeWidgetItem *QTreeWidget::itemFromIndex(const QModelIndex &index) const
02893 {
02894 Q_D(const QTreeWidget);
02895 return d->item(index);
02896 }
02897
02898 #ifndef QT_NO_DRAGANDDROP
02899
02900 void QTreeWidget::dropEvent(QDropEvent *event) {
02901 Q_D(QTreeWidget);
02902 if (event->source() == this && (event->proposedAction() == Qt::MoveAction ||
02903 dragDropMode() == QAbstractItemView::InternalMove)) {
02904 QModelIndex topIndex;
02905 int col = -1;
02906 int row = -1;
02907 if (d->dropOn(event, &row, &col, &topIndex)) {
02908 QList<QModelIndex> idxs = selectedIndexes();
02909 QList<QPersistentModelIndex> indexes;
02910 for (int i = 0; i < idxs.count(); i++)
02911 indexes.append(idxs.at(i));
02912
02913 if (indexes.contains(topIndex))
02914 return;
02915
02916
02917 QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
02918
02919
02920 QList<QTreeWidgetItem *> taken;
02921 for (int i = indexes.count() - 1; i >= 0; --i) {
02922 QTreeWidgetItem *parent = itemFromIndex(indexes.at(i));
02923 if (!parent || !parent->parent()) {
02924 taken.append(takeTopLevelItem(indexes.at(i).row()));
02925 } else {
02926 taken.append(parent->parent()->takeChild(indexes.at(i).row()));
02927 }
02928 }
02929
02930
02931 for (int i = 0; i < indexes.count(); ++i) {
02932
02933 if (row == -1) {
02934 if (topIndex.isValid()) {
02935 QTreeWidgetItem *parent = itemFromIndex(topIndex);
02936 parent->insertChild(parent->childCount(), taken.takeFirst());
02937 } else {
02938 insertTopLevelItem(topLevelItemCount(), taken.takeFirst());
02939 }
02940 } else {
02941 int r = dropRow.row() >= 0 ? dropRow.row() : row;
02942 if (topIndex.isValid()) {
02943 QTreeWidgetItem *parent = itemFromIndex(topIndex);
02944 parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
02945 } else {
02946 insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst());
02947 }
02948 }
02949 }
02950
02951 event->accept();
02952
02953 event->setDropAction(Qt::CopyAction);
02954 }
02955 }
02956
02957 QTreeView::dropEvent(event);
02958 }
02959 #endif
02960
02965 void QTreeWidget::setModel(QAbstractItemModel * )
02966 {
02967 qFatal("QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed.");
02968 }
02969
02973 bool QTreeWidget::event(QEvent *e)
02974 {
02975 return QTreeView::event(e);
02976 }
02977
02978 #include "moc_qtreewidget.cpp"
02979 #endif // QT_NO_TREEWIDGET