68 QAbstractItemViewPrivate::QAbstractItemViewPrivate() |
68 QAbstractItemViewPrivate::QAbstractItemViewPrivate() |
69 : model(QAbstractItemModelPrivate::staticEmptyModel()), |
69 : model(QAbstractItemModelPrivate::staticEmptyModel()), |
70 itemDelegate(0), |
70 itemDelegate(0), |
71 selectionModel(0), |
71 selectionModel(0), |
72 ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate), |
72 ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate), |
|
73 noSelectionOnMousePress(false), |
73 selectionMode(QAbstractItemView::ExtendedSelection), |
74 selectionMode(QAbstractItemView::ExtendedSelection), |
74 selectionBehavior(QAbstractItemView::SelectItems), |
75 selectionBehavior(QAbstractItemView::SelectItems), |
75 currentlyCommittingEditor(0), |
76 currentlyCommittingEditor(0), |
76 pressedModifiers(Qt::NoModifier), |
77 pressedModifiers(Qt::NoModifier), |
77 pressedPosition(QPoint(-1, -1)), |
78 pressedPosition(QPoint(-1, -1)), |
94 #endif |
95 #endif |
95 autoScroll(true), |
96 autoScroll(true), |
96 autoScrollMargin(16), |
97 autoScrollMargin(16), |
97 autoScrollCount(0), |
98 autoScrollCount(0), |
98 shouldScrollToCurrentOnShow(false), |
99 shouldScrollToCurrentOnShow(false), |
|
100 shouldClearStatusTip(false), |
99 alternatingColors(false), |
101 alternatingColors(false), |
100 textElideMode(Qt::ElideRight), |
102 textElideMode(Qt::ElideRight), |
101 verticalScrollMode(QAbstractItemView::ScrollPerItem), |
103 verticalScrollMode(QAbstractItemView::ScrollPerItem), |
102 horizontalScrollMode(QAbstractItemView::ScrollPerItem), |
104 horizontalScrollMode(QAbstractItemView::ScrollPerItem), |
103 currentIndexSet(false), |
105 currentIndexSet(false), |
136 #ifdef QT_SOFTKEYS_ENABLED |
138 #ifdef QT_SOFTKEYS_ENABLED |
137 doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q); |
139 doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q); |
138 #endif |
140 #endif |
139 } |
141 } |
140 |
142 |
|
143 void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index) |
|
144 { |
|
145 Q_Q(QAbstractItemView); |
|
146 if (hover == index) |
|
147 return; |
|
148 |
|
149 q->update(hover); //update the old one |
|
150 hover = index; |
|
151 q->update(hover); //update the new one |
|
152 } |
|
153 |
141 void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) |
154 void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) |
142 { |
155 { |
143 //we take a persistent model index because the model might change by emitting signals |
156 //we take a persistent model index because the model might change by emitting signals |
144 Q_Q(QAbstractItemView); |
157 Q_Q(QAbstractItemView); |
|
158 setHoverIndex(index); |
145 if (viewportEnteredNeeded || enteredIndex != index) { |
159 if (viewportEnteredNeeded || enteredIndex != index) { |
146 viewportEnteredNeeded = false; |
160 viewportEnteredNeeded = false; |
147 |
161 |
148 if (index.isValid()) { |
162 if (index.isValid()) { |
149 emit q->entered(index); |
163 emit q->entered(index); |
150 #ifndef QT_NO_STATUSTIP |
164 #ifndef QT_NO_STATUSTIP |
151 QString statustip = model->data(index, Qt::StatusTipRole).toString(); |
165 QString statustip = model->data(index, Qt::StatusTipRole).toString(); |
152 if (parent && !statustip.isEmpty()) { |
166 if (parent && (shouldClearStatusTip || !statustip.isEmpty())) { |
153 QStatusTipEvent tip(statustip); |
167 QStatusTipEvent tip(statustip); |
154 QApplication::sendEvent(parent, &tip); |
168 QApplication::sendEvent(parent, &tip); |
|
169 shouldClearStatusTip = !statustip.isEmpty(); |
155 } |
170 } |
156 #endif |
171 #endif |
157 } else { |
172 } else { |
158 #ifndef QT_NO_STATUSTIP |
173 #ifndef QT_NO_STATUSTIP |
159 if (parent) { |
174 if (parent && shouldClearStatusTip) { |
160 QString emptyString; |
175 QString emptyString; |
161 QStatusTipEvent tip( emptyString ); |
176 QStatusTipEvent tip( emptyString ); |
162 QApplication::sendEvent(parent, &tip); |
177 QApplication::sendEvent(parent, &tip); |
163 } |
178 } |
164 #endif |
179 #endif |
603 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) { |
618 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) { |
604 disconnect(d->model, SIGNAL(destroyed()), |
619 disconnect(d->model, SIGNAL(destroyed()), |
605 this, SLOT(_q_modelDestroyed())); |
620 this, SLOT(_q_modelDestroyed())); |
606 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
621 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
607 this, SLOT(dataChanged(QModelIndex,QModelIndex))); |
622 this, SLOT(dataChanged(QModelIndex,QModelIndex))); |
|
623 disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), |
|
624 this, SLOT(_q_headerDataChanged())); |
608 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
625 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
609 this, SLOT(rowsInserted(QModelIndex,int,int))); |
626 this, SLOT(rowsInserted(QModelIndex,int,int))); |
610 disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
627 disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
611 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); |
628 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); |
612 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
629 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
635 if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) { |
652 if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) { |
636 connect(d->model, SIGNAL(destroyed()), |
653 connect(d->model, SIGNAL(destroyed()), |
637 this, SLOT(_q_modelDestroyed())); |
654 this, SLOT(_q_modelDestroyed())); |
638 connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
655 connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
639 this, SLOT(dataChanged(QModelIndex,QModelIndex))); |
656 this, SLOT(dataChanged(QModelIndex,QModelIndex))); |
|
657 connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), |
|
658 this, SLOT(_q_headerDataChanged())); |
640 connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
659 connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
641 this, SLOT(rowsInserted(QModelIndex,int,int))); |
660 this, SLOT(rowsInserted(QModelIndex,int,int))); |
642 connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
661 connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
643 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); |
662 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); |
644 connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
663 connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
1530 */ |
1549 */ |
1531 bool QAbstractItemView::viewportEvent(QEvent *event) |
1550 bool QAbstractItemView::viewportEvent(QEvent *event) |
1532 { |
1551 { |
1533 Q_D(QAbstractItemView); |
1552 Q_D(QAbstractItemView); |
1534 switch (event->type()) { |
1553 switch (event->type()) { |
1535 case QEvent::HoverEnter: { |
1554 case QEvent::HoverMove: |
1536 QHoverEvent *he = static_cast<QHoverEvent*>(event); |
1555 case QEvent::HoverEnter: |
1537 d->hover = indexAt(he->pos()); |
1556 d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->pos())); |
1538 update(d->hover); |
1557 break; |
1539 break; } |
1558 case QEvent::HoverLeave: |
1540 case QEvent::HoverLeave: { |
1559 d->setHoverIndex(QModelIndex()); |
1541 update(d->hover); // update old |
1560 break; |
1542 d->hover = QModelIndex(); |
|
1543 break; } |
|
1544 case QEvent::HoverMove: { |
|
1545 QHoverEvent *he = static_cast<QHoverEvent*>(event); |
|
1546 QModelIndex old = d->hover; |
|
1547 d->hover = indexAt(he->pos()); |
|
1548 if (d->hover != old) |
|
1549 d->viewport->update(visualRect(old)|visualRect(d->hover)); |
|
1550 break; } |
|
1551 case QEvent::Enter: |
1561 case QEvent::Enter: |
1552 d->viewportEnteredNeeded = true; |
1562 d->viewportEnteredNeeded = true; |
1553 break; |
1563 break; |
1554 case QEvent::Leave: |
1564 case QEvent::Leave: |
|
1565 #ifndef QT_NO_STATUSTIP |
|
1566 if (d->shouldClearStatusTip && d->parent) { |
|
1567 QString empty; |
|
1568 QStatusTipEvent tip(empty); |
|
1569 QApplication::sendEvent(d->parent, &tip); |
|
1570 d->shouldClearStatusTip = false; |
|
1571 } |
|
1572 #endif |
1555 d->enteredIndex = QModelIndex(); |
1573 d->enteredIndex = QModelIndex(); |
1556 break; |
1574 break; |
1557 case QEvent::ToolTip: |
1575 case QEvent::ToolTip: |
1558 case QEvent::QueryWhatsThis: |
1576 case QEvent::QueryWhatsThis: |
1559 case QEvent::WhatsThis: { |
1577 case QEvent::WhatsThis: { |
1603 |
1621 |
1604 d->pressedAlreadySelected = d->selectionModel->isSelected(index); |
1622 d->pressedAlreadySelected = d->selectionModel->isSelected(index); |
1605 d->pressedIndex = index; |
1623 d->pressedIndex = index; |
1606 d->pressedModifiers = event->modifiers(); |
1624 d->pressedModifiers = event->modifiers(); |
1607 QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); |
1625 QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); |
|
1626 d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid(); |
1608 QPoint offset = d->offset(); |
1627 QPoint offset = d->offset(); |
1609 if ((command & QItemSelectionModel::Current) == 0) |
1628 if ((command & QItemSelectionModel::Current) == 0) |
1610 d->pressedPosition = pos + offset; |
1629 d->pressedPosition = pos + offset; |
1611 else if (!indexAt(d->pressedPosition).isValid()) |
1630 else if (!indexAt(d->pressedPosition - offset).isValid()) |
1612 d->pressedPosition = visualRect(currentIndex()).center() + offset; |
1631 d->pressedPosition = visualRect(currentIndex()).center() + offset; |
1613 |
1632 |
1614 if (edit(index, NoEditTriggers, event)) |
1633 if (edit(index, NoEditTriggers, event)) |
1615 return; |
1634 return; |
1616 |
1635 |
1741 EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers); |
1760 EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers); |
1742 bool edited = edit(index, trigger, event); |
1761 bool edited = edit(index, trigger, event); |
1743 |
1762 |
1744 d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; |
1763 d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; |
1745 |
1764 |
1746 //in the case the user presses on no item we might decide to clear the selection |
1765 if (d->selectionModel && d->noSelectionOnMousePress) { |
1747 if (d->selectionModel && !index.isValid()) |
1766 d->noSelectionOnMousePress = false; |
1748 d->selectionModel->select(QModelIndex(), selectionCommand(index, event)); |
1767 d->selectionModel->select(index, selectionCommand(index, event)); |
|
1768 } |
1749 |
1769 |
1750 setState(NoState); |
1770 setState(NoState); |
1751 |
1771 |
1752 if (click) { |
1772 if (click) { |
1753 emit clicked(index); |
1773 emit clicked(index); |
2046 */ |
2066 */ |
2047 void QAbstractItemView::focusInEvent(QFocusEvent *event) |
2067 void QAbstractItemView::focusInEvent(QFocusEvent *event) |
2048 { |
2068 { |
2049 Q_D(QAbstractItemView); |
2069 Q_D(QAbstractItemView); |
2050 QAbstractScrollArea::focusInEvent(event); |
2070 QAbstractScrollArea::focusInEvent(event); |
2051 if (selectionModel() |
2071 |
|
2072 const QItemSelectionModel* model = selectionModel(); |
|
2073 const bool currentIndexValid = currentIndex().isValid(); |
|
2074 |
|
2075 if (model |
2052 && !d->currentIndexSet |
2076 && !d->currentIndexSet |
2053 && !currentIndex().isValid()) { |
2077 && !currentIndexValid) { |
2054 bool autoScroll = d->autoScroll; |
2078 bool autoScroll = d->autoScroll; |
2055 d->autoScroll = false; |
2079 d->autoScroll = false; |
2056 QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index |
2080 QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index |
2057 if (index.isValid() && d->isIndexEnabled(index)) |
2081 if (index.isValid() && d->isIndexEnabled(index)) |
2058 selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); |
2082 selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); |
2059 d->autoScroll = autoScroll; |
2083 d->autoScroll = autoScroll; |
2060 } |
2084 } |
|
2085 |
|
2086 if (model && currentIndexValid) { |
|
2087 if (currentIndex().flags() != Qt::ItemIsEditable) |
|
2088 setAttribute(Qt::WA_InputMethodEnabled, false); |
|
2089 else |
|
2090 setAttribute(Qt::WA_InputMethodEnabled); |
|
2091 } |
|
2092 |
|
2093 if (!currentIndexValid) |
|
2094 setAttribute(Qt::WA_InputMethodEnabled, false); |
|
2095 |
2061 d->viewport->update(); |
2096 d->viewport->update(); |
2062 } |
2097 } |
2063 |
2098 |
2064 /*! |
2099 /*! |
2065 This function is called with the given \a event when the widget |
2100 This function is called with the given \a event when the widget |
2176 if (command != QItemSelectionModel::NoUpdate |
2211 if (command != QItemSelectionModel::NoUpdate |
2177 || style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) { |
2212 || style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) { |
2178 // note that we don't check if the new current index is enabled because moveCursor() makes sure it is |
2213 // note that we don't check if the new current index is enabled because moveCursor() makes sure it is |
2179 if (command & QItemSelectionModel::Current) { |
2214 if (command & QItemSelectionModel::Current) { |
2180 d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate); |
2215 d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate); |
2181 if (!indexAt(d->pressedPosition).isValid()) |
2216 if (!indexAt(d->pressedPosition - d->offset()).isValid()) |
2182 d->pressedPosition = visualRect(oldCurrent).center() + d->offset(); |
2217 d->pressedPosition = visualRect(oldCurrent).center() + d->offset(); |
2183 QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center()); |
2218 QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center()); |
2184 setSelection(rect, command); |
2219 setSelection(rect, command); |
2185 } else { |
2220 } else { |
2186 d->selectionModel->setCurrentIndex(newCurrent, command); |
2221 d->selectionModel->setCurrentIndex(newCurrent, command); |
2533 void QAbstractItemView::verticalScrollbarValueChanged(int value) |
2568 void QAbstractItemView::verticalScrollbarValueChanged(int value) |
2534 { |
2569 { |
2535 Q_D(QAbstractItemView); |
2570 Q_D(QAbstractItemView); |
2536 if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) |
2571 if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) |
2537 d->model->fetchMore(d->root); |
2572 d->model->fetchMore(d->root); |
2538 d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); |
2573 QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); |
|
2574 if (viewport()->rect().contains(posInVp)) |
|
2575 d->checkMouseMove(posInVp); |
2539 } |
2576 } |
2540 |
2577 |
2541 /*! |
2578 /*! |
2542 \internal |
2579 \internal |
2543 */ |
2580 */ |
2544 void QAbstractItemView::horizontalScrollbarValueChanged(int value) |
2581 void QAbstractItemView::horizontalScrollbarValueChanged(int value) |
2545 { |
2582 { |
2546 Q_D(QAbstractItemView); |
2583 Q_D(QAbstractItemView); |
2547 if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) |
2584 if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) |
2548 d->model->fetchMore(d->root); |
2585 d->model->fetchMore(d->root); |
2549 d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); |
2586 QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); |
|
2587 if (viewport()->rect().contains(posInVp)) |
|
2588 d->checkMouseMove(posInVp); |
2550 } |
2589 } |
2551 |
2590 |
2552 /*! |
2591 /*! |
2553 \internal |
2592 \internal |
2554 */ |
2593 */ |
3635 const bool rightButtonPressed = button & Qt::RightButton; |
3678 const bool rightButtonPressed = button & Qt::RightButton; |
3636 const bool shiftKeyPressed = modifiers & Qt::ShiftModifier; |
3679 const bool shiftKeyPressed = modifiers & Qt::ShiftModifier; |
3637 const bool controlKeyPressed = modifiers & Qt::ControlModifier; |
3680 const bool controlKeyPressed = modifiers & Qt::ControlModifier; |
3638 if (((index == pressedIndex && selectionModel->isSelected(index)) |
3681 if (((index == pressedIndex && selectionModel->isSelected(index)) |
3639 || !index.isValid()) && state != QAbstractItemView::DragSelectingState |
3682 || !index.isValid()) && state != QAbstractItemView::DragSelectingState |
3640 && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed) |
3683 && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid())) |
3641 return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags(); |
3684 return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags(); |
3642 return QItemSelectionModel::NoUpdate; |
3685 return QItemSelectionModel::NoUpdate; |
3643 } |
3686 } |
3644 case QEvent::KeyPress: { |
3687 case QEvent::KeyPress: { |
3645 // NoUpdate on Key movement and Ctrl |
3688 // NoUpdate on Key movement and Ctrl |