summaryrefslogtreecommitdiffstats
path: root/src/gui/itemviews/qtreeview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemviews/qtreeview.cpp')
-rw-r--r--src/gui/itemviews/qtreeview.cpp103
1 files changed, 71 insertions, 32 deletions
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 210534e916..3856293afd 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -1226,8 +1226,12 @@ bool QTreeView::viewportEvent(QEvent *event)
if (oldIndex != newIndex) {
QRect oldRect = visualRect(oldIndex);
QRect newRect = visualRect(newIndex);
- viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
- viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
+ oldRect.setLeft(oldRect.left() - d->indent);
+ newRect.setLeft(newRect.left() - d->indent);
+ //we need to paint the whole items (including the decoration) so that when the user
+ //moves the mouse over those elements they are updated
+ viewport()->update(oldRect);
+ viewport()->update(newRect);
}
}
if (selectionBehavior() == QAbstractItemView::SelectRows) {
@@ -1422,8 +1426,9 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
for (; i < viewItems.count() && y <= area.bottom(); ++i) {
const int itemHeight = d->itemHeight(i);
option.rect.setRect(0, y, viewportWidth, itemHeight);
- option.state = state | (viewItems.at(i).expanded
- ? QStyle::State_Open : QStyle::State_None);
+ option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
+ | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
+ | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
d->current = i;
d->spanning = viewItems.at(i).spanning;
if (!multipleRects || !drawn.contains(i)) {
@@ -1748,14 +1753,8 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect,
opt.rect = primitive;
const bool expanded = viewItem.expanded;
- const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children
- || d->hasVisibleChildren(index)); // not laid out yet, so we don't know
- bool moreSiblings = false;
- if (d->hiddenIndexes.isEmpty())
- moreSiblings = (d->model->rowCount(parent) - 1 > index.row());
- else
- moreSiblings = ((d->viewItems.size() > item +1)
- && (d->viewItems.at(item + 1).index.parent() == parent));
+ const bool children = viewItem.hasChildren;
+ bool moreSiblings = viewItem.hasMoreSiblings;
opt.state = QStyle::State_Item | extraFlags
| (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)
@@ -1845,9 +1844,7 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event)
return; // user clicked outside the items
const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
-
- int column = d->header->logicalIndexAt(event->x());
- QPersistentModelIndex persistent = firstColumnIndex.sibling(firstColumnIndex.row(), column);
+ const QPersistentModelIndex persistent = indexAt(event->pos());
if (d->pressedIndex != persistent) {
mousePressEvent(event);
@@ -2437,7 +2434,9 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
return;
}
- if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) {
+ const int parentRowCount = d->model->rowCount(parent);
+ const int delta = end - start + 1;
+ if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {
QAbstractItemView::rowsInserted(parent, start, end);
return;
}
@@ -2452,11 +2451,29 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
? d->viewItems.count()
: d->viewItems.at(parentItem).total) - 1;
- const int delta = end - start + 1;
+ if (parentRowCount == end + 1 && start > 0) {
+ //need to Update hasMoreSiblings
+ int previousRow = start - 1;
+ QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
+ bool isHidden = d->isRowHidden(previousSibilingModelIndex);
+ while (isHidden && previousRow > 0) {
+ previousRow--;
+ previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
+ isHidden = d->isRowHidden(previousSibilingModelIndex);
+ }
+ if (!isHidden) {
+ const int previousSibilling = d->viewIndex(previousSibilingModelIndex);
+ if(previousSibilling != -1)
+ d->viewItems[previousSibilling].hasMoreSiblings = true;
+ }
+ }
+
QVector<QTreeViewItem> insertedItems(delta);
for (int i = 0; i < delta; ++i) {
insertedItems[i].index = d->model->index(i + start, 0, parent);
insertedItems[i].level = childLevel;
+ insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index);
+ insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
}
if (d->viewItems.isEmpty())
d->defaultItemHeight = indexRowSizeHint(insertedItems[0].index);
@@ -2498,13 +2515,17 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
d->viewItems.begin() + insertPos + 1);
}
+ if (parentItem != -1)
+ d->viewItems[parentItem].hasChildren = true;
d->updateChildCount(parentItem, delta);
+
updateGeometries();
viewport()->update();
} else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) {
d->doDelayedItemsLayout();
} else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
- // the parent just went from 0 children to having some update to re-paint the decoration
+ // the parent just went from 0 children to more. update to re-paint the decoration
+ d->viewItems[parentItem].hasChildren = true;
viewport()->update();
}
QAbstractItemView::rowsInserted(parent, start, end);
@@ -2908,6 +2929,8 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
layout(item);
q->setState(oldState);
+ if (model->canFetchMore(index))
+ model->fetchMore(index);
if (emitSignal) {
emit q->expanded(index);
#ifndef QT_NO_ANIMATION
@@ -2915,8 +2938,6 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
beginAnimatedOperation();
#endif //QT_NO_ANIMATION
}
- if (model->canFetchMore(index))
- model->fetchMore(index);
}
void QTreeViewPrivate::collapse(int item, bool emitSignal)
@@ -3005,10 +3026,12 @@ void QTreeViewPrivate::beginAnimatedOperation()
animatedOperation.setEndValue(animatedOperation.top() + h);
}
- animatedOperation.after = renderTreeToPixmapForAnimation(rect);
+ if (!rect.isEmpty()) {
+ animatedOperation.after = renderTreeToPixmapForAnimation(rect);
- q->setState(QAbstractItemView::AnimatingState);
- animatedOperation.start(); //let's start the animation
+ q->setState(QAbstractItemView::AnimatingState);
+ animatedOperation.start(); //let's start the animation
+ }
}
void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
@@ -3125,7 +3148,7 @@ void QTreeViewPrivate::layout(int i)
int hidden = 0;
int last = 0;
int children = 0;
-
+ QTreeViewItem *item = 0;
for (int j = first; j < first + count; ++j) {
current = model->index(j - first, 0, parent);
if (isRowHidden(current)) {
@@ -3133,17 +3156,25 @@ void QTreeViewPrivate::layout(int i)
last = j - hidden + children;
} else {
last = j - hidden + children;
- viewItems[last].index = current;
- viewItems[last].level = level;
- viewItems[last].height = 0;
- viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent);
- viewItems[last].expanded = false;
- viewItems[last].total = 0;
+ if (item)
+ item->hasMoreSiblings = true;
+ item = &viewItems[last];
+ item->index = current;
+ item->level = level;
+ item->height = 0;
+ item->spanning = q->isFirstColumnSpanned(current.row(), parent);
+ item->expanded = false;
+ item->total = 0;
+ item->hasMoreSiblings = false;
if (isIndexExpanded(current)) {
- viewItems[last].expanded = true;
+ item->expanded = true;
layout(last);
- children += viewItems[last].total;
+ item = &viewItems[last];
+ children += item->total;
+ item->hasChildren = item->total > 0;
last = j - hidden + children;
+ } else {
+ item->hasChildren = hasVisibleChildren(current);
}
}
}
@@ -3699,6 +3730,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
const int delta = end - start + 1;
+ int previousSibiling = -1;
int removedCount = 0;
for (int item = firstChildItem; item <= lastChildItem; ) {
Q_ASSERT(viewItems.at(item).level == childLevel);
@@ -3706,6 +3738,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
//Q_ASSERT(modelIndex.parent() == parent);
const int count = viewItems.at(item).total + 1;
if (modelIndex.row() < start) {
+ previousSibiling = item;
// not affected by the removal
item += count;
} else if (modelIndex.row() <= end) {
@@ -3723,7 +3756,13 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
}
}
+ if (previousSibiling != -1 && after && model->rowCount(parent) == start)
+ viewItems[previousSibiling].hasMoreSiblings = false;
+
+
updateChildCount(parentItem, -removedCount);
+ if (parentItem != -1 && viewItems.at(parentItem).total == 0)
+ viewItems[parentItem].hasChildren = false; //every children have been removed;
if (after) {
q->updateGeometries();
viewport->update();