/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtreeview.h"

#include <qheaderview.h>
#include <qitemdelegate.h>
#include <qapplication.h>
#include <qscrollbar.h>
#include <qpainter.h>
#include <qstack.h>
#include <qstyle.h>
#include <qstyleoption.h>
#include <qevent.h>
#include <qpen.h>
#include <qdebug.h>
#include <QMetaMethod>
#include <private/qscrollbar_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif

#include <private/qapplication_p.h>
#include <private/qtreeview_p.h>
#include <private/qheaderview_p.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
    \class QTreeView
    \brief The QTreeView class provides a default model/view implementation of a tree view.

    \ingroup model-view
    \ingroup advanced
    \inmodule QtWidgets

    \image windows-treeview.png

    A QTreeView implements a tree representation of items from a
    model. This class is used to provide standard hierarchical lists that
    were previously provided by the \c QListView class, but using the more
    flexible approach provided by Qt's model/view architecture.

    The QTreeView class is one of the \l{Model/View Classes} and is part of
    Qt's \l{Model/View Programming}{model/view framework}.

    QTreeView implements the interfaces defined by the
    QAbstractItemView class to allow it to display data provided by
    models derived from the QAbstractItemModel class.

    It is simple to construct a tree view displaying data from a
    model. In the following example, the contents of a directory are
    supplied by a QFileSystemModel and displayed as a tree:

    \snippet shareddirmodel/main.cpp 3
    \snippet shareddirmodel/main.cpp 6

    The model/view architecture ensures that the contents of the tree view
    are updated as the model changes.

    Items that have children can be in an expanded (children are
    visible) or collapsed (children are hidden) state. When this state
    changes a collapsed() or expanded() signal is emitted with the
    model index of the relevant item.

    The amount of indentation used to indicate levels of hierarchy is
    controlled by the \l indentation property.

    Headers in tree views are constructed using the QHeaderView class and can
    be hidden using \c{header()->hide()}. Note that each header is configured
    with its \l{QHeaderView::}{stretchLastSection} property set to true,
    ensuring that the view does not waste any of the space assigned to it for
    its header. If this value is set to true, this property will override the
    resize mode set on the last section in the header.

    By default, all columns in a tree view are movable except the first. To
    disable movement of these columns, use QHeaderView's
    \l {QHeaderView::}{setSectionsMovable()} function. For more information
    about rearranging sections, see \l {Moving Header Sections}.

    \section1 Key Bindings

    QTreeView supports a set of key bindings that enable the user to
    navigate in the view and interact with the contents of items:

    \table
    \header \li Key \li Action
    \row \li Up   \li Moves the cursor to the item in the same column on
         the previous row. If the parent of the current item has no more rows to
         navigate to, the cursor moves to the relevant item in the last row
         of the sibling that precedes the parent.
    \row \li Down \li Moves the cursor to the item in the same column on
         the next row. If the parent of the current item has no more rows to
         navigate to, the cursor moves to the relevant item in the first row
         of the sibling that follows the parent.
    \row \li Left  \li Hides the children of the current item (if present)
         by collapsing a branch.
    \row \li Minus \li Same as Left.
    \row \li Right \li Reveals the children of the current item (if present)
         by expanding a branch.
    \row \li Plus  \li Same as Right.
    \row \li Asterisk  \li Expands the current item and all its children
         (if present).
    \row \li PageUp   \li Moves the cursor up one page.
    \row \li PageDown \li Moves the cursor down one page.
    \row \li Home \li Moves the cursor to an item in the same column of the first
         row of the first top-level item in the model.
    \row \li End  \li Moves the cursor to an item in the same column of the last
         row of the last top-level item in the model.
    \row \li F2   \li In editable models, this opens the current item for editing.
         The Escape key can be used to cancel the editing process and revert
         any changes to the data displayed.
    \endtable

    \omit
    Describe the expanding/collapsing concept if not covered elsewhere.
    \endomit

    \section1 Improving Performance

    It is possible to give the view hints about the data it is handling in order
    to improve its performance when displaying large numbers of items. One approach
    that can be taken for views that are intended to display items with equal heights
    is to set the \l uniformRowHeights property to true.

    \sa QListView, QTreeWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,
        {Dir View Example}
*/


/*!
  \fn void QTreeView::expanded(const QModelIndex &index)

  This signal is emitted when the item specified by \a index is expanded.
*/


/*!
  \fn void QTreeView::collapsed(const QModelIndex &index)

  This signal is emitted when the item specified by \a index is collapsed.
*/

/*!
    Constructs a tree view with a \a parent to represent a model's
    data. Use setModel() to set the model.

    \sa QAbstractItemModel
*/
QTreeView::QTreeView(QWidget *parent)
    : QAbstractItemView(*new QTreeViewPrivate, parent)
{
    Q_D(QTreeView);
    d->initialize();
}

/*!
  \internal
*/
QTreeView::QTreeView(QTreeViewPrivate &dd, QWidget *parent)
    : QAbstractItemView(dd, parent)
{
    Q_D(QTreeView);
    d->initialize();
}

/*!
  Destroys the tree view.
*/
QTreeView::~QTreeView()
{
}

/*!
  \reimp
*/
void QTreeView::setModel(QAbstractItemModel *model)
{
    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()));
        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
                   this, SLOT(rowsRemoved(QModelIndex,int,int)));
        disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
    }
    d->viewItems.clear();
    d->expandedIndexes.clear();
    d->hiddenIndexes.clear();
    d->geometryRecursionBlock = true;   // do not update geometries due to signals from the headers
    d->header->setModel(model);
    d->geometryRecursionBlock = false;
    QAbstractItemView::setModel(model);

    // QAbstractItemView connects to a private slot
    disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
               this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
    // do header layout after the tree
    disconnect(d->model, SIGNAL(layoutChanged()),
               d->header, SLOT(_q_layoutChanged()));
    // QTreeView has a public slot for this
    connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
            this, SLOT(rowsRemoved(QModelIndex,int,int)));

    connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));

    if (d->sortingEnabled)
        d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
}

/*!
  \reimp
*/
void QTreeView::setRootIndex(const QModelIndex &index)
{
    Q_D(QTreeView);
    d->header->setRootIndex(index);
    QAbstractItemView::setRootIndex(index);
}

/*!
  \reimp
*/
void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
{
    Q_D(QTreeView);
    Q_ASSERT(selectionModel);
    if (d->selectionModel) {
        // support row editing
        disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
                   d->model, SLOT(submit()));
    }

    d->header->setSelectionModel(selectionModel);
    QAbstractItemView::setSelectionModel(selectionModel);

    if (d->selectionModel) {
        // support row editing
        connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
                d->model, SLOT(submit()));
    }
}

/*!
  Returns the header for the tree view.

  \sa QAbstractItemModel::headerData()
*/
QHeaderView *QTreeView::header() const
{
    Q_D(const QTreeView);
    return d->header;
}

/*!
    Sets the header for the tree view, to the given \a header.

    The view takes ownership over the given \a header and deletes it
    when a new header is set.

    \sa QAbstractItemModel::headerData()
*/
void QTreeView::setHeader(QHeaderView *header)
{
    Q_D(QTreeView);
    if (header == d->header || !header)
        return;
    if (d->header && d->header->parent() == this)
        delete d->header;
    d->header = header;
    d->header->setParent(this);
    d->header->setFirstSectionMovable(false);

    if (!d->header->model()) {
        d->header->setModel(d->model);
        if (d->selectionModel)
            d->header->setSelectionModel(d->selectionModel);
    }

    connect(d->header, SIGNAL(sectionResized(int,int,int)),
            this, SLOT(columnResized(int,int,int)));
    connect(d->header, SIGNAL(sectionMoved(int,int,int)),
            this, SLOT(columnMoved()));
    connect(d->header, SIGNAL(sectionCountChanged(int,int)),
            this, SLOT(columnCountChanged(int,int)));
    connect(d->header, SIGNAL(sectionHandleDoubleClicked(int)),
            this, SLOT(resizeColumnToContents(int)));
    connect(d->header, SIGNAL(geometriesChanged()),
            this, SLOT(updateGeometries()));

    setSortingEnabled(d->sortingEnabled);
    d->updateGeometry();
}

/*!
  \property QTreeView::autoExpandDelay
  \brief The delay time before items in a tree are opened during a drag and drop operation.
  \since 4.3

  This property holds the amount of time in milliseconds that the user must wait over
  a node before that node will automatically open or close.  If the time is
  set to less then 0 then it will not be activated.

  By default, this property has a value of -1, meaning that auto-expansion is disabled.
*/
int QTreeView::autoExpandDelay() const
{
    Q_D(const QTreeView);
    return d->autoExpandDelay;
}

void QTreeView::setAutoExpandDelay(int delay)
{
    Q_D(QTreeView);
    d->autoExpandDelay = delay;
}

/*!
  \property QTreeView::indentation
  \brief indentation of the items in the tree view.

  This property holds the indentation measured in pixels of the items for each
  level in the tree view. For top-level items, the indentation specifies the
  horizontal distance from the viewport edge to the items in the first column;
  for child items, it specifies their indentation from their parent items.

  By default, the value of this property is style dependent. Thus, when the style
  changes, this property updates from it. Calling setIndentation() stops the updates,
  calling resetIndentation() will restore default behavior.
*/
int QTreeView::indentation() const
{
    Q_D(const QTreeView);
    return d->indent;
}

void QTreeView::setIndentation(int i)
{
    Q_D(QTreeView);
    if (!d->customIndent || (i != d->indent)) {
        d->indent = i;
        d->customIndent = true;
        d->viewport->update();
    }
}

void QTreeView::resetIndentation()
{
    Q_D(QTreeView);
    if (d->customIndent) {
        d->updateIndentationFromStyle();
        d->customIndent = false;
    }
}

/*!
  \property QTreeView::rootIsDecorated
  \brief whether to show controls for expanding and collapsing top-level items

  Items with children are typically shown with controls to expand and collapse
  them, allowing their children to be shown or hidden. If this property is
  false, these controls are not shown for top-level items. This can be used to
  make a single level tree structure appear like a simple list of items.

  By default, this property is \c true.
*/
bool QTreeView::rootIsDecorated() const
{
    Q_D(const QTreeView);
    return d->rootDecoration;
}

void QTreeView::setRootIsDecorated(bool show)
{
    Q_D(QTreeView);
    if (show != d->rootDecoration) {
        d->rootDecoration = show;
        d->viewport->update();
    }
}

/*!
  \property QTreeView::uniformRowHeights
  \brief whether all items in the treeview have the same height

  This property should only be set to true if it is guaranteed that all items
  in the view has the same height. This enables the view to do some
  optimizations.

  The height is obtained from the first item in the view.  It is updated
  when the data changes on that item.

  \note If the editor size hint is bigger than the cell size hint, then the
  size hint of the editor will be used.

  By default, this property is \c false.
*/
bool QTreeView::uniformRowHeights() const
{
    Q_D(const QTreeView);
    return d->uniformRowHeights;
}

void QTreeView::setUniformRowHeights(bool uniform)
{
    Q_D(QTreeView);
    d->uniformRowHeights = uniform;
}

/*!
  \property QTreeView::itemsExpandable
  \brief whether the items are expandable by the user.

  This property holds whether the user can expand and collapse items
  interactively.

  By default, this property is \c true.

*/
bool QTreeView::itemsExpandable() const
{
    Q_D(const QTreeView);
    return d->itemsExpandable;
}

void QTreeView::setItemsExpandable(bool enable)
{
    Q_D(QTreeView);
    d->itemsExpandable = enable;
}

/*!
  \property QTreeView::expandsOnDoubleClick
  \since 4.4
  \brief whether the items can be expanded by double-clicking.

  This property holds whether the user can expand and collapse items
  by double-clicking. The default value is true.

  \sa itemsExpandable
*/
bool QTreeView::expandsOnDoubleClick() const
{
    Q_D(const QTreeView);
    return d->expandsOnDoubleClick;
}

void QTreeView::setExpandsOnDoubleClick(bool enable)
{
    Q_D(QTreeView);
    d->expandsOnDoubleClick = enable;
}

/*!
  Returns the horizontal position of the \a column in the viewport.
*/
int QTreeView::columnViewportPosition(int column) const
{
    Q_D(const QTreeView);
    return d->header->sectionViewportPosition(column);
}

/*!
  Returns the width of the \a column.

  \sa resizeColumnToContents(), setColumnWidth()
*/
int QTreeView::columnWidth(int column) const
{
    Q_D(const QTreeView);
    return d->header->sectionSize(column);
}

/*!
  \since 4.2

  Sets the width of the given \a column to the \a width specified.

  \sa columnWidth(), resizeColumnToContents()
*/
void QTreeView::setColumnWidth(int column, int width)
{
    Q_D(QTreeView);
    d->header->resizeSection(column, width);
}

/*!
  Returns the column in the tree view whose header covers the \a x
  coordinate given.
*/
int QTreeView::columnAt(int x) const
{
    Q_D(const QTreeView);
    return d->header->logicalIndexAt(x);
}

/*!
    Returns \c true if the \a column is hidden; otherwise returns \c false.

    \sa hideColumn(), isRowHidden()
*/
bool QTreeView::isColumnHidden(int column) const
{
    Q_D(const QTreeView);
    return d->header->isSectionHidden(column);
}

/*!
  If \a hide is true the \a column is hidden, otherwise the \a column is shown.

  \sa hideColumn(), setRowHidden()
*/
void QTreeView::setColumnHidden(int column, bool hide)
{
    Q_D(QTreeView);
    if (column < 0 || column >= d->header->count())
        return;
    d->header->setSectionHidden(column, hide);
}

/*!
  \property QTreeView::headerHidden
  \brief whether the header is shown or not.
  \since 4.4

  If this property is \c true, the header is not shown otherwise it is.
  The default value is false.

  \sa header()
*/
bool QTreeView::isHeaderHidden() const
{
    Q_D(const QTreeView);
    return d->header->isHidden();
}

void QTreeView::setHeaderHidden(bool hide)
{
    Q_D(QTreeView);
    d->header->setHidden(hide);
}

/*!
    Returns \c true if the item in the given \a row of the \a parent is hidden;
    otherwise returns \c false.

    \sa setRowHidden(), isColumnHidden()
*/
bool QTreeView::isRowHidden(int row, const QModelIndex &parent) const
{
    Q_D(const QTreeView);
    if (!d->model)
        return false;
    return d->isRowHidden(d->model->index(row, 0, parent));
}

/*!
  If \a hide is true the \a row with the given \a parent is hidden, otherwise the \a row is shown.

  \sa isRowHidden(), setColumnHidden()
*/
void QTreeView::setRowHidden(int row, const QModelIndex &parent, bool hide)
{
    Q_D(QTreeView);
    if (!d->model)
        return;
    QModelIndex index = d->model->index(row, 0, parent);
    if (!index.isValid())
        return;

    if (hide) {
        d->hiddenIndexes.insert(index);
    } else if(d->isPersistent(index)) { //if the index is not persistent, it cannot be in the set
        d->hiddenIndexes.remove(index);
    }

    d->doDelayedItemsLayout();
}

/*!
  \since 4.3

  Returns \c true if the item in first column in the given \a row
  of the \a parent is spanning all the columns; otherwise returns \c false.

  \sa setFirstColumnSpanned()
*/
bool QTreeView::isFirstColumnSpanned(int row, const QModelIndex &parent) const
{
    Q_D(const QTreeView);
    if (d->spanningIndexes.isEmpty() || !d->model)
        return false;
    const QModelIndex index = d->model->index(row, 0, parent);
    return d->spanningIndexes.contains(index);
}

/*!
  \since 4.3

  If \a span is true the item in the first column in the \a row
  with the given \a parent is set to span all columns, otherwise all items
  on the \a row are shown.

  \sa isFirstColumnSpanned()
*/
void QTreeView::setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)
{
    Q_D(QTreeView);
    if (!d->model)
        return;
    const QModelIndex index = d->model->index(row, 0, parent);
    if (!index.isValid())
        return;

    if (span)
        d->spanningIndexes.insert(index);
    else
        d->spanningIndexes.remove(index);

    d->executePostedLayout();
    int i = d->viewIndex(index);
    if (i >= 0)
        d->viewItems[i].spanning = span;

    d->viewport->update();
}

/*!
  \reimp
*/
void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    Q_D(QTreeView);

    // if we are going to do a complete relayout anyway, there is no need to update
    if (d->delayedPendingLayout)
        return;

    // refresh the height cache here; we don't really lose anything by getting the size hint,
    // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway

    bool sizeChanged = false;
    int topViewIndex = d->viewIndex(topLeft);
    if (topViewIndex == 0) {
        int newDefaultItemHeight = indexRowSizeHint(topLeft);
        sizeChanged = d->defaultItemHeight != newDefaultItemHeight;
        d->defaultItemHeight = newDefaultItemHeight;
    }

    if (topViewIndex != -1) {
        if (topLeft.row() == bottomRight.row()) {
            int oldHeight = d->itemHeight(topViewIndex);
            d->invalidateHeightCache(topViewIndex);
            sizeChanged |= (oldHeight != d->itemHeight(topViewIndex));
            if (topLeft.column() == 0)
                d->viewItems[topViewIndex].hasChildren = d->hasVisibleChildren(topLeft);
        } else {
            int bottomViewIndex = d->viewIndex(bottomRight);
            for (int i = topViewIndex; i <= bottomViewIndex; ++i) {
                int oldHeight = d->itemHeight(i);
                d->invalidateHeightCache(i);
                sizeChanged |= (oldHeight != d->itemHeight(i));
                if (topLeft.column() == 0)
                    d->viewItems[i].hasChildren = d->hasVisibleChildren(d->viewItems.at(i).index);
            }
        }
    }

    if (sizeChanged) {
        d->updateScrollBars();
        d->viewport->update();
    }
    QAbstractItemView::dataChanged(topLeft, bottomRight, roles);
}

/*!
  Hides the \a column given.

  \note This function should only be called after the model has been
  initialized, as the view needs to know the number of columns in order to
  hide \a column.

  \sa showColumn(), setColumnHidden()
*/
void QTreeView::hideColumn(int column)
{
    Q_D(QTreeView);
    if (d->header->isSectionHidden(column))
        return;
    d->header->hideSection(column);
    doItemsLayout();
}

/*!
  Shows the given \a column in the tree view.

  \sa hideColumn(), setColumnHidden()
*/
void QTreeView::showColumn(int column)
{
    Q_D(QTreeView);
    if (!d->header->isSectionHidden(column))
        return;
    d->header->showSection(column);
    doItemsLayout();
}

/*!
  \fn void QTreeView::expand(const QModelIndex &index)

  Expands the model item specified by the \a index.

  \sa expanded()
*/
void QTreeView::expand(const QModelIndex &index)
{
    Q_D(QTreeView);
    if (!d->isIndexValid(index))
        return;
    if (index.flags() & Qt::ItemNeverHasChildren)
        return;
    if (d->isIndexExpanded(index))
        return;
    if (d->delayedPendingLayout) {
        //A complete relayout is going to be performed, just store the expanded index, no need to layout.
        if (d->storeExpanded(index))
            emit expanded(index);
        return;
    }

    int i = d->viewIndex(index);
    if (i != -1) { // is visible
        d->expand(i, true);
        if (!d->isAnimating()) {
            updateGeometries();
            d->viewport->update();
        }
    } else if (d->storeExpanded(index)) {
        emit expanded(index);
    }
}

/*!
  \fn void QTreeView::collapse(const QModelIndex &index)

  Collapses the model item specified by the \a index.

  \sa collapsed()
*/
void QTreeView::collapse(const QModelIndex &index)
{
    Q_D(QTreeView);
    if (!d->isIndexValid(index))
        return;
    if (!d->isIndexExpanded(index))
        return;
    //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll
    d->delayedAutoScroll.stop();

    if (d->delayedPendingLayout) {
        //A complete relayout is going to be performed, just un-store the expanded index, no need to layout.
        if (d->isPersistent(index) && d->expandedIndexes.remove(index))
            emit collapsed(index);
        return;
    }
    int i = d->viewIndex(index);
    if (i != -1) { // is visible
        d->collapse(i, true);
        if (!d->isAnimating()) {
            updateGeometries();
            viewport()->update();
        }
    } else {
        if (d->isPersistent(index) && d->expandedIndexes.remove(index))
            emit collapsed(index);
    }
}

/*!
  \fn bool QTreeView::isExpanded(const QModelIndex &index) const

  Returns \c true if the model item \a index is expanded; otherwise returns
  false.

  \sa expand(), expanded(), setExpanded()
*/
bool QTreeView::isExpanded(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    return d->isIndexExpanded(index);
}

/*!
  Sets the item referred to by \a index to either collapse or expanded,
  depending on the value of \a expanded.

  \sa expanded(), expand(), isExpanded()
*/
void QTreeView::setExpanded(const QModelIndex &index, bool expanded)
{
    if (expanded)
        this->expand(index);
    else
        this->collapse(index);
}

/*!
    \since 4.2
    \property QTreeView::sortingEnabled
    \brief whether sorting is enabled

    If this property is \c true, sorting is enabled for the tree; if the property
    is false, sorting is not enabled. The default value is false.

    \note In order to avoid performance issues, it is recommended that
    sorting is enabled \e after inserting the items into the tree.
    Alternatively, you could also insert the items into a list before inserting
    the items into the tree.

    \sa sortByColumn()
*/

void QTreeView::setSortingEnabled(bool enable)
{
    Q_D(QTreeView);
    header()->setSortIndicatorShown(enable);
    header()->setSectionsClickable(enable);
    if (enable) {
        //sortByColumn has to be called before we connect or set the sortingEnabled flag
        // 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);
    } else {
        disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
                   this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
    }
    d->sortingEnabled = enable;
}

bool QTreeView::isSortingEnabled() const
{
    Q_D(const QTreeView);
    return d->sortingEnabled;
}

/*!
    \since 4.2
    \property QTreeView::animated
    \brief whether animations are enabled

    If this property is \c true the treeview will animate expansion
    and collapsing of branches. If this property is \c false, the treeview
    will expand or collapse branches immediately without showing
    the animation.

    By default, this property is \c false.
*/

void QTreeView::setAnimated(bool animate)
{
    Q_D(QTreeView);
    d->animationsEnabled = animate;
}

bool QTreeView::isAnimated() const
{
    Q_D(const QTreeView);
    return d->animationsEnabled;
}

/*!
    \since 4.2
    \property QTreeView::allColumnsShowFocus
    \brief whether items should show keyboard focus using all columns

    If this property is \c true all columns will show focus, otherwise only
    one column will show focus.

    The default is false.
*/

void QTreeView::setAllColumnsShowFocus(bool enable)
{
    Q_D(QTreeView);
    if (d->allColumnsShowFocus == enable)
        return;
    d->allColumnsShowFocus = enable;
    d->viewport->update();
}

bool QTreeView::allColumnsShowFocus() const
{
    Q_D(const QTreeView);
    return d->allColumnsShowFocus;
}

/*!
    \property QTreeView::wordWrap
    \brief the item text word-wrapping policy
    \since 4.3

    If this property is \c true then the item text is wrapped where
    necessary at word-breaks; otherwise it is not wrapped at all.
    This property is \c false by default.

    Note that even if wrapping is enabled, the cell will not be
    expanded to fit all text. Ellipsis will be inserted according to
    the current \l{QAbstractItemView::}{textElideMode}.
*/
void QTreeView::setWordWrap(bool on)
{
    Q_D(QTreeView);
    if (d->wrapItemText == on)
        return;
    d->wrapItemText = on;
    d->doDelayedItemsLayout();
}

bool QTreeView::wordWrap() const
{
    Q_D(const QTreeView);
    return d->wrapItemText;
}

/*!
    \since 5.2

    This specifies that the tree structure should be placed at logical index \a index.
    If \index is set to -1 then the tree will always follow visual index 0.

    \sa treePosition(), QHeaderView::swapSections(), QHeaderView::moveSection()
*/

void QTreeView::setTreePosition(int index)
{
    Q_D(QTreeView);
    d->treePosition = index;
    d->viewport->update();
}

/*!
    \since 5.2

    Return the logical index the tree is set on. If the return value is -1 then the
    tree is placed on the visual index 0.

    \sa setTreePosition()
*/

int QTreeView::treePosition() const
{
    Q_D(const QTreeView);
    return d->treePosition;
}

/*!
  \reimp
 */
void QTreeView::keyboardSearch(const QString &search)
{
    Q_D(QTreeView);
    if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
        return;

    // Do a relayout nows, so that we can utilize viewItems
    d->executePostedLayout();
    if (d->viewItems.isEmpty())
        return;

    QModelIndex start;
    if (currentIndex().isValid())
        start = currentIndex();
    else
        start = d->viewItems.at(0).index;

    bool skipRow = false;
    bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
    qint64 keyboardInputTimeElapsed;
    if (keyboardTimeWasValid)
        keyboardInputTimeElapsed = d->keyboardInputTime.restart();
    else
        d->keyboardInputTime.start();
    if (search.isEmpty() || !keyboardTimeWasValid
        || keyboardInputTimeElapsed > QApplication::keyboardInputInterval()) {
        d->keyboardInput = search;
        skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
    } else {
        d->keyboardInput += search;
    }

    // special case for searches with same key like 'aaaaa'
    bool sameKey = false;
    if (d->keyboardInput.length() > 1) {
        int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
        sameKey = (c == d->keyboardInput.length());
        if (sameKey)
            skipRow = true;
    }

    // skip if we are searching for the same key or a new search started
    if (skipRow) {
        if (indexBelow(start).isValid()) {
            start = indexBelow(start);
        } else {
            const int origCol = start.column();
            start = d->viewItems.at(0).index;
            if (origCol != start.column())
                start = start.sibling(start.row(), origCol);
        }
    }

    int startIndex = d->viewIndex(start);
    if (startIndex <= -1)
        return;

    int previousLevel = -1;
    int bestAbove = -1;
    int bestBelow = -1;
    QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
    for (int i = 0; i < d->viewItems.count(); ++i) {
        if ((int)d->viewItems.at(i).level > previousLevel) {
            QModelIndex searchFrom = d->viewItems.at(i).index;
            if (start.column() > 0)
                searchFrom = searchFrom.sibling(searchFrom.row(), start.column());
            if (searchFrom.parent() == start.parent())
                searchFrom = start;
            QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString);
            if (match.count()) {
                int hitIndex = d->viewIndex(match.at(0));
                if (hitIndex >= 0 && hitIndex < startIndex)
                    bestAbove = bestAbove == -1 ? hitIndex : qMin(hitIndex, bestAbove);
                else if (hitIndex >= startIndex)
                    bestBelow = bestBelow == -1 ? hitIndex : qMin(hitIndex, bestBelow);
            }
        }
        previousLevel = d->viewItems.at(i).level;
    }

    QModelIndex index;
    if (bestBelow > -1)
        index = d->viewItems.at(bestBelow).index;
    else if (bestAbove > -1)
        index = d->viewItems.at(bestAbove).index;

    if (start.column() > 0)
        index = index.sibling(index.row(), start.column());

    if (index.isValid())
        setCurrentIndex(index);
}

/*!
  Returns the rectangle on the viewport occupied by the item at \a index.
  If the index is not visible or explicitly hidden, the returned rectangle is invalid.
*/
QRect QTreeView::visualRect(const QModelIndex &index) const
{
    Q_D(const QTreeView);

    if (!d->isIndexValid(index) || isIndexHidden(index))
        return QRect();

    d->executePostedLayout();

    int vi = d->viewIndex(index);
    if (vi < 0)
        return QRect();

    bool spanning = d->viewItems.at(vi).spanning;

    // if we have a spanning item, make the selection stretch from left to right
    int x = (spanning ? 0 : columnViewportPosition(index.column()));
    int w = (spanning ? d->header->length() : columnWidth(index.column()));
    // handle indentation
    if (d->isTreePosition(index.column())) {
        int i = d->indentationForItem(vi);
        w -= i;
        if (!isRightToLeft())
            x += i;
    }

    int y = d->coordinateForItem(vi);
    int h = d->itemHeight(vi);

    return QRect(x, y, w, h);
}

/*!
    Scroll the contents of the tree view until the given model item
    \a index is visible. The \a hint parameter specifies more
    precisely where the item should be located after the
    operation.
    If any of the parents of the model item are collapsed, they will
    be expanded to ensure that the model item is visible.
*/
void QTreeView::scrollTo(const QModelIndex &index, ScrollHint hint)
{
    Q_D(QTreeView);

    if (!d->isIndexValid(index))
        return;

    d->executePostedLayout();
    d->updateScrollBars();

    // Expand all parents if the parent(s) of the node are not expanded.
    QModelIndex parent = index.parent();
    while (parent != d->root && parent.isValid() && state() == NoState && d->itemsExpandable) {
        if (!isExpanded(parent))
            expand(parent);
        parent = d->model->parent(parent);
    }

    int item = d->viewIndex(index);
    if (item < 0)
        return;

    QRect area = d->viewport->rect();

    // vertical
    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
        int top = verticalScrollBar()->value();
        int bottom = top + verticalScrollBar()->pageStep();
        if (hint == EnsureVisible && item >= top && item < bottom) {
            // nothing to do
        } else if (hint == PositionAtTop || (hint == EnsureVisible && item < top)) {
            verticalScrollBar()->setValue(item);
        } else { // PositionAtBottom or PositionAtCenter
            const int currentItemHeight = d->itemHeight(item);
            int y = (hint == PositionAtCenter
                 //we center on the current item with a preference to the top item (ie. -1)
                     ? area.height() / 2 + currentItemHeight - 1
                 //otherwise we simply take the whole space
                     : area.height());
            if (y > currentItemHeight) {
                while (item >= 0) {
                    y -= d->itemHeight(item);
                    if (y < 0) { //there is no more space left
                        item++;
                        break;
                    }
                    item--;
                }
            }
            verticalScrollBar()->setValue(item);
        }
    } else { // ScrollPerPixel
        QRect rect(columnViewportPosition(index.column()),
                   d->coordinateForItem(item), // ### slow for items outside the view
                   columnWidth(index.column()),
                   d->itemHeight(item));

        if (rect.isEmpty()) {
            // nothing to do
        } else if (hint == EnsureVisible && area.contains(rect)) {
            d->viewport->update(rect);
            // nothing to do
        } else {
            bool above = (hint == EnsureVisible
                        && (rect.top() < area.top()
                            || area.height() < rect.height()));
            bool below = (hint == EnsureVisible
                        && rect.bottom() > area.bottom()
                        && rect.height() < area.height());

            int verticalValue = verticalScrollBar()->value();
            if (hint == PositionAtTop || above)
                verticalValue += rect.top();
            else if (hint == PositionAtBottom || below)
                verticalValue += rect.bottom() - area.height();
            else if (hint == PositionAtCenter)
                verticalValue += rect.top() - ((area.height() - rect.height()) / 2);
            verticalScrollBar()->setValue(verticalValue);
        }
    }
    // horizontal
    int viewportWidth = d->viewport->width();
    int horizontalOffset = d->header->offset();
    int horizontalPosition = d->header->sectionPosition(index.column());
    int cellWidth = d->header->sectionSize(index.column());

    if (hint == PositionAtCenter) {
        horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
    } else {
        if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
            horizontalScrollBar()->setValue(horizontalPosition);
        else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
            horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
    }
}

/*!
  \reimp
*/
void QTreeView::timerEvent(QTimerEvent *event)
{
    Q_D(QTreeView);
    if (event->timerId() == d->columnResizeTimerID) {
        updateGeometries();
        killTimer(d->columnResizeTimerID);
        d->columnResizeTimerID = 0;
        QRect rect;
        int viewportHeight = d->viewport->height();
        int viewportWidth = d->viewport->width();
        for (int i = d->columnsToUpdate.size() - 1; i >= 0; --i) {
            int column = d->columnsToUpdate.at(i);
            int x = columnViewportPosition(column);
            if (isRightToLeft())
                rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);
            else
                rect |= QRect(x, 0, viewportWidth - x, viewportHeight);
        }
        d->viewport->update(rect.normalized());
        d->columnsToUpdate.clear();
    } else if (event->timerId() == d->openTimer.timerId()) {
        QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
        if (state() == QAbstractItemView::DraggingState
            && d->viewport->rect().contains(pos)) {
            QModelIndex index = indexAt(pos);
            setExpanded(index, !isExpanded(index));
        }
        d->openTimer.stop();
    }

    QAbstractItemView::timerEvent(event);
}

/*!
  \reimp
*/
#if QT_CONFIG(draganddrop)
void QTreeView::dragMoveEvent(QDragMoveEvent *event)
{
    Q_D(QTreeView);
    if (d->autoExpandDelay >= 0)
        d->openTimer.start(d->autoExpandDelay, this);
    QAbstractItemView::dragMoveEvent(event);
}
#endif

/*!
  \reimp
*/
bool QTreeView::viewportEvent(QEvent *event)
{
    Q_D(QTreeView);
    switch (event->type()) {
    case QEvent::HoverEnter:
    case QEvent::HoverLeave:
    case QEvent::HoverMove: {
        QHoverEvent *he = static_cast<QHoverEvent*>(event);
        int oldBranch = d->hoverBranch;
        d->hoverBranch = d->itemDecorationAt(he->pos());
        QModelIndex newIndex = indexAt(he->pos());
        if (d->hover != newIndex || d->hoverBranch != oldBranch) {
            // Update the whole hovered over row. No need to update the old hovered
            // row, that is taken care in superclass hover handling.
            QRect rect = visualRect(newIndex);
            rect.setX(0);
            rect.setWidth(viewport()->width());
            viewport()->update(rect);
        }
        break; }
    default:
        break;
    }
    return QAbstractItemView::viewportEvent(event);
}

/*!
  \reimp
*/
void QTreeView::paintEvent(QPaintEvent *event)
{
    Q_D(QTreeView);
    d->executePostedLayout();
    QPainter painter(viewport());
#if QT_CONFIG(animation)
    if (d->isAnimating()) {
        drawTree(&painter, event->region() - d->animatedOperation.rect());
        d->drawAnimatedOperation(&painter);
    } else
#endif // animation
    {
        drawTree(&painter, event->region());
#if QT_CONFIG(draganddrop)
        d->paintDropIndicator(&painter);
#endif
    }
}

int QTreeViewPrivate::logicalIndexForTree() const
{
    int index = treePosition;
    if (index < 0)
        index = header->logicalIndex(0);
    return index;
}

void QTreeViewPrivate::paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const
{
    Q_Q(const QTreeView);
    if (!alternatingColors || !q->style()->styleHint(QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea, option, q))
        return;
    int rowHeight = defaultItemHeight;
    if (rowHeight <= 0) {
        rowHeight = itemDelegate->sizeHint(*option, QModelIndex()).height();
        if (rowHeight <= 0)
            return;
    }
    while (y <= bottom) {
        option->rect.setRect(0, y, viewport->width(), rowHeight);
        option->features.setFlag(QStyleOptionViewItem::Alternate, current & 1);
        ++current;
        q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, option, painter, q);
        y += rowHeight;
    }
}

bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos)
{
    Q_Q(QTreeView);
    // we want to handle mousePress in EditingState (persistent editors)
    if ((state != QAbstractItemView::NoState
                && state != QAbstractItemView::EditingState)
                || !viewport->rect().contains(pos))
        return true;

    int i = itemDecorationAt(pos);
    if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {
        if (viewItems.at(i).expanded)
            collapse(i, true);
        else
            expand(i, true);
        if (!isAnimating()) {
            q->updateGeometries();
            viewport->update();
        }
        return true;
    }
    return false;
}

void QTreeViewPrivate::_q_modelDestroyed()
{
    //we need to clear the viewItems because it contains QModelIndexes to
    //the model currently being destroyed
    viewItems.clear();
    QAbstractItemViewPrivate::_q_modelDestroyed();
}

/*!
  \reimp

  We have a QTreeView way of knowing what elements are on the viewport
*/
QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
{
    Q_ASSERT(r);
    Q_Q(const QTreeView);
    if (spanningIndexes.isEmpty())
        return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);
    QModelIndexList list;
    for (const QModelIndex &idx : indexes) {
        if (idx.column() > 0 && q->isFirstColumnSpanned(idx.row(), idx.parent()))
            continue;
        list << idx;
    }
    return QAbstractItemViewPrivate::draggablePaintPairs(list, r);
}

void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex &current) const
{
    const int row = viewIndex(current); // get the index in viewItems[]
    option->state = option->state | (viewItems.at(row).expanded ? QStyle::State_Open : QStyle::State_None)
                                  | (viewItems.at(row).hasChildren ? QStyle::State_Children : QStyle::State_None)
                                  | (viewItems.at(row).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);

    option->showDecorationSelected = (selectionBehavior & QTreeView::SelectRows)
                                     || option->showDecorationSelected;

    QVector<int> logicalIndices; // index = visual index of visible columns only. data = logical index.
    QVector<QStyleOptionViewItem::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex, visible columns only.
    const bool spanning = viewItems.at(row).spanning;
    const int left = (spanning ? header->visualIndex(0) : 0);
    const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
    calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);

    const int visualIndex = logicalIndices.indexOf(current.column());
    option->viewItemPosition = viewItemPosList.at(visualIndex);
}


/*!
  \since 4.2
  Draws the part of the tree intersecting the given \a region using the specified
  \a painter.

  \sa paintEvent()
*/
void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
{
    Q_D(const QTreeView);
    const QVector<QTreeViewItem> viewItems = d->viewItems;

    QStyleOptionViewItem option = d->viewOptionsV1();
    const QStyle::State state = option.state;
    d->current = 0;

    if (viewItems.count() == 0 || d->header->count() == 0 || !d->itemDelegate) {
        d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
        return;
    }

    int firstVisibleItemOffset = 0;
    const int firstVisibleItem = d->firstVisibleItem(&firstVisibleItemOffset);
    if (firstVisibleItem < 0) {
        d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
        return;
    }

    const int viewportWidth = d->viewport->width();

    QPoint hoverPos = d->viewport->mapFromGlobal(QCursor::pos());
    d->hoverBranch = d->itemDecorationAt(hoverPos);

    QVector<int> drawn;
    bool multipleRects = (region.rectCount() > 1);
    for (const QRect &a : region) {
        const QRect area = (multipleRects
                            ? QRect(0, a.y(), viewportWidth, a.height())
                            : a);
        d->leftAndRight = d->startAndEndColumns(area);

        int i = firstVisibleItem; // the first item at the top of the viewport
        int y = firstVisibleItemOffset; // we may only see part of the first item

        // start at the top of the viewport  and iterate down to the update area
        for (; i < viewItems.count(); ++i) {
            const int itemHeight = d->itemHeight(i);
            if (y + itemHeight > area.top())
                break;
            y += itemHeight;
        }

        // paint the visible rows
        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)
                                 | (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)) {
                drawRow(painter, option, viewItems.at(i).index);
                if (multipleRects)   // even if the rect only intersects the item,
                    drawn.append(i); // the entire item will be painted
            }
            y += itemHeight;
        }

        if (y <= area.bottom()) {
            d->current = i;
            d->paintAlternatingRowColors(painter, &option, y, area.bottom());
        }
    }
}

/// ### move to QObject :)
static inline bool ancestorOf(QObject *widget, QObject *other)
{
    for (QObject *parent = other; parent != nullptr; parent = parent->parent()) {
        if (parent == widget)
            return true;
    }
    return false;
}

void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left, int right) const
{
    const int columnCount = header->count();
    /* 'left' and 'right' are the left-most and right-most visible visual indices.
       Compute the first visible logical indices before and after the left and right.
       We will use these values to determine the QStyleOptionViewItem::viewItemPosition. */
    int logicalIndexBeforeLeft = -1, logicalIndexAfterRight = -1;
    for (int visualIndex = left - 1; visualIndex >= 0; --visualIndex) {
        int logicalIndex = header->logicalIndex(visualIndex);
        if (!header->isSectionHidden(logicalIndex)) {
            logicalIndexBeforeLeft = logicalIndex;
            break;
        }
    }

    for (int visualIndex = left; visualIndex < columnCount; ++visualIndex) {
        int logicalIndex = header->logicalIndex(visualIndex);
        if (!header->isSectionHidden(logicalIndex)) {
            if (visualIndex > right) {
                logicalIndexAfterRight = logicalIndex;
                break;
            }
            logicalIndices->append(logicalIndex);
        }
    }

    itemPositions->resize(logicalIndices->count());
    for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->count(); ++currentLogicalSection) {
        const int headerSection = logicalIndices->at(currentLogicalSection);
        // determine the viewItemPosition depending on the position of column 0
        int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->count()
                                 ? logicalIndexAfterRight
                                 : logicalIndices->at(currentLogicalSection + 1);
        int prevLogicalSection = currentLogicalSection - 1 < 0
                                 ? logicalIndexBeforeLeft
                                 : logicalIndices->at(currentLogicalSection - 1);
        QStyleOptionViewItem::ViewItemPosition pos;
        if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
            || (headerSection == 0 && nextLogicalSection == -1) || spanning)
            pos = QStyleOptionViewItem::OnlyOne;
        else if (isTreePosition(headerSection) || (nextLogicalSection != 0 && prevLogicalSection == -1))
            pos = QStyleOptionViewItem::Beginning;
        else if (nextLogicalSection == 0 || nextLogicalSection == -1)
            pos = QStyleOptionViewItem::End;
        else
            pos = QStyleOptionViewItem::Middle;
        (*itemPositions)[currentLogicalSection] = pos;
    }
}

/*!
  \internal
  Get sizeHint width for single index (providing existing hint and style option) and index in viewIndex i.
*/
int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const
{
    QWidget *editor = editorForIndex(index).widget.data();
    if (editor && persistent.contains(editor)) {
        hint = qMax(hint, editor->sizeHint().width());
        int min = editor->minimumSize().width();
        int max = editor->maximumSize().width();
        hint = qBound(min, hint, max);
    }
    int xhint = delegateForIndex(index)->sizeHint(option, index).width();
    hint = qMax(hint, xhint + (isTreePosition(index.column()) ? indentationForItem(i) : 0));
    return hint;
}

/*!
    Draws the row in the tree view that contains the model item \a index,
    using the \a painter given. The \a option controls how the item is
    displayed.

    \sa setAlternatingRowColors()
*/
void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
                        const QModelIndex &index) const
{
    Q_D(const QTreeView);
    QStyleOptionViewItem opt = option;
    const QPoint offset = d->scrollDelayOffset;
    const int y = option.rect.y() + offset.y();
    const QModelIndex parent = index.parent();
    const QHeaderView *header = d->header;
    const QModelIndex current = currentIndex();
    const QModelIndex hover = d->hover;
    const bool reverse = isRightToLeft();
    const QStyle::State state = opt.state;
    const bool spanning = d->spanning;
    const int left = (spanning ? header->visualIndex(0) : d->leftAndRight.first);
    const int right = (spanning ? header->visualIndex(0) : d->leftAndRight.second);
    const bool alternate = d->alternatingColors;
    const bool enabled = (state & QStyle::State_Enabled) != 0;
    const bool allColumnsShowFocus = d->allColumnsShowFocus;


    // when the row contains an index widget which has focus,
    // we want to paint the entire row as active
    bool indexWidgetHasFocus = false;
    if ((current.row() == index.row()) && !d->editorIndexHash.isEmpty()) {
        const int r = index.row();
        QWidget *fw = QApplication::focusWidget();
        for (int c = 0; c < header->count(); ++c) {
            QModelIndex idx = d->model->index(r, c, parent);
            if (QWidget *editor = indexWidget(idx)) {
                if (ancestorOf(editor, fw)) {
                    indexWidgetHasFocus = true;
                    break;
                }
            }
        }
    }

    const bool widgetHasFocus = hasFocus();
    bool currentRowHasFocus = false;
    if (allColumnsShowFocus && widgetHasFocus && current.isValid()) {
        // check if the focus index is before or after the visible columns
        const int r = index.row();
        for (int c = 0; c < left && !currentRowHasFocus; ++c) {
            QModelIndex idx = d->model->index(r, c, parent);
            currentRowHasFocus = (idx == current);
        }
        QModelIndex parent = d->model->parent(index);
        for (int c = right; c < header->count() && !currentRowHasFocus; ++c) {
            currentRowHasFocus = (d->model->index(r, c, parent) == current);
        }
    }

    // ### special case: treeviews with multiple columns draw
    // the selections differently than with only one column
    opt.showDecorationSelected = (d->selectionBehavior & SelectRows)
                                 || option.showDecorationSelected;

    int width, height = option.rect.height();
    int position;
    QModelIndex modelIndex;
    const bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
                  && index.parent() == hover.parent()
                  && index.row() == hover.row();

    QVector<int> logicalIndices;
    QVector<QStyleOptionViewItem::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex
    d->calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);

    for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) {
        int headerSection = logicalIndices.at(currentLogicalSection);
        position = columnViewportPosition(headerSection) + offset.x();
        width = header->sectionSize(headerSection);

        if (spanning) {
            int lastSection = header->logicalIndex(header->count() - 1);
            if (!reverse) {
                width = columnViewportPosition(lastSection) + header->sectionSize(lastSection) - position;
            } else {
                width += position - columnViewportPosition(lastSection);
                position = columnViewportPosition(lastSection);
            }
        }

        modelIndex = d->model->index(index.row(), headerSection, parent);
        if (!modelIndex.isValid())
            continue;
        opt.state = state;

        opt.viewItemPosition = viewItemPosList.at(currentLogicalSection);

        // fake activeness when row editor has focus
        if (indexWidgetHasFocus)
            opt.state |= QStyle::State_Active;

        if (d->selectionModel->isSelected(modelIndex))
            opt.state |= QStyle::State_Selected;
        if (widgetHasFocus && (current == modelIndex)) {
            if (allColumnsShowFocus)
                currentRowHasFocus = true;
            else
                opt.state |= QStyle::State_HasFocus;
        }
        opt.state.setFlag(QStyle::State_MouseOver,
                          (hoverRow || modelIndex == hover)
                          && (option.showDecorationSelected || d->hoverBranch == -1));

        if (enabled) {
            QPalette::ColorGroup cg;
            if ((d->model->flags(modelIndex) & Qt::ItemIsEnabled) == 0) {
                opt.state &= ~QStyle::State_Enabled;
                cg = QPalette::Disabled;
            } else if (opt.state & QStyle::State_Active) {
                cg = QPalette::Active;
            } else {
                cg = QPalette::Inactive;
            }
            opt.palette.setCurrentColorGroup(cg);
        }

        if (alternate) {
            opt.features.setFlag(QStyleOptionViewItem::Alternate, d->current & 1);
        }

        /* Prior to Qt 4.3, the background of the branch (in selected state and
           alternate row color was provided by the view. For backward compatibility,
           this is now delegated to the style using PE_PanelViewItemRow which
           does the appropriate fill */
        if (d->isTreePosition(headerSection)) {
            const int i = d->indentationForItem(d->current);
            QRect branches(reverse ? position + width - i : position, y, i, height);
            const bool setClipRect = branches.width() > width;
            if (setClipRect) {
                painter->save();
                painter->setClipRect(QRect(position, y, width, height));
            }
            // draw background for the branch (selection + alternate row)
            opt.rect = branches;
            if (style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, &opt, this))
                style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);

            // draw background of the item (only alternate row). rest of the background
            // is provided by the delegate
            QStyle::State oldState = opt.state;
            opt.state &= ~QStyle::State_Selected;
            opt.rect.setRect(reverse ? position : i + position, y, width - i, height);
            style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
            opt.state = oldState;

            if (d->indent != 0)
                drawBranches(painter, branches, index);
            if (setClipRect)
                painter->restore();
        } else {
            QStyle::State oldState = opt.state;
            opt.state &= ~QStyle::State_Selected;
            opt.rect.setRect(position, y, width, height);
            style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
            opt.state = oldState;
        }

        d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
    }

    if (currentRowHasFocus) {
        QStyleOptionFocusRect o;
        o.QStyleOption::operator=(option);
        o.state |= QStyle::State_KeyboardFocusChange;
        QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
                                  ? QPalette::Normal : QPalette::Disabled;
        o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
                                                 ? QPalette::Highlight : QPalette::Window);
        int x = 0;
        if (!option.showDecorationSelected)
            x = header->sectionPosition(0) + d->indentationForItem(d->current);
        QRect focusRect(x - header->offset(), y, header->length() - x, height);
        o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), focusRect);
        style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
        // if we show focus on all columns and the first section is moved,
        // we have to split the focus rect into two rects
        if (allColumnsShowFocus && !option.showDecorationSelected
            && header->sectionsMoved() && (header->visualIndex(0) != 0)) {
            QRect sectionRect(0, y, header->sectionPosition(0), height);
            o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), sectionRect);
            style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
        }
    }
}

/*!
  Draws the branches in the tree view on the same row as the model item
  \a index, using the \a painter given. The branches are drawn in the
  rectangle specified by \a rect.
*/
void QTreeView::drawBranches(QPainter *painter, const QRect &rect,
                             const QModelIndex &index) const
{
    Q_D(const QTreeView);
    const bool reverse = isRightToLeft();
    const int indent = d->indent;
    const int outer = d->rootDecoration ? 0 : 1;
    const int item = d->current;
    const QTreeViewItem &viewItem = d->viewItems.at(item);
    int level = viewItem.level;
    QRect primitive(reverse ? rect.left() : rect.right() + 1, rect.top(), indent, rect.height());

    QModelIndex parent = index.parent();
    QModelIndex current = parent;
    QModelIndex ancestor = current.parent();

    QStyleOptionViewItem opt = viewOptions();
    QStyle::State extraFlags = QStyle::State_None;
    if (isEnabled())
        extraFlags |= QStyle::State_Enabled;
    if (hasFocus())
        extraFlags |= QStyle::State_Active;
    QPoint oldBO = painter->brushOrigin();
    if (verticalScrollMode() == QAbstractItemView::ScrollPerPixel)
        painter->setBrushOrigin(QPoint(0, verticalOffset()));

    if (d->alternatingColors) {
        opt.features.setFlag(QStyleOptionViewItem::Alternate, d->current & 1);
    }

    // When hovering over a row, pass State_Hover for painting the branch
    // indicators if it has the decoration (aka branch) selected.
    bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
                    && opt.showDecorationSelected
                    && index.parent() == d->hover.parent()
                    && index.row() == d->hover.row();

    if (d->selectionModel->isSelected(index))
        extraFlags |= QStyle::State_Selected;

    if (level >= outer) {
        // start with the innermost branch
        primitive.moveLeft(reverse ? primitive.left() : primitive.left() - indent);
        opt.rect = primitive;

        const bool expanded = viewItem.expanded;
        const bool children = viewItem.hasChildren;
        bool moreSiblings = viewItem.hasMoreSiblings;

        opt.state = QStyle::State_Item | extraFlags
                    | (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)
                    | (children ? QStyle::State_Children : QStyle::State_None)
                    | (expanded ? QStyle::State_Open : QStyle::State_None);
        opt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch);

        style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
    }
    // then go out level by level
    for (--level; level >= outer; --level) { // we have already drawn the innermost branch
        primitive.moveLeft(reverse ? primitive.left() + indent : primitive.left() - indent);
        opt.rect = primitive;
        opt.state = extraFlags;
        bool moreSiblings = false;
        if (d->hiddenIndexes.isEmpty()) {
            moreSiblings = (d->model->rowCount(ancestor) - 1 > current.row());
        } else {
            int successor = item + viewItem.total + 1;
            while (successor < d->viewItems.size()
                   && d->viewItems.at(successor).level >= uint(level)) {
                const QTreeViewItem &successorItem = d->viewItems.at(successor);
                if (successorItem.level == uint(level)) {
                    moreSiblings = true;
                    break;
                }
                successor += successorItem.total + 1;
            }
        }
        if (moreSiblings)
            opt.state |= QStyle::State_Sibling;
        opt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch);

        style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
        current = ancestor;
        ancestor = current.parent();
    }
    painter->setBrushOrigin(oldBO);
}

/*!
  \reimp
*/
void QTreeView::mousePressEvent(QMouseEvent *event)
{
    Q_D(QTreeView);
    bool handled = false;
    if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, nullptr, this) == QEvent::MouseButtonPress)
        handled = d->expandOrCollapseItemAtPos(event->pos());
    if (!handled && d->itemDecorationAt(event->pos()) == -1)
        QAbstractItemView::mousePressEvent(event);
    else
        d->pressedIndex = QModelIndex();
}

/*!
  \reimp
*/
void QTreeView::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QTreeView);
    if (d->itemDecorationAt(event->pos()) == -1) {
        QAbstractItemView::mouseReleaseEvent(event);
    } else {
        if (state() == QAbstractItemView::DragSelectingState || state() == QAbstractItemView::DraggingState)
            setState(QAbstractItemView::NoState);
        if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, nullptr, this) == QEvent::MouseButtonRelease)
            d->expandOrCollapseItemAtPos(event->pos());
    }
}

/*!
  \reimp
*/
void QTreeView::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_D(QTreeView);
    if (state() != NoState || !d->viewport->rect().contains(event->pos()))
        return;

    int i = d->itemDecorationAt(event->pos());
    if (i == -1) {
        i = d->itemAtCoordinate(event->y());
        if (i == -1)
            return; // user clicked outside the items

        const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
        const QPersistentModelIndex persistent = indexAt(event->pos());

        if (d->pressedIndex != persistent) {
            mousePressEvent(event);
            return;
        }

        // signal handlers may change the model
        emit doubleClicked(persistent);

        if (!persistent.isValid())
            return;

        if (edit(persistent, DoubleClicked, event) || state() != NoState)
            return; // the double click triggered editing

        if (!style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, this))
            emit activated(persistent);

        d->pressedIndex = QModelIndex();
        d->executePostedLayout(); // we need to make sure viewItems is updated
        if (d->itemsExpandable
            && d->expandsOnDoubleClick
            && d->hasVisibleChildren(persistent)) {
            if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {
                // find the new index of the item
                for (i = 0; i < d->viewItems.count(); ++i) {
                    if (d->viewItems.at(i).index == firstColumnIndex)
                        break;
                }
                if (i == d->viewItems.count())
                    return;
            }
            if (d->viewItems.at(i).expanded)
                d->collapse(i, true);
            else
                d->expand(i, true);
            updateGeometries();
            viewport()->update();
        }
    }
}

/*!
  \reimp
*/
void QTreeView::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QTreeView);
    if (d->itemDecorationAt(event->pos()) == -1) // ### what about expanding/collapsing state ?
        QAbstractItemView::mouseMoveEvent(event);
}

/*!
  \reimp
*/
void QTreeView::keyPressEvent(QKeyEvent *event)
{
    Q_D(QTreeView);
    QModelIndex current = currentIndex();
    //this is the management of the expansion
    if (d->isIndexValid(current) && d->model && d->itemsExpandable) {
        switch (event->key()) {
        case Qt::Key_Asterisk: {
            expandRecursively(current);
            break; }
        case Qt::Key_Plus:
            expand(current);
            break;
        case Qt::Key_Minus:
            collapse(current);
            break;
        }
    }

    QAbstractItemView::keyPressEvent(event);
}

/*!
  \reimp
*/
QModelIndex QTreeView::indexAt(const QPoint &point) const
{
    Q_D(const QTreeView);
    d->executePostedLayout();

    int visualIndex = d->itemAtCoordinate(point.y());
    QModelIndex idx = d->modelIndex(visualIndex);
    if (!idx.isValid())
        return QModelIndex();

    if (d->viewItems.at(visualIndex).spanning)
        return idx;

    int column = d->columnAt(point.x());
    if (column == idx.column())
        return idx;
    if (column < 0)
        return QModelIndex();
    return idx.sibling(idx.row(), column);
}

/*!
  Returns the model index of the item above \a index.
*/
QModelIndex QTreeView::indexAbove(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    if (!d->isIndexValid(index))
        return QModelIndex();
    d->executePostedLayout();
    int i = d->viewIndex(index);
    if (--i < 0)
        return QModelIndex();
    const QModelIndex firstColumnIndex = d->viewItems.at(i).index;
    return firstColumnIndex.sibling(firstColumnIndex.row(), index.column());
}

/*!
  Returns the model index of the item below \a index.
*/
QModelIndex QTreeView::indexBelow(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    if (!d->isIndexValid(index))
        return QModelIndex();
    d->executePostedLayout();
    int i = d->viewIndex(index);
    if (++i >= d->viewItems.count())
        return QModelIndex();
    const QModelIndex firstColumnIndex = d->viewItems.at(i).index;
    return firstColumnIndex.sibling(firstColumnIndex.row(), index.column());
}

/*!
    \internal

    Lays out the items in the tree view.
*/
void QTreeView::doItemsLayout()
{
    Q_D(QTreeView);
    if (!d->customIndent) {
        // ### Qt 6: move to event()
        // QAbstractItemView calls this method in case of a style change,
        // so update the indentation here if it wasn't set manually.
        d->updateIndentationFromStyle();
    }
    if (d->hasRemovedItems) {
        //clean the QSet that may contains old (and this invalid) indexes
        d->hasRemovedItems = false;
        QSet<QPersistentModelIndex>::iterator it = d->expandedIndexes.begin();
        while (it != d->expandedIndexes.end()) {
            if (!it->isValid())
                it = d->expandedIndexes.erase(it);
            else
                ++it;
        }
        it = d->hiddenIndexes.begin();
        while (it != d->hiddenIndexes.end()) {
            if (!it->isValid())
                it = d->hiddenIndexes.erase(it);
            else
                ++it;
        }
    }
    d->viewItems.clear(); // prepare for new layout
    QModelIndex parent = d->root;
    if (d->model->hasChildren(parent)) {
        d->layout(-1);
    }
    QAbstractItemView::doItemsLayout();
    d->header->doItemsLayout();
}

/*!
  \reimp
*/
void QTreeView::reset()
{
    Q_D(QTreeView);
    d->expandedIndexes.clear();
    d->hiddenIndexes.clear();
    d->spanningIndexes.clear();
    d->viewItems.clear();
    QAbstractItemView::reset();
}

/*!
  Returns the horizontal offset of the items in the treeview.

  Note that the tree view uses the horizontal header section
  positions to determine the positions of columns in the view.

  \sa verticalOffset()
*/
int QTreeView::horizontalOffset() const
{
    Q_D(const QTreeView);
    return d->header->offset();
}

/*!
  Returns the vertical offset of the items in the tree view.

  \sa horizontalOffset()
*/
int QTreeView::verticalOffset() const
{
    Q_D(const QTreeView);
    if (d->verticalScrollMode == QAbstractItemView::ScrollPerItem) {
        if (d->uniformRowHeights)
            return verticalScrollBar()->value() * d->defaultItemHeight;
        // If we are scrolling per item and have non-uniform row heights,
        // finding the vertical offset in pixels is going to be relatively slow.
        // ### find a faster way to do this
        d->executePostedLayout();
        int offset = 0;
        const int cnt = std::min(d->viewItems.count(), verticalScrollBar()->value());
        for (int i = 0; i < cnt; ++i)
            offset += d->itemHeight(i);
        return offset;
    }
    // scroll per pixel
    return verticalScrollBar()->value();
}

/*!
    Move the cursor in the way described by \a cursorAction, using the
    information provided by the button \a modifiers.
*/
QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
{
    Q_D(QTreeView);
    Q_UNUSED(modifiers);

    d->executePostedLayout();

    QModelIndex current = currentIndex();
    if (!current.isValid()) {
        int i = d->below(-1);
        int c = 0;
        while (c < d->header->count() && d->header->isSectionHidden(d->header->logicalIndex(c)))
            ++c;
        if (i < d->viewItems.count() && c < d->header->count()) {
            return d->modelIndex(i, d->header->logicalIndex(c));
        }
        return QModelIndex();
    }
    int vi = -1;
    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:
#ifdef QT_KEYPAD_NAVIGATION
        if (vi == d->viewItems.count()-1 && QApplicationPrivate::keypadNavigationEnabled())
            return d->model->index(0, current.column(), d->root);
#endif
        return d->modelIndex(d->below(vi), current.column());
    case MovePrevious:
    case MoveUp:
#ifdef QT_KEYPAD_NAVIGATION
        if (vi == 0 && QApplicationPrivate::keypadNavigationEnabled())
            return d->modelIndex(d->viewItems.count() - 1, current.column());
#endif
        return d->modelIndex(d->above(vi), current.column());
    case MoveLeft: {
        QScrollBar *sb = horizontalScrollBar();
        if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) {
            d->collapse(vi, true);
            d->moveCursorUpdatedView = true;
        } else {
            bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, nullptr, this);
            if (descend) {
                QModelIndex par = current.parent();
                if (par.isValid() && par != rootIndex())
                    return par;
                else
                    descend = false;
            }
            if (!descend) {
                if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {
                    int visualColumn = d->header->visualIndex(current.column()) - 1;
                    while (visualColumn >= 0 && isColumnHidden(d->header->logicalIndex(visualColumn)))
                        visualColumn--;
                    int newColumn = d->header->logicalIndex(visualColumn);
                    QModelIndex next = current.sibling(current.row(), newColumn);
                    if (next.isValid())
                        return next;
                }

                int oldValue = sb->value();
                sb->setValue(sb->value() - sb->singleStep());
                if (oldValue != sb->value())
                    d->moveCursorUpdatedView = true;
            }

        }
        updateGeometries();
        viewport()->update();
        break;
    }
    case MoveRight:
        if (vi < d->viewItems.count() && !d->viewItems.at(vi).expanded && d->itemsExpandable
            && d->hasVisibleChildren(d->viewItems.at(vi).index)) {
            d->expand(vi, true);
            d->moveCursorUpdatedView = true;
        } else {
            bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, nullptr, this);
            if (descend) {
                QModelIndex idx = d->modelIndex(d->below(vi));
                if (idx.parent() == current)
                    return idx;
                else
                    descend = false;
            }
            if (!descend) {
                if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {
                    int visualColumn = d->header->visualIndex(current.column()) + 1;
                    while (visualColumn < d->model->columnCount(current.parent()) && isColumnHidden(d->header->logicalIndex(visualColumn)))
                        visualColumn++;
                    const int newColumn = d->header->logicalIndex(visualColumn);
                    const QModelIndex next = current.sibling(current.row(), newColumn);
                    if (next.isValid())
                        return next;
                }

                //last restort: we change the scrollbar value
                QScrollBar *sb = horizontalScrollBar();
                int oldValue = sb->value();
                sb->setValue(sb->value() + sb->singleStep());
                if (oldValue != sb->value())
                    d->moveCursorUpdatedView = true;
            }
        }
        updateGeometries();
        viewport()->update();
        break;
    case MovePageUp:
        return d->modelIndex(d->pageUp(vi), current.column());
    case MovePageDown:
        return d->modelIndex(d->pageDown(vi), current.column());
    case MoveHome:
        return d->modelIndex(d->itemForKeyHome(), current.column());
    case MoveEnd:
        return d->modelIndex(d->itemForKeyEnd(), current.column());
    }
    return current;
}

/*!
  Applies the selection \a command to the items in or touched by the
  rectangle, \a rect.

  \sa selectionCommand()
*/
void QTreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
{
    Q_D(QTreeView);
    if (!selectionModel() || rect.isNull())
        return;

    d->executePostedLayout();
    QPoint tl(isRightToLeft() ? qMax(rect.left(), rect.right())
              : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom()));
    QPoint br(isRightToLeft() ? qMin(rect.left(), rect.right()) :
              qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom()));
    QModelIndex topLeft = indexAt(tl);
    QModelIndex bottomRight = indexAt(br);
    if (!topLeft.isValid() && !bottomRight.isValid()) {
        if (command & QItemSelectionModel::Clear)
            selectionModel()->clear();
        return;
    }
    if (!topLeft.isValid() && !d->viewItems.isEmpty())
        topLeft = d->viewItems.constFirst().index;
    if (!bottomRight.isValid() && !d->viewItems.isEmpty()) {
        const int column = d->header->logicalIndex(d->header->count() - 1);
        const QModelIndex index = d->viewItems.constLast().index;
        bottomRight = index.sibling(index.row(), column);
    }

    if (!d->isIndexEnabled(topLeft) || !d->isIndexEnabled(bottomRight))
        return;

    d->select(topLeft, bottomRight, command);
}

/*!
  Returns the rectangle from the viewport of the items in the given
  \a selection.

  Since 4.7, the returned region only contains rectangles intersecting
  (or included in) the viewport.
*/
QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) const
{
    Q_D(const QTreeView);
    if (selection.isEmpty())
        return QRegion();

    QRegion selectionRegion;
    const QRect &viewportRect = d->viewport->rect();
    for (const auto &range : selection) {
        if (!range.isValid())
            continue;
        QModelIndex parent = range.parent();
        QModelIndex leftIndex = range.topLeft();
        int columnCount = d->model->columnCount(parent);
        while (leftIndex.isValid() && isIndexHidden(leftIndex)) {
            if (leftIndex.column() + 1 < columnCount)
                leftIndex = d->model->index(leftIndex.row(), leftIndex.column() + 1, parent);
            else
                leftIndex = QModelIndex();
        }
        if (!leftIndex.isValid())
            continue;
        const QRect leftRect = visualRect(leftIndex);
        int top = leftRect.top();
        QModelIndex rightIndex = range.bottomRight();
        while (rightIndex.isValid() && isIndexHidden(rightIndex)) {
            if (rightIndex.column() - 1 >= 0)
                rightIndex = d->model->index(rightIndex.row(), rightIndex.column() - 1, parent);
            else
                rightIndex = QModelIndex();
        }
        if (!rightIndex.isValid())
            continue;
        const QRect rightRect = visualRect(rightIndex);
        int bottom = rightRect.bottom();
        if (top > bottom)
            qSwap<int>(top, bottom);
        int height = bottom - top + 1;
        if (d->header->sectionsMoved()) {
            for (int c = range.left(); c <= range.right(); ++c) {
                const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
                if (viewportRect.intersects(rangeRect))
                    selectionRegion += rangeRect;
            }
        } else {
            QRect combined = leftRect|rightRect;
            combined.setX(columnViewportPosition(isRightToLeft() ? range.right() : range.left()));
            if (viewportRect.intersects(combined))
                selectionRegion += combined;
        }
    }
    return selectionRegion;
}

/*!
  \reimp
*/
QModelIndexList QTreeView::selectedIndexes() const
{
    QModelIndexList viewSelected;
    QModelIndexList modelSelected;
    if (selectionModel())
        modelSelected = selectionModel()->selectedIndexes();
    for (int i = 0; i < modelSelected.count(); ++i) {
        // check that neither the parents nor the index is hidden before we add
        QModelIndex index = modelSelected.at(i);
        while (index.isValid() && !isIndexHidden(index))
            index = index.parent();
        if (index.isValid())
            continue;
        viewSelected.append(modelSelected.at(i));
    }
    return viewSelected;
}

/*!
  Scrolls the contents of the tree view by (\a dx, \a dy).
*/
void QTreeView::scrollContentsBy(int dx, int dy)
{
    Q_D(QTreeView);

    d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling

    dx = isRightToLeft() ? -dx : dx;
    if (dx) {
        int oldOffset = d->header->offset();
        d->header->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());
        if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
            int newOffset = d->header->offset();
            dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
        }
    }

    const int itemHeight = d->defaultItemHeight <= 0 ? sizeHintForRow(0) : d->defaultItemHeight;
    if (d->viewItems.isEmpty() || itemHeight == 0)
        return;

    // guestimate the number of items in the viewport
    int viewCount = d->viewport->height() / itemHeight;
    int maxDeltaY = qMin(d->viewItems.count(), viewCount);
    // no need to do a lot of work if we are going to redraw the whole thing anyway
    if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {
        verticalScrollBar()->update();
        d->viewport->update();
        return;
    }

    if (dy && verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
        int currentScrollbarValue = verticalScrollBar()->value();
        int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy)
        int currentViewIndex = currentScrollbarValue; // the first visible item
        int previousViewIndex = previousScrollbarValue;
        dy = 0;
        if (previousViewIndex < currentViewIndex) { // scrolling down
            for (int i = previousViewIndex; i < currentViewIndex; ++i) {
                if (i < d->viewItems.count())
                    dy -= d->itemHeight(i);
            }
        } else if (previousViewIndex > currentViewIndex) { // scrolling up
            for (int i = previousViewIndex - 1; i >= currentViewIndex; --i) {
                if (i < d->viewItems.count())
                    dy += d->itemHeight(i);
            }
        }
    }

    d->scrollContentsBy(dx, dy);
}

/*!
  This slot is called whenever a column has been moved.
*/
void QTreeView::columnMoved()
{
    Q_D(QTreeView);
    updateEditorGeometries();
    d->viewport->update();
}

/*!
  \internal
*/
void QTreeView::reexpand()
{
    // do nothing
}

/*!
  Informs the view that the rows from the \a start row to the \a end row
  inclusive have been inserted into the \a parent model item.
*/
void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
{
    Q_D(QTreeView);
    // if we are going to do a complete relayout anyway, there is no need to update
    if (d->delayedPendingLayout) {
        QAbstractItemView::rowsInserted(parent, start, end);
        return;
    }

    //don't add a hierarchy on a column != 0
    if (parent.column() != 0 && parent.isValid()) {
        QAbstractItemView::rowsInserted(parent, start, end);
        return;
    }

    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;
    }

    const int parentItem = d->viewIndex(parent);
    if (((parentItem != -1) && d->viewItems.at(parentItem).expanded)
        || (parent == d->root)) {
        d->doDelayedItemsLayout();
    } else if (parentItem != -1 && parentRowCount == delta) {
        // 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);
}

/*!
  Informs the view that the rows from the \a start row to the \a end row
  inclusive are about to removed from the given \a parent model item.
*/
void QTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
    Q_D(QTreeView);
    QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
    d->viewItems.clear();
}

/*!
    \since 4.1

    Informs the view that the rows from the \a start row to the \a end row
    inclusive have been removed from the given \a parent model item.
*/
void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end)
{
    Q_D(QTreeView);
    d->viewItems.clear();
    d->doDelayedItemsLayout();
    d->hasRemovedItems = true;
    d->_q_rowsRemoved(parent, start, end);
}

/*!
  Informs the tree view that the number of columns in the tree view has
  changed from \a oldCount to \a newCount.
*/
void QTreeView::columnCountChanged(int oldCount, int newCount)
{
    Q_D(QTreeView);
    if (oldCount == 0 && newCount > 0) {
        //if the first column has just been added we need to relayout.
        d->doDelayedItemsLayout();
    }

    if (isVisible())
        updateGeometries();
    viewport()->update();
}

/*!
  Resizes the \a column given to the size of its contents.

  \sa columnWidth(), setColumnWidth(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTreeView::resizeColumnToContents(int column)
{
    Q_D(QTreeView);
    d->executePostedLayout();
    if (column < 0 || column >= d->header->count())
        return;
    int contents = sizeHintForColumn(column);
    int header = d->header->isHidden() ? 0 : d->header->sectionSizeHint(column);
    d->header->resizeSection(column, qMax(contents, header));
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
  \obsolete
  \overload

  This function is deprecated. Use
  sortByColumn(int column, Qt::SortOrder order) instead.
  Sorts the model by the values in the given \a column.
*/
void QTreeView::sortByColumn(int column)
{
    Q_D(QTreeView);
    sortByColumn(column, d->header->sortIndicatorOrder());
}
#endif

/*!
  \since 4.2

  Sorts the model by the values in the given \a column and \a order.

  \a column may be -1, in which case no sort indicator will be shown
  and the model will return to its natural, unsorted order. Note that not
  all models support this and may even crash in this case.

  \sa sortingEnabled
*/
void QTreeView::sortByColumn(int column, Qt::SortOrder order)
{
    Q_D(QTreeView);
    if (column < -1)
        return;
    // If sorting is enabled it will emit a signal connected to
    // _q_sortIndicatorChanged, which then actually sorts
    d->header->setSortIndicator(column, order);
    // If sorting is not enabled, force to sort now
    if (!d->sortingEnabled)
        d->model->sort(column, order);
}

/*!
  \reimp
*/
void QTreeView::selectAll()
{
    Q_D(QTreeView);
    if (!selectionModel())
        return;
    SelectionMode mode = d->selectionMode;
    d->executePostedLayout(); //make sure we lay out the items
    if (mode != SingleSelection && mode != NoSelection && !d->viewItems.isEmpty()) {
        const QModelIndex &idx = d->viewItems.constLast().index;
        QModelIndex lastItemIndex = idx.sibling(idx.row(), d->model->columnCount(idx.parent()) - 1);
        d->select(d->viewItems.constFirst().index, lastItemIndex,
                  QItemSelectionModel::ClearAndSelect
                  |QItemSelectionModel::Rows);
    }
}

/*!
  \reimp
*/
QSize QTreeView::viewportSizeHint() const
{
    Q_D(const QTreeView);
    d->executePostedLayout(); // Make sure that viewItems are up to date.

    if (d->viewItems.size() == 0)
        return QAbstractItemView::viewportSizeHint();

    // Get rect for last item
    const QRect deepestRect = visualRect(d->viewItems.last().index);

    if (!deepestRect.isValid())
        return QAbstractItemView::viewportSizeHint();

    QSize result = QSize(d->header->length(), deepestRect.bottom() + 1);

    // add size for header
    result += QSize(0, d->header->isHidden() ? 0 : d->header->height());

    return result;
}

/*!
  \since 4.2
  Expands all expandable items.

  \warning: if the model contains a large number of items,
  this function will take some time to execute.

  \sa collapseAll(), expand(), collapse(), setExpanded()
*/
void QTreeView::expandAll()
{
    Q_D(QTreeView);
    d->viewItems.clear();
    d->interruptDelayedItemsLayout();
    d->layout(-1, true);
    updateGeometries();
    d->viewport->update();
}

/*!
  \since 5.13
  Expands the item at the given \a index and all its children to the
  given \a depth. The \a depth is relative to the given \a index.
  A \a depth of -1 will expand all children, a \a depth of 0 will
  only expand the given \a index.

  \warning: if the model contains a large number of items,
  this function will take some time to execute.

  \sa expandAll()
*/
void QTreeView::expandRecursively(const QModelIndex &index, int depth)
{
    Q_D(QTreeView);

    if (depth < -1)
        return;
    // do layouting only once after expanding is done
    d->doDelayedItemsLayout();
    expand(index);
    if (depth == 0)
        return;
    QStack<QPair<QModelIndex, int>> parents;
    parents.push({index, 0});
    while (!parents.isEmpty()) {
        const QPair<QModelIndex, int> elem = parents.pop();
        const QModelIndex &parent = elem.first;
        const int curDepth = elem.second;
        const int rowCount = d->model->rowCount(parent);
        for (int row = 0; row < rowCount; ++row) {
            const QModelIndex child = d->model->index(row, 0, parent);
            if (!d->isIndexValid(child))
                break;
            if (depth == -1 || curDepth + 1 < depth)
                parents.push({child, curDepth + 1});
            if (d->isIndexExpanded(child))
                continue;
            if (d->storeExpanded(child))
                emit expanded(child);
        }
    }
}

/*!
  \since 4.2

  Collapses all expanded items.

  \sa expandAll(), expand(), collapse(), setExpanded()
*/
void QTreeView::collapseAll()
{
    Q_D(QTreeView);
    QSet<QPersistentModelIndex> old_expandedIndexes;
    old_expandedIndexes = d->expandedIndexes;
    d->expandedIndexes.clear();
    if (!signalsBlocked() && isSignalConnected(QMetaMethod::fromSignal(&QTreeView::collapsed))) {
        QSet<QPersistentModelIndex>::const_iterator i = old_expandedIndexes.constBegin();
        for (; i != old_expandedIndexes.constEnd(); ++i) {
            const QPersistentModelIndex &mi = (*i);
            if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))
                emit collapsed(mi);
        }
    }
    doItemsLayout();
}

/*!
  \since 4.3
  Expands all expandable items to the given \a depth.

  \sa expandAll(), collapseAll(), expand(), collapse(), setExpanded()
*/
void QTreeView::expandToDepth(int depth)
{
    Q_D(QTreeView);
    d->viewItems.clear();
    QSet<QPersistentModelIndex> old_expandedIndexes;
    old_expandedIndexes = d->expandedIndexes;
    d->expandedIndexes.clear();
    d->interruptDelayedItemsLayout();
    d->layout(-1);
    for (int i = 0; i < d->viewItems.count(); ++i) {
        if (d->viewItems.at(i).level <= (uint)depth) {
            d->viewItems[i].expanded = true;
            d->layout(i);
            d->storeExpanded(d->viewItems.at(i).index);
        }
    }

    bool someSignalEnabled = isSignalConnected(QMetaMethod::fromSignal(&QTreeView::collapsed));
    someSignalEnabled |= isSignalConnected(QMetaMethod::fromSignal(&QTreeView::expanded));

    if (!signalsBlocked() && someSignalEnabled) {
        // emit signals
        QSet<QPersistentModelIndex> collapsedIndexes = old_expandedIndexes - d->expandedIndexes;
        QSet<QPersistentModelIndex>::const_iterator i = collapsedIndexes.constBegin();
        for (; i != collapsedIndexes.constEnd(); ++i) {
            const QPersistentModelIndex &mi = (*i);
            if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))
                emit collapsed(mi);
        }

        QSet<QPersistentModelIndex> expandedIndexs = d->expandedIndexes - old_expandedIndexes;
        i = expandedIndexs.constBegin();
        for (; i != expandedIndexs.constEnd(); ++i) {
            const QPersistentModelIndex &mi = (*i);
            if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))
                emit expanded(mi);
        }
    }

    updateGeometries();
    d->viewport->update();
}

/*!
    This function is called whenever \a{column}'s size is changed in
    the header. \a oldSize and \a newSize give the previous size and
    the new size in pixels.

    \sa setColumnWidth()
*/
void QTreeView::columnResized(int column, int /* oldSize */, int /* newSize */)
{
    Q_D(QTreeView);
    d->columnsToUpdate.append(column);
    if (d->columnResizeTimerID == 0)
        d->columnResizeTimerID = startTimer(0);
}

/*!
  \reimp
*/
void QTreeView::updateGeometries()
{
    Q_D(QTreeView);
    if (d->header) {
        if (d->geometryRecursionBlock)
            return;
        d->geometryRecursionBlock = true;
        int height = 0;
        if (!d->header->isHidden()) {
            height = qMax(d->header->minimumHeight(), d->header->sizeHint().height());
            height = qMin(height, d->header->maximumHeight());
        }
        setViewportMargins(0, height, 0, 0);
        QRect vg = d->viewport->geometry();
        QRect geometryRect(vg.left(), vg.top() - height, vg.width(), height);
        d->header->setGeometry(geometryRect);
        QMetaObject::invokeMethod(d->header, "updateGeometries");
        d->updateScrollBars();
        d->geometryRecursionBlock = false;
    }
    QAbstractItemView::updateGeometries();
}

/*!
  Returns the size hint for the \a column's width or -1 if there is no
  model.

  If you need to set the width of a given column to a fixed value, call
  QHeaderView::resizeSection() on the view's header.

  If you reimplement this function in a subclass, note that the value you
  return is only used when resizeColumnToContents() is called. In that case,
  if a larger column width is required by either the view's header or
  the item delegate, that width will be used instead.

  \sa QWidget::sizeHint, header(), QHeaderView::resizeContentsPrecision()
*/
int QTreeView::sizeHintForColumn(int column) const
{
    Q_D(const QTreeView);
    d->executePostedLayout();
    if (d->viewItems.isEmpty())
        return -1;
    ensurePolished();
    int w = 0;
    QStyleOptionViewItem option = d->viewOptionsV1();
    const QVector<QTreeViewItem> viewItems = d->viewItems;

    const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.

    int offset = 0;
    int start = d->firstVisibleItem(&offset);
    int end = d->lastVisibleItem(start, offset);
    if (start < 0 || end < 0 || end == viewItems.size() - 1) {
        end = viewItems.size() - 1;
        if (maximumProcessRows < 0) {
            start = 0;
        } else if (maximumProcessRows == 0) {
            start = qMax(0, end - 1);
            int remainingHeight = viewport()->height();
            while (start > 0 && remainingHeight > 0) {
                remainingHeight -= d->itemHeight(start);
                --start;
            }
        } else {
            start = qMax(0, end - maximumProcessRows);
        }
    }

    int rowsProcessed = 0;

    for (int i = start; i <= end; ++i) {
        if (viewItems.at(i).spanning)
            continue; // we have no good size hint
        QModelIndex index = viewItems.at(i).index;
        index = index.sibling(index.row(), column);
        w = d->widthHintForIndex(index, w, option, i);
        ++rowsProcessed;
        if (rowsProcessed == maximumProcessRows)
            break;
    }

    --end;
    int actualBottom = viewItems.size() - 1;

    if (maximumProcessRows == 0)
        rowsProcessed = 0; // skip the while loop

    while (rowsProcessed != maximumProcessRows && (start > 0 || end < actualBottom)) {
        int idx  = -1;

        if ((rowsProcessed % 2 && start > 0) || end == actualBottom) {
            while (start > 0) {
                --start;
                if (viewItems.at(start).spanning)
                    continue;
                idx = start;
                break;
            }
        } else {
            while (end < actualBottom) {
                ++end;
                if (viewItems.at(end).spanning)
                    continue;
                idx = end;
                break;
            }
        }
        if (idx < 0)
            continue;

        QModelIndex index = viewItems.at(idx).index;
        index = index.sibling(index.row(), column);
        w = d->widthHintForIndex(index, w, option, idx);
        ++rowsProcessed;
    }
    return w;
}

/*!
  Returns the size hint for the row indicated by \a index.

  \sa sizeHintForColumn(), uniformRowHeights()
*/
int QTreeView::indexRowSizeHint(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    if (!d->isIndexValid(index) || !d->itemDelegate)
        return 0;

    int start = -1;
    int end = -1;
    int indexRow = index.row();
    int count = d->header->count();
    bool emptyHeader = (count == 0);
    QModelIndex parent = index.parent();

    if (count && isVisible()) {
        // If the sections have moved, we end up checking too many or too few
        start = d->header->visualIndexAt(0);
    } else {
        // If the header has not been laid out yet, we use the model directly
        count = d->model->columnCount(parent);
    }

    if (isRightToLeft()) {
        start = (start == -1 ? count - 1 : start);
        end = 0;
    } else {
        start = (start == -1 ? 0 : start);
        end = count - 1;
    }

    if (end < start)
        qSwap(end, start);

    int height = -1;
    QStyleOptionViewItem option = d->viewOptionsV1();
    // ### If we want word wrapping in the items,
    // ### we need to go through all the columns
    // ### and set the width of the column

    // Hack to speed up the function
    option.rect.setWidth(-1);

    for (int column = start; column <= end; ++column) {
        int logicalColumn = emptyHeader ? column : d->header->logicalIndex(column);
        if (d->header->isSectionHidden(logicalColumn))
            continue;
        QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);
        if (idx.isValid()) {
            QWidget *editor = d->editorForIndex(idx).widget.data();
            if (editor && d->persistent.contains(editor)) {
                height = qMax(height, editor->sizeHint().height());
                int min = editor->minimumSize().height();
                int max = editor->maximumSize().height();
                height = qBound(min, height, max);
            }
            int hint = d->delegateForIndex(idx)->sizeHint(option, idx).height();
            height = qMax(height, hint);
        }
    }

    return height;
}

/*!
    \since 4.3
    Returns the height of the row indicated by the given \a index.
    \sa indexRowSizeHint()
*/
int QTreeView::rowHeight(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    d->executePostedLayout();
    int i = d->viewIndex(index);
    if (i == -1)
        return 0;
    return d->itemHeight(i);
}

/*!
  \internal
*/
void QTreeView::horizontalScrollbarAction(int action)
{
    QAbstractItemView::horizontalScrollbarAction(action);
}

/*!
  \reimp
*/
bool QTreeView::isIndexHidden(const QModelIndex &index) const
{
    return (isColumnHidden(index.column()) || isRowHidden(index.row(), index.parent()));
}

/*
  private implementation
*/
void QTreeViewPrivate::initialize()
{
    Q_Q(QTreeView);

    updateIndentationFromStyle();
    updateStyledFrameWidths();
    q->setSelectionBehavior(QAbstractItemView::SelectRows);
    q->setSelectionMode(QAbstractItemView::SingleSelection);
    q->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
    q->setAttribute(Qt::WA_MacShowFocusRect);

    QHeaderView *header = new QHeaderView(Qt::Horizontal, q);
    header->setSectionsMovable(true);
    header->setStretchLastSection(true);
    header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
    q->setHeader(header);
#if QT_CONFIG(animation)
    animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, q) > 0;
    QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
#endif // animation
}

void QTreeViewPrivate::expand(int item, bool emitSignal)
{
    Q_Q(QTreeView);

    if (item == -1 || viewItems.at(item).expanded)
        return;
    const QModelIndex index = viewItems.at(item).index;
    if (index.flags() & Qt::ItemNeverHasChildren)
        return;

#if QT_CONFIG(animation)
    if (emitSignal && animationsEnabled)
        prepareAnimatedOperation(item, QVariantAnimation::Forward);
#endif // animation
     //if already animating, stateBeforeAnimation is set to the correct value
    if (state != QAbstractItemView::AnimatingState)
        stateBeforeAnimation = state;
    q->setState(QAbstractItemView::ExpandingState);
    storeExpanded(index);
    viewItems[item].expanded = true;
    layout(item);
    q->setState(stateBeforeAnimation);

    if (model->canFetchMore(index))
        model->fetchMore(index);
    if (emitSignal) {
        emit q->expanded(index);
#if QT_CONFIG(animation)
        if (animationsEnabled)
            beginAnimatedOperation();
#endif // animation
    }
}

void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
{
    viewItems.insert(pos, count, viewItem);
    QTreeViewItem *items = viewItems.data();
    for (int i = pos + count; i < viewItems.count(); i++)
        if (items[i].parentItem >= pos)
            items[i].parentItem += count;
}

void QTreeViewPrivate::removeViewItems(int pos, int count)
{
    viewItems.remove(pos, count);
    QTreeViewItem *items = viewItems.data();
    for (int i = pos; i < viewItems.count(); i++)
        if (items[i].parentItem >= pos)
            items[i].parentItem -= count;
}

#if 0
bool QTreeViewPrivate::checkViewItems() const
{
    for (int i = 0; i < viewItems.count(); ++i) {
        const QTreeViewItem &vi = viewItems.at(i);
        if (vi.parentItem == -1) {
            Q_ASSERT(!vi.index.parent().isValid() || vi.index.parent() == root);
        } else {
            Q_ASSERT(vi.index.parent() == viewItems.at(vi.parentItem).index);
        }
    }
    return true;
}
#endif

void QTreeViewPrivate::collapse(int item, bool emitSignal)
{
    Q_Q(QTreeView);

    if (item == -1 || expandedIndexes.isEmpty())
        return;

    //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll
    delayedAutoScroll.stop();

    int total = viewItems.at(item).total;
    const QModelIndex &modelIndex = viewItems.at(item).index;
    if (!isPersistent(modelIndex))
        return; // if the index is not persistent, no chances it is expanded
    QSet<QPersistentModelIndex>::iterator it = expandedIndexes.find(modelIndex);
    if (it == expandedIndexes.end() || viewItems.at(item).expanded == false)
        return; // nothing to do

#if QT_CONFIG(animation)
    if (emitSignal && animationsEnabled)
        prepareAnimatedOperation(item, QVariantAnimation::Backward);
#endif // animation

    //if already animating, stateBeforeAnimation is set to the correct value
    if (state != QAbstractItemView::AnimatingState)
        stateBeforeAnimation = state;
    q->setState(QAbstractItemView::CollapsingState);
    expandedIndexes.erase(it);
    viewItems[item].expanded = false;
    int index = item;
    while (index > -1) {
        viewItems[index].total -= total;
        index = viewItems[index].parentItem;
    }
    removeViewItems(item + 1, total); // collapse
    q->setState(stateBeforeAnimation);

    if (emitSignal) {
        emit q->collapsed(modelIndex);
#if QT_CONFIG(animation)
        if (animationsEnabled)
            beginAnimatedOperation();
#endif // animation
    }
}

#if QT_CONFIG(animation)
void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction)
{
    animatedOperation.item = item;
    animatedOperation.viewport = viewport;
    animatedOperation.setDirection(direction);

    int top = coordinateForItem(item) + itemHeight(item);
    QRect rect = viewport->rect();
    rect.setTop(top);
    if (direction == QVariantAnimation::Backward) {
        const int limit = rect.height() * 2;
        int h = 0;
        int c = item + viewItems.at(item).total + 1;
        for (int i = item + 1; i < c && h < limit; ++i)
            h += itemHeight(i);
        rect.setHeight(h);
        animatedOperation.setEndValue(top + h);
    }
    animatedOperation.setStartValue(top);
    animatedOperation.before = renderTreeToPixmapForAnimation(rect);
}

void QTreeViewPrivate::beginAnimatedOperation()
{
    Q_Q(QTreeView);

    QRect rect = viewport->rect();
    rect.setTop(animatedOperation.top());
    if (animatedOperation.direction() == QVariantAnimation::Forward) {
        const int limit = rect.height() * 2;
        int h = 0;
        int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1;
        for (int i = animatedOperation.item + 1; i < c && h < limit; ++i)
            h += itemHeight(i);
        rect.setHeight(h);
        animatedOperation.setEndValue(animatedOperation.top() + h);
    }

    if (!rect.isEmpty()) {
        animatedOperation.after = renderTreeToPixmapForAnimation(rect);

        q->setState(QAbstractItemView::AnimatingState);
        animatedOperation.start(); //let's start the animation
    }
}

void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
{
    const int start = animatedOperation.startValue().toInt(),
        end = animatedOperation.endValue().toInt(),
        current = animatedOperation.currentValue().toInt();
    bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;
    const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;
    painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());
    const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before;
    painter->drawPixmap(0, current, bottom);
}

QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) const
{
    Q_Q(const QTreeView);
    QPixmap pixmap(rect.size() * q->devicePixelRatioF());
    pixmap.setDevicePixelRatio(q->devicePixelRatioF());
    if (rect.size().isEmpty())
        return pixmap;
    pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels.
    QPainter painter(&pixmap);
    painter.fillRect(QRect(QPoint(0,0), rect.size()), q->palette().base());
    painter.translate(0, -rect.top());
    q->drawTree(&painter, QRegion(rect));
    painter.end();

    //and now let's render the editors the editors
    QStyleOptionViewItem option = viewOptionsV1();
    for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
        QWidget *editor = it.key();
        const QModelIndex &index = it.value();
        option.rect = q->visualRect(index);
        if (option.rect.isValid()) {

            if (QAbstractItemDelegate *delegate = delegateForIndex(index))
                delegate->updateEditorGeometry(editor, option, index);

            const QPoint pos = editor->pos();
            if (rect.contains(pos)) {
                editor->render(&pixmap, pos - rect.topLeft());
                //the animation uses pixmap to display the treeview's content
                //the editor is rendered on this pixmap and thus can (should) be hidden
                editor->hide();
            }
        }
    }


    return pixmap;
}

void QTreeViewPrivate::_q_endAnimatedOperation()
{
    Q_Q(QTreeView);
    q->setState(stateBeforeAnimation);
    q->updateGeometries();
    viewport->update();
}
#endif // animation

void QTreeViewPrivate::_q_modelAboutToBeReset()
{
    viewItems.clear();
}

void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
    if (start <= 0 && 0 <= end)
        viewItems.clear();
    QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);
}

void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)
{
    if (start <= 0 && 0 <= end)
        doDelayedItemsLayout();
    QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
}

/** \internal
    creates and initialize the viewItem structure of the children of the element \li

    set \a recursiveExpanding if the function has to expand all the children (called from expandAll)
    \a afterIsUninitialized is when we recurse from layout(-1), it means all the items after 'i' are
    not yet initialized and need not to be moved
 */
void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninitialized)
{
    Q_Q(QTreeView);
    QModelIndex current;
    QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i);

    if (i>=0 && !parent.isValid()) {
        //modelIndex() should never return something invalid for the real items.
        //This can happen if columncount has been set to 0.
        //To avoid infinite loop we stop here.
        return;
    }

    int count = 0;
    if (model->hasChildren(parent)) {
        if (model->canFetchMore(parent))
            model->fetchMore(parent);
        count = model->rowCount(parent);
    }

    bool expanding = true;
    if (i == -1) {
        if (uniformRowHeights) {
            QModelIndex index = model->index(0, 0, parent);
            defaultItemHeight = q->indexRowSizeHint(index);
        }
        viewItems.resize(count);
        afterIsUninitialized = true;
    } else if (viewItems[i].total != (uint)count) {
        if (!afterIsUninitialized)
            insertViewItems(i + 1, count, QTreeViewItem()); // expand
        else if (count > 0)
            viewItems.resize(viewItems.count() + count);
    } else {
        expanding = false;
    }

    int first = i + 1;
    int level = (i >= 0 ? viewItems.at(i).level + 1 : 0);
    int hidden = 0;
    int last = 0;
    int children = 0;
    QTreeViewItem *item = nullptr;
    for (int j = first; j < first + count; ++j) {
        current = model->index(j - first, 0, parent);
        if (isRowHidden(current)) {
            ++hidden;
            last = j - hidden + children;
        } else {
            last = j - hidden + children;
            if (item)
                item->hasMoreSiblings = true;
            item = &viewItems[last];
            item->index = current;
            item->parentItem = i;
            item->level = level;
            item->height = 0;
            item->spanning = q->isFirstColumnSpanned(current.row(), parent);
            item->expanded = false;
            item->total = 0;
            item->hasMoreSiblings = false;
            if ((recursiveExpanding && !(current.flags() & Qt::ItemNeverHasChildren)) || isIndexExpanded(current)) {
                if (recursiveExpanding && storeExpanded(current) && !q->signalsBlocked())
                    emit q->expanded(current);
                item->expanded = true;
                layout(last, recursiveExpanding, afterIsUninitialized);
                item = &viewItems[last];
                children += item->total;
                item->hasChildren = item->total > 0;
                last = j - hidden + children;
            } else {
                item->hasChildren = hasVisibleChildren(current);
            }
        }
    }

    // remove hidden items
    if (hidden > 0) {
        if (!afterIsUninitialized)
            removeViewItems(last + 1, hidden);
        else
            viewItems.resize(viewItems.size() - hidden);
    }

    if (!expanding)
        return; // nothing changed

    while (i > -1) {
        viewItems[i].total += count - hidden;
        i = viewItems[i].parentItem;
    }
}

int QTreeViewPrivate::pageUp(int i) const
{
    int index = itemAtCoordinate(coordinateForItem(i) - viewport->height());
    while (isItemHiddenOrDisabled(index))
        index--;
    if (index == -1)
        index = 0;
    while (isItemHiddenOrDisabled(index))
        index++;
    return index >= viewItems.count() ? 0 : index;
}

int QTreeViewPrivate::pageDown(int i) const
{
    int index = itemAtCoordinate(coordinateForItem(i) + viewport->height());
    while (isItemHiddenOrDisabled(index))
        index++;
    if (index == -1 || index >= viewItems.count())
        index = viewItems.count() - 1;
    while (isItemHiddenOrDisabled(index))
        index--;
    return index == -1 ? viewItems.count() - 1 : index;
}

int QTreeViewPrivate::itemForKeyHome() const
{
    int index = 0;
    while (isItemHiddenOrDisabled(index))
        index++;
    return index >= viewItems.count() ? 0 : index;
}

int QTreeViewPrivate::itemForKeyEnd() const
{
    int index = viewItems.count() - 1;
    while (isItemHiddenOrDisabled(index))
        index--;
    return index == -1 ? viewItems.count() - 1 : index;
}

int QTreeViewPrivate::indentationForItem(int item) const
{
    if (item < 0 || item >= viewItems.count())
        return 0;
    int level = viewItems.at(item).level;
    if (rootDecoration)
        ++level;
    return level * indent;
}

int QTreeViewPrivate::itemHeight(int item) const
{
    if (uniformRowHeights)
        return defaultItemHeight;
    if (viewItems.isEmpty())
        return 0;
    const QModelIndex &index = viewItems.at(item).index;
    if (!index.isValid())
        return 0;
    int height = viewItems.at(item).height;
    if (height <= 0) {
        height = q_func()->indexRowSizeHint(index);
        viewItems[item].height = height;
    }
    return qMax(height, 0);
}


/*!
  \internal
  Returns the viewport y coordinate for \a item.
*/
int QTreeViewPrivate::coordinateForItem(int item) const
{
    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
        if (uniformRowHeights)
            return (item * defaultItemHeight) - vbar->value();
        // ### optimize (maybe do like QHeaderView by letting items have startposition)
        int y = 0;
        for (int i = 0; i < viewItems.count(); ++i) {
            if (i == item)
                return y - vbar->value();
            y += itemHeight(i);
        }
    } else { // ScrollPerItem
        int topViewItemIndex = vbar->value();
        if (uniformRowHeights)
            return defaultItemHeight * (item - topViewItemIndex);
        if (item >= topViewItemIndex) {
            // search in the visible area first and continue down
            // ### slow if the item is not visible
            int viewItemCoordinate = 0;
            int viewItemIndex = topViewItemIndex;
            while (viewItemIndex < viewItems.count()) {
                if (viewItemIndex == item)
                    return viewItemCoordinate;
                viewItemCoordinate += itemHeight(viewItemIndex);
                ++viewItemIndex;
            }
            // below the last item in the view
            Q_ASSERT(false);
            return viewItemCoordinate;
        } else {
            // search the area above the viewport (used for editor widgets)
            int viewItemCoordinate = 0;
            for (int viewItemIndex = topViewItemIndex; viewItemIndex > 0; --viewItemIndex) {
                if (viewItemIndex == item)
                    return viewItemCoordinate;
                viewItemCoordinate -= itemHeight(viewItemIndex - 1);
            }
            return viewItemCoordinate;
        }
    }
    return 0;
}

/*!
  \internal
  Returns the index of the view item at the
  given viewport \a coordinate.

  \sa modelIndex()
*/
int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
{
    const int itemCount = viewItems.count();
    if (itemCount == 0)
        return -1;
    if (uniformRowHeights && defaultItemHeight <= 0)
        return -1;
    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
        if (uniformRowHeights) {
            const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight;
            return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
        }
        // ### optimize
        int viewItemCoordinate = 0;
        const int contentsCoordinate = coordinate + vbar->value();
        for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {
            viewItemCoordinate += itemHeight(viewItemIndex);
            if (viewItemCoordinate > contentsCoordinate)
                return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
        }
    } else { // ScrollPerItem
        int topViewItemIndex = vbar->value();
        if (uniformRowHeights) {
            if (coordinate < 0)
                coordinate -= defaultItemHeight - 1;
            const int viewItemIndex = topViewItemIndex + (coordinate / defaultItemHeight);
            return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
        }
        if (coordinate >= 0) {
            // the coordinate is in or below the viewport
            int viewItemCoordinate = 0;
            for (int viewItemIndex = topViewItemIndex; viewItemIndex < viewItems.count(); ++viewItemIndex) {
                viewItemCoordinate += itemHeight(viewItemIndex);
                if (viewItemCoordinate > coordinate)
                    return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
            }
        } else {
            // the coordinate is above the viewport
            int viewItemCoordinate = 0;
            for (int viewItemIndex = topViewItemIndex; viewItemIndex >= 0; --viewItemIndex) {
                if (viewItemCoordinate <= coordinate)
                    return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
                viewItemCoordinate -= itemHeight(viewItemIndex);
            }
        }
    }
    return -1;
}

int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const
{
    if (!_index.isValid() || viewItems.isEmpty())
        return -1;

    const int totalCount = viewItems.count();
    const QModelIndex index = _index.sibling(_index.row(), 0);
    const int row = index.row();
    const quintptr internalId = index.internalId();

    // We start nearest to the lastViewedItem
    int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem);
    for (int i = 0; i < localCount; ++i) {
        const QModelIndex &idx1 = viewItems.at(lastViewedItem + i).index;
        if (idx1.row() == row && idx1.internalId() == internalId) {
            lastViewedItem = lastViewedItem + i;
            return lastViewedItem;
        }
        const QModelIndex &idx2 = viewItems.at(lastViewedItem - i - 1).index;
        if (idx2.row() == row && idx2.internalId() == internalId) {
            lastViewedItem = lastViewedItem - i - 1;
            return lastViewedItem;
        }
    }

    for (int j = qMax(0, lastViewedItem + localCount); j < totalCount; ++j) {
        const QModelIndex &idx = viewItems.at(j).index;
        if (idx.row() == row && idx.internalId() == internalId) {
            lastViewedItem = j;
            return j;
        }
    }
    for (int j = qMin(totalCount, lastViewedItem - localCount) - 1; j >= 0; --j) {
        const QModelIndex &idx = viewItems.at(j).index;
        if (idx.row() == row && idx.internalId() == internalId) {
            lastViewedItem = j;
            return j;
        }
    }

    // nothing found
    return -1;
}

QModelIndex QTreeViewPrivate::modelIndex(int i, int column) const
{
    if (i < 0 || i >= viewItems.count())
        return QModelIndex();

    QModelIndex ret = viewItems.at(i).index;
    if (column)
        ret = ret.sibling(ret.row(), column);
    return ret;
}

int QTreeViewPrivate::firstVisibleItem(int *offset) const
{
    const int value = vbar->value();
    if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
        if (offset)
            *offset = 0;
        return (value < 0 || value >= viewItems.count()) ? -1 : value;
    }
    // ScrollMode == ScrollPerPixel
    if (uniformRowHeights) {
        if (!defaultItemHeight)
            return -1;

        if (offset)
            *offset = -(value % defaultItemHeight);
        return value / defaultItemHeight;
    }
    int y = 0; // ### (maybe do like QHeaderView by letting items have startposition)
    for (int i = 0; i < viewItems.count(); ++i) {
        y += itemHeight(i); // the height value is cached
        if (y > value) {
            if (offset)
                *offset = y - value - itemHeight(i);
            return i;
        }
    }
    return -1;
}

int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const
{
    if (firstVisual < 0 || offset < 0) {
        firstVisual = firstVisibleItem(&offset);
        if (firstVisual < 0)
            return -1;
    }
    int y = - offset;
    int value = viewport->height();

    for (int i = firstVisual; i < viewItems.count(); ++i) {
        y += itemHeight(i); // the height value is cached
        if (y > value)
            return i;
    }
    return viewItems.size() - 1;
}

int QTreeViewPrivate::columnAt(int x) const
{
    return header->logicalIndexAt(x);
}

void QTreeViewPrivate::updateScrollBars()
{
    Q_Q(QTreeView);
    QSize viewportSize = viewport->size();
    if (!viewportSize.isValid())
        viewportSize = QSize(0, 0);

    executePostedLayout();
    if (viewItems.isEmpty()) {
        q->doItemsLayout();
    }

    int itemsInViewport = 0;
    if (uniformRowHeights) {
        if (defaultItemHeight <= 0)
            itemsInViewport = viewItems.count();
        else
            itemsInViewport = viewportSize.height() / defaultItemHeight;
    } else {
        const int itemsCount = viewItems.count();
        const int viewportHeight = viewportSize.height();
        for (int height = 0, item = itemsCount - 1; item >= 0; --item) {
            height += itemHeight(item);
            if (height > viewportHeight)
                break;
            ++itemsInViewport;
        }
    }
    if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
        if (!viewItems.isEmpty())
            itemsInViewport = qMax(1, itemsInViewport);
        vbar->setRange(0, viewItems.count() - itemsInViewport);
        vbar->setPageStep(itemsInViewport);
        vbar->setSingleStep(1);
    } else { // scroll per pixel
        int contentsHeight = 0;
        if (uniformRowHeights) {
            contentsHeight = defaultItemHeight * viewItems.count();
        } else { // ### (maybe do like QHeaderView by letting items have startposition)
            for (int i = 0; i < viewItems.count(); ++i)
                contentsHeight += itemHeight(i);
        }
        vbar->setRange(0, contentsHeight - viewportSize.height());
        vbar->setPageStep(viewportSize.height());
        vbar->d_func()->itemviewChangeSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
    }

    const int columnCount = header->count();
    const int viewportWidth = viewportSize.width();
    int columnsInViewport = 0;
    for (int width = 0, column = columnCount - 1; column >= 0; --column) {
        int logical = header->logicalIndex(column);
        width += header->sectionSize(logical);
        if (width > viewportWidth)
            break;
        ++columnsInViewport;
    }
    if (columnCount > 0)
        columnsInViewport = qMax(1, columnsInViewport);
    if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) {
        hbar->setRange(0, columnCount - columnsInViewport);
        hbar->setPageStep(columnsInViewport);
        hbar->setSingleStep(1);
    } else { // scroll per pixel
        const int horizontalLength = header->length();
        const QSize maxSize = q->maximumViewportSize();
        if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0)
            viewportSize = maxSize;
        hbar->setPageStep(viewportSize.width());
        hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
        hbar->d_func()->itemviewChangeSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
    }
}

int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
{
    Q_Q(const QTreeView);
    executePostedLayout();
    bool spanned = false;
    if (!spanningIndexes.isEmpty()) {
        const QModelIndex index = q->indexAt(pos);
        if (index.isValid())
            spanned = q->isFirstColumnSpanned(index.row(), index.parent());
    }
    const int column = spanned ? 0 : header->logicalIndexAt(pos.x());
    if (!isTreePosition(column))
        return -1; // no logical index at x

    int viewItemIndex = itemAtCoordinate(pos.y());
    QRect returning = itemDecorationRect(modelIndex(viewItemIndex));
    if (!returning.contains(pos))
        return -1;

    return viewItemIndex;
}

QRect QTreeViewPrivate::itemDecorationRect(const QModelIndex &index) const
{
    Q_Q(const QTreeView);
    if (!rootDecoration && index.parent() == root)
        return QRect(); // no decoration at root

    int viewItemIndex = viewIndex(index);
    if (viewItemIndex < 0 || !hasVisibleChildren(viewItems.at(viewItemIndex).index))
        return QRect();

    int itemIndentation = indentationForItem(viewItemIndex);
    int position = header->sectionViewportPosition(logicalIndexForTree());
    int size = header->sectionSize(logicalIndexForTree());

    QRect rect;
    if (q->isRightToLeft())
        rect = QRect(position + size - itemIndentation, coordinateForItem(viewItemIndex),
                     indent, itemHeight(viewItemIndex));
    else
        rect = QRect(position + itemIndentation - indent, coordinateForItem(viewItemIndex),
                     indent, itemHeight(viewItemIndex));
    QStyleOption opt;
    opt.initFrom(q);
    opt.rect = rect;
    return q->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &opt, q);
}

QVector<QPair<int, int> > QTreeViewPrivate::columnRanges(const QModelIndex &topIndex,
                                                         const QModelIndex &bottomIndex) const
{
    const int topVisual = header->visualIndex(topIndex.column()),
        bottomVisual = header->visualIndex(bottomIndex.column());

    const int start = qMin(topVisual, bottomVisual);
    const int end = qMax(topVisual, bottomVisual);

    QList<int> logicalIndexes;

    //we iterate over the visual indexes to get the logical indexes
    for (int c = start; c <= end; c++) {
        const int logical = header->logicalIndex(c);
        if (!header->isSectionHidden(logical)) {
            logicalIndexes << logical;
        }
    }
    //let's sort the list
    std::sort(logicalIndexes.begin(), logicalIndexes.end());

    QVector<QPair<int, int> > ret;
    QPair<int, int> current;
    current.first = -2; // -1 is not enough because -1+1 = 0
    current.second = -2;
    for(int i = 0; i < logicalIndexes.count(); ++i) {
        const int logicalColumn = logicalIndexes.at(i);
        if (current.second + 1 != logicalColumn) {
            if (current.first != -2) {
                //let's save the current one
                ret += current;
            }
            //let's start a new one
            current.first = current.second = logicalColumn;
        } else {
            current.second++;
        }
    }

    //let's get the last range
    if (current.first != -2) {
        ret += current;
    }

    return ret;
}

void QTreeViewPrivate::select(const QModelIndex &topIndex, const QModelIndex &bottomIndex,
                              QItemSelectionModel::SelectionFlags command)
{
    Q_Q(QTreeView);
    QItemSelection selection;
    const int top = viewIndex(topIndex),
        bottom = viewIndex(bottomIndex);

    const QVector<QPair<int, int> > colRanges = columnRanges(topIndex, bottomIndex);
    QVector<QPair<int, int> >::const_iterator it;
    for (it = colRanges.begin(); it != colRanges.end(); ++it) {
        const int left = (*it).first,
            right = (*it).second;

        QModelIndex previous;
        QItemSelectionRange currentRange;
        QStack<QItemSelectionRange> rangeStack;
        for (int i = top; i <= bottom; ++i) {
            QModelIndex index = modelIndex(i);
            QModelIndex parent = index.parent();
            QModelIndex previousParent = previous.parent();
            if (previous.isValid() && parent == previousParent) {
                // same parent
                if (qAbs(previous.row() - index.row()) > 1) {
                    //a hole (hidden index inside a range) has been detected
                    if (currentRange.isValid()) {
                        selection.append(currentRange);
                    }
                    //let's start a new range
                    currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
                } else {
                    QModelIndex tl = model->index(currentRange.top(), currentRange.left(),
                        currentRange.parent());
                    currentRange = QItemSelectionRange(tl, index.sibling(index.row(), right));
                }
            } else if (previous.isValid() && parent == model->index(previous.row(), 0, previousParent)) {
                // item is child of previous
                rangeStack.push(currentRange);
                currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
            } else {
                if (currentRange.isValid())
                    selection.append(currentRange);
                if (rangeStack.isEmpty()) {
                    currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
                } else {
                    currentRange = rangeStack.pop();
                    index = currentRange.bottomRight(); //let's resume the range
                    --i; //we process again the current item
                }
            }
            previous = index;
        }
        if (currentRange.isValid())
            selection.append(currentRange);
        for (int i = 0; i < rangeStack.count(); ++i)
            selection.append(rangeStack.at(i));
    }
    q->selectionModel()->select(selection, command);
}

QPair<int,int> QTreeViewPrivate::startAndEndColumns(const QRect &rect) const
{
    Q_Q(const QTreeView);
    int start = header->visualIndexAt(rect.left());
    int end = header->visualIndexAt(rect.right());
    if (q->isRightToLeft()) {
        start = (start == -1 ? header->count() - 1 : start);
        end = (end == -1 ? 0 : end);
    } else {
        start = (start == -1 ? 0 : start);
        end = (end == -1 ? header->count() - 1 : end);
    }
    return qMakePair<int,int>(qMin(start, end), qMax(start, end));
}

bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const
{
    Q_Q(const QTreeView);
    if (parent.flags() & Qt::ItemNeverHasChildren)
        return false;
    if (model->hasChildren(parent)) {
        if (hiddenIndexes.isEmpty())
            return true;
        if (q->isIndexHidden(parent))
            return false;
        int rowCount = model->rowCount(parent);
        for (int i = 0; i < rowCount; ++i) {
            if (!q->isRowHidden(i, parent))
                return true;
        }
        if (rowCount == 0)
            return true;
    }
    return false;
}

void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
{
    model->sort(column, order);
}

int QTreeViewPrivate::accessibleTree2Index(const QModelIndex &index) const
{
    Q_Q(const QTreeView);

    // Note that this will include the header, even if its hidden.
    return (q->visualIndex(index) + (q->header() ? 1 : 0)) * index.model()->columnCount() + index.column();
}

void QTreeViewPrivate::updateIndentationFromStyle()
{
    Q_Q(const QTreeView);
    indent = q->style()->pixelMetric(QStyle::PM_TreeViewIndentation, nullptr, q);
}

/*!
  \reimp
 */
void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    QAbstractItemView::currentChanged(current, previous);

    if (allColumnsShowFocus()) {
        if (previous.isValid()) {
            QRect previousRect = visualRect(previous);
            previousRect.setX(0);
            previousRect.setWidth(viewport()->width());
            viewport()->update(previousRect);
        }
        if (current.isValid()) {
            QRect currentRect = visualRect(current);
            currentRect.setX(0);
            currentRect.setWidth(viewport()->width());
            viewport()->update(currentRect);
        }
    }
#ifndef QT_NO_ACCESSIBILITY
    if (QAccessible::isActive() && current.isValid()) {
        Q_D(QTreeView);

        QAccessibleEvent event(this, QAccessible::Focus);
        event.setChild(d->accessibleTree2Index(current));
        QAccessible::updateAccessibility(&event);
    }
#endif
}

/*!
  \reimp
 */
void QTreeView::selectionChanged(const QItemSelection &selected,
                                 const QItemSelection &deselected)
{
    QAbstractItemView::selectionChanged(selected, deselected);
#ifndef QT_NO_ACCESSIBILITY
    if (QAccessible::isActive()) {
        Q_D(QTreeView);

        // ### does not work properly for selection ranges.
        QModelIndex sel = selected.indexes().value(0);
        if (sel.isValid()) {
            int entry = d->accessibleTree2Index(sel);
            Q_ASSERT(entry >= 0);
            QAccessibleEvent event(this, QAccessible::SelectionAdd);
            event.setChild(entry);
            QAccessible::updateAccessibility(&event);
        }
        QModelIndex desel = deselected.indexes().value(0);
        if (desel.isValid()) {
            int entry = d->accessibleTree2Index(desel);
            Q_ASSERT(entry >= 0);
            QAccessibleEvent event(this, QAccessible::SelectionRemove);
            event.setChild(entry);
            QAccessible::updateAccessibility(&event);
        }
    }
#endif
}

int QTreeView::visualIndex(const QModelIndex &index) const
{
    Q_D(const QTreeView);
    d->executePostedLayout();
    return d->viewIndex(index);
}

/*!
   \internal
*/

void QTreeView::verticalScrollbarValueChanged(int value)
{
    Q_D(QTreeView);
    if (!d->viewItems.isEmpty() && value == verticalScrollBar()->maximum()) {
        QModelIndex ret = d->viewItems.last().index;
        // Root index will be handled by base class implementation
        while (ret.isValid()) {
            if (isExpanded(ret) && d->model->canFetchMore(ret)) {
                d->model->fetchMore(ret);
                break;
            }
            ret = ret.parent();
        }
    }
    QAbstractItemView::verticalScrollbarValueChanged(value);
}

QT_END_NAMESPACE

#include "moc_qtreeview.cpp"
