src/gui/itemviews/qtreeview.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
child 18 2f34d5167611
--- a/src/gui/itemviews/qtreeview.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/gui/itemviews/qtreeview.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -215,6 +215,13 @@
     Q_D(QTreeView);
     if (model == d->model)
         return;
+    if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
+        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                this, SLOT(rowsRemoved(QModelIndex,int,int)));
+
+        disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
+    }
+
     if (d->selectionModel) { // support row editing
         disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
                    d->model, SLOT(submit()));
@@ -838,10 +845,10 @@
         // because otherwise it will not call sort on the model.
         sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
         connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
-                this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)), Qt::UniqueConnection);
+                this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
     } else {
         disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
-                   this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)));
+                   this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
     }
     d->sortingEnabled = enable;
 }
@@ -1226,8 +1233,12 @@
             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 +1433,9 @@
         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 +1760,8 @@
         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 +1851,7 @@
             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);
@@ -2116,6 +2120,12 @@
     if (vi < 0)
         vi = qMax(0, d->viewIndex(current));
 
+    if (isRightToLeft()) {
+        if (cursorAction == MoveRight)
+            cursorAction = MoveLeft;
+        else if (cursorAction == MoveLeft)
+            cursorAction = MoveRight;
+    }
     switch (cursorAction) {
     case MoveNext:
     case MoveDown:
@@ -2437,7 +2447,9 @@
         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 +2464,29 @@
                                                     ? 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 +2528,17 @@
                   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);
@@ -2740,6 +2774,7 @@
     d->executePostedLayout();
     if (d->viewItems.isEmpty())
         return -1;
+    ensurePolished();
     int w = 0;
     QStyleOptionViewItemV4 option = d->viewOptionsV4();
     const QVector<QTreeViewItem> viewItems = d->viewItems;
@@ -3127,7 +3162,7 @@
     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)) {
@@ -3135,17 +3170,25 @@
             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);
             }
         }
     }
@@ -3701,6 +3744,7 @@
 
         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);
@@ -3708,6 +3752,7 @@
             //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) {
@@ -3725,7 +3770,13 @@
             }
         }
 
+        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();