Qt 4.8
qtreeview.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "qtreeview.h"
42 
43 #ifndef QT_NO_TREEVIEW
44 #include <qheaderview.h>
45 #include <qitemdelegate.h>
46 #include <qapplication.h>
47 #include <qscrollbar.h>
48 #include <qpainter.h>
49 #include <qstack.h>
50 #include <qstyle.h>
51 #include <qstyleoption.h>
52 #include <qevent.h>
53 #include <qpen.h>
54 #include <qdebug.h>
55 #ifndef QT_NO_ACCESSIBILITY
56 #include <qaccessible.h>
57 #include <qaccessible2.h>
58 #endif
59 
60 #include <private/qtreeview_p.h>
61 
63 
197  : QAbstractItemView(*new QTreeViewPrivate, parent)
198 {
199  Q_D(QTreeView);
200  d->initialize();
201 }
202 
207  : QAbstractItemView(dd, parent)
208 {
209  Q_D(QTreeView);
210  d->initialize();
211 }
212 
217 {
218 }
219 
224 {
225  Q_D(QTreeView);
226  if (model == d->model)
227  return;
228  if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
229  disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
230  this, SLOT(rowsRemoved(QModelIndex,int,int)));
231 
232  disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
233  }
234 
235  if (d->selectionModel) { // support row editing
236  disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
237  d->model, SLOT(submit()));
238  disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
239  this, SLOT(rowsRemoved(QModelIndex,int,int)));
240  disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
241  }
242  d->viewItems.clear();
243  d->expandedIndexes.clear();
244  d->hiddenIndexes.clear();
245  d->header->setModel(model);
247 
248  // QAbstractItemView connects to a private slot
249  disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
250  this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
251  // do header layout after the tree
252  disconnect(d->model, SIGNAL(layoutChanged()),
253  d->header, SLOT(_q_layoutChanged()));
254  // QTreeView has a public slot for this
255  connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
256  this, SLOT(rowsRemoved(QModelIndex,int,int)));
257 
258  connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
259 
260  if (d->sortingEnabled)
261  d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
262 }
263 
268 {
269  Q_D(QTreeView);
270  d->header->setRootIndex(index);
272 }
273 
278 {
279  Q_D(QTreeView);
280  Q_ASSERT(selectionModel);
281  if (d->selectionModel) {
282  // support row editing
283  disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
284  d->model, SLOT(submit()));
285  }
286 
287  d->header->setSelectionModel(selectionModel);
288  QAbstractItemView::setSelectionModel(selectionModel);
289 
290  if (d->selectionModel) {
291  // support row editing
292  connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
293  d->model, SLOT(submit()));
294  }
295 }
296 
303 {
304  Q_D(const QTreeView);
305  return d->header;
306 }
307 
317 {
318  Q_D(QTreeView);
319  if (header == d->header || !header)
320  return;
321  if (d->header && d->header->parent() == this)
322  delete d->header;
323  d->header = header;
324  d->header->setParent(this);
325 
326  if (!d->header->model()) {
327  d->header->setModel(d->model);
328  if (d->selectionModel)
329  d->header->setSelectionModel(d->selectionModel);
330  }
331 
332  connect(d->header, SIGNAL(sectionResized(int,int,int)),
333  this, SLOT(columnResized(int,int,int)));
334  connect(d->header, SIGNAL(sectionMoved(int,int,int)),
335  this, SLOT(columnMoved()));
336  connect(d->header, SIGNAL(sectionCountChanged(int,int)),
337  this, SLOT(columnCountChanged(int,int)));
338  connect(d->header, SIGNAL(sectionHandleDoubleClicked(int)),
339  this, SLOT(resizeColumnToContents(int)));
340  connect(d->header, SIGNAL(geometriesChanged()),
341  this, SLOT(updateGeometries()));
342 
343  setSortingEnabled(d->sortingEnabled);
344 }
345 
360 int QTreeView::autoExpandDelay() const
361 {
362  Q_D(const QTreeView);
363  return d->autoExpandDelay;
364 }
365 
367 {
368  Q_D(QTreeView);
369  d->autoExpandDelay = delay;
370 }
371 
386 int QTreeView::indentation() const
387 {
388  Q_D(const QTreeView);
389  return d->indent;
390 }
391 
393 {
394  Q_D(QTreeView);
395  if (i != d->indent) {
396  d->indent = i;
397  d->viewport->update();
398  }
399 }
400 
415 bool QTreeView::rootIsDecorated() const
416 {
417  Q_D(const QTreeView);
418  return d->rootDecoration;
419 }
420 
422 {
423  Q_D(QTreeView);
424  if (show != d->rootDecoration) {
425  d->rootDecoration = show;
426  d->viewport->update();
427  }
428 }
429 
446 bool QTreeView::uniformRowHeights() const
447 {
448  Q_D(const QTreeView);
449  return d->uniformRowHeights;
450 }
451 
453 {
454  Q_D(QTreeView);
455  d->uniformRowHeights = uniform;
456 }
457 
471 bool QTreeView::itemsExpandable() const
472 {
473  Q_D(const QTreeView);
474  return d->itemsExpandable;
475 }
476 
478 {
479  Q_D(QTreeView);
480  d->itemsExpandable = enable;
481 }
482 
497 {
498  Q_D(const QTreeView);
499  return d->expandsOnDoubleClick;
500 }
501 
503 {
504  Q_D(QTreeView);
505  d->expandsOnDoubleClick = enable;
506 }
507 
512 {
513  Q_D(const QTreeView);
514  return d->header->sectionViewportPosition(column);
515 }
516 
522 int QTreeView::columnWidth(int column) const
523 {
524  Q_D(const QTreeView);
525  return d->header->sectionSize(column);
526 }
527 
538 void QTreeView::setColumnWidth(int column, int width)
539 {
540  Q_D(QTreeView);
541  d->header->resizeSection(column, width);
542 }
543 
548 int QTreeView::columnAt(int x) const
549 {
550  Q_D(const QTreeView);
551  return d->header->logicalIndexAt(x);
552 }
553 
559 bool QTreeView::isColumnHidden(int column) const
560 {
561  Q_D(const QTreeView);
562  return d->header->isSectionHidden(column);
563 }
564 
570 void QTreeView::setColumnHidden(int column, bool hide)
571 {
572  Q_D(QTreeView);
573  if (column < 0 || column >= d->header->count())
574  return;
575  d->header->setSectionHidden(column, hide);
576 }
577 
592 {
593  Q_D(const QTreeView);
594  return d->header->isHidden();
595 }
596 
598 {
599  Q_D(QTreeView);
600  d->header->setHidden(hide);
601 }
602 
609 bool QTreeView::isRowHidden(int row, const QModelIndex &parent) const
610 {
611  Q_D(const QTreeView);
612  if (!d->model)
613  return false;
614  return d->isRowHidden(d->model->index(row, 0, parent));
615 }
616 
622 void QTreeView::setRowHidden(int row, const QModelIndex &parent, bool hide)
623 {
624  Q_D(QTreeView);
625  if (!d->model)
626  return;
627  QModelIndex index = d->model->index(row, 0, parent);
628  if (!index.isValid())
629  return;
630 
631  if (hide) {
632  d->hiddenIndexes.insert(index);
633  } else if(d->isPersistent(index)) { //if the index is not persistent, it cannot be in the set
634  d->hiddenIndexes.remove(index);
635  }
636 
637  d->doDelayedItemsLayout();
638 }
639 
652 {
653  Q_D(const QTreeView);
654  if (d->spanningIndexes.isEmpty() || !d->model)
655  return false;
656  QModelIndex index = d->model->index(row, 0, parent);
657  for (int i = 0; i < d->spanningIndexes.count(); ++i)
658  if (d->spanningIndexes.at(i) == index)
659  return true;
660  return false;
661 }
662 
675 void QTreeView::setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)
676 {
677  Q_D(QTreeView);
678  if (!d->model)
679  return;
680  QModelIndex index = d->model->index(row, 0, parent);
681  if (!index.isValid())
682  return;
683 
684  if (span) {
685  QPersistentModelIndex persistent(index);
686  if (!d->spanningIndexes.contains(persistent))
687  d->spanningIndexes.append(persistent);
688  } else {
689  QPersistentModelIndex persistent(index);
690  int i = d->spanningIndexes.indexOf(persistent);
691  if (i >= 0)
692  d->spanningIndexes.remove(i);
693  }
694 
695  d->executePostedLayout();
696  int i = d->viewIndex(index);
697  if (i >= 0)
698  d->viewItems[i].spanning = span;
699 
700  d->viewport->update();
701 }
702 
706 void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
707 {
708  Q_D(QTreeView);
709 
710  // if we are going to do a complete relayout anyway, there is no need to update
711  if (d->delayedPendingLayout)
712  return;
713 
714  // refresh the height cache here; we don't really lose anything by getting the size hint,
715  // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway
716 
717  bool sizeChanged = false;
718  int topViewIndex = d->viewIndex(topLeft);
719  if (topViewIndex == 0) {
720  int newDefaultItemHeight = indexRowSizeHint(topLeft);
721  sizeChanged = d->defaultItemHeight != newDefaultItemHeight;
722  d->defaultItemHeight = newDefaultItemHeight;
723  }
724 
725  if (topViewIndex != -1) {
726  if (topLeft.row() == bottomRight.row()) {
727  int oldHeight = d->itemHeight(topViewIndex);
728  d->invalidateHeightCache(topViewIndex);
729  sizeChanged |= (oldHeight != d->itemHeight(topViewIndex));
730  if (topLeft.column() == 0)
731  d->viewItems[topViewIndex].hasChildren = d->hasVisibleChildren(topLeft);
732  } else {
733  int bottomViewIndex = d->viewIndex(bottomRight);
734  for (int i = topViewIndex; i <= bottomViewIndex; ++i) {
735  int oldHeight = d->itemHeight(i);
736  d->invalidateHeightCache(i);
737  sizeChanged |= (oldHeight != d->itemHeight(i));
738  if (topLeft.column() == 0)
739  d->viewItems[i].hasChildren = d->hasVisibleChildren(d->viewItems.at(i).index);
740  }
741  }
742  }
743 
744  if (sizeChanged) {
745  d->updateScrollBars();
746  d->viewport->update();
747  }
748  QAbstractItemView::dataChanged(topLeft, bottomRight);
749 }
750 
760 void QTreeView::hideColumn(int column)
761 {
762  Q_D(QTreeView);
763  d->header->hideSection(column);
764 }
765 
771 void QTreeView::showColumn(int column)
772 {
773  Q_D(QTreeView);
774  d->header->showSection(column);
775 }
776 
788 {
789  Q_D(QTreeView);
790  if (!d->isIndexValid(index))
791  return;
792  if (d->delayedPendingLayout) {
793  //A complete relayout is going to be performed, just store the expanded index, no need to layout.
794  if (d->storeExpanded(index))
795  emit expanded(index);
796  return;
797  }
798 
799  int i = d->viewIndex(index);
800  if (i != -1) { // is visible
801  d->expand(i, true);
802  if (!d->isAnimating()) {
804  d->viewport->update();
805  }
806  } else if (d->storeExpanded(index)) {
807  emit expanded(index);
808  }
809 }
810 
822 {
823  Q_D(QTreeView);
824  if (!d->isIndexValid(index))
825  return;
826  //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll
827  d->delayedAutoScroll.stop();
828 
829  if (d->delayedPendingLayout) {
830  //A complete relayout is going to be performed, just un-store the expanded index, no need to layout.
831  if (d->isPersistent(index) && d->expandedIndexes.remove(index))
832  emit collapsed(index);
833  return;
834  }
835  int i = d->viewIndex(index);
836  if (i != -1) { // is visible
837  d->collapse(i, true);
838  if (!d->isAnimating()) {
840  viewport()->update();
841  }
842  } else {
843  if (d->isPersistent(index) && d->expandedIndexes.remove(index))
844  emit collapsed(index);
845  }
846 }
847 
860 {
861  Q_D(const QTreeView);
862  return d->isIndexExpanded(index);
863 }
864 
872 {
873  if (expanded)
874  this->expand(index);
875  else
876  this->collapse(index);
877 }
878 
899 {
900  Q_D(QTreeView);
901  header()->setSortIndicatorShown(enable);
902  header()->setClickable(enable);
903  if (enable) {
904  //sortByColumn has to be called before we connect or set the sortingEnabled flag
905  // because otherwise it will not call sort on the model.
906  sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
907  connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
908  this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
909  } else {
910  disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
911  this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
912  }
913  d->sortingEnabled = enable;
914 }
915 
917 {
918  Q_D(const QTreeView);
919  return d->sortingEnabled;
920 }
921 
938 void QTreeView::setAnimated(bool animate)
939 {
940  Q_D(QTreeView);
941  d->animationsEnabled = animate;
942 }
943 
945 {
946  Q_D(const QTreeView);
947  return d->animationsEnabled;
948 }
949 
965 {
966  Q_D(QTreeView);
967  if (d->allColumnsShowFocus == enable)
968  return;
969  d->allColumnsShowFocus = enable;
970  d->viewport->update();
971 }
972 
974 {
975  Q_D(const QTreeView);
976  return d->allColumnsShowFocus;
977 }
978 
996 {
997  Q_D(QTreeView);
998  if (d->wrapItemText == on)
999  return;
1000  d->wrapItemText = on;
1001  d->doDelayedItemsLayout();
1002 }
1003 
1004 bool QTreeView::wordWrap() const
1005 {
1006  Q_D(const QTreeView);
1007  return d->wrapItemText;
1008 }
1009 
1010 
1015 {
1016  Q_D(QTreeView);
1017  if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
1018  return;
1019 
1020  QModelIndex start;
1021  if (currentIndex().isValid())
1022  start = currentIndex();
1023  else
1024  start = d->model->index(0, 0, d->root);
1025 
1026  bool skipRow = false;
1027  bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
1028  qint64 keyboardInputTimeElapsed = d->keyboardInputTime.restart();
1029  if (search.isEmpty() || !keyboardTimeWasValid
1030  || keyboardInputTimeElapsed > QApplication::keyboardInputInterval()) {
1031  d->keyboardInput = search;
1032  skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
1033  } else {
1034  d->keyboardInput += search;
1035  }
1036 
1037  // special case for searches with same key like 'aaaaa'
1038  bool sameKey = false;
1039  if (d->keyboardInput.length() > 1) {
1040  int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
1041  sameKey = (c == d->keyboardInput.length());
1042  if (sameKey)
1043  skipRow = true;
1044  }
1045 
1046  // skip if we are searching for the same key or a new search started
1047  if (skipRow) {
1048  if (indexBelow(start).isValid())
1049  start = indexBelow(start);
1050  else
1051  start = d->model->index(0, start.column(), d->root);
1052  }
1053 
1054  d->executePostedLayout();
1055  int startIndex = d->viewIndex(start);
1056  if (startIndex <= -1)
1057  return;
1058 
1059  int previousLevel = -1;
1060  int bestAbove = -1;
1061  int bestBelow = -1;
1062  QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
1063  for (int i = 0; i < d->viewItems.count(); ++i) {
1064  if ((int)d->viewItems.at(i).level > previousLevel) {
1065  QModelIndex searchFrom = d->viewItems.at(i).index;
1066  if (searchFrom.parent() == start.parent())
1067  searchFrom = start;
1068  QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString);
1069  if (match.count()) {
1070  int hitIndex = d->viewIndex(match.at(0));
1071  if (hitIndex >= 0 && hitIndex < startIndex)
1072  bestAbove = bestAbove == -1 ? hitIndex : qMin(hitIndex, bestAbove);
1073  else if (hitIndex >= startIndex)
1074  bestBelow = bestBelow == -1 ? hitIndex : qMin(hitIndex, bestBelow);
1075  }
1076  }
1077  previousLevel = d->viewItems.at(i).level;
1078  }
1079 
1081  if (bestBelow > -1)
1082  index = d->viewItems.at(bestBelow).index;
1083  else if (bestAbove > -1)
1084  index = d->viewItems.at(bestAbove).index;
1085 
1086  if (index.isValid()) {
1087  QItemSelectionModel::SelectionFlags flags = (d->selectionMode == SingleSelection
1088  ? QItemSelectionModel::SelectionFlags(
1090  |d->selectionBehaviorFlags())
1091  : QItemSelectionModel::SelectionFlags(
1093  selectionModel()->setCurrentIndex(index, flags);
1094  }
1095 }
1096 
1102 {
1103  Q_D(const QTreeView);
1104 
1105  if (!d->isIndexValid(index) || isIndexHidden(index))
1106  return QRect();
1107 
1108  d->executePostedLayout();
1109 
1110  int vi = d->viewIndex(index);
1111  if (vi < 0)
1112  return QRect();
1113 
1114  bool spanning = d->viewItems.at(vi).spanning;
1115 
1116  // if we have a spanning item, make the selection stretch from left to right
1117  int x = (spanning ? 0 : columnViewportPosition(index.column()));
1118  int w = (spanning ? d->header->length() : columnWidth(index.column()));
1119  // handle indentation
1120  if (index.column() == 0) {
1121  int i = d->indentationForItem(vi);
1122  w -= i;
1123  if (!isRightToLeft())
1124  x += i;
1125  }
1126 
1127  int y = d->coordinateForItem(vi);
1128  int h = d->itemHeight(vi);
1129 
1130  return QRect(x, y, w, h);
1131 }
1132 
1142 {
1143  Q_D(QTreeView);
1144 
1145  if (!d->isIndexValid(index))
1146  return;
1147 
1148  d->executePostedLayout();
1149  d->updateScrollBars();
1150 
1151  // Expand all parents if the parent(s) of the node are not expanded.
1152  QModelIndex parent = index.parent();
1153  while (parent.isValid() && state() == NoState && d->itemsExpandable) {
1154  if (!isExpanded(parent))
1155  expand(parent);
1156  parent = d->model->parent(parent);
1157  }
1158 
1159  int item = d->viewIndex(index);
1160  if (item < 0)
1161  return;
1162 
1163  QRect area = d->viewport->rect();
1164 
1165  // vertical
1167  int top = verticalScrollBar()->value();
1168  int bottom = top + verticalScrollBar()->pageStep();
1169  if (hint == EnsureVisible && item >= top && item < bottom) {
1170  // nothing to do
1171  } else if (hint == PositionAtTop || (hint == EnsureVisible && item < top)) {
1172  verticalScrollBar()->setValue(item);
1173  } else { // PositionAtBottom or PositionAtCenter
1174  const int currentItemHeight = d->itemHeight(item);
1175  int y = (hint == PositionAtCenter
1176  //we center on the current item with a preference to the top item (ie. -1)
1177  ? area.height() / 2 + currentItemHeight - 1
1178  //otherwise we simply take the whole space
1179  : area.height());
1180  if (y > currentItemHeight) {
1181  while (item >= 0) {
1182  y -= d->itemHeight(item);
1183  if (y < 0) { //there is no more space left
1184  item++;
1185  break;
1186  }
1187  item--;
1188  }
1189  }
1190  verticalScrollBar()->setValue(item);
1191  }
1192  } else { // ScrollPerPixel
1194  d->coordinateForItem(item), // ### slow for items outside the view
1195  columnWidth(index.column()),
1196  d->itemHeight(item));
1197 
1198  if (rect.isEmpty()) {
1199  // nothing to do
1200  } else if (hint == EnsureVisible && area.contains(rect)) {
1201  d->viewport->update(rect);
1202  // nothing to do
1203  } else {
1204  bool above = (hint == EnsureVisible
1205  && (rect.top() < area.top()
1206  || area.height() < rect.height()));
1207  bool below = (hint == EnsureVisible
1208  && rect.bottom() > area.bottom()
1209  && rect.height() < area.height());
1210 
1211  int verticalValue = verticalScrollBar()->value();
1212  if (hint == PositionAtTop || above)
1213  verticalValue += rect.top();
1214  else if (hint == PositionAtBottom || below)
1215  verticalValue += rect.bottom() - area.height();
1216  else if (hint == PositionAtCenter)
1217  verticalValue += rect.top() - ((area.height() - rect.height()) / 2);
1218  verticalScrollBar()->setValue(verticalValue);
1219  }
1220  }
1221  // horizontal
1222  int viewportWidth = d->viewport->width();
1223  int horizontalOffset = d->header->offset();
1224  int horizontalPosition = d->header->sectionPosition(index.column());
1225  int cellWidth = d->header->sectionSize(index.column());
1226 
1227  if (hint == PositionAtCenter) {
1228  horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
1229  } else {
1230  if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
1231  horizontalScrollBar()->setValue(horizontalPosition);
1232  else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
1233  horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
1234  }
1235 }
1236 
1241 {
1242  Q_D(QTreeView);
1243  if (event->timerId() == d->columnResizeTimerID) {
1244  updateGeometries();
1245  killTimer(d->columnResizeTimerID);
1246  d->columnResizeTimerID = 0;
1247  QRect rect;
1248  int viewportHeight = d->viewport->height();
1249  int viewportWidth = d->viewport->width();
1250  for (int i = d->columnsToUpdate.size() - 1; i >= 0; --i) {
1251  int column = d->columnsToUpdate.at(i);
1252  int x = columnViewportPosition(column);
1253  if (isRightToLeft())
1254  rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);
1255  else
1256  rect |= QRect(x, 0, viewportWidth - x, viewportHeight);
1257  }
1258  d->viewport->update(rect.normalized());
1259  d->columnsToUpdate.clear();
1260  } else if (event->timerId() == d->openTimer.timerId()) {
1261  QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
1263  && d->viewport->rect().contains(pos)) {
1264  QModelIndex index = indexAt(pos);
1265  setExpanded(index, !isExpanded(index));
1266  }
1267  d->openTimer.stop();
1268  }
1269 
1271 }
1272 
1276 #ifndef QT_NO_DRAGANDDROP
1278 {
1279  Q_D(QTreeView);
1280  if (d->autoExpandDelay >= 0)
1281  d->openTimer.start(d->autoExpandDelay, this);
1283 }
1284 #endif
1285 
1290 {
1291  Q_D(QTreeView);
1292  switch (event->type()) {
1293  case QEvent::HoverEnter:
1294  case QEvent::HoverLeave:
1295  case QEvent::HoverMove: {
1296  QHoverEvent *he = static_cast<QHoverEvent*>(event);
1297  int oldBranch = d->hoverBranch;
1298  d->hoverBranch = d->itemDecorationAt(he->pos());
1299  QModelIndex newIndex = indexAt(he->pos());
1300  if (d->hover != newIndex || d->hoverBranch != oldBranch) {
1301  // Update the whole hovered over row. No need to update the old hovered
1302  // row, that is taken care in superclass hover handling.
1303  QRect rect = visualRect(newIndex);
1304  rect.setX(0);
1305  rect.setWidth(viewport()->width());
1306  viewport()->update(rect);
1307  }
1308  break; }
1309  default:
1310  break;
1311  }
1312  return QAbstractItemView::viewportEvent(event);
1313 }
1314 
1319 {
1320  Q_D(QTreeView);
1321  d->executePostedLayout();
1322  QPainter painter(viewport());
1323 #ifndef QT_NO_ANIMATION
1324  if (d->isAnimating()) {
1325  drawTree(&painter, event->region() - d->animatedOperation.rect());
1326  d->drawAnimatedOperation(&painter);
1327  } else
1328 #endif //QT_NO_ANIMATION
1329  {
1330  drawTree(&painter, event->region());
1331 #ifndef QT_NO_DRAGANDDROP
1332  d->paintDropIndicator(&painter);
1333 #endif
1334  }
1335 }
1336 
1338 {
1339  Q_Q(const QTreeView);
1340  if (!alternatingColors || !q->style()->styleHint(QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea, option, q))
1341  return;
1342  int rowHeight = defaultItemHeight;
1343  if (rowHeight <= 0) {
1344  rowHeight = itemDelegate->sizeHint(*option, QModelIndex()).height();
1345  if (rowHeight <= 0)
1346  return;
1347  }
1348  while (y <= bottom) {
1349  option->rect.setRect(0, y, viewport->width(), rowHeight);
1350  if (current & 1) {
1352  } else {
1353  option->features &= ~QStyleOptionViewItemV2::Alternate;
1354  }
1355  ++current;
1356  q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, option, painter, q);
1357  y += rowHeight;
1358  }
1359 }
1360 
1362 {
1363  Q_Q(QTreeView);
1364  // we want to handle mousePress in EditingState (persistent editors)
1367  || !viewport->rect().contains(pos))
1368  return true;
1369 
1370  int i = itemDecorationAt(pos);
1371  if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {
1372  if (viewItems.at(i).expanded)
1373  collapse(i, true);
1374  else
1375  expand(i, true);
1376  if (!isAnimating()) {
1377  q->updateGeometries();
1378  viewport->update();
1379  }
1380  return true;
1381  }
1382  return false;
1383 }
1384 
1386 {
1387  //we need to clear that list because it contais QModelIndex to
1388  //the model currently being destroyed
1389  viewItems.clear();
1391 }
1392 
1399 {
1400  Q_ASSERT(r);
1401  Q_Q(const QTreeView);
1402  if (spanningIndexes.isEmpty())
1404  QModelIndexList list;
1405  foreach (const QModelIndex &idx, indexes) {
1406  if (idx.column() > 0 && q->isFirstColumnSpanned(idx.row(), idx.parent()))
1407  continue;
1408  list << idx;
1409  }
1411 }
1412 
1414 {
1415  const int row = viewIndex(current); // get the index in viewItems[]
1416  option->state = option->state | (viewItems.at(row).expanded ? QStyle::State_Open : QStyle::State_None)
1417  | (viewItems.at(row).hasChildren ? QStyle::State_Children : QStyle::State_None)
1418  | (viewItems.at(row).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
1419 
1421  || option->showDecorationSelected;
1422 
1423  QVector<int> logicalIndices; // index = visual index of visible columns only. data = logical index.
1424  QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex, visible columns only.
1425  const bool spanning = viewItems.at(row).spanning;
1426  const int left = (spanning ? header->visualIndex(0) : 0);
1427  const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
1428  calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
1429 
1430  int columnIndex = 0;
1431  for (int visualIndex = 0; visualIndex < current.column(); ++visualIndex) {
1432  int logicalIndex = header->logicalIndex(visualIndex);
1433  if (!header->isSectionHidden(logicalIndex)) {
1434  ++columnIndex;
1435  }
1436  }
1437 
1438  option->viewItemPosition = viewItemPosList.at(columnIndex);
1439 }
1440 
1441 
1452 void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
1453 {
1454  Q_D(const QTreeView);
1455  const QVector<QTreeViewItem> viewItems = d->viewItems;
1456 
1457  QStyleOptionViewItemV4 option = d->viewOptionsV4();
1458  const QStyle::State state = option.state;
1459  d->current = 0;
1460 
1461  if (viewItems.count() == 0 || d->header->count() == 0 || !d->itemDelegate) {
1462  d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
1463  return;
1464  }
1465 
1466  int firstVisibleItemOffset = 0;
1467  const int firstVisibleItem = d->firstVisibleItem(&firstVisibleItemOffset);
1468  if (firstVisibleItem < 0) {
1469  d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
1470  return;
1471  }
1472 
1473  const int viewportWidth = d->viewport->width();
1474 
1475  QPoint hoverPos = d->viewport->mapFromGlobal(QCursor::pos());
1476  d->hoverBranch = d->itemDecorationAt(hoverPos);
1477 
1478  QVector<QRect> rects = region.rects();
1479  QVector<int> drawn;
1480  bool multipleRects = (rects.size() > 1);
1481  for (int a = 0; a < rects.size(); ++a) {
1482  const QRect area = (multipleRects
1483  ? QRect(0, rects.at(a).y(), viewportWidth, rects.at(a).height())
1484  : rects.at(a));
1485  d->leftAndRight = d->startAndEndColumns(area);
1486 
1487  int i = firstVisibleItem; // the first item at the top of the viewport
1488  int y = firstVisibleItemOffset; // we may only see part of the first item
1489 
1490  // start at the top of the viewport and iterate down to the update area
1491  for (; i < viewItems.count(); ++i) {
1492  const int itemHeight = d->itemHeight(i);
1493  if (y + itemHeight > area.top())
1494  break;
1495  y += itemHeight;
1496  }
1497 
1498  // paint the visible rows
1499  for (; i < viewItems.count() && y <= area.bottom(); ++i) {
1500  const int itemHeight = d->itemHeight(i);
1501  option.rect.setRect(0, y, viewportWidth, itemHeight);
1502  option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
1505  d->current = i;
1506  d->spanning = viewItems.at(i).spanning;
1507  if (!multipleRects || !drawn.contains(i)) {
1508  drawRow(painter, option, viewItems.at(i).index);
1509  if (multipleRects) // even if the rect only intersects the item,
1510  drawn.append(i); // the entire item will be painted
1511  }
1512  y += itemHeight;
1513  }
1514 
1515  if (y <= area.bottom()) {
1516  d->current = i;
1517  d->paintAlternatingRowColors(painter, &option, y, area.bottom());
1518  }
1519  }
1520 }
1521 
1523 static inline bool ancestorOf(QObject *widget, QObject *other)
1524 {
1525  for (QObject *parent = other; parent != 0; parent = parent->parent()) {
1526  if (parent == widget)
1527  return true;
1528  }
1529  return false;
1530 }
1531 
1533 {
1534  const int columnCount = header->count();
1535  /* 'left' and 'right' are the left-most and right-most visible visual indices.
1536  Compute the first visible logical indices before and after the left and right.
1537  We will use these values to determine the QStyleOptionViewItemV4::viewItemPosition. */
1538  int logicalIndexBeforeLeft = -1, logicalIndexAfterRight = -1;
1539  for (int visualIndex = left - 1; visualIndex >= 0; --visualIndex) {
1540  int logicalIndex = header->logicalIndex(visualIndex);
1541  if (!header->isSectionHidden(logicalIndex)) {
1542  logicalIndexBeforeLeft = logicalIndex;
1543  break;
1544  }
1545  }
1546 
1547  for (int visualIndex = left; visualIndex < columnCount; ++visualIndex) {
1548  int logicalIndex = header->logicalIndex(visualIndex);
1549  if (!header->isSectionHidden(logicalIndex)) {
1550  if (visualIndex > right) {
1551  logicalIndexAfterRight = logicalIndex;
1552  break;
1553  }
1554  logicalIndices->append(logicalIndex);
1555  }
1556  }
1557 
1558  itemPositions->resize(logicalIndices->count());
1559  for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->count(); ++currentLogicalSection) {
1560  const int headerSection = logicalIndices->at(currentLogicalSection);
1561  // determine the viewItemPosition depending on the position of column 0
1562  int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->count()
1563  ? logicalIndexAfterRight
1564  : logicalIndices->at(currentLogicalSection + 1);
1565  int prevLogicalSection = currentLogicalSection - 1 < 0
1566  ? logicalIndexBeforeLeft
1567  : logicalIndices->at(currentLogicalSection - 1);
1569  if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
1570  || (headerSection == 0 && nextLogicalSection == -1) || spanning)
1572  else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1))
1574  else if (nextLogicalSection == 0 || nextLogicalSection == -1)
1576  else
1578  (*itemPositions)[currentLogicalSection] = pos;
1579  }
1580 }
1581 
1582 
1590 void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
1591  const QModelIndex &index) const
1592 {
1593  Q_D(const QTreeView);
1594  QStyleOptionViewItemV4 opt = option;
1595  const QPoint offset = d->scrollDelayOffset;
1596  const int y = option.rect.y() + offset.y();
1597  const QModelIndex parent = index.parent();
1598  const QHeaderView *header = d->header;
1599  const QModelIndex current = currentIndex();
1600  const QModelIndex hover = d->hover;
1601  const bool reverse = isRightToLeft();
1602  const QStyle::State state = opt.state;
1603  const bool spanning = d->spanning;
1604  const int left = (spanning ? header->visualIndex(0) : d->leftAndRight.first);
1605  const int right = (spanning ? header->visualIndex(0) : d->leftAndRight.second);
1606  const bool alternate = d->alternatingColors;
1607  const bool enabled = (state & QStyle::State_Enabled) != 0;
1608  const bool allColumnsShowFocus = d->allColumnsShowFocus;
1609 
1610 
1611  // when the row contains an index widget which has focus,
1612  // we want to paint the entire row as active
1613  bool indexWidgetHasFocus = false;
1614  if ((current.row() == index.row()) && !d->editorIndexHash.isEmpty()) {
1615  const int r = index.row();
1617  for (int c = 0; c < header->count(); ++c) {
1618  QModelIndex idx = d->model->index(r, c, parent);
1619  if (QWidget *editor = indexWidget(idx)) {
1620  if (ancestorOf(editor, fw)) {
1621  indexWidgetHasFocus = true;
1622  break;
1623  }
1624  }
1625  }
1626  }
1627 
1628  const bool widgetHasFocus = hasFocus();
1629  bool currentRowHasFocus = false;
1630  if (allColumnsShowFocus && widgetHasFocus && current.isValid()) {
1631  // check if the focus index is before or after the visible columns
1632  const int r = index.row();
1633  for (int c = 0; c < left && !currentRowHasFocus; ++c) {
1634  QModelIndex idx = d->model->index(r, c, parent);
1635  currentRowHasFocus = (idx == current);
1636  }
1637  QModelIndex parent = d->model->parent(index);
1638  for (int c = right; c < header->count() && !currentRowHasFocus; ++c) {
1639  currentRowHasFocus = (d->model->index(r, c, parent) == current);
1640  }
1641  }
1642 
1643  // ### special case: treeviews with multiple columns draw
1644  // the selections differently than with only one column
1645  opt.showDecorationSelected = (d->selectionBehavior & SelectRows)
1646  || option.showDecorationSelected;
1647 
1648  int width, height = option.rect.height();
1649  int position;
1650  QModelIndex modelIndex;
1651  const bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
1652  && index.parent() == hover.parent()
1653  && index.row() == hover.row();
1654 
1655  QVector<int> logicalIndices;
1656  QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex
1657  d->calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
1658 
1659  for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) {
1660  int headerSection = logicalIndices.at(currentLogicalSection);
1661  position = columnViewportPosition(headerSection) + offset.x();
1662  width = header->sectionSize(headerSection);
1663 
1664  if (spanning) {
1665  int lastSection = header->logicalIndex(header->count() - 1);
1666  if (!reverse) {
1667  width = columnViewportPosition(lastSection) + header->sectionSize(lastSection) - position;
1668  } else {
1669  width += position - columnViewportPosition(lastSection);
1670  position = columnViewportPosition(lastSection);
1671  }
1672  }
1673 
1674  modelIndex = d->model->index(index.row(), headerSection, parent);
1675  if (!modelIndex.isValid())
1676  continue;
1677  opt.state = state;
1678 
1679  opt.viewItemPosition = viewItemPosList.at(currentLogicalSection);
1680 
1681  // fake activeness when row editor has focus
1682  if (indexWidgetHasFocus)
1683  opt.state |= QStyle::State_Active;
1684 
1685  if (d->selectionModel->isSelected(modelIndex))
1687  if (widgetHasFocus && (current == modelIndex)) {
1688  if (allColumnsShowFocus)
1689  currentRowHasFocus = true;
1690  else
1692  }
1693  if ((hoverRow || modelIndex == hover)
1694  && (option.showDecorationSelected || (d->hoverBranch == -1)))
1696  else
1698 
1699  if (enabled) {
1701  if ((d->model->flags(modelIndex) & Qt::ItemIsEnabled) == 0) {
1702  opt.state &= ~QStyle::State_Enabled;
1703  cg = QPalette::Disabled;
1704  } else if (opt.state & QStyle::State_Active) {
1705  cg = QPalette::Active;
1706  } else {
1707  cg = QPalette::Inactive;
1708  }
1709  opt.palette.setCurrentColorGroup(cg);
1710  }
1711 
1712  if (alternate) {
1713  if (d->current & 1) {
1715  } else {
1716  opt.features &= ~QStyleOptionViewItemV2::Alternate;
1717  }
1718  }
1719 
1720  /* Prior to Qt 4.3, the background of the branch (in selected state and
1721  alternate row color was provided by the view. For backward compatibility,
1722  this is now delegated to the style using PE_PanelViewItemRow which
1723  does the appropriate fill */
1724  if (headerSection == 0) {
1725  const int i = d->indentationForItem(d->current);
1726  QRect branches(reverse ? position + width - i : position, y, i, height);
1727  const bool setClipRect = branches.width() > width;
1728  if (setClipRect) {
1729  painter->save();
1730  painter->setClipRect(QRect(position, y, width, height));
1731  }
1732  // draw background for the branch (selection + alternate row)
1733  opt.rect = branches;
1734  style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
1735 
1736  // draw background of the item (only alternate row). rest of the background
1737  // is provided by the delegate
1738  QStyle::State oldState = opt.state;
1739  opt.state &= ~QStyle::State_Selected;
1740  opt.rect.setRect(reverse ? position : i + position, y, width - i, height);
1741  style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
1742  opt.state = oldState;
1743 
1744  drawBranches(painter, branches, index);
1745  if (setClipRect)
1746  painter->restore();
1747  } else {
1748  QStyle::State oldState = opt.state;
1749  opt.state &= ~QStyle::State_Selected;
1750  opt.rect.setRect(position, y, width, height);
1751  style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
1752  opt.state = oldState;
1753  }
1754 
1755  d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
1756  }
1757 
1758  if (currentRowHasFocus) {
1760  o.QStyleOption::operator=(option);
1764  o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
1766  int x = 0;
1767  if (!option.showDecorationSelected)
1768  x = header->sectionPosition(0) + d->indentationForItem(d->current);
1769  QRect focusRect(x - header->offset(), y, header->length() - x, height);
1770  o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), focusRect);
1772  // if we show focus on all columns and the first section is moved,
1773  // we have to split the focus rect into two rects
1774  if (allColumnsShowFocus && !option.showDecorationSelected
1775  && header->sectionsMoved() && (header->visualIndex(0) != 0)) {
1776  QRect sectionRect(0, y, header->sectionPosition(0), height);
1777  o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), sectionRect);
1779  }
1780  }
1781 }
1782 
1789  const QModelIndex &index) const
1790 {
1791  Q_D(const QTreeView);
1792  const bool reverse = isRightToLeft();
1793  const int indent = d->indent;
1794  const int outer = d->rootDecoration ? 0 : 1;
1795  const int item = d->current;
1796  const QTreeViewItem &viewItem = d->viewItems.at(item);
1797  int level = viewItem.level;
1798  QRect primitive(reverse ? rect.left() : rect.right() + 1, rect.top(), indent, rect.height());
1799 
1800  QModelIndex parent = index.parent();
1801  QModelIndex current = parent;
1802  QModelIndex ancestor = current.parent();
1803 
1805  QStyle::State extraFlags = QStyle::State_None;
1806  if (isEnabled())
1807  extraFlags |= QStyle::State_Enabled;
1808  if (window()->isActiveWindow())
1809  extraFlags |= QStyle::State_Active;
1810  QPoint oldBO = painter->brushOrigin();
1812  painter->setBrushOrigin(QPoint(0, verticalOffset()));
1813 
1814  if (d->alternatingColors) {
1815  if (d->current & 1) {
1817  } else {
1818  opt.features &= ~QStyleOptionViewItemV2::Alternate;
1819  }
1820  }
1821 
1822  // When hovering over a row, pass State_Hover for painting the branch
1823  // indicators if it has the decoration (aka branch) selected.
1825  && opt.showDecorationSelected
1826  && index.parent() == d->hover.parent()
1827  && index.row() == d->hover.row();
1828 
1829  if (d->selectionModel->isSelected(index))
1830  extraFlags |= QStyle::State_Selected;
1831 
1832  if (level >= outer) {
1833  // start with the innermost branch
1834  primitive.moveLeft(reverse ? primitive.left() : primitive.left() - indent);
1835  opt.rect = primitive;
1836 
1837  const bool expanded = viewItem.expanded;
1838  const bool children = viewItem.hasChildren;
1839  bool moreSiblings = viewItem.hasMoreSiblings;
1840 
1841  opt.state = QStyle::State_Item | extraFlags
1842  | (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)
1844  | (expanded ? QStyle::State_Open : QStyle::State_None);
1845  if (hoverRow || item == d->hoverBranch)
1847  else
1848  opt.state &= ~QStyle::State_MouseOver;
1849  style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
1850  }
1851  // then go out level by level
1852  for (--level; level >= outer; --level) { // we have already drawn the innermost branch
1853  primitive.moveLeft(reverse ? primitive.left() + indent : primitive.left() - indent);
1854  opt.rect = primitive;
1855  opt.state = extraFlags;
1856  bool moreSiblings = false;
1857  if (d->hiddenIndexes.isEmpty()) {
1858  moreSiblings = (d->model->rowCount(ancestor) - 1 > current.row());
1859  } else {
1860  int successor = item + viewItem.total + 1;
1861  while (successor < d->viewItems.size()
1862  && d->viewItems.at(successor).level >= uint(level)) {
1863  const QTreeViewItem &successorItem = d->viewItems.at(successor);
1864  if (successorItem.level == uint(level)) {
1865  moreSiblings = true;
1866  break;
1867  }
1868  successor += successorItem.total + 1;
1869  }
1870  }
1871  if (moreSiblings)
1873  if (hoverRow || item == d->hoverBranch)
1875  else
1876  opt.state &= ~QStyle::State_MouseOver;
1877  style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
1878  current = ancestor;
1879  ancestor = current.parent();
1880  }
1881  painter->setBrushOrigin(oldBO);
1882 }
1883 
1888 {
1889  Q_D(QTreeView);
1890  bool handled = false;
1892  handled = d->expandOrCollapseItemAtPos(event->pos());
1893  if (!handled && d->itemDecorationAt(event->pos()) == -1)
1895 }
1896 
1901 {
1902  Q_D(QTreeView);
1903  if (d->itemDecorationAt(event->pos()) == -1) {
1905  } else {
1909  d->expandOrCollapseItemAtPos(event->pos());
1910  }
1911 }
1912 
1917 {
1918  Q_D(QTreeView);
1919  if (state() != NoState || !d->viewport->rect().contains(event->pos()))
1920  return;
1921 
1922  int i = d->itemDecorationAt(event->pos());
1923  if (i == -1) {
1924  i = d->itemAtCoordinate(event->y());
1925  if (i == -1)
1926  return; // user clicked outside the items
1927 
1928  const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
1929  const QPersistentModelIndex persistent = indexAt(event->pos());
1930 
1931  if (d->pressedIndex != persistent) {
1932  mousePressEvent(event);
1933  return;
1934  }
1935 
1936  // signal handlers may change the model
1937  emit doubleClicked(persistent);
1938 
1939  if (!persistent.isValid())
1940  return;
1941 
1942  if (edit(persistent, DoubleClicked, event) || state() != NoState)
1943  return; // the double click triggered editing
1944 
1946  emit activated(persistent);
1947 
1948  d->executePostedLayout(); // we need to make sure viewItems is updated
1949  if (d->itemsExpandable
1950  && d->expandsOnDoubleClick
1951  && d->hasVisibleChildren(persistent)) {
1952  if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {
1953  // find the new index of the item
1954  for (i = 0; i < d->viewItems.count(); ++i) {
1955  if (d->viewItems.at(i).index == firstColumnIndex)
1956  break;
1957  }
1958  if (i == d->viewItems.count())
1959  return;
1960  }
1961  if (d->viewItems.at(i).expanded)
1962  d->collapse(i, true);
1963  else
1964  d->expand(i, true);
1965  updateGeometries();
1966  viewport()->update();
1967  }
1968  }
1969 }
1970 
1975 {
1976  Q_D(QTreeView);
1977  if (d->itemDecorationAt(event->pos()) == -1) // ### what about expanding/collapsing state ?
1979 }
1980 
1985 {
1986  Q_D(QTreeView);
1987  QModelIndex current = currentIndex();
1988  //this is the management of the expansion
1989  if (d->isIndexValid(current) && d->model && d->itemsExpandable) {
1990  switch (event->key()) {
1991  case Qt::Key_Asterisk: {
1992  QStack<QModelIndex> parents;
1993  parents.push(current);
1994  while (!parents.isEmpty()) {
1995  QModelIndex parent = parents.pop();
1996  for (int row = 0; row < d->model->rowCount(parent); ++row) {
1997  QModelIndex child = d->model->index(row, 0, parent);
1998  if (!d->isIndexValid(child))
1999  break;
2000  parents.push(child);
2001  expand(child);
2002  }
2003  }
2004  expand(current);
2005  break; }
2006  case Qt::Key_Plus:
2007  expand(current);
2008  break;
2009  case Qt::Key_Minus:
2010  collapse(current);
2011  break;
2012  }
2013  }
2014 
2016 }
2017 
2022 {
2023  Q_D(const QTreeView);
2024  d->executePostedLayout();
2025 
2026  int visualIndex = d->itemAtCoordinate(point.y());
2027  QModelIndex idx = d->modelIndex(visualIndex);
2028  if (!idx.isValid())
2029  return QModelIndex();
2030 
2031  if (d->viewItems.at(visualIndex).spanning)
2032  return idx;
2033 
2034  int column = d->columnAt(point.x());
2035  if (column == idx.column())
2036  return idx;
2037  if (column < 0)
2038  return QModelIndex();
2039  return idx.sibling(idx.row(), column);
2040 }
2041 
2046 {
2047  Q_D(const QTreeView);
2048  if (!d->isIndexValid(index))
2049  return QModelIndex();
2050  d->executePostedLayout();
2051  int i = d->viewIndex(index);
2052  if (--i < 0)
2053  return QModelIndex();
2054  return d->viewItems.at(i).index;
2055 }
2056 
2061 {
2062  Q_D(const QTreeView);
2063  if (!d->isIndexValid(index))
2064  return QModelIndex();
2065  d->executePostedLayout();
2066  int i = d->viewIndex(index);
2067  if (++i >= d->viewItems.count())
2068  return QModelIndex();
2069  return d->viewItems.at(i).index;
2070 }
2071 
2081 {
2082  Q_D(QTreeView);
2083  if (d->hasRemovedItems) {
2084  //clean the QSet that may contains old (and this invalid) indexes
2085  d->hasRemovedItems = false;
2086  QSet<QPersistentModelIndex>::iterator it = d->expandedIndexes.begin();
2087  while (it != d->expandedIndexes.constEnd()) {
2088  if (!it->isValid())
2089  it = d->expandedIndexes.erase(it);
2090  else
2091  ++it;
2092  }
2093  it = d->hiddenIndexes.begin();
2094  while (it != d->hiddenIndexes.constEnd()) {
2095  if (!it->isValid())
2096  it = d->hiddenIndexes.erase(it);
2097  else
2098  ++it;
2099  }
2100  }
2101  d->viewItems.clear(); // prepare for new layout
2102  QModelIndex parent = d->root;
2103  if (d->model->hasChildren(parent)) {
2104  d->layout(-1);
2105  }
2107  d->header->doItemsLayout();
2108 }
2109 
2114 {
2115  Q_D(QTreeView);
2116  d->expandedIndexes.clear();
2117  d->hiddenIndexes.clear();
2118  d->spanningIndexes.clear();
2119  d->viewItems.clear();
2121 }
2122 
2132 {
2133  Q_D(const QTreeView);
2134  return d->header->offset();
2135 }
2136 
2143 {
2144  Q_D(const QTreeView);
2145  if (d->verticalScrollMode == QAbstractItemView::ScrollPerItem) {
2146  if (d->uniformRowHeights)
2147  return verticalScrollBar()->value() * d->defaultItemHeight;
2148  // If we are scrolling per item and have non-uniform row heights,
2149  // finding the vertical offset in pixels is going to be relatively slow.
2150  // ### find a faster way to do this
2151  d->executePostedLayout();
2152  int offset = 0;
2153  for (int i = 0; i < d->viewItems.count(); ++i) {
2154  if (i == verticalScrollBar()->value())
2155  return offset;
2156  offset += d->itemHeight(i);
2157  }
2158  return 0;
2159  }
2160  // scroll per pixel
2161  return verticalScrollBar()->value();
2162 }
2163 
2168 QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
2169 {
2170  Q_D(QTreeView);
2171  Q_UNUSED(modifiers);
2172 
2173  d->executePostedLayout();
2174 
2175  QModelIndex current = currentIndex();
2176  if (!current.isValid()) {
2177  int i = d->below(-1);
2178  int c = 0;
2179  while (c < d->header->count() && d->header->isSectionHidden(c))
2180  ++c;
2181  if (i < d->viewItems.count() && c < d->header->count()) {
2182  return d->modelIndex(i, c);
2183  }
2184  return QModelIndex();
2185  }
2186  int vi = -1;
2187 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
2188  // Selection behavior is slightly different on the Mac.
2189  if (d->selectionMode == QAbstractItemView::ExtendedSelection
2190  && d->selectionModel
2191  && d->selectionModel->hasSelection()) {
2192 
2193  const bool moveUpDown = (cursorAction == MoveUp || cursorAction == MoveDown);
2194  const bool moveNextPrev = (cursorAction == MoveNext || cursorAction == MovePrevious);
2195  const bool contiguousSelection = moveUpDown && (modifiers & Qt::ShiftModifier);
2196 
2197  // Use the outermost index in the selection as the current index
2198  if (!contiguousSelection && (moveUpDown || moveNextPrev)) {
2199 
2200  // Find outermost index.
2201  const bool useTopIndex = (cursorAction == MoveUp || cursorAction == MovePrevious);
2202  int index = useTopIndex ? INT_MAX : INT_MIN;
2203  const QItemSelection selection = d->selectionModel->selection();
2204  for (int i = 0; i < selection.count(); ++i) {
2205  const QItemSelectionRange &range = selection.at(i);
2206  int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight());
2207  if (candidate >= 0)
2208  index = useTopIndex ? qMin(index, candidate) : qMax(index, candidate);
2209  }
2210 
2211  if (index >= 0 && index < INT_MAX)
2212  vi = index;
2213  }
2214  }
2215 #endif
2216  if (vi < 0)
2217  vi = qMax(0, d->viewIndex(current));
2218 
2219  if (isRightToLeft()) {
2220  if (cursorAction == MoveRight)
2221  cursorAction = MoveLeft;
2222  else if (cursorAction == MoveLeft)
2223  cursorAction = MoveRight;
2224  }
2225  switch (cursorAction) {
2226  case MoveNext:
2227  case MoveDown:
2228 #ifdef QT_KEYPAD_NAVIGATION
2229  if (vi == d->viewItems.count()-1 && QApplication::keypadNavigationEnabled())
2230  return d->model->index(0, current.column(), d->root);
2231 #endif
2232  return d->modelIndex(d->below(vi), current.column());
2233  case MovePrevious:
2234  case MoveUp:
2235 #ifdef QT_KEYPAD_NAVIGATION
2236  if (vi == 0 && QApplication::keypadNavigationEnabled())
2237  return d->modelIndex(d->viewItems.count() - 1, current.column());
2238 #endif
2239  return d->modelIndex(d->above(vi), current.column());
2240  case MoveLeft: {
2242  if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) {
2243  d->collapse(vi, true);
2244  d->moveCursorUpdatedView = true;
2245  } else {
2247  if (descend) {
2248  QModelIndex par = current.parent();
2249  if (par.isValid() && par != rootIndex())
2250  return par;
2251  else
2252  descend = false;
2253  }
2254  if (!descend) {
2255  if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {
2256  int visualColumn = d->header->visualIndex(current.column()) - 1;
2257  while (visualColumn >= 0 && isColumnHidden(d->header->logicalIndex(visualColumn)))
2258  visualColumn--;
2259  int newColumn = d->header->logicalIndex(visualColumn);
2260  QModelIndex next = current.sibling(current.row(), newColumn);
2261  if (next.isValid())
2262  return next;
2263  }
2264 
2265  int oldValue = sb->value();
2266  sb->setValue(sb->value() - sb->singleStep());
2267  if (oldValue != sb->value())
2268  d->moveCursorUpdatedView = true;
2269  }
2270 
2271  }
2272  updateGeometries();
2273  viewport()->update();
2274  break;
2275  }
2276  case MoveRight:
2277  if (vi < d->viewItems.count() && !d->viewItems.at(vi).expanded && d->itemsExpandable
2278  && d->hasVisibleChildren(d->viewItems.at(vi).index)) {
2279  d->expand(vi, true);
2280  d->moveCursorUpdatedView = true;
2281  } else {
2283  if (descend) {
2284  QModelIndex idx = d->modelIndex(d->below(vi));
2285  if (idx.parent() == current)
2286  return idx;
2287  else
2288  descend = false;
2289  }
2290  if (!descend) {
2291  if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {
2292  int visualColumn = d->header->visualIndex(current.column()) + 1;
2293  while (visualColumn < d->model->columnCount(current.parent()) && isColumnHidden(d->header->logicalIndex(visualColumn)))
2294  visualColumn++;
2295 
2296  QModelIndex next = current.sibling(current.row(), visualColumn);
2297  if (next.isValid())
2298  return next;
2299  }
2300 
2301  //last restort: we change the scrollbar value
2303  int oldValue = sb->value();
2304  sb->setValue(sb->value() + sb->singleStep());
2305  if (oldValue != sb->value())
2306  d->moveCursorUpdatedView = true;
2307  }
2308  }
2309  updateGeometries();
2310  viewport()->update();
2311  break;
2312  case MovePageUp:
2313  return d->modelIndex(d->pageUp(vi), current.column());
2314  case MovePageDown:
2315  return d->modelIndex(d->pageDown(vi), current.column());
2316  case MoveHome:
2317  return d->model->index(0, current.column(), d->root);
2318  case MoveEnd:
2319  return d->modelIndex(d->viewItems.count() - 1, current.column());
2320  }
2321  return current;
2322 }
2323 
2330 void QTreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
2331 {
2332  Q_D(QTreeView);
2333  if (!selectionModel() || rect.isNull())
2334  return;
2335 
2336  d->executePostedLayout();
2337  QPoint tl(isRightToLeft() ? qMax(rect.left(), rect.right())
2338  : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom()));
2339  QPoint br(isRightToLeft() ? qMin(rect.left(), rect.right()) :
2340  qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom()));
2341  QModelIndex topLeft = indexAt(tl);
2342  QModelIndex bottomRight = indexAt(br);
2343  if (!topLeft.isValid() && !bottomRight.isValid()) {
2344  if (command & QItemSelectionModel::Clear)
2345  selectionModel()->clear();
2346  return;
2347  }
2348  if (!topLeft.isValid() && !d->viewItems.isEmpty())
2349  topLeft = d->viewItems.first().index;
2350  if (!bottomRight.isValid() && !d->viewItems.isEmpty()) {
2351  const int column = d->header->logicalIndex(d->header->count() - 1);
2352  const QModelIndex index = d->viewItems.last().index;
2353  bottomRight = index.sibling(index.row(), column);
2354  }
2355 
2356  if (!d->isIndexEnabled(topLeft) || !d->isIndexEnabled(bottomRight))
2357  return;
2358 
2359  d->select(topLeft, bottomRight, command);
2360 }
2361 
2370 {
2371  Q_D(const QTreeView);
2372  if (selection.isEmpty())
2373  return QRegion();
2374 
2375  QRegion selectionRegion;
2376  const QRect &viewportRect = d->viewport->rect();
2377  for (int i = 0; i < selection.count(); ++i) {
2378  QItemSelectionRange range = selection.at(i);
2379  if (!range.isValid())
2380  continue;
2381  QModelIndex parent = range.parent();
2382  QModelIndex leftIndex = range.topLeft();
2383  int columnCount = d->model->columnCount(parent);
2384  while (leftIndex.isValid() && isIndexHidden(leftIndex)) {
2385  if (leftIndex.column() + 1 < columnCount)
2386  leftIndex = d->model->index(leftIndex.row(), leftIndex.column() + 1, parent);
2387  else
2388  leftIndex = QModelIndex();
2389  }
2390  if (!leftIndex.isValid())
2391  continue;
2392  const QRect leftRect = visualRect(leftIndex);
2393  int top = leftRect.top();
2394  QModelIndex rightIndex = range.bottomRight();
2395  while (rightIndex.isValid() && isIndexHidden(rightIndex)) {
2396  if (rightIndex.column() - 1 >= 0)
2397  rightIndex = d->model->index(rightIndex.row(), rightIndex.column() - 1, parent);
2398  else
2399  rightIndex = QModelIndex();
2400  }
2401  if (!rightIndex.isValid())
2402  continue;
2403  const QRect rightRect = visualRect(rightIndex);
2404  int bottom = rightRect.bottom();
2405  if (top > bottom)
2406  qSwap<int>(top, bottom);
2407  int height = bottom - top + 1;
2408  if (d->header->sectionsMoved()) {
2409  for (int c = range.left(); c <= range.right(); ++c) {
2410  const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
2411  if (viewportRect.intersects(rangeRect))
2412  selectionRegion += rangeRect;
2413  }
2414  } else {
2415  QRect combined = leftRect|rightRect;
2416  combined.setX(columnViewportPosition(isRightToLeft() ? range.right() : range.left()));
2417  if (viewportRect.intersects(combined))
2418  selectionRegion += combined;
2419  }
2420  }
2421  return selectionRegion;
2422 }
2423 
2428 {
2429  QModelIndexList viewSelected;
2430  QModelIndexList modelSelected;
2431  if (selectionModel())
2432  modelSelected = selectionModel()->selectedIndexes();
2433  for (int i = 0; i < modelSelected.count(); ++i) {
2434  // check that neither the parents nor the index is hidden before we add
2435  QModelIndex index = modelSelected.at(i);
2436  while (index.isValid() && !isIndexHidden(index))
2437  index = index.parent();
2438  if (index.isValid())
2439  continue;
2440  viewSelected.append(modelSelected.at(i));
2441  }
2442  return viewSelected;
2443 }
2444 
2448 void QTreeView::scrollContentsBy(int dx, int dy)
2449 {
2450  Q_D(QTreeView);
2451 
2452  d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
2453 
2454  dx = isRightToLeft() ? -dx : dx;
2455  if (dx) {
2457  int oldOffset = d->header->offset();
2458  if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
2459  d->header->setOffsetToLastSection();
2460  else
2461  d->header->setOffsetToSectionPosition(horizontalScrollBar()->value());
2462  int newOffset = d->header->offset();
2463  dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
2464  } else {
2465  d->header->setOffset(horizontalScrollBar()->value());
2466  }
2467  }
2468 
2469  const int itemHeight = d->defaultItemHeight <= 0 ? sizeHintForRow(0) : d->defaultItemHeight;
2470  if (d->viewItems.isEmpty() || itemHeight == 0)
2471  return;
2472 
2473  // guestimate the number of items in the viewport
2474  int viewCount = d->viewport->height() / itemHeight;
2475  int maxDeltaY = qMin(d->viewItems.count(), viewCount);
2476  // no need to do a lot of work if we are going to redraw the whole thing anyway
2477  if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {
2479  d->viewport->update();
2480  return;
2481  }
2482 
2484  int currentScrollbarValue = verticalScrollBar()->value();
2485  int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy)
2486  int currentViewIndex = currentScrollbarValue; // the first visible item
2487  int previousViewIndex = previousScrollbarValue;
2488  const QVector<QTreeViewItem> viewItems = d->viewItems;
2489  dy = 0;
2490  if (previousViewIndex < currentViewIndex) { // scrolling down
2491  for (int i = previousViewIndex; i < currentViewIndex; ++i) {
2492  if (i < d->viewItems.count())
2493  dy -= d->itemHeight(i);
2494  }
2495  } else if (previousViewIndex > currentViewIndex) { // scrolling up
2496  for (int i = previousViewIndex - 1; i >= currentViewIndex; --i) {
2497  if (i < d->viewItems.count())
2498  dy += d->itemHeight(i);
2499  }
2500  }
2501  }
2502 
2503  d->scrollContentsBy(dx, dy);
2504 }
2505 
2510 {
2511  Q_D(QTreeView);
2513  d->viewport->update();
2514 }
2515 
2520 {
2521  // do nothing
2522 }
2523 
2528 void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
2529 {
2530  Q_D(QTreeView);
2531  // if we are going to do a complete relayout anyway, there is no need to update
2532  if (d->delayedPendingLayout) {
2533  QAbstractItemView::rowsInserted(parent, start, end);
2534  return;
2535  }
2536 
2537  //don't add a hierarchy on a column != 0
2538  if (parent.column() != 0 && parent.isValid()) {
2539  QAbstractItemView::rowsInserted(parent, start, end);
2540  return;
2541  }
2542 
2543  const int parentRowCount = d->model->rowCount(parent);
2544  const int delta = end - start + 1;
2545  if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {
2546  QAbstractItemView::rowsInserted(parent, start, end);
2547  return;
2548  }
2549 
2550  const int parentItem = d->viewIndex(parent);
2551  if (((parentItem != -1) && d->viewItems.at(parentItem).expanded)
2552  || (parent == d->root)) {
2553  d->doDelayedItemsLayout();
2554  } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
2555  // the parent just went from 0 children to more. update to re-paint the decoration
2556  d->viewItems[parentItem].hasChildren = true;
2557  viewport()->update();
2558  }
2559  QAbstractItemView::rowsInserted(parent, start, end);
2560 }
2561 
2567 {
2568  Q_D(QTreeView);
2569  QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
2570  d->viewItems.clear();
2571 }
2572 
2582 void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end)
2583 {
2584  Q_D(QTreeView);
2585  d->viewItems.clear();
2586  d->doDelayedItemsLayout();
2587  d->hasRemovedItems = true;
2588  d->_q_rowsRemoved(parent, start, end);
2589 }
2590 
2595 void QTreeView::columnCountChanged(int oldCount, int newCount)
2596 {
2597  Q_D(QTreeView);
2598  if (oldCount == 0 && newCount > 0) {
2599  //if the first column has just been added we need to relayout.
2600  d->doDelayedItemsLayout();
2601  }
2602 
2603  if (isVisible())
2604  updateGeometries();
2605  viewport()->update();
2606 }
2607 
2614 {
2615  Q_D(QTreeView);
2616  d->executePostedLayout();
2617  if (column < 0 || column >= d->header->count())
2618  return;
2619  int contents = sizeHintForColumn(column);
2620  int header = d->header->isHidden() ? 0 : d->header->sectionSizeHint(column);
2621  d->header->resizeSection(column, qMax(contents, header));
2622 }
2623 
2633 void QTreeView::sortByColumn(int column)
2634 {
2635  Q_D(QTreeView);
2636  sortByColumn(column, d->header->sortIndicatorOrder());
2637 }
2638 
2654 {
2655  Q_D(QTreeView);
2656 
2657  //If sorting is enabled will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts
2658  d->header->setSortIndicator(column, order);
2659  //If sorting is not enabled, force to sort now.
2660  if (!d->sortingEnabled)
2661  d->model->sort(column, order);
2662 }
2663 
2668 {
2669  Q_D(QTreeView);
2670  if (!selectionModel())
2671  return;
2672  SelectionMode mode = d->selectionMode;
2673  d->executePostedLayout(); //make sure we lay out the items
2674  if (mode != SingleSelection && !d->viewItems.isEmpty()) {
2675  const QModelIndex &idx = d->viewItems.last().index;
2676  QModelIndex lastItemIndex = idx.sibling(idx.row(), d->model->columnCount(idx.parent()) - 1);
2677  d->select(d->viewItems.first().index, lastItemIndex,
2680  }
2681 }
2682 
2696 {
2697  Q_D(QTreeView);
2698  d->viewItems.clear();
2699  d->interruptDelayedItemsLayout();
2700  d->layout(-1, true);
2701  updateGeometries();
2702  d->viewport->update();
2703 }
2704 
2716 {
2717  Q_D(QTreeView);
2718  d->expandedIndexes.clear();
2719  doItemsLayout();
2720 }
2721 
2732 {
2733  Q_D(QTreeView);
2734  d->viewItems.clear();
2735  d->expandedIndexes.clear();
2736  d->interruptDelayedItemsLayout();
2737  d->layout(-1);
2738  for (int i = 0; i < d->viewItems.count(); ++i) {
2739  if (d->viewItems.at(i).level <= (uint)depth) {
2740  d->viewItems[i].expanded = true;
2741  d->layout(i);
2742  d->storeExpanded(d->viewItems.at(i).index);
2743  }
2744  }
2745  updateGeometries();
2746  d->viewport->update();
2747 }
2748 
2756 void QTreeView::columnResized(int column, int /* oldSize */, int /* newSize */)
2757 {
2758  Q_D(QTreeView);
2759  d->columnsToUpdate.append(column);
2760  if (d->columnResizeTimerID == 0)
2761  d->columnResizeTimerID = startTimer(0);
2762 }
2763 
2768 {
2769  Q_D(QTreeView);
2770  if (d->header) {
2771  if (d->geometryRecursionBlock)
2772  return;
2773  d->geometryRecursionBlock = true;
2774  QSize hint = d->header->isHidden() ? QSize(0, 0) : d->header->sizeHint();
2775  setViewportMargins(0, hint.height(), 0, 0);
2776  QRect vg = d->viewport->geometry();
2777  QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height());
2778  d->header->setGeometry(geometryRect);
2779  //d->header->setOffset(horizontalScrollBar()->value()); // ### bug ???
2780  QMetaObject::invokeMethod(d->header, "updateGeometries");
2781  d->updateScrollBars();
2782  d->geometryRecursionBlock = false;
2783  }
2785 }
2786 
2801 int QTreeView::sizeHintForColumn(int column) const
2802 {
2803  Q_D(const QTreeView);
2804  d->executePostedLayout();
2805  if (d->viewItems.isEmpty())
2806  return -1;
2807  ensurePolished();
2808  int w = 0;
2809  QStyleOptionViewItemV4 option = d->viewOptionsV4();
2810  const QVector<QTreeViewItem> viewItems = d->viewItems;
2811 
2812  int start = 0;
2813  int end = viewItems.count();
2814  if(end > 1000) { //if we have too many item this function would be too slow.
2815  //we get a good approximation by only iterate over 1000 items.
2816  start = qMax(0, d->firstVisibleItem() - 100);
2817  end = qMin(end, start + 900);
2818  }
2819 
2820  for (int i = start; i < end; ++i) {
2821  if (viewItems.at(i).spanning)
2822  continue; // we have no good size hint
2823  QModelIndex index = viewItems.at(i).index;
2824  index = index.sibling(index.row(), column);
2825  QWidget *editor = d->editorForIndex(index).widget.data();
2826  if (editor && d->persistent.contains(editor)) {
2827  w = qMax(w, editor->sizeHint().width());
2828  int min = editor->minimumSize().width();
2829  int max = editor->maximumSize().width();
2830  w = qBound(min, w, max);
2831  }
2832  int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
2833  w = qMax(w, hint + (column == 0 ? d->indentationForItem(i) : 0));
2834  }
2835  return w;
2836 }
2837 
2844 {
2845  Q_D(const QTreeView);
2846  if (!d->isIndexValid(index) || !d->itemDelegate)
2847  return 0;
2848 
2849  int start = -1;
2850  int end = -1;
2851  int indexRow = index.row();
2852  int count = d->header->count();
2853  bool emptyHeader = (count == 0);
2854  QModelIndex parent = index.parent();
2855 
2856  if (count && isVisible()) {
2857  // If the sections have moved, we end up checking too many or too few
2858  start = d->header->visualIndexAt(0);
2859  } else {
2860  // If the header has not been laid out yet, we use the model directly
2861  count = d->model->columnCount(parent);
2862  }
2863 
2864  if (isRightToLeft()) {
2865  start = (start == -1 ? count - 1 : start);
2866  end = 0;
2867  } else {
2868  start = (start == -1 ? 0 : start);
2869  end = count - 1;
2870  }
2871 
2872  if (end < start)
2873  qSwap(end, start);
2874 
2875  int height = -1;
2876  QStyleOptionViewItemV4 option = d->viewOptionsV4();
2877  // ### If we want word wrapping in the items,
2878  // ### we need to go through all the columns
2879  // ### and set the width of the column
2880 
2881  // Hack to speed up the function
2882  option.rect.setWidth(-1);
2883 
2884  for (int column = start; column <= end; ++column) {
2885  int logicalColumn = emptyHeader ? column : d->header->logicalIndex(column);
2886  if (d->header->isSectionHidden(logicalColumn))
2887  continue;
2888  QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);
2889  if (idx.isValid()) {
2890  QWidget *editor = d->editorForIndex(idx).widget.data();
2891  if (editor && d->persistent.contains(editor)) {
2892  height = qMax(height, editor->sizeHint().height());
2893  int min = editor->minimumSize().height();
2894  int max = editor->maximumSize().height();
2895  height = qBound(min, height, max);
2896  }
2897  int hint = d->delegateForIndex(idx)->sizeHint(option, idx).height();
2898  height = qMax(height, hint);
2899  }
2900  }
2901 
2902  return height;
2903 }
2904 
2914 {
2915  Q_D(const QTreeView);
2916  d->executePostedLayout();
2917  int i = d->viewIndex(index);
2918  if (i == -1)
2919  return 0;
2920  return d->itemHeight(i);
2921 }
2922 
2927 {
2929 }
2930 
2935 {
2936  return (isColumnHidden(index.column()) || isRowHidden(index.row(), index.parent()));
2937 }
2938 
2939 /*
2940  private implementation
2941 */
2943 {
2944  Q_Q(QTreeView);
2945  updateStyledFrameWidths();
2946  q->setSelectionBehavior(QAbstractItemView::SelectRows);
2947  q->setSelectionMode(QAbstractItemView::SingleSelection);
2948  q->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
2949  q->setAttribute(Qt::WA_MacShowFocusRect);
2950 
2952  header->setMovable(true);
2953  header->setStretchLastSection(true);
2955  q->setHeader(header);
2956 #ifndef QT_NO_ANIMATION
2957  QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
2958 #endif //QT_NO_ANIMATION
2959 }
2960 
2961 void QTreeViewPrivate::expand(int item, bool emitSignal)
2962 {
2963  Q_Q(QTreeView);
2964 
2965  if (item == -1 || viewItems.at(item).expanded)
2966  return;
2967 
2968 #ifndef QT_NO_ANIMATION
2969  if (emitSignal && animationsEnabled)
2970  prepareAnimatedOperation(item, QVariantAnimation::Forward);
2971 #endif //QT_NO_ANIMATION
2972  //if already animating, stateBeforeAnimation is set to the correct value
2974  stateBeforeAnimation = state;
2975  q->setState(QAbstractItemView::ExpandingState);
2976  const QModelIndex index = viewItems.at(item).index;
2977  storeExpanded(index);
2978  viewItems[item].expanded = true;
2979  layout(item);
2980  q->setState(stateBeforeAnimation);
2981 
2982  if (model->canFetchMore(index))
2983  model->fetchMore(index);
2984  if (emitSignal) {
2985  emit q->expanded(index);
2986 #ifndef QT_NO_ANIMATION
2987  if (animationsEnabled)
2988  beginAnimatedOperation();
2989 #endif //QT_NO_ANIMATION
2990  }
2991 }
2992 
2993 void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
2994 {
2995  viewItems.insert(pos, count, viewItem);
2996  QTreeViewItem *items = viewItems.data();
2997  for (int i = pos + count; i < viewItems.count(); i++)
2998  if (items[i].parentItem >= pos)
2999  items[i].parentItem += count;
3000 #ifndef QT_NO_ACCESSIBILITY
3001 #ifdef Q_WS_X11
3002  Q_Q(QTreeView);
3003  if (QAccessible::isActive()) {
3005  }
3006 #endif
3007 #endif
3008 }
3009 
3011 {
3012  viewItems.remove(pos, count);
3013  QTreeViewItem *items = viewItems.data();
3014  for (int i = pos; i < viewItems.count(); i++)
3015  if (items[i].parentItem >= pos)
3016  items[i].parentItem -= count;
3017 #ifndef QT_NO_ACCESSIBILITY
3018 #ifdef Q_WS_X11
3019  Q_Q(QTreeView);
3020  if (QAccessible::isActive()) {
3022  }
3023 #endif
3024 #endif
3025 }
3026 
3027 #if 0
3028 bool QTreeViewPrivate::checkViewItems() const
3029 {
3030  for (int i = 0; i < viewItems.count(); ++i) {
3031  const QTreeViewItem &vi = viewItems.at(i);
3032  if (vi.parentItem == -1) {
3033  Q_ASSERT(!vi.index.parent().isValid() || vi.index.parent() == root);
3034  } else {
3035  Q_ASSERT(vi.index.parent() == viewItems.at(vi.parentItem).index);
3036  }
3037  }
3038  return true;
3039 }
3040 #endif
3041 
3042 void QTreeViewPrivate::collapse(int item, bool emitSignal)
3043 {
3044  Q_Q(QTreeView);
3045 
3046  if (item == -1 || expandedIndexes.isEmpty())
3047  return;
3048 
3049  //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll
3050  delayedAutoScroll.stop();
3051 
3052  int total = viewItems.at(item).total;
3053  const QModelIndex &modelIndex = viewItems.at(item).index;
3054  if (!isPersistent(modelIndex))
3055  return; // if the index is not persistent, no chances it is expanded
3056  QSet<QPersistentModelIndex>::iterator it = expandedIndexes.find(modelIndex);
3057  if (it == expandedIndexes.end() || viewItems.at(item).expanded == false)
3058  return; // nothing to do
3059 
3060 #ifndef QT_NO_ANIMATION
3061  if (emitSignal && animationsEnabled)
3062  prepareAnimatedOperation(item, QVariantAnimation::Backward);
3063 #endif //QT_NO_ANIMATION
3064 
3065  //if already animating, stateBeforeAnimation is set to the correct value
3067  stateBeforeAnimation = state;
3069  expandedIndexes.erase(it);
3070  viewItems[item].expanded = false;
3071  int index = item;
3072  while (index > -1) {
3073  viewItems[index].total -= total;
3074  index = viewItems[index].parentItem;
3075  }
3076  removeViewItems(item + 1, total); // collapse
3077  q->setState(stateBeforeAnimation);
3078 
3079  if (emitSignal) {
3080  emit q->collapsed(modelIndex);
3081 #ifndef QT_NO_ANIMATION
3082  if (animationsEnabled)
3083  beginAnimatedOperation();
3084 #endif //QT_NO_ANIMATION
3085  }
3086 }
3087 
3088 #ifndef QT_NO_ANIMATION
3090 {
3091  animatedOperation.item = item;
3092  animatedOperation.viewport = viewport;
3093  animatedOperation.setDirection(direction);
3094 
3095  int top = coordinateForItem(item) + itemHeight(item);
3096  QRect rect = viewport->rect();
3097  rect.setTop(top);
3098  if (direction == QVariantAnimation::Backward) {
3099  const int limit = rect.height() * 2;
3100  int h = 0;
3101  int c = item + viewItems.at(item).total + 1;
3102  for (int i = item + 1; i < c && h < limit; ++i)
3103  h += itemHeight(i);
3104  rect.setHeight(h);
3105  animatedOperation.setEndValue(top + h);
3106  }
3107  animatedOperation.setStartValue(top);
3108  animatedOperation.before = renderTreeToPixmapForAnimation(rect);
3109 }
3110 
3112 {
3113  Q_Q(QTreeView);
3114 
3115  QRect rect = viewport->rect();
3116  rect.setTop(animatedOperation.top());
3117  if (animatedOperation.direction() == QVariantAnimation::Forward) {
3118  const int limit = rect.height() * 2;
3119  int h = 0;
3120  int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1;
3121  for (int i = animatedOperation.item + 1; i < c && h < limit; ++i)
3122  h += itemHeight(i);
3123  rect.setHeight(h);
3124  animatedOperation.setEndValue(animatedOperation.top() + h);
3125  }
3126 
3127  if (!rect.isEmpty()) {
3128  animatedOperation.after = renderTreeToPixmapForAnimation(rect);
3129 
3130  q->setState(QAbstractItemView::AnimatingState);
3131  animatedOperation.start(); //let's start the animation
3132  }
3133 }
3134 
3136 {
3137  const int start = animatedOperation.startValue().toInt(),
3138  end = animatedOperation.endValue().toInt(),
3139  current = animatedOperation.currentValue().toInt();
3140  bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;
3141  const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;
3142  painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());
3143  const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before;
3144  painter->drawPixmap(0, current, bottom);
3145 }
3146 
3148 {
3149  Q_Q(const QTreeView);
3150  QPixmap pixmap(rect.size());
3151  if (rect.size().isEmpty())
3152  return pixmap;
3153  pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels.
3154  QPainter painter(&pixmap);
3155  painter.fillRect(QRect(QPoint(0,0), rect.size()), q->palette().base());
3156  painter.translate(0, -rect.top());
3157  q->drawTree(&painter, QRegion(rect));
3158  painter.end();
3159 
3160  //and now let's render the editors the editors
3161  QStyleOptionViewItemV4 option = viewOptionsV4();
3162  for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
3163  QWidget *editor = it.key();
3164  const QModelIndex &index = it.value();
3165  option.rect = q->visualRect(index);
3166  if (option.rect.isValid()) {
3167 
3168  if (QAbstractItemDelegate *delegate = delegateForIndex(index))
3169  delegate->updateEditorGeometry(editor, option, index);
3170 
3171  const QPoint pos = editor->pos();
3172  if (rect.contains(pos)) {
3173  editor->render(&pixmap, pos - rect.topLeft());
3174  //the animation uses pixmap to display the treeview's content
3175  //the editor is rendered on this pixmap and thus can (should) be hidden
3176  editor->hide();
3177  }
3178  }
3179  }
3180 
3181 
3182  return pixmap;
3183 }
3184 
3186 {
3187  Q_Q(QTreeView);
3188  q->setState(stateBeforeAnimation);
3189  q->updateGeometries();
3190  viewport->update();
3191 }
3192 #endif //QT_NO_ANIMATION
3193 
3195 {
3196  viewItems.clear();
3197 }
3198 
3200 {
3201  if (start <= 0 && 0 <= end)
3202  viewItems.clear();
3204 }
3205 
3207 {
3208  if (start <= 0 && 0 <= end)
3209  doDelayedItemsLayout();
3210  QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
3211 }
3212 
3220 void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninitialized)
3221 {
3222  Q_Q(QTreeView);
3223  QModelIndex current;
3224  QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i);
3225 
3226  if (i>=0 && !parent.isValid()) {
3227  //modelIndex() should never return something invalid for the real items.
3228  //This can happen if columncount has been set to 0.
3229  //To avoid infinite loop we stop here.
3230  return;
3231  }
3232 
3233  int count = 0;
3234  if (model->hasChildren(parent)) {
3235  if (model->canFetchMore(parent))
3236  model->fetchMore(parent);
3237  count = model->rowCount(parent);
3238  }
3239 
3240  bool expanding = true;
3241  if (i == -1) {
3242  if (uniformRowHeights) {
3243  QModelIndex index = model->index(0, 0, parent);
3244  defaultItemHeight = q->indexRowSizeHint(index);
3245  }
3246  viewItems.resize(count);
3247  afterIsUninitialized = true;
3248  } else if (viewItems[i].total != (uint)count) {
3249  if (!afterIsUninitialized)
3250  insertViewItems(i + 1, count, QTreeViewItem()); // expand
3251  else if (count > 0)
3252  viewItems.resize(viewItems.count() + count);
3253  } else {
3254  expanding = false;
3255  }
3256 
3257  int first = i + 1;
3258  int level = (i >= 0 ? viewItems.at(i).level + 1 : 0);
3259  int hidden = 0;
3260  int last = 0;
3261  int children = 0;
3262  QTreeViewItem *item = 0;
3263  for (int j = first; j < first + count; ++j) {
3264  current = model->index(j - first, 0, parent);
3265  if (isRowHidden(current)) {
3266  ++hidden;
3267  last = j - hidden + children;
3268  } else {
3269  last = j - hidden + children;
3270  if (item)
3271  item->hasMoreSiblings = true;
3272  item = &viewItems[last];
3273  item->index = current;
3274  item->parentItem = i;
3275  item->level = level;
3276  item->height = 0;
3277  item->spanning = q->isFirstColumnSpanned(current.row(), parent);
3278  item->expanded = false;
3279  item->total = 0;
3280  item->hasMoreSiblings = false;
3281  if (recursiveExpanding || isIndexExpanded(current)) {
3282  if (recursiveExpanding)
3283  expandedIndexes.insert(current);
3284  item->expanded = true;
3285  layout(last, recursiveExpanding, afterIsUninitialized);
3286  item = &viewItems[last];
3287  children += item->total;
3288  item->hasChildren = item->total > 0;
3289  last = j - hidden + children;
3290  } else {
3291  item->hasChildren = hasVisibleChildren(current);
3292  }
3293  }
3294  }
3295 
3296  // remove hidden items
3297  if (hidden > 0) {
3298  if (!afterIsUninitialized)
3299  removeViewItems(last + 1, hidden);
3300  else
3301  viewItems.resize(viewItems.size() - hidden);
3302  }
3303 
3304  if (!expanding)
3305  return; // nothing changed
3306 
3307  while (i > -1) {
3308  viewItems[i].total += count - hidden;
3309  i = viewItems[i].parentItem;
3310  }
3311 }
3312 
3314 {
3315  int index = itemAtCoordinate(coordinateForItem(i) - viewport->height());
3316  while (isItemHiddenOrDisabled(index))
3317  index--;
3318  return index == -1 ? 0 : index;
3319 }
3320 
3322 {
3323  int index = itemAtCoordinate(coordinateForItem(i) + viewport->height());
3324  while (isItemHiddenOrDisabled(index))
3325  index++;
3326  return index == -1 ? viewItems.count() - 1 : index;
3327 }
3328 
3330 {
3331  if (item < 0 || item >= viewItems.count())
3332  return 0;
3333  int level = viewItems.at(item).level;
3334  if (rootDecoration)
3335  ++level;
3336  return level * indent;
3337 }
3338 
3339 int QTreeViewPrivate::itemHeight(int item) const
3340 {
3341  if (uniformRowHeights)
3342  return defaultItemHeight;
3343  if (viewItems.isEmpty())
3344  return 0;
3345  const QModelIndex &index = viewItems.at(item).index;
3346  if (!index.isValid())
3347  return 0;
3348  int height = viewItems.at(item).height;
3349  if (height <= 0) {
3350  height = q_func()->indexRowSizeHint(index);
3351  viewItems[item].height = height;
3352  }
3353  return qMax(height, 0);
3354 }
3355 
3356 
3365 {
3367  if (uniformRowHeights)
3368  return (item * defaultItemHeight) - vbar->value();
3369  // ### optimize (spans or caching)
3370  int y = 0;
3371  for (int i = 0; i < viewItems.count(); ++i) {
3372  if (i == item)
3373  return y - vbar->value();
3374  y += itemHeight(i);
3375  }
3376  } else { // ScrollPerItem
3377  int topViewItemIndex = vbar->value();
3378  if (uniformRowHeights)
3379  return defaultItemHeight * (item - topViewItemIndex);
3380  if (item >= topViewItemIndex) {
3381  // search in the visible area first and continue down
3382  // ### slow if the item is not visible
3383  int viewItemCoordinate = 0;
3384  int viewItemIndex = topViewItemIndex;
3385  while (viewItemIndex < viewItems.count()) {
3386  if (viewItemIndex == item)
3387  return viewItemCoordinate;
3388  viewItemCoordinate += itemHeight(viewItemIndex);
3389  ++viewItemIndex;
3390  }
3391  // below the last item in the view
3392  Q_ASSERT(false);
3393  return viewItemCoordinate;
3394  } else {
3395  // search the area above the viewport (used for editor widgets)
3396  int viewItemCoordinate = 0;
3397  for (int viewItemIndex = topViewItemIndex; viewItemIndex > 0; --viewItemIndex) {
3398  if (viewItemIndex == item)
3399  return viewItemCoordinate;
3400  viewItemCoordinate -= itemHeight(viewItemIndex - 1);
3401  }
3402  return viewItemCoordinate;
3403  }
3404  }
3405  return 0;
3406 }
3407 
3418 int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
3419 {
3420  const int itemCount = viewItems.count();
3421  if (itemCount == 0)
3422  return -1;
3423  if (uniformRowHeights && defaultItemHeight <= 0)
3424  return -1;
3426  if (uniformRowHeights) {
3427  const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight;
3428  return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
3429  }
3430  // ### optimize
3431  int viewItemCoordinate = 0;
3432  const int contentsCoordinate = coordinate + vbar->value();
3433  for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {
3434  viewItemCoordinate += itemHeight(viewItemIndex);
3435  if (viewItemCoordinate >= contentsCoordinate)
3436  return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
3437  }
3438  } else { // ScrollPerItem
3439  int topViewItemIndex = vbar->value();
3440  if (uniformRowHeights) {
3441  if (coordinate < 0)
3442  coordinate -= defaultItemHeight - 1;
3443  const int viewItemIndex = topViewItemIndex + (coordinate / defaultItemHeight);
3444  return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
3445  }
3446  if (coordinate >= 0) {
3447  // the coordinate is in or below the viewport
3448  int viewItemCoordinate = 0;
3449  for (int viewItemIndex = topViewItemIndex; viewItemIndex < viewItems.count(); ++viewItemIndex) {
3450  viewItemCoordinate += itemHeight(viewItemIndex);
3451  if (viewItemCoordinate > coordinate)
3452  return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
3453  }
3454  } else {
3455  // the coordinate is above the viewport
3456  int viewItemCoordinate = 0;
3457  for (int viewItemIndex = topViewItemIndex; viewItemIndex >= 0; --viewItemIndex) {
3458  if (viewItemCoordinate <= coordinate)
3459  return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
3460  viewItemCoordinate -= itemHeight(viewItemIndex);
3461  }
3462  }
3463  }
3464  return -1;
3465 }
3466 
3468 {
3469  if (!_index.isValid() || viewItems.isEmpty())
3470  return -1;
3471 
3472  const int totalCount = viewItems.count();
3473  const QModelIndex index = _index.sibling(_index.row(), 0);
3474  const int row = index.row();
3475  const qint64 internalId = index.internalId();
3476 
3477  // We start nearest to the lastViewedItem
3478  int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem);
3479  for (int i = 0; i < localCount; ++i) {
3480  const QModelIndex &idx1 = viewItems.at(lastViewedItem + i).index;
3481  if (idx1.row() == row && idx1.internalId() == internalId) {
3482  lastViewedItem = lastViewedItem + i;
3483  return lastViewedItem;
3484  }
3485  const QModelIndex &idx2 = viewItems.at(lastViewedItem - i - 1).index;
3486  if (idx2.row() == row && idx2.internalId() == internalId) {
3487  lastViewedItem = lastViewedItem - i - 1;
3488  return lastViewedItem;
3489  }
3490  }
3491 
3492  for (int j = qMax(0, lastViewedItem + localCount); j < totalCount; ++j) {
3493  const QModelIndex &idx = viewItems.at(j).index;
3494  if (idx.row() == row && idx.internalId() == internalId) {
3495  lastViewedItem = j;
3496  return j;
3497  }
3498  }
3499  for (int j = qMin(totalCount, lastViewedItem - localCount) - 1; j >= 0; --j) {
3500  const QModelIndex &idx = viewItems.at(j).index;
3501  if (idx.row() == row && idx.internalId() == internalId) {
3502  lastViewedItem = j;
3503  return j;
3504  }
3505  }
3506 
3507  // nothing found
3508  return -1;
3509 }
3510 
3512 {
3513  if (i < 0 || i >= viewItems.count())
3514  return QModelIndex();
3515 
3516  QModelIndex ret = viewItems.at(i).index;
3517  if (column)
3518  ret = ret.sibling(ret.row(), column);
3519  return ret;
3520 }
3521 
3523 {
3524  const int value = vbar->value();
3526  if (offset)
3527  *offset = 0;
3528  return (value < 0 || value >= viewItems.count()) ? -1 : value;
3529  }
3530  // ScrollMode == ScrollPerPixel
3531  if (uniformRowHeights) {
3532  if (!defaultItemHeight)
3533  return -1;
3534 
3535  if (offset)
3536  *offset = -(value % defaultItemHeight);
3537  return value / defaultItemHeight;
3538  }
3539  int y = 0; // ### optimize (use spans ?)
3540  for (int i = 0; i < viewItems.count(); ++i) {
3541  y += itemHeight(i); // the height value is cached
3542  if (y > value) {
3543  if (offset)
3544  *offset = y - value - itemHeight(i);
3545  return i;
3546  }
3547  }
3548  return -1;
3549 }
3550 
3552 {
3553  return header->logicalIndexAt(x);
3554 }
3555 
3557 {
3558  Q_Q(QTreeView);
3559  QSize viewportSize = viewport->size();
3560  if (!viewportSize.isValid())
3561  viewportSize = QSize(0, 0);
3562 
3563  if (viewItems.isEmpty()) {
3564  q->doItemsLayout();
3565  }
3566 
3567  int itemsInViewport = 0;
3568  if (uniformRowHeights) {
3569  if (defaultItemHeight <= 0)
3570  itemsInViewport = viewItems.count();
3571  else
3572  itemsInViewport = viewportSize.height() / defaultItemHeight;
3573  } else {
3574  const int itemsCount = viewItems.count();
3575  const int viewportHeight = viewportSize.height();
3576  for (int height = 0, item = itemsCount - 1; item >= 0; --item) {
3577  height += itemHeight(item);
3578  if (height > viewportHeight)
3579  break;
3580  ++itemsInViewport;
3581  }
3582  }
3584  if (!viewItems.isEmpty())
3585  itemsInViewport = qMax(1, itemsInViewport);
3586  vbar->setRange(0, viewItems.count() - itemsInViewport);
3587  vbar->setPageStep(itemsInViewport);
3588  vbar->setSingleStep(1);
3589  } else { // scroll per pixel
3590  int contentsHeight = 0;
3591  if (uniformRowHeights) {
3592  contentsHeight = defaultItemHeight * viewItems.count();
3593  } else { // ### optimize (spans or caching)
3594  for (int i = 0; i < viewItems.count(); ++i)
3595  contentsHeight += itemHeight(i);
3596  }
3597  vbar->setRange(0, contentsHeight - viewportSize.height());
3598  vbar->setPageStep(viewportSize.height());
3599  vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
3600  }
3601 
3602  const int columnCount = header->count();
3603  const int viewportWidth = viewportSize.width();
3604  int columnsInViewport = 0;
3605  for (int width = 0, column = columnCount - 1; column >= 0; --column) {
3606  int logical = header->logicalIndex(column);
3607  width += header->sectionSize(logical);
3608  if (width > viewportWidth)
3609  break;
3610  ++columnsInViewport;
3611  }
3612  if (columnCount > 0)
3613  columnsInViewport = qMax(1, columnsInViewport);
3615  hbar->setRange(0, columnCount - columnsInViewport);
3616  hbar->setPageStep(columnsInViewport);
3617  hbar->setSingleStep(1);
3618  } else { // scroll per pixel
3619  const int horizontalLength = header->length();
3620  const QSize maxSize = q->maximumViewportSize();
3621  if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0)
3622  viewportSize = maxSize;
3623  hbar->setPageStep(viewportSize.width());
3624  hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
3625  hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
3626  }
3627 }
3628 
3630 {
3631  executePostedLayout();
3632  int x = pos.x();
3633  int column = header->logicalIndexAt(x);
3634  if (column != 0)
3635  return -1; // no logical index at x
3636 
3637  int viewItemIndex = itemAtCoordinate(pos.y());
3638  QRect returning = itemDecorationRect(modelIndex(viewItemIndex));
3639  if (!returning.contains(pos))
3640  return -1;
3641 
3642  return viewItemIndex;
3643 }
3644 
3646 {
3647  Q_Q(const QTreeView);
3648  if (!rootDecoration && index.parent() == root)
3649  return QRect(); // no decoration at root
3650 
3651  int viewItemIndex = viewIndex(index);
3652  if (viewItemIndex < 0 || !hasVisibleChildren(viewItems.at(viewItemIndex).index))
3653  return QRect();
3654 
3655  int itemIndentation = indentationForItem(viewItemIndex);
3657  int size = header->sectionSize(0);
3658 
3659  QRect rect;
3660  if (q->isRightToLeft())
3661  rect = QRect(position + size - itemIndentation, coordinateForItem(viewItemIndex),
3662  indent, itemHeight(viewItemIndex));
3663  else
3664  rect = QRect(position + itemIndentation - indent, coordinateForItem(viewItemIndex),
3665  indent, itemHeight(viewItemIndex));
3666  QStyleOption opt;
3667  opt.initFrom(q);
3668  opt.rect = rect;
3669  return q->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &opt, q);
3670 }
3671 
3673  const QModelIndex &bottomIndex) const
3674 {
3675  const int topVisual = header->visualIndex(topIndex.column()),
3676  bottomVisual = header->visualIndex(bottomIndex.column());
3677 
3678  const int start = qMin(topVisual, bottomVisual);
3679  const int end = qMax(topVisual, bottomVisual);
3680 
3681  QList<int> logicalIndexes;
3682 
3683  //we iterate over the visual indexes to get the logical indexes
3684  for (int c = start; c <= end; c++) {
3685  const int logical = header->logicalIndex(c);
3686  if (!header->isSectionHidden(logical)) {
3687  logicalIndexes << logical;
3688  }
3689  }
3690  //let's sort the list
3691  qSort(logicalIndexes.begin(), logicalIndexes.end());
3692 
3693  QList<QPair<int, int> > ret;
3694  QPair<int, int> current;
3695  current.first = -2; // -1 is not enough because -1+1 = 0
3696  current.second = -2;
3697  for(int i = 0; i < logicalIndexes.count(); ++i) {
3698  const int logicalColumn = logicalIndexes.at(i);
3699  if (current.second + 1 != logicalColumn) {
3700  if (current.first != -2) {
3701  //let's save the current one
3702  ret += current;
3703  }
3704  //let's start a new one
3705  current.first = current.second = logicalColumn;
3706  } else {
3707  current.second++;
3708  }
3709  }
3710 
3711  //let's get the last range
3712  if (current.first != -2) {
3713  ret += current;
3714  }
3715 
3716  return ret;
3717 }
3718 
3719 void QTreeViewPrivate::select(const QModelIndex &topIndex, const QModelIndex &bottomIndex,
3720  QItemSelectionModel::SelectionFlags command)
3721 {
3722  Q_Q(QTreeView);
3723  QItemSelection selection;
3724  const int top = viewIndex(topIndex),
3725  bottom = viewIndex(bottomIndex);
3726 
3727  const QList< QPair<int, int> > colRanges = columnRanges(topIndex, bottomIndex);
3728  QList< QPair<int, int> >::const_iterator it;
3729  for (it = colRanges.begin(); it != colRanges.end(); ++it) {
3730  const int left = (*it).first,
3731  right = (*it).second;
3732 
3733  QModelIndex previous;
3734  QItemSelectionRange currentRange;
3735  QStack<QItemSelectionRange> rangeStack;
3736  for (int i = top; i <= bottom; ++i) {
3737  QModelIndex index = modelIndex(i);
3738  QModelIndex parent = index.parent();
3739  QModelIndex previousParent = previous.parent();
3740  if (previous.isValid() && parent == previousParent) {
3741  // same parent
3742  if (qAbs(previous.row() - index.row()) > 1) {
3743  //a hole (hidden index inside a range) has been detected
3744  if (currentRange.isValid()) {
3745  selection.append(currentRange);
3746  }
3747  //let's start a new range
3748  currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
3749  } else {
3750  QModelIndex tl = model->index(currentRange.top(), currentRange.left(),
3751  currentRange.parent());
3752  currentRange = QItemSelectionRange(tl, index.sibling(index.row(), right));
3753  }
3754  } else if (previous.isValid() && parent == model->index(previous.row(), 0, previousParent)) {
3755  // item is child of previous
3756  rangeStack.push(currentRange);
3757  currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
3758  } else {
3759  if (currentRange.isValid())
3760  selection.append(currentRange);
3761  if (rangeStack.isEmpty()) {
3762  currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));
3763  } else {
3764  currentRange = rangeStack.pop();
3765  index = currentRange.bottomRight(); //let's resume the range
3766  --i; //we process again the current item
3767  }
3768  }
3769  previous = index;
3770  }
3771  if (currentRange.isValid())
3772  selection.append(currentRange);
3773  for (int i = 0; i < rangeStack.count(); ++i)
3774  selection.append(rangeStack.at(i));
3775  }
3776  q->selectionModel()->select(selection, command);
3777 }
3778 
3780 {
3781  Q_Q(const QTreeView);
3782  int start = header->visualIndexAt(rect.left());
3783  int end = header->visualIndexAt(rect.right());
3784  if (q->isRightToLeft()) {
3785  start = (start == -1 ? header->count() - 1 : start);
3786  end = (end == -1 ? 0 : end);
3787  } else {
3788  start = (start == -1 ? 0 : start);
3789  end = (end == -1 ? header->count() - 1 : end);
3790  }
3791  return qMakePair<int,int>(qMin(start, end), qMax(start, end));
3792 }
3793 
3795 {
3796  Q_Q(const QTreeView);
3797  if (model->hasChildren(parent)) {
3798  if (hiddenIndexes.isEmpty())
3799  return true;
3800  if (q->isIndexHidden(parent))
3801  return false;
3802  int rowCount = model->rowCount(parent);
3803  for (int i = 0; i < rowCount; ++i) {
3804  if (!q->isRowHidden(i, parent))
3805  return true;
3806  }
3807  if (rowCount == 0)
3808  return true;
3809  }
3810  return false;
3811 }
3812 
3814 {
3815  model->sort(column, order);
3816 }
3817 
3821 void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
3822 {
3823  QAbstractItemView::currentChanged(current, previous);
3824 
3825  if (allColumnsShowFocus()) {
3826  if (previous.isValid()) {
3827  QRect previousRect = visualRect(previous);
3828  previousRect.setX(0);
3829  previousRect.setWidth(viewport()->width());
3830  viewport()->update(previousRect);
3831  }
3832  if (current.isValid()) {
3833  QRect currentRect = visualRect(current);
3834  currentRect.setX(0);
3835  currentRect.setWidth(viewport()->width());
3836  viewport()->update(currentRect);
3837  }
3838  }
3839 #ifndef QT_NO_ACCESSIBILITY
3840  if (QAccessible::isActive() && current.isValid()) {
3841 #ifdef Q_WS_X11
3842  int entry = (visualIndex(current) + (header()?1:0))*current.model()->columnCount()+current.column() + 1;
3844 #else
3845  int entry = visualIndex(current) + 1;
3846  if (header())
3847  ++entry;
3849 #endif
3850  }
3851 #endif
3852 }
3853 
3858  const QItemSelection &deselected)
3859 {
3860  QAbstractItemView::selectionChanged(selected, deselected);
3861 #ifndef QT_NO_ACCESSIBILITY
3862  if (QAccessible::isActive()) {
3863  // ### does not work properly for selection ranges.
3864  QModelIndex sel = selected.indexes().value(0);
3865  if (sel.isValid()) {
3866 #ifdef Q_WS_X11
3867  int entry = (visualIndex(sel) + (header()?1:0))*sel.model()->columnCount()+sel.column() + 1;
3868  Q_ASSERT(entry > 0);
3870 #else
3871  int entry = visualIndex(sel) + 1;
3872  if (header())
3873  ++entry;
3875 #endif
3876  }
3877  QModelIndex desel = deselected.indexes().value(0);
3878  if (desel.isValid()) {
3879 #ifdef Q_WS_X11
3880  int entry = (visualIndex(desel) + (header()?1:0))*desel.model()->columnCount()+desel.column() + 1;
3881  Q_ASSERT(entry > 0);
3883 #else
3884  int entry = visualIndex(desel) + 1;
3885  if (header())
3886  ++entry;
3888 #endif
3889  }
3890  }
3891 #endif
3892 }
3893 
3895 {
3896  Q_D(const QTreeView);
3897  d->executePostedLayout();
3898  return d->viewIndex(index);
3899 }
3900 
3902 
3903 #include "moc_qtreeview.cpp"
3904 
3905 #endif // QT_NO_TREEVIEW
bool isHeaderHidden() const
Definition: qtreeview.cpp:591
SelectionMode
This enum indicates how the view responds to user selections:
bool isIndexHidden(const QModelIndex &index) const
Reimplemented Function
Definition: qtreeview.cpp:2934
QPoint pos() const
int startTimer(int interval)
Starts a timer and returns a timer identifier, or returns zero if it could not start a timer...
Definition: qobject.cpp:1623
void mousePressEvent(QMouseEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1887
static int keyboardInputInterval()
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
double d
Definition: qnumeric_p.h:62
QSize maximumSize
the widget&#39;s maximum size in pixels
Definition: qwidget.h:173
void setHeaderHidden(bool hide)
Definition: qtreeview.cpp:597
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of columns for the children of the given parent.
int itemAtCoordinate(int coordinate) const
Returns the index of the view item at the given viewport coordinate.
Definition: qtreeview.cpp:3418
virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
This slot is called when rows are about to be removed.
bool enabled
whether the widget is enabled
Definition: qwidget.h:157
QSize minimumSize
the widget&#39;s minimum size
Definition: qwidget.h:172
void reexpand()
Definition: qtreeview.cpp:2519
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
Move the cursor in the way described by cursorAction, using the information provided by the button mo...
Definition: qtreeview.cpp:2168
void keyboardSearch(const QString &search)
Reimplemented Function
Definition: qtreeview.cpp:1014
void setViewportMargins(int left, int top, int right, int bottom)
Sets the margins around the scrolling area to left, top, right and bottom.
static void updateAccessibility(QObject *, int who, Event reason)
Notifies accessibility clients about a change in object&#39;s accessibility information.
The QAbstractItemDelegate class is used to display and edit data items from a model.
static QAbstractItemModel * staticEmptyModel()
The QKeyEvent class describes a key event.
Definition: qevent.h:224
QPair< int, int > startAndEndColumns(const QRect &rect) const
Definition: qtreeview.cpp:3779
The QItemSelectionModel class keeps track of a view&#39;s selected items.
void mouseDoubleClickEvent(QMouseEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1916
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:231
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
int left() const
Returns the column index corresponding to the leftmost selected column in the selection range...
static bool ancestorOf(QObject *widget, QObject *other)
move to QObject :)
Definition: qtreeview.cpp:1523
int y() const
virtual void clear()
Clears the selection model.
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void dragMoveEvent(QDragMoveEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1277
void setRowHidden(int row, const QModelIndex &parent, bool hide)
If hide is true the row with the given parent is hidden, otherwise the row is shown.
Definition: qtreeview.cpp:622
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QSize size() const
QPointer< QWidget > widget
void updateGeometries()
Reimplemented Function
Definition: qtreeview.cpp:2767
virtual QStyleOptionViewItem viewOptions() const
Returns a QStyleOptionViewItem structure populated with the view&#39;s palette, font, state...
virtual void setSelectionModel(QItemSelectionModel *selectionModel)
Sets the current selection model to the given selectionModel.
void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command)
Definition: qtreeview.cpp:3719
void currentChanged(const QModelIndex &current, const QModelIndex &previous)
Reimplemented Function
Definition: qtreeview.cpp:3821
ScrollMode horizontalScrollMode() const
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
QModelIndex bottomRight() const
Returns the index for the item located at the bottom-right corner of the selection range...
void rowsRemoved(const QModelIndex &parent, int first, int last)
Informs the view that the rows from the start row to the end row inclusive have been removed from the...
Definition: qtreeview.cpp:2582
void prepareAnimatedOperation(int item, QVariantAnimation::Direction d)
Definition: qtreeview.cpp:3089
QModelIndexList selectedIndexes() const
Reimplemented Function
Definition: qtreeview.cpp:2427
QModelIndex sibling(int row, int column) const
Returns the sibling at row and column.
void ensurePolished() const
Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette).
Definition: qwidget.cpp:10024
void setUniformRowHeights(bool uniform)
Definition: qtreeview.cpp:452
void mouseMoveEvent(QMouseEvent *event)
This function is called with the given event when a mouse move event is sent to the widget...
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
#define it(className, varName)
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
Applies the selection command to the items in or touched by the rectangle, rect.
Definition: qtreeview.cpp:2330
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
int minimum() const
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const =0
This pure abstract function must be reimplemented if you want to provide custom rendering.
void setStretchLastSection(bool stretch)
int visualIndex(int logicalIndex) const
Returns the visual index position of the section specified by the given logicalIndex, or -1 otherwise.
bool isVisible() const
Definition: qwidget.h:1005
void showColumn(int column)
Shows the given column in the tree view.
Definition: qtreeview.cpp:771
bool isValid() const
Returns true if the selection range is valid; otherwise returns false.
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of rows under the given parent.
QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const
Definition: qtreeview.cpp:3147
virtual void setRootIndex(const QModelIndex &index)
Sets the root item to the item at the given index.
void setDefaultAlignment(Qt::Alignment alignment)
bool isRowHidden(int row, const QModelIndex &parent) const
Returns true if the item in the given row of the parent is hidden; otherwise returns false...
Definition: qtreeview.cpp:609
bool isAnimated() const
Definition: qtreeview.cpp:944
QModelIndexList selectedIndexes() const
Returns a list of all selected model item indexes.
static C reverse(const C &l)
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation...
Definition: qpainter.cpp:2801
The QHoverEvent class contains parameters that describe a mouse event.
Definition: qevent.h:125
void adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option, const QModelIndex &current) const
Definition: qtreeview.cpp:1413
#define SLOT(a)
Definition: qobjectdefs.h:226
T1 first
Definition: qpair.h:65
void scrollContentsBy(int dx, int dy)
Scrolls the contents of the tree view by (dx, dy).
Definition: qtreeview.cpp:2448
int rowHeight(const QModelIndex &index) const
Returns the height of the row indicated by the given index.
Definition: qtreeview.cpp:2913
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
void restore()
Restores the current painter state (pops a saved state off the stack).
Definition: qpainter.cpp:1620
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
The QStyleOptionViewItemV4 class is used to describe the parameters necessary for drawing a frame in ...
Definition: qstyleoption.h:609
QRect normalized() const
Returns a normalized rectangle; i.e., a rectangle that has a non-negative width and height...
Definition: qrect.cpp:322
T2 second
Definition: qpair.h:66
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
The QItemSelectionRange class manages information about a range of selected items in a model...
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
void setHeader(QHeaderView *header)
Sets the header for the tree view, to the given header.
Definition: qtreeview.cpp:316
void updateScrollBars()
Definition: qtreeview.cpp:3556
static bool match(const uchar *found, const char *target, uint len)
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int)
This slot is called when columns are about to be removed.
Definition: qtreeview.cpp:3199
void timerEvent(QTimerEvent *event)
This function is called with the given event when a timer event is sent to the widget.
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
bool isFirstColumnSpanned(int row, const QModelIndex &parent) const
Returns true if the item in first column in the given row of the parent is spanning all the columns; ...
Definition: qtreeview.cpp:651
int columnViewportPosition(int column) const
Returns the horizontal position of the column in the viewport.
Definition: qtreeview.cpp:511
QScrollBar * verticalScrollBar() const
Returns the vertical scroll bar.
QModelIndex indexBelow(const QModelIndex &index) const
Returns the model index of the item below index.
Definition: qtreeview.cpp:2060
QModelIndex modelIndex(int i, int column=0) const
Definition: qtreeview.cpp:3511
The QStack class is a template class that provides a stack.
Definition: qcontainerfwd.h:63
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
int sizeHintForColumn(int column) const
Returns the size hint for the column&#39;s width or -1 if there is no model.
Definition: qtreeview.cpp:2801
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
int right() const
Returns the column index corresponding to the rightmost selected column in the selection range...
QRegion visualRegionForSelection(const QItemSelection &selection) const
Returns the rectangle from the viewport of the items in the given selection.
Definition: qtreeview.cpp:2369
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
Reimplemented Function
Definition: qtreeview.cpp:1398
void setSelectionModel(QItemSelectionModel *selectionModel)
Reimplemented Function
Definition: qtreeview.cpp:277
bool expandsOnDoubleClick() const
void layout(int item, bool recusiveExpanding=false, bool afterIsUninitialized=false)
Definition: qtreeview.cpp:3220
void resizeColumnToContents(int column)
Resizes the column given to the size of its contents.
Definition: qtreeview.cpp:2613
void reset()
Reimplemented Function
Definition: qtreeview.cpp:2113
void setModel(QAbstractItemModel *model)
Reimplemented Function
Definition: qtreeview.cpp:223
bool isExpanded(const QModelIndex &index) const
Returns true if the model item index is expanded; otherwise returns false.
Definition: qtreeview.cpp:859
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
bool isActiveWindow() const
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
QAbstractItemDelegate * itemDelegate() const
Returns the item delegate used by this view and model.
bool hasFocus() const
Definition: qwidget.cpp:6583
virtual void doItemsLayout()
This function is intended to lay out the items in the view.
ViewItemPosition
This enum is used to represent the placement of the item on a row.
Definition: qstyleoption.h:613
The QDragMoveEvent class provides an event which is sent while a drag and drop action is in progress...
Definition: qevent.h:530
int pageDown(int item) const
Definition: qtreeview.cpp:3321
bool isColumnHidden(int column) const
Returns true if the column is hidden; otherwise returns false.
Definition: qtreeview.cpp:559
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void drawAnimatedOperation(QPainter *painter) const
Definition: qtreeview.cpp:3135
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
void selectAll()
Reimplemented Function
Definition: qtreeview.cpp:2667
#define Q_D(Class)
Definition: qglobal.h:2482
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition: qpalette.h:107
int height() const
bool sectionsMoved() const
Returns true if sections in the header has been moved; otherwise returns false;.
void setBrushOrigin(int x, int y)
Sets the brush&#39;s origin to point (x, y).
Definition: qpainter.h:825
QModelIndex parent() const
Returns the parent model item index of the items in the selection range.
void keyPressEvent(QKeyEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1984
void dragMoveEvent(QDragMoveEvent *event)
This function is called continuously with the given event during a drag and drop operation over the w...
bool isSectionHidden(int logicalIndex) const
Returns true if the section specified by logicalIndex is explicitly hidden from the user; otherwise r...
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
QWidget * indexWidget(const QModelIndex &index) const
Returns the widget for the item at the given index.
void save()
Saves the current painter state (pushes the state onto a stack).
Definition: qpainter.cpp:1590
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:95
void collapse(const QModelIndex &index)
Collapses the model item specified by the index.
Definition: qtreeview.cpp:821
int indentation() const
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
QStyle * style() const
Definition: qwidget.cpp:2742
#define Q_Q(Class)
Definition: qglobal.h:2483
void horizontalScrollbarAction(int action)
Definition: qtreeview.cpp:2926
The QStyleOptionViewItemV2 class is used to describe the parameters necessary for drawing a frame in ...
Definition: qstyleoption.h:562
ColorGroup
Definition: qpalette.h:92
int columnAt(int x) const
Definition: qtreeview.cpp:3551
QColor backgroundColor
the background color on which the focus rectangle is being drawn
Definition: qstyleoption.h:109
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Reimplemented Function
Definition: qtreeview.cpp:3857
void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
Sets the model item index to be the current item, and emits currentChanged().
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible)
Scroll the contents of the tree view until the given model item index is visible. ...
Definition: qtreeview.cpp:1141
virtual void sort(int column, Qt::SortOrder order=Qt::AscendingOrder)
Sorts the model by column in the given order.
T pop()
Removes the top item from the stack and returns it.
Definition: qstack.h:67
QWidget * viewport() const
Returns the viewport widget.
QModelIndex topLeft() const
Returns the index for the item located at the top-left corner of the selection range.
virtual void setModel(QAbstractItemModel *model)
Sets the model for the view to present.
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
Returns the index of the item in the model specified by the given row, column and parent index...
void setCurrentColorGroup(ColorGroup cg)
Set the palette&#39;s current color group to cg.
Definition: qpalette.h:105
void expanded(const QModelIndex &index)
This signal is emitted when the item specified by index is expanded.
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
#define SIGNAL(a)
Definition: qobjectdefs.h:227
for(int ii=mo->methodOffset();ii< mo->methodCount();++ii)
void calcLogicalIndices(QVector< int > *logicalIndices, QVector< QStyleOptionViewItemV4::ViewItemPosition > *itemPositions, int left, int right) const
Definition: qtreeview.cpp:1532
int itemHeight(int item) const
Definition: qtreeview.cpp:3339
void setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)
If span is true the item in the first column in the row with the given parent is set to span all colu...
Definition: qtreeview.cpp:675
void collapseAll()
Collapses all expanded items.
Definition: qtreeview.cpp:2715
int width() const
Returns the width.
Definition: qsize.h:126
SortOrder
Definition: qnamespace.h:189
The QScrollBar widget provides a vertical or horizontal scroll bar.
Definition: qscrollbar.h:59
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
int value() const
void setColumnHidden(int column, bool hide)
If hide is true the column is hidden, otherwise the column is shown.
Definition: qtreeview.cpp:570
virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
This slot is called when columns are about to be removed.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Direction
This enum describes the direction of the animation when in Running state.
void rowsInserted(const QModelIndex &parent, int start, int end)
Informs the view that the rows from the start row to the end row inclusive have been inserted into th...
Definition: qtreeview.cpp:2528
int offset() const
Returns the offset of the header: this is the header&#39;s left-most (or top-most for vertical headers) v...
ViewItemFeatures features
a bitwise OR of the features that describe this view item
Definition: qstyleoption.h:577
int coordinateForItem(int item) const
Returns the viewport y coordinate for item.
Definition: qtreeview.cpp:3364
QPoint brushOrigin() const
Returns the currently set brush origin.
Definition: qpainter.cpp:2168
ScrollMode verticalScrollMode() const
void setClickable(bool clickable)
If clickable is true, the header will respond to single clicks.
qint64 internalId() const
Returns a qint64 used by the model to associate the index with the internal data structure.
void setAllColumnsShowFocus(bool enable)
Definition: qtreeview.cpp:964
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
virtual bool hasChildren(const QModelIndex &parent=QModelIndex()) const
Returns true if parent has any children; otherwise returns false.
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QItemSelectionModel * selectionModel() const
Returns the current selection model.
int width() const
The QTreeView class provides a default model/view implementation of a tree view.
Definition: qtreeview.h:58
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
int row() const
Returns the row this model index refers to.
int horizontalOffset() const
Returns the horizontal offset of the items in the treeview.
Definition: qtreeview.cpp:2131
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous)
This slot is called when a new item becomes the current item.
const QAbstractItemModel * model() const
Returns a pointer to the model containing the item that this index refers to.
void mouseReleaseEvent(QMouseEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1900
int viewIndex(const QModelIndex &index) const
Definition: qtreeview.cpp:3467
iterator end()
Definition: qset.h:169
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
The QStyleOptionFocusRect class is used to describe the parameters for drawing a focus rectangle with...
Definition: qstyleoption.h:103
const QRegion & region() const
Returns the region that needs to be updated.
Definition: qevent.h:306
const char * styleHint(const QFontDef &request)
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition: qcoreevent.h:346
bool showDecorationSelected
whether the decoration should be highlighted on selected items
Definition: qstyleoption.h:553
int visualIndex(const QModelIndex &index) const
Definition: qtreeview.cpp:3894
void expandAll()
Expands all expandable items.
Definition: qtreeview.cpp:2695
unsigned int uint
Definition: qglobal.h:996
void setSortingEnabled(bool enable)
Definition: qtreeview.cpp:898
virtual void reset()
Reset the internal state of the view.
QModelIndex currentIndex() const
Returns the model index of the current item.
void setRootIsDecorated(bool show)
Definition: qtreeview.cpp:421
void keyPressEvent(QKeyEvent *event)
This function is called with the given event when a key event is sent to the widget.
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
int verticalOffset() const
Returns the vertical offset of the items in the tree view.
Definition: qtreeview.cpp:2142
T value(int i) const
Returns the value at index position i in the list.
Definition: qlist.h:661
int columnWidth(int column) const
Returns the width of the column.
Definition: qtreeview.cpp:522
QSize size
the size of the widget excluding any window frame
Definition: qwidget.h:165
virtual bool canFetchMore(const QModelIndex &parent) const
Returns true if there is more data available for parent; otherwise returns false. ...
__int64 qint64
Definition: qglobal.h:942
void activated(const QModelIndex &index)
This signal is emitted when the item specified by index is activated by the user. ...
void show()
Shows the widget and its child widgets.
int sectionViewportPosition(int logicalIndex) const
Returns the section viewport position of the given logicalIndex.
int length() const
Returns the length along the orientation of the header.
QRect itemDecorationRect(const QModelIndex &index) const
Definition: qtreeview.cpp:3645
QAbstractItemView::SelectionBehavior selectionBehavior() const
void setRootIndex(const QModelIndex &index)
Reimplemented Function
Definition: qtreeview.cpp:267
void push(const T &t)
Adds element t to the top of the stack.
Definition: qstack.h:60
void setX(int x)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:282
uint hasMoreSiblings
Definition: qtreeview_p.h:73
bool isValid() const
Returns true if this model index is valid; otherwise returns false.
void expand(const QModelIndex &index)
Expands the model item specified by the index.
Definition: qtreeview.cpp:787
QRect rect() const
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
~QTreeView()
Destroys the tree view.
Definition: qtreeview.cpp:216
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
bool isEnabled() const
Definition: qwidget.h:948
void hide()
Hides the widget.
Definition: qwidget.h:501
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
bool wordWrap() const
The QAbstractItemModel class provides the abstract interface for item model classes.
static bool isActive()
Returns true if an accessibility implementation has been requested during the runtime of the applicat...
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
void columnResized(int column, int oldSize, int newSize)
This function is called whenever {column}&#39;s size is changed in the header.
Definition: qtreeview.cpp:2756
ViewItemPosition viewItemPosition
Gives the position of this view item relative to other items.
Definition: qstyleoption.h:619
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition: qpixmap.cpp:1080
QTreeView(QWidget *parent=0)
Constructs a tree view with a parent to represent a model&#39;s data.
Definition: qtreeview.cpp:196
virtual void fetchMore(const QModelIndex &parent)
Fetches any available data for the items with the parent specified by the parent index.
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
This slot is called when the selection is changed.
int firstVisibleItem(int *offset=0) const
Definition: qtreeview.cpp:3522
The QAbstractItemView class provides the basic functionality for item view classes.
int pageUp(int item) const
Definition: qtreeview.cpp:3313
void _q_modelAboutToBeReset()
Definition: qtreeview.cpp:3194
void columnCountChanged(int oldCount, int newCount)
Informs the tree view that the number of columns in the tree view has changed from oldCount to newCou...
Definition: qtreeview.cpp:2595
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
bool isSortingEnabled() const
Definition: qtreeview.cpp:916
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction...
Definition: qstyle.cpp:2087
void setAnimated(bool enable)
Definition: qtreeview.cpp:938
The QItemSelection class manages information about selected items in a model.
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:131
void setColumnWidth(int column, int width)
Sets the width of the given column to the width specified.
Definition: qtreeview.cpp:538
void expandToDepth(int depth)
Expands all expandable items to the given depth.
Definition: qtreeview.cpp:2731
int visualIndexAt(int position) const
Returns the visual index of the section that covers the given position in the viewport.
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int x() const
int logicalIndex(int visualIndex) const
Returns the logicalIndex for the section at the given visualIndex position, or -1 if visualIndex < 0 ...
Qt::LayoutDirection layoutDirection() const
bool rootIsDecorated() const
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
QPoint pos
the position of the widget within its parent widget
Definition: qwidget.h:163
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
State
Definition: qaudio.h:59
The QPersistentModelIndex class is used to locate data in a data model.
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
void setSortIndicatorShown(bool show)
bool itemsExpandable() const
int y() const
Returns the y position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:98
void expand(int item, bool emitSignal)
Definition: qtreeview.cpp:2961
void setExpandsOnDoubleClick(bool enable)
Definition: qtreeview.cpp:502
void timerEvent(QTimerEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1240
void _q_endAnimatedOperation()
Definition: qtreeview.cpp:3185
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
QRect visualRect(const QModelIndex &index) const
Returns the rectangle on the viewport occupied by the item at index.
Definition: qtreeview.cpp:1101
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
void setIndentation(int i)
Definition: qtreeview.cpp:392
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
void setMovable(bool movable)
If movable is true, the header may be moved by the user; otherwise it is fixed in place...
QHeaderView * header() const
Returns the header for the tree view.
Definition: qtreeview.cpp:302
The QModelIndex class is used to locate data in a data model.
QScrollBar * horizontalScrollBar() const
Returns the horizontal scroll bar.
void setItemsExpandable(bool enable)
Definition: qtreeview.cpp:477
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
int count() const
Returns the number of sections in the header.
void columnMoved()
This slot is called whenever a column has been moved.
Definition: qtreeview.cpp:2509
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
int sectionSize(int logicalIndex) const
Returns the width (or height for vertical headers) of the given logicalIndex.
bool hasVisibleChildren(const QModelIndex &parent) const
Definition: qtreeview.cpp:3794
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
uint hasChildren
Definition: qtreeview_p.h:72
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:123
bool uniformRowHeights() const
void edit(const QModelIndex &index)
Starts editing the item corresponding to the given index if it is editable.
virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end)
This slot is called when columns have been removed.
void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const
Definition: qtreeview.cpp:1337
void paintEvent(QPaintEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1318
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
void doItemsLayout()
Lays out the items in the tree view.
Definition: qtreeview.cpp:2080
void mouseMoveEvent(QMouseEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1974
void collapse(int item, bool emitSignal)
Definition: qtreeview.cpp:3042
QModelIndex index
Definition: qtreeview_p.h:68
State state() const
Returns the item view&#39;s state.
bool contains(const T &t) const
Returns true if the vector contains an occurrence of value; otherwise returns false.
Definition: qvector.h:731
void setExpanded(const QModelIndex &index, bool expand)
Sets the item referred to by index to either collapse or expanded, depending on the value of expanded...
Definition: qtreeview.cpp:871
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
quint16 index
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
Informs the view that the rows from the start row to the end row inclusive are about to removed from ...
Definition: qtreeview.cpp:2566
void mouseReleaseEvent(QMouseEvent *event)
This function is called with the given event when a mouse button is released, after a mouse press eve...
virtual void rowsInserted(const QModelIndex &parent, int start, int end)
This slot is called when rows are inserted.
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
This slot is called when items are changed in the model.
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
int depth() const
Definition: qpaintdevice.h:103
virtual void updateGeometries()
Updates the geometry of the child widgets of the view.
int indexRowSizeHint(const QModelIndex &index) const
Returns the size hint for the row indicated by index.
Definition: qtreeview.cpp:2843
int top() const
Returns the row index corresponding to the uppermost selected row in the selection range...
void drawTree(QPainter *painter, const QRegion &region) const
Draws the part of the tree intersecting the given region using the specified painter.
Definition: qtreeview.cpp:1452
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device...
Definition: qpainter.cpp:5619
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
void sortByColumn(int column, Qt::SortOrder order)
Sets the model up for sorting by the values in the given column and order.
Definition: qtreeview.cpp:2653
int itemDecorationAt(const QPoint &pos) const
Definition: qtreeview.cpp:3629
int singleStep() const
QLayout * layout() const
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed...
Definition: qwidget.cpp:10073
int columnAt(int x) const
Returns the column in the tree view whose header covers the x coordinate given.
Definition: qtreeview.cpp:548
void _q_sortIndicatorChanged(int column, Qt::SortOrder order)
Definition: qtreeview.cpp:3813
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
bool isRightToLeft() const
Definition: qwidget.h:428
bool intersects(const QRect &r) const
Returns true if this rectangle intersects with the given rectangle (i.
Definition: qrect.cpp:1429
void removeViewItems(int pos, int count)
Definition: qtreeview.cpp:3010
CursorAction
This enum describes the different ways to navigate between items,.
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
int sectionPosition(int logicalIndex) const
Returns the section position of the given logicalIndex, or -1 if the section is hidden.
QModelIndexList indexes() const
Returns a list of model indexes that correspond to the selected items.
void doubleClicked(const QModelIndex &index)
This signal is emitted when a mouse button is double-clicked.
The QStyleOptionViewItem class is used to describe the parameters used to draw an item in a view widg...
Definition: qstyleoption.h:539
void hideColumn(int column)
Hides the column given.
Definition: qtreeview.cpp:760
bool allColumnsShowFocus() const
virtual void horizontalScrollbarAction(int action)
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
void setWordWrap(bool on)
Definition: qtreeview.cpp:995
int logicalIndexAt(int position) const
Returns the section that covers the given position in the viewport.
QModelIndex indexAbove(const QModelIndex &index) const
Returns the model index of the item above index.
Definition: qtreeview.cpp:2045
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
int indentationForItem(int item) const
Definition: qtreeview.cpp:3329
void _q_columnsRemoved(const QModelIndex &, int, int)
This slot is called when columns have been removed.
Definition: qtreeview.cpp:3206
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
QModelIndex indexAt(const QPoint &p) const
Reimplemented Function
Definition: qtreeview.cpp:2021
QModelIndex rootIndex() const
Returns the model index of the model&#39;s root item.
QAbstractItemModel * model() const
Returns the model that this view is presenting.
static const KeyPair *const end
virtual void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
Draws the row in the tree view that contains the model item index, using the painter given...
Definition: qtreeview.cpp:1590
void insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
Definition: qtreeview.cpp:2993
void collapsed(const QModelIndex &index)
This signal is emitted when the item specified by index is collapsed.
bool event(QEvent *event)
Reimplemented Function
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
void render(QPaintDevice *target, const QPoint &targetOffset=QPoint(), const QRegion &sourceRegion=QRegion(), RenderFlags renderFlags=RenderFlags(DrawWindowBackground|DrawChildren))
Renders the sourceRegion of this widget into the target using renderFlags to determine how to render...
Definition: qwidget.cpp:5372
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
Reimplemented Function
Definition: qtreeview.cpp:706
int pageStep() const
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or 0 if no widget in this applicati...
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
void setState(State state)
Sets the item view&#39;s state to the given state.
void mousePressEvent(QMouseEvent *event)
This function is called with the given event when a mouse button is pressed while the cursor is insid...
bool expandOrCollapseItemAtPos(const QPoint &pos)
Definition: qtreeview.cpp:1361
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
#define INT_MAX
virtual int sizeHintForRow(int row) const
Returns the height size hint for the specified row or -1 if there is no model.
bool viewportEvent(QEvent *event)
Reimplemented Function
Definition: qtreeview.cpp:1289
virtual void updateEditorGeometries()
Updates the geometry of the open editor widgets in the view.
bool end()
Ends painting.
Definition: qpainter.cpp:1929
bool viewportEvent(QEvent *event)
This function is used to handle tool tips, and What&#39;s This? mode, if the given event is a QEvent::Too...
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
QList< QPair< int, int > > columnRanges(const QModelIndex &topIndex, const QModelIndex &bottomIndex) const
Definition: qtreeview.cpp:3672
static QPoint pos()
Returns the position of the cursor (hot spot) in global screen coordinates.
Definition: qcursor_mac.mm:310
int column() const
Returns the column this model index refers to.
The QHeaderView class provides a header row or header column for item views.
Definition: qheaderview.h:58
void _q_modelDestroyed()
Definition: qtreeview.cpp:1385
static int area(const QSize &s)
Definition: qicon.cpp:155
void setAutoExpandDelay(int delay)
Definition: qtreeview.cpp:366
bool isValid() const
Returns true if this persistent model index is valid; otherwise returns false.
void beginAnimatedOperation()
Definition: qtreeview.cpp:3111
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition: qobject.cpp:1650
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
Qt::LayoutDirection direction
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
Definition: qpainter.cpp:3311
int autoExpandDelay() const
virtual void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const
Draws the branches in the tree view on the same row as the model item index, using the painter given...
Definition: qtreeview.cpp:1788