src/gui/itemviews/qlistview.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   355     return d->layoutMode;
   355     return d->layoutMode;
   356 }
   356 }
   357 
   357 
   358 /*!
   358 /*!
   359     \property QListView::spacing
   359     \property QListView::spacing
   360     \brief the space between items in the layout
   360     \brief the space around the items in the layout
   361 
   361 
   362     This property is the size of the empty space that is padded around
   362     This property is the size of the empty space that is padded around
   363     an item in the layout.
   363     an item in the layout.
   364 
   364 
   365     Setting this property when the view is visible will cause the
   365     Setting this property when the view is visible will cause the
   771   \reimp
   771   \reimp
   772 */
   772 */
   773 void QListView::mouseMoveEvent(QMouseEvent *e)
   773 void QListView::mouseMoveEvent(QMouseEvent *e)
   774 {
   774 {
   775     if (!isVisible())
   775     if (!isVisible())
   776 	return;
   776         return;
   777     Q_D(QListView);
   777     Q_D(QListView);
   778     QAbstractItemView::mouseMoveEvent(e);
   778     QAbstractItemView::mouseMoveEvent(e);
   779     if (state() == DragSelectingState
   779     if (state() == DragSelectingState
   780         && d->showElasticBand
   780         && d->showElasticBand
   781         && d->selectionMode != SingleSelection
   781         && d->selectionMode != SingleSelection
   830 
   830 
   831     if (delta.isNull())
   831     if (delta.isNull())
   832       return;
   832       return;
   833 
   833 
   834     bool listWrap = (d->viewMode == ListMode) && d->wrapItemText;
   834     bool listWrap = (d->viewMode == ListMode) && d->wrapItemText;
   835     bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0) 
   835     bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0)
   836 				|| (d->flow == TopToBottom && delta.height() != 0);
   836                                 || (d->flow == TopToBottom && delta.height() != 0);
   837 
   837 
   838     // We post a delayed relayout in the following cases :
   838     // We post a delayed relayout in the following cases :
   839     // - we're wrapping
   839     // - we're wrapping
   840     // - the state is NoState, we're adjusting and the size has changed in the flowing direction
   840     // - the state is NoState, we're adjusting and the size has changed in the flowing direction
   841     if (listWrap 
   841     if (listWrap
   842         || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) {
   842         || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) {
   843 	d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
   843         d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
   844     } else {	
   844     } else {
   845         QAbstractItemView::resizeEvent(e);
   845         QAbstractItemView::resizeEvent(e);
   846     }
   846     }
   847 }
   847 }
   848 
   848 
   849 #ifndef QT_NO_DRAGANDDROP
   849 #ifndef QT_NO_DRAGANDDROP
   851 /*!
   851 /*!
   852   \reimp
   852   \reimp
   853 */
   853 */
   854 void QListView::dragMoveEvent(QDragMoveEvent *e)
   854 void QListView::dragMoveEvent(QDragMoveEvent *e)
   855 {
   855 {
   856     if (!d_func()->commonListView->filterDragMoveEvent(e))
   856     Q_D(QListView);
   857         QAbstractItemView::dragMoveEvent(e);
   857     if (!d->commonListView->filterDragMoveEvent(e)) {
       
   858         if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight)
       
   859             static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e);
       
   860         else
       
   861             QAbstractItemView::dragMoveEvent(e);
       
   862     }
   858 }
   863 }
   859 
   864 
   860 
   865 
   861 /*!
   866 /*!
   862   \reimp
   867   \reimp
   959     const bool enabled = (state & QStyle::State_Enabled) != 0;
   964     const bool enabled = (state & QStyle::State_Enabled) != 0;
   960 
   965 
   961     bool alternateBase = false;
   966     bool alternateBase = false;
   962     int previousRow = -2; // trigger the alternateBase adjustment on first pass
   967     int previousRow = -2; // trigger the alternateBase adjustment on first pass
   963 
   968 
       
   969     int maxSize = (flow() == TopToBottom)
       
   970         ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
       
   971         : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
       
   972 
   964     QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
   973     QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
   965     for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
   974     for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
   966         Q_ASSERT((*it).isValid());
   975         Q_ASSERT((*it).isValid());
   967         option.rect = visualRect(*it);
   976         option.rect = visualRect(*it);
   968 
   977 
   969         if (flow() == TopToBottom)
   978         if (flow() == TopToBottom)
   970             option.rect.setWidth(qMin(viewport()->size().width(), option.rect.width()));
   979             option.rect.setWidth(qMin(maxSize, option.rect.width()));
   971         else
   980         else
   972             option.rect.setHeight(qMin(viewport()->size().height(), option.rect.height()));
   981             option.rect.setHeight(qMin(maxSize, option.rect.height()));
   973 
   982 
   974         option.state = state;
   983         option.state = state;
   975         if (selections && selections->isSelected(*it))
   984         if (selections && selections->isSelected(*it))
   976             option.state |= QStyle::State_Selected;
   985             option.state |= QStyle::State_Selected;
   977         if (enabled) {
   986         if (enabled) {
  1140             intersectVector = d->intersectingSet(rect);
  1149             intersectVector = d->intersectingSet(rect);
  1141             d->removeCurrentAndDisabled(&intersectVector, current);
  1150             d->removeCurrentAndDisabled(&intersectVector, current);
  1142         }
  1151         }
  1143         return d->closestIndex(initialRect, intersectVector);
  1152         return d->closestIndex(initialRect, intersectVector);
  1144     case MovePageUp:
  1153     case MovePageUp:
  1145         rect.moveTop(rect.top() - d->viewport->height());
  1154         // move current by (visibileRowCount - 1) items.
       
  1155         // rect.translate(0, -rect.height()); will happen in the switch fallthrough for MoveUp.
       
  1156         rect.moveTop(rect.top() - d->viewport->height() + 2 * rect.height());
  1146         if (rect.top() < rect.height())
  1157         if (rect.top() < rect.height())
  1147             rect.moveTop(rect.height());
  1158             rect.moveTop(rect.height());
  1148     case MovePrevious:
  1159     case MovePrevious:
  1149     case MoveUp:
  1160     case MoveUp:
  1150         while (intersectVector.isEmpty()) {
  1161         while (intersectVector.isEmpty()) {
  1166             intersectVector = d->intersectingSet(rect);
  1177             intersectVector = d->intersectingSet(rect);
  1167             d->removeCurrentAndDisabled(&intersectVector, current);
  1178             d->removeCurrentAndDisabled(&intersectVector, current);
  1168         }
  1179         }
  1169         return d->closestIndex(initialRect, intersectVector);
  1180         return d->closestIndex(initialRect, intersectVector);
  1170     case MovePageDown:
  1181     case MovePageDown:
  1171         rect.moveTop(rect.top() + d->viewport->height());
  1182         // move current by (visibileRowCount - 1) items.
       
  1183         // rect.translate(0, rect.height()); will happen in the switch fallthrough for MoveDown.
       
  1184         rect.moveTop(rect.top() + d->viewport->height() - 2 * rect.height());
  1172         if (rect.bottom() > contents.height() - rect.height())
  1185         if (rect.bottom() > contents.height() - rect.height())
  1173             rect.moveBottom(contents.height() - rect.height());
  1186             rect.moveBottom(contents.height() - rect.height());
  1174     case MoveNext:
  1187     case MoveNext:
  1175     case MoveDown:
  1188     case MoveDown:
  1176         while (intersectVector.isEmpty()) {
  1189         while (intersectVector.isEmpty()) {
  1438     Q_D(QListView);
  1451     Q_D(QListView);
  1439     // showing the scroll bars will trigger a resize event,
  1452     // showing the scroll bars will trigger a resize event,
  1440     // so we set the state to expanding to avoid
  1453     // so we set the state to expanding to avoid
  1441     // triggering another layout
  1454     // triggering another layout
  1442     QAbstractItemView::State oldState = state();
  1455     QAbstractItemView::State oldState = state();
  1443     setState(ExpandingState); 
  1456     setState(ExpandingState);
  1444     if (d->model->columnCount(d->root) > 0) { // no columns means no contents
  1457     if (d->model->columnCount(d->root) > 0) { // no columns means no contents
  1445         d->resetBatchStartRow();
  1458         d->resetBatchStartRow();
  1446         if (layoutMode() == SinglePass)
  1459         if (layoutMode() == SinglePass)
  1447             d->doItemsLayout(d->model->rowCount(d->root)); // layout everything
  1460             d->doItemsLayout(d->model->rowCount(d->root)); // layout everything
  1448         else if (!d->batchLayoutTimer.isActive()) {
  1461         else if (!d->batchLayoutTimer.isActive()) {
  1802         selection.select(br, br);
  1815         selection.select(br, br);
  1803 
  1816 
  1804     return selection;
  1817     return selection;
  1805 }
  1818 }
  1806 
  1819 
       
  1820 #ifndef QT_NO_DRAGANDDROP
       
  1821 QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const
       
  1822 {
       
  1823     if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
       
  1824         return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx);
       
  1825     else
       
  1826         return QAbstractItemViewPrivate::position(pos, rect, idx);
       
  1827 }
       
  1828 #endif
       
  1829 
  1807 /*
  1830 /*
  1808  * Common ListView Implementation
  1831  * Common ListView Implementation
  1809 */
  1832 */
  1810 
  1833 
  1811 void QCommonListViewBase::appendHiddenRow(int row)
  1834 void QCommonListViewBase::appendHiddenRow(int row)
  1820 
  1843 
  1821 void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
  1844 void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
  1822 {
  1845 {
  1823     horizontalScrollBar()->setSingleStep(step.width() + spacing());
  1846     horizontalScrollBar()->setSingleStep(step.width() + spacing());
  1824     horizontalScrollBar()->setPageStep(viewport()->width());
  1847     horizontalScrollBar()->setPageStep(viewport()->width());
  1825     horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
  1848     horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width() - 2 * spacing());
  1826 }
  1849 }
  1827 
  1850 
  1828 void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
  1851 void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
  1829 {
  1852 {
  1830     verticalScrollBar()->setSingleStep(step.height() + spacing());
  1853     verticalScrollBar()->setSingleStep(step.height() + spacing());
  1831     verticalScrollBar()->setPageStep(viewport()->height());
  1854     verticalScrollBar()->setPageStep(viewport()->height());
  1832     verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
  1855     verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height() - 2 * spacing());
  1833 }
  1856 }
  1834 
  1857 
  1835 void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
  1858 void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
  1836 {
  1859 {
  1837     dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
  1860     dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
  1891 {
  1914 {
  1892     // FIXME: Until the we can provide a proper drop indicator
  1915     // FIXME: Until the we can provide a proper drop indicator
  1893     // in IconMode, it makes no sense to show it
  1916     // in IconMode, it makes no sense to show it
  1894     dd->paintDropIndicator(painter);
  1917     dd->paintDropIndicator(painter);
  1895 }
  1918 }
       
  1919 
       
  1920 QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
       
  1921 {
       
  1922     QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
       
  1923     if (!dd->overwrite) {
       
  1924         const int margin = 2;
       
  1925         if (pos.x() - rect.left() < margin) {
       
  1926             r = QAbstractItemView::AboveItem;   // Visually, on the left
       
  1927         } else if (rect.right() - pos.x() < margin) {
       
  1928             r = QAbstractItemView::BelowItem;   // Visually, on the right
       
  1929         } else if (rect.contains(pos, true)) {
       
  1930             r = QAbstractItemView::OnItem;
       
  1931         }
       
  1932     } else {
       
  1933         QRect touchingRect = rect;
       
  1934         touchingRect.adjust(-1, -1, 1, 1);
       
  1935         if (touchingRect.contains(pos, false)) {
       
  1936             r = QAbstractItemView::OnItem;
       
  1937         }
       
  1938     }
       
  1939 
       
  1940     if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled)))
       
  1941         r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
       
  1942 
       
  1943     return r;
       
  1944 }
       
  1945 
       
  1946 void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
       
  1947 {
       
  1948     if (qq->dragDropMode() == QAbstractItemView::InternalMove
       
  1949         && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction)))
       
  1950         return;
       
  1951 
       
  1952     // ignore by default
       
  1953     event->ignore();
       
  1954 
       
  1955     QModelIndex index = qq->indexAt(event->pos());
       
  1956     dd->hover = index;
       
  1957     if (!dd->droppingOnItself(event, index)
       
  1958         && dd->canDecode(event)) {
       
  1959 
       
  1960         if (index.isValid() && dd->showDropIndicator) {
       
  1961             QRect rect = qq->visualRect(index);
       
  1962             dd->dropIndicatorPosition = position(event->pos(), rect, index);
       
  1963             switch (dd->dropIndicatorPosition) {
       
  1964             case QAbstractItemView::AboveItem:
       
  1965                 if (dd->isIndexDropEnabled(index.parent())) {
       
  1966                     dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height());
       
  1967                     event->accept();
       
  1968                 } else {
       
  1969                     dd->dropIndicatorRect = QRect();
       
  1970                 }
       
  1971                 break;
       
  1972             case QAbstractItemView::BelowItem:
       
  1973                 if (dd->isIndexDropEnabled(index.parent())) {
       
  1974                     dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height());
       
  1975                     event->accept();
       
  1976                 } else {
       
  1977                     dd->dropIndicatorRect = QRect();
       
  1978                 }
       
  1979                 break;
       
  1980             case QAbstractItemView::OnItem:
       
  1981                 if (dd->isIndexDropEnabled(index)) {
       
  1982                     dd->dropIndicatorRect = rect;
       
  1983                     event->accept();
       
  1984                 } else {
       
  1985                     dd->dropIndicatorRect = QRect();
       
  1986                 }
       
  1987                 break;
       
  1988             case QAbstractItemView::OnViewport:
       
  1989                 dd->dropIndicatorRect = QRect();
       
  1990                 if (dd->isIndexDropEnabled(qq->rootIndex())) {
       
  1991                     event->accept(); // allow dropping in empty areas
       
  1992                 }
       
  1993                 break;
       
  1994             }
       
  1995         } else {
       
  1996             dd->dropIndicatorRect = QRect();
       
  1997             dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
       
  1998             if (dd->isIndexDropEnabled(qq->rootIndex())) {
       
  1999                 event->accept(); // allow dropping in empty areas
       
  2000             }
       
  2001         }
       
  2002         dd->viewport->update();
       
  2003     } // can decode
       
  2004 
       
  2005     if (dd->shouldAutoScroll(event->pos()))
       
  2006         qq->startAutoScroll();
       
  2007 }
       
  2008 
  1896 #endif //QT_NO_DRAGANDDROP
  2009 #endif //QT_NO_DRAGANDDROP
  1897 
  2010 
  1898 void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
  2011 void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
  1899 {
  2012 {
  1900     if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
  2013     if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
  2296         }
  2409         }
  2297     }
  2410     }
  2298     return ret;
  2411     return ret;
  2299 }
  2412 }
  2300 
  2413 
       
  2414 void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &)
       
  2415 {
       
  2416     dd->doDelayedItemsLayout();
       
  2417 }
       
  2418 
       
  2419 
  2301 QRect QListModeViewBase::mapToViewport(const QRect &rect) const
  2420 QRect QListModeViewBase::mapToViewport(const QRect &rect) const
  2302 {
  2421 {
  2303     if (isWrapping())
  2422     if (isWrapping())
  2304         return rect;
  2423         return rect;
  2305     // If the listview is in "listbox-mode", the items are as wide as the view.
  2424     // If the listview is in "listbox-mode", the items are as wide as the view.