summaryrefslogtreecommitdiff
path: root/src/gui/itemviews/qtreeview_p.h
blob: 589a224da4b9b35c98916e6047cfde879c1b2c57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QTREEVIEW_P_H
#define QTREEVIEW_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include "private/qabstractitemview_p.h"
#include <QtCore/qvariantanimation.h>

#ifndef QT_NO_TREEVIEW

QT_BEGIN_NAMESPACE

struct QTreeViewItem
{
    QTreeViewItem() : expanded(false), spanning(false), hasChildren(false),
                      hasMoreSiblings(false), total(0), level(0), height(0) {}
    QModelIndex index; // we remove items whenever the indexes are invalidated
    uint expanded : 1;
    uint spanning : 1;
    uint hasChildren : 1; // if the item has visible children (even if collapsed)
    uint hasMoreSiblings : 1;
    uint total : 28; // total number of children visible
    uint level : 16; // indentation
    int height : 16; // row height
};

class QTreeViewPrivate : public QAbstractItemViewPrivate
{
    Q_DECLARE_PUBLIC(QTreeView)
public:

    QTreeViewPrivate()
        : QAbstractItemViewPrivate(),
          header(0), indent(20), lastViewedItem(0), defaultItemHeight(-1),
          uniformRowHeights(false), rootDecoration(true),
          itemsExpandable(true), sortingEnabled(false),
          expandsOnDoubleClick(true),
          allColumnsShowFocus(false), current(0), spanning(false),
          animationsEnabled(false), columnResizeTimerID(0),
          autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {}

    ~QTreeViewPrivate() {}
    void initialize();

    QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;

#ifndef QT_NO_ANIMATION
    struct AnimatedOperation : public QVariantAnimation
    {
        int item;
        QPixmap before;
        QPixmap after;
        QWidget *viewport;
        AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
        int top() const { return startValue().toInt(); }
        QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
        void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
        void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
    } animatedOperation;
    void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
    void beginAnimatedOperation();
    void drawAnimatedOperation(QPainter *painter) const;
    QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
    void _q_endAnimatedOperation();
#endif //QT_NO_ANIMATION

    void expand(int item, bool emitSignal);
    void collapse(int item, bool emitSignal);

    void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int);
    void _q_columnsRemoved(const QModelIndex &, int, int);
    void _q_modelAboutToBeReset();
    void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
    void _q_modelDestroyed();

    void layout(int item);

    int pageUp(int item) const;
    int pageDown(int item) const;

    int itemHeight(int item) const;
    int indentationForItem(int item) const;
    int coordinateForItem(int item) const;
    int itemAtCoordinate(int coordinate) const;

    int viewIndex(const QModelIndex &index) const;
    QModelIndex modelIndex(int i, int column = 0) const;

    int firstVisibleItem(int *offset = 0) const;
    int columnAt(int x) const;
    bool hasVisibleChildren( const QModelIndex& parent) const;

    void relayout(const QModelIndex &parent);
    bool expandOrCollapseItemAtPos(const QPoint &pos);

    void updateScrollBars();

    int itemDecorationAt(const QPoint &pos) const;
    QRect itemDecorationRect(const QModelIndex &index) const;


    QList<QPair<int, int> > columnRanges(const QModelIndex &topIndex, const QModelIndex &bottomIndex) const;
    void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command);

    QPair<int,int> startAndEndColumns(const QRect &rect) const;

    void updateChildCount(const int parentItem, const int delta);
    void rowsRemoved(const QModelIndex &parent,
                     int start, int end, bool before);

    void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const;

    QHeaderView *header;
    int indent;

    mutable QVector<QTreeViewItem> viewItems;
    mutable int lastViewedItem;
    int defaultItemHeight; // this is just a number; contentsHeight() / numItems
    bool uniformRowHeights; // used when all rows have the same height
    bool rootDecoration;
    bool itemsExpandable;
    bool sortingEnabled;
    bool expandsOnDoubleClick;
    bool allColumnsShowFocus;

    // used for drawing
    mutable QPair<int,int> leftAndRight;
    mutable int current;
    mutable bool spanning;

    // used when expanding and collapsing items
    QSet<QPersistentModelIndex> expandedIndexes;
    bool animationsEnabled;

    inline bool storeExpanded(const QPersistentModelIndex &idx) {
        if (expandedIndexes.contains(idx))
            return false;
        expandedIndexes.insert(idx);
        return true;
    }

    inline bool isIndexExpanded(const QModelIndex &idx) const {
        //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
        return isPersistent(idx) && expandedIndexes.contains(idx);
    }

    // used when hiding and showing items
    QSet<QPersistentModelIndex> hiddenIndexes;

    inline bool isRowHidden(const QModelIndex &idx) const {
        //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
        return isPersistent(idx) && hiddenIndexes.contains(idx);
    }

    inline bool isItemHiddenOrDisabled(int i) const {
        if (i < 0 || i >= viewItems.count())
            return false;
        const QModelIndex index = viewItems.at(i).index;
        return isRowHidden(index) || !isIndexEnabled(index);
    }

    inline int above(int item) const
        { int i = item; while (isItemHiddenOrDisabled(--item)){} return item < 0 ? i : item; }
    inline int below(int item) const
        { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.count() ? i : item; }
    inline void invalidateHeightCache(int item) const
        { viewItems[item].height = 0; }

    // used for spanning rows
    QVector<QPersistentModelIndex> spanningIndexes;

    // used for updating resized columns
    int columnResizeTimerID;
    QList<int> columnsToUpdate;

    // used for the automatic opening of nodes during DND
    int autoExpandDelay;
    QBasicTimer openTimer;

    // used for drawing hilighted expand/collapse indicators
    int hoverBranch;

    // used for blocking recursion when calling setViewportMargins from updateGeometries
    bool geometryRecursionBlock;
};

QT_END_NAMESPACE

#endif // QT_NO_TREEVIEW

#endif // QTREEVIEW_P_H