1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtWidgets module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QTREEVIEW_P_H 41 #define QTREEVIEW_P_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists purely as an 48 // implementation detail. This header file may change from version to 49 // version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include <QtWidgets/private/qtwidgetsglobal_p.h> 55 #include "private/qabstractitemview_p.h" 56 #if QT_CONFIG(animation) 57 #include <QtCore/qvariantanimation.h> 58 #endif 59 #include <QtCore/qabstractitemmodel.h> 60 #include <QtCore/qvector.h> 61 62 QT_REQUIRE_CONFIG(treeview); 63 64 QT_BEGIN_NAMESPACE 65 66 struct QTreeViewItem 67 { QTreeViewItemQTreeViewItem68 QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false), 69 hasMoreSiblings(false), total(0), level(0), height(0) {} 70 QModelIndex index; // we remove items whenever the indexes are invalidated 71 int parentItem; // parent item index in viewItems 72 uint expanded : 1; 73 uint spanning : 1; 74 uint hasChildren : 1; // if the item has visible children (even if collapsed) 75 uint hasMoreSiblings : 1; 76 uint total : 28; // total number of children visible 77 uint level : 16; // indentation 78 int height : 16; // row height 79 }; 80 81 Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE); 82 83 class Q_WIDGETS_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate 84 { Q_DECLARE_PUBLIC(QTreeView)85 Q_DECLARE_PUBLIC(QTreeView) 86 public: 87 88 QTreeViewPrivate() 89 : QAbstractItemViewPrivate(), 90 header(nullptr), indent(20), lastViewedItem(0), defaultItemHeight(-1), 91 uniformRowHeights(false), rootDecoration(true), 92 itemsExpandable(true), sortingEnabled(false), 93 expandsOnDoubleClick(true), 94 allColumnsShowFocus(false), customIndent(false), current(0), spanning(false), 95 animationsEnabled(false), columnResizeTimerID(0), 96 autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false), 97 treePosition(0) {} 98 ~QTreeViewPrivate()99 ~QTreeViewPrivate() {} 100 void initialize(); 101 int logicalIndexForTree() const; isTreePosition(int logicalIndex)102 inline bool isTreePosition(int logicalIndex) const 103 { 104 return logicalIndex == logicalIndexForTree(); 105 } 106 107 QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const override; 108 void adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex ¤t) const override; 109 110 #if QT_CONFIG(animation) 111 struct AnimatedOperation : public QVariantAnimation 112 { 113 int item; 114 QPixmap before; 115 QPixmap after; 116 QWidget *viewport; AnimatedOperationAnimatedOperation117 AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } topAnimatedOperation118 int top() const { return startValue().toInt(); } rectAnimatedOperation119 QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; } updateCurrentValueAnimatedOperation120 void updateCurrentValue(const QVariant &) override { viewport->update(rect()); } updateStateAnimatedOperation121 void updateState(State state, State) override { if (state == Stopped) before = after = QPixmap(); } 122 } animatedOperation; 123 void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); 124 void beginAnimatedOperation(); 125 void drawAnimatedOperation(QPainter *painter) const; 126 QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; 127 void _q_endAnimatedOperation(); 128 #endif // animation 129 130 void expand(int item, bool emitSignal); 131 void collapse(int item, bool emitSignal); 132 133 void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int) override; 134 void _q_columnsRemoved(const QModelIndex &, int, int) override; 135 void _q_modelAboutToBeReset(); 136 void _q_sortIndicatorChanged(int column, Qt::SortOrder order); 137 void _q_modelDestroyed() override; 138 139 void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false); 140 141 int pageUp(int item) const; 142 int pageDown(int item) const; 143 int itemForKeyHome() const; 144 int itemForKeyEnd() const; 145 146 int itemHeight(int item) const; 147 int indentationForItem(int item) const; 148 int coordinateForItem(int item) const; 149 int itemAtCoordinate(int coordinate) const; 150 151 int viewIndex(const QModelIndex &index) const; 152 QModelIndex modelIndex(int i, int column = 0) const; 153 154 void insertViewItems(int pos, int count, const QTreeViewItem &viewItem); 155 void removeViewItems(int pos, int count); 156 #if 0 157 bool checkViewItems() const; 158 #endif 159 160 int firstVisibleItem(int *offset = nullptr) const; 161 int lastVisibleItem(int firstVisual = -1, int offset = -1) const; 162 int columnAt(int x) const; 163 bool hasVisibleChildren( const QModelIndex& parent) const; 164 165 bool expandOrCollapseItemAtPos(const QPoint &pos); 166 167 void updateScrollBars(); 168 169 int itemDecorationAt(const QPoint &pos) const; 170 QRect itemDecorationRect(const QModelIndex &index) const; 171 172 173 QVector<QPair<int, int> > columnRanges(const QModelIndex &topIndex, const QModelIndex &bottomIndex) const; 174 void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command); 175 176 QPair<int,int> startAndEndColumns(const QRect &rect) const; 177 178 void updateChildCount(const int parentItem, const int delta); 179 180 void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const; 181 182 // logicalIndices: vector of currently visibly logical indices 183 // itemPositions: vector of view item positions (beginning/middle/end/onlyone) 184 void calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left, int right) const; 185 int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const; 186 QHeaderView *header; 187 int indent; 188 189 mutable QVector<QTreeViewItem> viewItems; 190 mutable int lastViewedItem; 191 int defaultItemHeight; // this is just a number; contentsHeight() / numItems 192 bool uniformRowHeights; // used when all rows have the same height 193 bool rootDecoration; 194 bool itemsExpandable; 195 bool sortingEnabled; 196 bool expandsOnDoubleClick; 197 bool allColumnsShowFocus; 198 bool customIndent; 199 200 // used for drawing 201 mutable QPair<int,int> leftAndRight; 202 mutable int current; 203 mutable bool spanning; 204 205 // used when expanding and collapsing items 206 QSet<QPersistentModelIndex> expandedIndexes; 207 bool animationsEnabled; 208 storeExpanded(const QPersistentModelIndex & idx)209 inline bool storeExpanded(const QPersistentModelIndex &idx) { 210 if (expandedIndexes.contains(idx)) 211 return false; 212 expandedIndexes.insert(idx); 213 return true; 214 } 215 isIndexExpanded(const QModelIndex & idx)216 inline bool isIndexExpanded(const QModelIndex &idx) const { 217 //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow 218 return !(idx.flags() & Qt::ItemNeverHasChildren) && isPersistent(idx) && expandedIndexes.contains(idx); 219 } 220 221 // used when hiding and showing items 222 QSet<QPersistentModelIndex> hiddenIndexes; 223 isRowHidden(const QModelIndex & idx)224 inline bool isRowHidden(const QModelIndex &idx) const { 225 if (hiddenIndexes.isEmpty()) 226 return false; 227 //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow 228 return isPersistent(idx) && hiddenIndexes.contains(idx); 229 } 230 isItemHiddenOrDisabled(int i)231 inline bool isItemHiddenOrDisabled(int i) const { 232 if (i < 0 || i >= viewItems.count()) 233 return false; 234 const QModelIndex index = viewItems.at(i).index; 235 return isRowHidden(index) || !isIndexEnabled(index); 236 } 237 above(int item)238 inline int above(int item) const 239 { int i = item; while (isItemHiddenOrDisabled(--item)){} return item < 0 ? i : item; } below(int item)240 inline int below(int item) const 241 { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.count() ? i : item; } invalidateHeightCache(int item)242 inline void invalidateHeightCache(int item) const 243 { viewItems[item].height = 0; } 244 accessibleTable2Index(const QModelIndex & index)245 inline int accessibleTable2Index(const QModelIndex &index) const { 246 return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column(); 247 } 248 249 int accessibleTree2Index(const QModelIndex &index) const; 250 251 void updateIndentationFromStyle(); 252 253 // used for spanning rows 254 QSet<QPersistentModelIndex> spanningIndexes; 255 256 // used for updating resized columns 257 int columnResizeTimerID; 258 QList<int> columnsToUpdate; 259 260 // used for the automatic opening of nodes during DND 261 int autoExpandDelay; 262 QBasicTimer openTimer; 263 264 // used for drawing hilighted expand/collapse indicators 265 mutable int hoverBranch; 266 267 // used for blocking recursion when calling setViewportMargins from updateGeometries 268 bool geometryRecursionBlock; 269 270 // If we should clean the set 271 bool hasRemovedItems; 272 273 // tree position 274 int treePosition; 275 }; 276 277 QT_END_NAMESPACE 278 279 #endif // QTREEVIEW_P_H 280