Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/itemviews/qtreeview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6767    \ingroup model-view
    6868    \ingroup advanced
    69     \mainclass
     69
    7070
    7171    A QTreeView implements a tree representation of items from a
     
    216216    if (model == d->model)
    217217        return;
     218    if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
     219        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
     220                this, SLOT(rowsRemoved(QModelIndex,int,int)));
     221
     222        disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
     223    }
     224
    218225    if (d->selectionModel) { // support row editing
    219226        disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    239246            this, SLOT(rowsRemoved(QModelIndex,int,int)));
    240247
    241     connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
    242             this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
    243     connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
    244             this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
    245 
    246248    connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
    247249
    248250    if (d->sortingEnabled)
    249         sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
     251        d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
    250252}
    251253
     
    268270    Q_ASSERT(selectionModel);
    269271    if (d->selectionModel) {
    270         if (d->allColumnsShowFocus) {
    271             QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    272                                 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    273         }
    274272        // support row editing
    275273        disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    281279
    282280    if (d->selectionModel) {
    283         if (d->allColumnsShowFocus) {
    284             QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    285                              this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    286         }
    287281        // support row editing
    288282        connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    681675    // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway
    682676
    683     QModelIndex top = topLeft.sibling(topLeft.row(), 0);
    684     int topViewIndex = d->viewIndex(top);
     677    int topViewIndex = d->viewIndex(topLeft);
    685678    if (topViewIndex == 0)
    686         d->defaultItemHeight = indexRowSizeHint(top);
     679        d->defaultItemHeight = indexRowSizeHint(topLeft);
    687680    bool sizeChanged = false;
    688681    if (topViewIndex != -1) {
     
    692685            sizeChanged = (oldHeight != d->itemHeight(topViewIndex));
    693686        } else {
    694             QModelIndex bottom = bottomRight.sibling(bottomRight.row(), 0);
    695             int bottomViewIndex = d->viewIndex(bottom);
     687            int bottomViewIndex = d->viewIndex(bottomRight);
    696688            for (int i = topViewIndex; i <= bottomViewIndex; ++i) {
    697689                int oldHeight = d->itemHeight(i);
     
    847839{
    848840    Q_D(QTreeView);
    849     d->sortingEnabled = enable;
    850841    header()->setSortIndicatorShown(enable);
    851842    header()->setClickable(enable);
    852843    if (enable) {
     844        //sortByColumn has to be called before we connect or set the sortingEnabled flag
     845        // because otherwise it will not call sort on the model.
     846        sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
    853847        connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    854                 this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)));
    855         sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
     848                this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
    856849    } else {
    857850        disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    858                    this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)));
    859     }
     851                   this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
     852    }
     853    d->sortingEnabled = enable;
    860854}
    861855
     
    907901    if (d->allColumnsShowFocus == enable)
    908902        return;
    909     if (d->selectionModel) {
    910         if (enable) {
    911             QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    912                              this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    913         } else {
    914             QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    915                                 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    916         }
    917     }
    918903    d->allColumnsShowFocus = enable;
    919904    d->viewport->update();
     
    11181103            verticalScrollBar()->setValue(item);
    11191104        } else { // PositionAtBottom or PositionAtCenter
    1120             int itemLocation = item;
     1105            const int currentItemHeight = d->itemHeight(item);
    11211106            int y = (hint == PositionAtCenter
    1122                      ? area.height() / 2
     1107                 //we center on the current item with a preference to the top item (ie. -1)
     1108                     ? area.height() / 2 + currentItemHeight - 1
     1109                 //otherwise we simply take the whole space
    11231110                     : area.height());
    1124             while (y > 0 && item > 0)
    1125                 y -= d->itemHeight(item--);
    1126             // end up half over the top of the area
    1127             if (y < 0 && item < itemLocation)
    1128                 ++item;
    1129             // end up half over the bottom of the area
    1130             if (item >= 0 && item < itemLocation)
    1131                 ++item;
     1111            if (y > currentItemHeight) {
     1112                while (item >= 0) {
     1113                    y -= d->itemHeight(item);
     1114                    if (y < 0) { //there is no more space left
     1115                        item++;
     1116                        break;
     1117                    }
     1118                    item--;
     1119                }
     1120            }
    11321121            verticalScrollBar()->setValue(item);
    11331122        }
     
    11411130            // nothing to do
    11421131        } else if (hint == EnsureVisible && area.contains(rect)) {
    1143             d->setDirtyRegion(rect);
     1132            d->viewport->update(rect);
    11441133            // nothing to do
    11451134        } else {
     
    12451234                QRect oldRect = visualRect(oldIndex);
    12461235                QRect newRect = visualRect(newIndex);
    1247                 viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
    1248                 viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
     1236                oldRect.setLeft(oldRect.left() - d->indent);
     1237                newRect.setLeft(newRect.left() - d->indent);
     1238                //we need to paint the whole items (including the decoration) so that when the user
     1239                //moves the mouse over those elements they are updated
     1240                viewport()->update(oldRect);
     1241                viewport()->update(newRect);
    12491242            }
    12501243        }
     
    12731266    d->executePostedLayout();
    12741267    QPainter painter(viewport());
     1268#ifndef QT_NO_ANIMATION
    12751269    if (d->isAnimating()) {
    1276         drawTree(&painter, event->region() - d->animationRect());
     1270        drawTree(&painter, event->region() - d->animatedOperation.rect());
    12771271        d->drawAnimatedOperation(&painter);
    1278     } else {
     1272    } else
     1273#endif //QT_NO_ANIMATION
     1274    {
    12791275        drawTree(&painter, event->region());
    12801276#ifndef QT_NO_DRAGANDDROP
     
    13121308    Q_Q(QTreeView);
    13131309    // we want to handle mousePress in EditingState (persistent editors)
    1314     if ((q->state() != QAbstractItemView::NoState
    1315                 && q->state() != QAbstractItemView::EditingState)
     1310    if ((state != QAbstractItemView::NoState
     1311                && state != QAbstractItemView::EditingState)
    13161312                || !viewport->rect().contains(pos))
    13171313        return true;
    13181314
    13191315    int i = itemDecorationAt(pos);
    1320     if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) {
     1316    if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {
    13211317        if (viewItems.at(i).expanded)
    13221318            collapse(i, true);
     
    13251321        if (!isAnimating()) {
    13261322            q->updateGeometries();
    1327             q->viewport()->update();
     1323            viewport->update();
    13281324        }
    13291325        return true;
     
    13391335    QAbstractItemViewPrivate::_q_modelDestroyed();
    13401336}
     1337
     1338/*!
     1339  \reimp
     1340
     1341  We have a QTreeView way of knowing what elements are on the viewport
     1342*/
     1343QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
     1344{
     1345    Q_ASSERT(r);
     1346    return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);
     1347    Q_Q(const QTreeView);
     1348    QRect &rect = *r;
     1349    const QRect viewportRect = viewport->rect();
     1350    int itemOffset = 0;
     1351    int row = firstVisibleItem(&itemOffset);
     1352    QPair<int, int> startEnd = startAndEndColumns(viewportRect);
     1353    QVector<int> columns;
     1354    for (int i = startEnd.first; i <= startEnd.second; ++i) {
     1355        int logical = header->logicalIndex(i);
     1356        if (!header->isSectionHidden(logical))
     1357            columns += logical;
     1358    }
     1359    QSet<QModelIndex> visibleIndexes;
     1360    for (; itemOffset < viewportRect.bottom() && row < viewItems.count(); ++row) {
     1361        const QModelIndex &index = viewItems.at(row).index;
     1362        for (int colIndex = 0; colIndex < columns.count(); ++colIndex)
     1363            visibleIndexes += index.sibling(index.row(), columns.at(colIndex));
     1364        itemOffset += itemHeight(row);
     1365    }
     1366
     1367    //now that we have the visible indexes, we can try to find those which are selected
     1368    QItemViewPaintPairs ret;
     1369    for (int i = 0; i < indexes.count(); ++i) {
     1370        const QModelIndex &index = indexes.at(i);
     1371        if (visibleIndexes.contains(index)) {
     1372            const QRect current = q->visualRect(index);
     1373            ret += qMakePair(current, index);
     1374            rect |= current;
     1375        }
     1376    }
     1377    rect &= viewportRect;
     1378    return ret;
     1379}
     1380
    13411381
    13421382/*!
     
    13941434            const int itemHeight = d->itemHeight(i);
    13951435            option.rect.setRect(0, y, viewportWidth, itemHeight);
    1396             option.state = state | (viewItems.at(i).expanded
    1397                                     ? QStyle::State_Open : QStyle::State_None);
     1436            option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
     1437                                 | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
     1438                                 | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
    13981439            d->current = i;
    13991440            d->spanning = viewItems.at(i).spanning;
     
    15471588                                 : logicalIndices.at(currentLogicalSection - 1);
    15481589        if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
    1549             || (headerSection == 0 && nextLogicalSection == -1))
     1590            || (headerSection == 0 && nextLogicalSection == -1) || spanning)
    15501591            opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
    15511592        else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1))
     
    17201761
    17211762        const bool expanded = viewItem.expanded;
    1722         const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children
    1723                                 || d->hasVisibleChildren(index)); // not laid out yet, so we don't know
    1724         bool moreSiblings = false;
    1725         if (d->hiddenIndexes.isEmpty())
    1726             moreSiblings = (d->model->rowCount(parent) - 1 > index.row());
    1727         else
    1728             moreSiblings = ((d->viewItems.size() > item +1)
    1729                             && (d->viewItems.at(item + 1).index.parent() == parent));
     1763        const bool children = viewItem.hasChildren;
     1764        bool moreSiblings = viewItem.hasMoreSiblings;
    17301765
    17311766        opt.state = QStyle::State_Item | extraFlags
     
    18161851            return; // user clicked outside the items
    18171852
    1818         const QModelIndex &index = d->viewItems.at(i).index;
    1819 
    1820         int column = d->header->logicalIndexAt(event->x());
    1821         QPersistentModelIndex persistent = index.sibling(index.row(), column);
     1853        const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
     1854        const QPersistentModelIndex persistent = indexAt(event->pos());
    18221855
    18231856        if (d->pressedIndex != persistent) {
     
    18421875            && d->expandsOnDoubleClick
    18431876            && d->hasVisibleChildren(persistent)) {
    1844             if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == persistent))) {
     1877            if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {
    18451878                // find the new index of the item
    18461879                for (i = 0; i < d->viewItems.count(); ++i) {
    1847                     if (d->viewItems.at(i).index == persistent)
     1880                    if (d->viewItems.at(i).index == firstColumnIndex)
    18481881                        break;
    18491882                }
     
    20732106            int index = useTopIndex ? INT_MAX : INT_MIN;
    20742107            const QItemSelection selection = d->selectionModel->selection();
    2075             foreach (const QItemSelectionRange &range, selection) {
     2108            for (int i = 0; i < selection.count(); ++i) {
     2109                const QItemSelectionRange &range = selection.at(i);
    20762110                int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight());
    20772111                if (candidate >= 0)
     
    20872121        vi = qMax(0, d->viewIndex(current));
    20882122
     2123    if (isRightToLeft()) {
     2124        if (cursorAction == MoveRight)
     2125            cursorAction = MoveLeft;
     2126        else if (cursorAction == MoveLeft)
     2127            cursorAction = MoveRight;
     2128    }
    20892129    switch (cursorAction) {
    20902130    case MoveNext:
     
    24082448    }
    24092449
    2410     if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) {
     2450    const int parentRowCount = d->model->rowCount(parent);
     2451    const int delta = end - start + 1;
     2452    if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {
    24112453        QAbstractItemView::rowsInserted(parent, start, end);
    24122454        return;
     
    24232465                                                    : d->viewItems.at(parentItem).total) - 1;
    24242466
    2425         int firstColumn = 0;
    2426         while (isColumnHidden(firstColumn) && firstColumn < header()->count() - 1)
    2427             ++firstColumn;
    2428 
    2429         const int delta = end - start + 1;
     2467        if (parentRowCount == end + 1 && start > 0) {
     2468            //need to Update hasMoreSiblings
     2469            int previousRow = start - 1;
     2470            QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
     2471            bool isHidden = d->isRowHidden(previousSibilingModelIndex);
     2472            while (isHidden && previousRow > 0) {
     2473                previousRow--;
     2474                previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
     2475                isHidden = d->isRowHidden(previousSibilingModelIndex);
     2476            }
     2477            if (!isHidden) {
     2478                const int previousSibilling = d->viewIndex(previousSibilingModelIndex);
     2479                if(previousSibilling != -1)
     2480                    d->viewItems[previousSibilling].hasMoreSiblings = true;
     2481            }
     2482        }
     2483
    24302484        QVector<QTreeViewItem> insertedItems(delta);
    24312485        for (int i = 0; i < delta; ++i) {
    2432             insertedItems[i].index = d->model->index(i + start, firstColumn, parent);
     2486            insertedItems[i].index = d->model->index(i + start, 0, parent);
    24332487            insertedItems[i].level = childLevel;
     2488            insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index);
     2489            insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
    24342490        }
    24352491        if (d->viewItems.isEmpty())
     
    24732529        }
    24742530
     2531        if (parentItem != -1)
     2532            d->viewItems[parentItem].hasChildren = true;
    24752533        d->updateChildCount(parentItem, delta);
     2534
    24762535        updateGeometries();
    24772536        viewport()->update();
     
    24792538        d->doDelayedItemsLayout();
    24802539    } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
    2481         // the parent just went from 0 children to having some update to re-paint the decoration
     2540        // the parent just went from 0 children to more. update to re-paint the decoration
     2541        d->viewItems[parentItem].hasChildren = true;
    24822542        viewport()->update();
    24832543    }
     
    26132673        d->layout(i);
    26142674        QModelIndex idx = d->viewItems.at(i).index;
    2615         d->expandedIndexes.insert(idx.sibling(idx.row(), 0));
     2675        d->expandedIndexes.insert(idx);
    26162676    }
    26172677    updateGeometries();
     
    27152775    if (d->viewItems.isEmpty())
    27162776        return -1;
     2777    ensurePolished();
    27172778    int w = 0;
    27182779    QStyleOptionViewItemV4 option = d->viewOptionsV4();
     
    27722833    if (isRightToLeft()) {
    27732834        start = (start == -1 ? count - 1 : start);
    2774         end = (end == -1 ? 0 : end);
     2835        end = 0;
    27752836    } else {
    27762837        start = (start == -1 ? 0 : start);
    2777         end = (end == -1 ? count - 1 : end);
    2778     }
    2779 
    2780     int tmp = start;
    2781     start = qMin(start, end);
    2782     end = qMax(tmp, end);
     2838        end = count - 1;
     2839    }
     2840
     2841    if (end < start)
     2842        qSwap(end, start);
    27832843
    27842844    int height = -1;
     
    28282888
    28292889/*!
    2830   \reimp
     2890  \internal
    28312891*/
    28322892void QTreeView::horizontalScrollbarAction(int action)
     
    28602920    header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
    28612921    q->setHeader(header);
    2862 
    2863     // animation
    2864     QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate()));
    2865     QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection);
     2922#ifndef QT_NO_ANIMATION
     2923    QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
     2924#endif //QT_NO_ANIMATION
    28662925}
    28672926
     
    28732932        return;
    28742933
     2934#ifndef QT_NO_ANIMATION
    28752935    if (emitSignal && animationsEnabled)
    2876         prepareAnimatedOperation(item, AnimatedOperation::Expand);
    2877 
    2878     QAbstractItemView::State oldState = q->state();
     2936        prepareAnimatedOperation(item, QVariantAnimation::Forward);
     2937#endif //QT_NO_ANIMATION
     2938    QAbstractItemView::State oldState = state;
    28792939    q->setState(QAbstractItemView::ExpandingState);
    28802940    const QModelIndex index = viewItems.at(item).index;
     
    28842944    q->setState(oldState);
    28852945
     2946    if (model->canFetchMore(index))
     2947        model->fetchMore(index);
    28862948    if (emitSignal) {
    28872949        emit q->expanded(index);
     2950#ifndef QT_NO_ANIMATION
    28882951        if (animationsEnabled)
    28892952            beginAnimatedOperation();
    2890     }
    2891     if (model->canFetchMore(index))
    2892         model->fetchMore(index);
     2953#endif //QT_NO_ANIMATION
     2954    }
    28932955}
    28942956
     
    29112973        return; // nothing to do
    29122974
     2975#ifndef QT_NO_ANIMATION
    29132976    if (emitSignal && animationsEnabled)
    2914         prepareAnimatedOperation(item, AnimatedOperation::Collapse);
    2915 
    2916     QAbstractItemView::State oldState = q->state();
     2977        prepareAnimatedOperation(item, QVariantAnimation::Backward);
     2978#endif //QT_NO_ANIMATION
     2979
     2980    QAbstractItemView::State oldState = state;
    29172981    q->setState(QAbstractItemView::CollapsingState);
    29182982    expandedIndexes.erase(it);
     
    29312995    if (emitSignal) {
    29322996        emit q->collapsed(modelIndex);
     2997#ifndef QT_NO_ANIMATION
    29332998        if (animationsEnabled)
    29342999            beginAnimatedOperation();
    2935     }
    2936 }
    2937 
    2938 void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type)
     3000#endif //QT_NO_ANIMATION
     3001    }
     3002}
     3003
     3004#ifndef QT_NO_ANIMATION
     3005void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction)
    29393006{
    29403007    animatedOperation.item = item;
    2941     animatedOperation.type = type;
     3008    animatedOperation.viewport = viewport;
     3009    animatedOperation.setDirection(direction);
    29423010
    29433011    int top = coordinateForItem(item) + itemHeight(item);
    29443012    QRect rect = viewport->rect();
    29453013    rect.setTop(top);
    2946     if (type == AnimatedOperation::Collapse) {
     3014    if (direction == QVariantAnimation::Backward) {
    29473015        const int limit = rect.height() * 2;
    29483016        int h = 0;
     
    29513019            h += itemHeight(i);
    29523020        rect.setHeight(h);
    2953         animatedOperation.duration = h;
    2954     }
    2955     animatedOperation.top = top;
     3021        animatedOperation.setEndValue(top + h);
     3022    }
     3023    animatedOperation.setStartValue(top);
    29563024    animatedOperation.before = renderTreeToPixmapForAnimation(rect);
    29573025}
     
    29623030
    29633031    QRect rect = viewport->rect();
    2964     rect.setTop(animatedOperation.top);
    2965     if (animatedOperation.type == AnimatedOperation::Expand) {
     3032    rect.setTop(animatedOperation.top());
     3033    if (animatedOperation.direction() == QVariantAnimation::Forward) {
    29663034        const int limit = rect.height() * 2;
    29673035        int h = 0;
     
    29703038            h += itemHeight(i);
    29713039        rect.setHeight(h);
    2972         animatedOperation.duration = h;
    2973     }
    2974 
    2975     animatedOperation.after = renderTreeToPixmapForAnimation(rect);
    2976 
    2977     q->setState(QAbstractItemView::AnimatingState);
    2978 
    2979     timeline.stop();
    2980     timeline.setDuration(250);
    2981     timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration);
    2982     timeline.start();
    2983 }
    2984 
    2985 void QTreeViewPrivate::_q_endAnimatedOperation()
    2986 {
    2987     Q_Q(QTreeView);
    2988     animatedOperation.before = QPixmap();
    2989     animatedOperation.after = QPixmap();
    2990     q->setState(QAbstractItemView::NoState);
    2991     q->updateGeometries();
    2992     viewport->update();
    2993 }
    2994 
    2995 void QTreeViewPrivate::_q_animate()
    2996 {
    2997     QRect rect = viewport->rect();
    2998     rect.moveTop(animatedOperation.top);
    2999     viewport->repaint(rect);
     3040        animatedOperation.setEndValue(animatedOperation.top() + h);
     3041    }
     3042
     3043    if (!rect.isEmpty()) {
     3044        animatedOperation.after = renderTreeToPixmapForAnimation(rect);
     3045
     3046        q->setState(QAbstractItemView::AnimatingState);
     3047        animatedOperation.start(); //let's start the animation
     3048    }
    30003049}
    30013050
    30023051void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
    30033052{
    3004     int start = timeline.startFrame();
    3005     int end = timeline.endFrame();
    3006     bool collapsing = animatedOperation.type == AnimatedOperation::Collapse;
    3007     int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame();
     3053    const int start = animatedOperation.startValue().toInt(),
     3054        end = animatedOperation.endValue().toInt(),
     3055        current = animatedOperation.currentValue().toInt();
     3056    bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;
    30083057    const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;
    30093058    painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());
     
    30483097}
    30493098
    3050 void QTreeViewPrivate::_q_currentChanged(const QModelIndex &current, const QModelIndex &previous)
     3099void QTreeViewPrivate::_q_endAnimatedOperation()
    30513100{
    30523101    Q_Q(QTreeView);
    3053     if (previous.isValid()) {
    3054         QRect previousRect = q->visualRect(previous);
    3055         if (allColumnsShowFocus) {
    3056             previousRect.setX(0);
    3057             previousRect.setWidth(viewport->width());
    3058         }
    3059         viewport->update(previousRect);
    3060     }
    3061     if (current.isValid()) {
    3062         QRect currentRect = q->visualRect(current);
    3063         if (allColumnsShowFocus) {
    3064             currentRect.setX(0);
    3065             currentRect.setWidth(viewport->width());
    3066         }
    3067         viewport->update(currentRect);
    3068     }
    3069 }
     3102    q->setState(QAbstractItemView::NoState);
     3103    q->updateGeometries();
     3104    viewport->update();
     3105}
     3106#endif //QT_NO_ANIMATION
    30703107
    30713108void QTreeViewPrivate::_q_modelAboutToBeReset()
     
    30763113void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
    30773114{
    3078     Q_UNUSED(parent);
    30793115    if (start <= 0 && 0 <= end)
    30803116        viewItems.clear();
     3117    QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);
    30813118}
    30823119
    30833120void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)
    30843121{
    3085     Q_UNUSED(parent);
    30863122    if (start <= 0 && 0 <= end)
    30873123        doDelayedItemsLayout();
     3124    QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
    30883125}
    30893126
     
    30933130    QModelIndex current;
    30943131    QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i);
    3095     // modelIndex() will return an index that don't have a parent if column 0 is hidden,
    3096     // so we must make sure that parent points to the actual parent that has children.
    3097     if (parent != root)
    3098         parent = model->index(parent.row(), 0, parent.parent());
    30993132
    31003133    if (i>=0 && !parent.isValid()) {
     
    31303163    int last = 0;
    31313164    int children = 0;
    3132 
    3133     int firstColumn = 0;
    3134     while (header->isSectionHidden(firstColumn) && firstColumn < header->count())
    3135         ++firstColumn;
    3136 
     3165    QTreeViewItem *item = 0;
    31373166    for (int j = first; j < first + count; ++j) {
    3138         current = model->index(j - first, firstColumn, parent);
    3139         if (isRowHidden(current.sibling(current.row(), 0))) {
     3167        current = model->index(j - first, 0, parent);
     3168        if (isRowHidden(current)) {
    31403169            ++hidden;
    31413170            last = j - hidden + children;
    31423171        } else {
    31433172            last = j - hidden + children;
    3144             viewItems[last].index = current;
    3145             viewItems[last].level = level;
    3146             viewItems[last].height = 0;
    3147             viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent);
    3148             viewItems[last].expanded = false;
    3149             viewItems[last].total = 0;
     3173            if (item)
     3174                item->hasMoreSiblings = true;
     3175            item = &viewItems[last];
     3176            item->index = current;
     3177            item->level = level;
     3178            item->height = 0;
     3179            item->spanning = q->isFirstColumnSpanned(current.row(), parent);
     3180            item->expanded = false;
     3181            item->total = 0;
     3182            item->hasMoreSiblings = false;
    31503183            if (isIndexExpanded(current)) {
    3151                 viewItems[last].expanded = true;
     3184                item->expanded = true;
    31523185                layout(last);
    3153                 children += viewItems[last].total;
     3186                item = &viewItems[last];
     3187                children += item->total;
     3188                item->hasChildren = item->total > 0;
    31543189                last = j - hidden + children;
     3190            } else {
     3191                item->hasChildren = hasVisibleChildren(current);
    31553192            }
    31563193        }
     
    32183255int QTreeViewPrivate::coordinateForItem(int item) const
    32193256{
    3220     Q_Q(const QTreeView);
    32213257    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
    32223258        if (uniformRowHeights)
    3223             return (item * defaultItemHeight) - q->verticalScrollBar()->value();
     3259            return (item * defaultItemHeight) - vbar->value();
    32243260        // ### optimize (spans or caching)
    32253261        int y = 0;
    32263262        for (int i = 0; i < viewItems.count(); ++i) {
    32273263            if (i == item)
    3228                 return y - q->verticalScrollBar()->value();
     3264                return y - vbar->value();
    32293265            y += itemHeight(i);
    32303266        }
    32313267    } else { // ScrollPerItem
    3232         int topViewItemIndex = q->verticalScrollBar()->value();
     3268        int topViewItemIndex = vbar->value();
    32333269        if (uniformRowHeights)
    32343270            return defaultItemHeight * (item - topViewItemIndex);
     
    32703306int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
    32713307{
    3272     Q_Q(const QTreeView);
    32733308    const int itemCount = viewItems.count();
    32743309    if (itemCount == 0)
     
    32783313    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
    32793314        if (uniformRowHeights) {
    3280             const int viewItemIndex = (coordinate + q->verticalScrollBar()->value()) / defaultItemHeight;
     3315            const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight;
    32813316            return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
    32823317        }
    32833318        // ### optimize
    32843319        int viewItemCoordinate = 0;
    3285         const int contentsCoordinate = coordinate + q->verticalScrollBar()->value();
     3320        const int contentsCoordinate = coordinate + vbar->value();
    32863321        for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {
    32873322            viewItemCoordinate += itemHeight(viewItemIndex);
     
    32903325        }
    32913326    } else { // ScrollPerItem
    3292         int topViewItemIndex = q->verticalScrollBar()->value();
     3327        int topViewItemIndex = vbar->value();
    32933328        if (uniformRowHeights) {
    32943329            if (coordinate < 0)
     
    33203355int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const
    33213356{
    3322     Q_Q(const QTreeView);
    33233357    if (!_index.isValid() || viewItems.isEmpty())
    33243358        return -1;
    33253359
    33263360    const int totalCount = viewItems.count();
    3327     int firstColumn = 0;
    3328     while (q->isColumnHidden(firstColumn) && firstColumn < header->count())
    3329         ++firstColumn;
    3330     const QModelIndex index = _index.sibling(_index.row(), firstColumn);
     3361    const QModelIndex index = _index.sibling(_index.row(), 0);
    33313362
    33323363
     
    33863417int QTreeViewPrivate::firstVisibleItem(int *offset) const
    33873418{
    3388     Q_Q(const QTreeView);
    3389     const int value = q->verticalScrollBar()->value();
     3419    const int value = vbar->value();
    33903420    if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
    33913421        if (offset)
     
    34643494        if (!viewItems.isEmpty())
    34653495            itemsInViewport = qMax(1, itemsInViewport);
    3466         q->verticalScrollBar()->setRange(0, viewItems.count() - itemsInViewport);
    3467         q->verticalScrollBar()->setPageStep(itemsInViewport);
    3468         q->verticalScrollBar()->setSingleStep(1);
     3496        vbar->setRange(0, viewItems.count() - itemsInViewport);
     3497        vbar->setPageStep(itemsInViewport);
     3498        vbar->setSingleStep(1);
    34693499    } else { // scroll per pixel
    34703500        int contentsHeight = 0;
     
    34753505                contentsHeight += itemHeight(i);
    34763506        }
    3477         q->verticalScrollBar()->setRange(0, contentsHeight - viewportSize.height());
    3478         q->verticalScrollBar()->setPageStep(viewportSize.height());
    3479         q->verticalScrollBar()->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
     3507        vbar->setRange(0, contentsHeight - viewportSize.height());
     3508        vbar->setPageStep(viewportSize.height());
     3509        vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
    34803510    }
    34813511
     
    34933523        columnsInViewport = qMax(1, columnsInViewport);
    34943524    if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) {
    3495         q->horizontalScrollBar()->setRange(0, columnCount - columnsInViewport);
    3496         q->horizontalScrollBar()->setPageStep(columnsInViewport);
    3497         q->horizontalScrollBar()->setSingleStep(1);
     3525        hbar->setRange(0, columnCount - columnsInViewport);
     3526        hbar->setPageStep(columnsInViewport);
     3527        hbar->setSingleStep(1);
    34983528    } else { // scroll per pixel
    34993529        const int horizontalLength = header->length();
    35003530        const QSize maxSize = q->maximumViewportSize();
    3501         if (maxSize.width() >= horizontalLength && q->verticalScrollBar()->maximum() <= 0)
     3531        if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0)
    35023532            viewportSize = maxSize;
    3503         q->horizontalScrollBar()->setPageStep(viewportSize.width());
    3504         q->horizontalScrollBar()->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
    3505         q->horizontalScrollBar()->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
     3533        hbar->setPageStep(viewportSize.width());
     3534        hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
     3535        hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
    35063536    }
    35073537}
     
    35093539int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
    35103540{
    3511     const_cast<QTreeView *>(q_func())->executeDelayedItemsLayout();
     3541    executePostedLayout();
    35123542    int x = pos.x();
    35133543    int column = header->logicalIndexAt(x);
     
    35753605    current.first = -2; // -1 is not enough because -1+1 = 0
    35763606    current.second = -2;
    3577     foreach (int logicalColumn, logicalIndexes) {
     3607    for(int i = 0; i < logicalIndexes.count(); ++i) {
     3608        const int logicalColumn = logicalIndexes.at(i);
    35783609        if (current.second + 1 != logicalColumn) {
    35793610            if (current.first != -2) {
     
    37143745        const int delta = end - start + 1;
    37153746
     3747        int previousSibiling = -1;
    37163748        int removedCount = 0;
    37173749        for (int item = firstChildItem; item <= lastChildItem; ) {
     
    37213753            const int count = viewItems.at(item).total + 1;
    37223754            if (modelIndex.row() < start) {
     3755                previousSibiling = item;
    37233756                // not affected by the removal
    37243757                item += count;
     
    37383771        }
    37393772
     3773        if (previousSibiling != -1 && after && model->rowCount(parent) == start)
     3774            viewItems[previousSibiling].hasMoreSiblings = false;
     3775
     3776
    37403777        updateChildCount(parentItem, -removedCount);
     3778        if (parentItem != -1 && viewItems.at(parentItem).total == 0)
     3779            viewItems[parentItem].hasChildren = false; //every children have been removed;
    37413780        if (after) {
    37423781            q->updateGeometries();
     
    38103849#endif
    38113850    QAbstractItemView::currentChanged(current, previous);
     3851
     3852    if (allColumnsShowFocus()) {
     3853        if (previous.isValid()) {
     3854            QRect previousRect = visualRect(previous);
     3855            previousRect.setX(0);
     3856            previousRect.setWidth(viewport()->width());
     3857            viewport()->update(previousRect);
     3858        }
     3859        if (current.isValid()) {
     3860            QRect currentRect = visualRect(current);
     3861            currentRect.setX(0);
     3862            currentRect.setWidth(viewport()->width());
     3863            viewport()->update(currentRect);
     3864        }
     3865    }
    38123866}
    38133867
Note: See TracChangeset for help on using the changeset viewer.