353 Q_Q(QQuickSearchField);
355 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
356 if (!button || !button->isHovered() || !button->isEnabled()
357 || QQuickAbstractButtonPrivate::get(button)->touchId != -1)
364#if QT_CONFIG(quick_itemview)
365 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
366 itemView->positionViewAtIndex(index, QQuickItemView::Contain);
374 Q_Q(QQuickSearchField);
375 QQuickItem *item = qobject_cast<QQuickItem *>(object);
376 if (item && !item->parentItem()) {
378 item->setParentItem(popup->contentItem());
380 item->setParentItem(q);
381 QQuickItemPrivate::get(item)->setCulled(
true);
384 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object);
386 button->setFocusPolicy(Qt::NoFocus);
387 connect(button, &QQuickAbstractButton::clicked,
this,
389 connect(button, &QQuickAbstractButton::hoveredChanged,
this,
487 Q_Q(QQuickSearchField);
492 disconnect(
delegateModel, &QQmlInstanceModel::countChanged,
this,
494 disconnect(
delegateModel, &QQmlInstanceModel::createdItem,
this,
499 delegateModel = suggestionModel.value<QQmlInstanceModel *>();
501 if (!delegateModel && suggestionModel.isValid()) {
502 QQmlDelegateModel *dataModel =
new QQmlDelegateModel(qmlContext(q), q);
503 dataModel->setModel(suggestionModel);
505 if (q->isComponentComplete())
506 dataModel->componentComplete();
513 connect(
delegateModel, &QQmlInstanceModel::countChanged,
this,
515 connect(
delegateModel, &QQmlInstanceModel::createdItem,
this,
519 emit q->delegateModelChanged();
702QQuickSearchField::QQuickSearchField(QQuickItem *parent)
703 : QQuickControl(*(
new QQuickSearchFieldPrivate), parent)
705 Q_D(QQuickSearchField);
706 d->searchIndicator =
new QQuickIndicatorButton(
this);
707 d->clearIndicator =
new QQuickIndicatorButton(
this);
709 setFocusPolicy(Qt::StrongFocus);
710 setFlag(QQuickItem::ItemIsFocusScope);
711 setAcceptedMouseButtons(Qt::LeftButton);
713 setCursor(Qt::ArrowCursor);
719QQuickSearchField::~QQuickSearchField()
721 Q_D(QQuickSearchField);
722 d->removeImplicitSizeListener(d->searchIndicator->indicator());
723 d->removeImplicitSizeListener(d->clearIndicator->indicator());
726 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
727 &QQuickSearchFieldPrivate::popupVisibleChanged);
728 d->hideOldPopup(d->popup);
758void QQuickSearchField::setSuggestionModel(
const QVariant &model)
760 Q_D(QQuickSearchField);
762 QVariant suggestionModel = model;
763 if (suggestionModel.userType() == qMetaTypeId<QJSValue>())
764 suggestionModel = get<QJSValue>(std::move(suggestionModel)).toVariant();
766 if (d->suggestionModel == suggestionModel)
769 d->suggestionModel = suggestionModel;
770 d->createDelegateModel();
771 emit suggestionCountChanged();
772 emit suggestionModelChanged();
990void QQuickSearchField::setPopup(QQuickPopup *popup)
992 Q_D(QQuickSearchField);
993 if (d->popup == popup)
996 if (!d->popup.isExecuting())
1000 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::destroyed, d,
1001 &QQuickSearchFieldPrivate::popupDestroyed);
1002 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
1003 &QQuickSearchFieldPrivate::popupVisibleChanged);
1004 QQuickSearchFieldPrivate::hideOldPopup(d->popup);
1008 QQuickPopupPrivate::get(popup)->allowVerticalFlip =
true;
1009 popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
1010 QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d,
1011 &QQuickSearchFieldPrivate::popupVisibleChanged);
1014 QObjectPrivate::connect(popup, &QQuickPopup::destroyed, d,
1015 &QQuickSearchFieldPrivate::popupDestroyed);
1017#if QT_CONFIG(quick_itemview)
1018 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
1019 itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);
1024 if (!d->popup.isExecuting())
1025 emit popupChanged();
1070bool QQuickSearchField::eventFilter(QObject *object, QEvent *event)
1072 Q_D(QQuickSearchField);
1074 switch (event->type()) {
1075 case QEvent::MouseButtonRelease: {
1076 QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem);
1077 if (input->hasFocus()) {
1078 if (!d->text.isEmpty() && !d->isPopupVisible() && (d->delegateModel && d->delegateModel->count() > 0))
1083 case QEvent::FocusOut: {
1084 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1085 const bool usingPopupWindows =
1086 d->popup ? QQuickPopupPrivate::get(d->popup)->usePopupWindow() :
false;
1087 if (qGuiApp->focusObject() !=
this && !(hasActiveFocus && !usingPopupWindows))
1088 d->hidePopup(
false);
1094 return QQuickControl::eventFilter(object, event);
1097void QQuickSearchField::focusInEvent(QFocusEvent *event)
1099 Q_D(QQuickSearchField);
1100 QQuickControl::focusInEvent(event);
1102 if ((event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason
1103 || event->reason() == Qt::ShortcutFocusReason)
1105 d->contentItem->forceActiveFocus(event->reason());
1108void QQuickSearchField::focusOutEvent(QFocusEvent *event)
1110 Q_D(QQuickSearchField);
1111 QQuickControl::focusOutEvent(event);
1113 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1114 const bool usingPopupWindows = d->popup && QQuickPopupPrivate::get(d->popup)->usePopupWindow();
1116 if (qGuiApp->focusObject() != d->contentItem && !(hasActiveFocus && !usingPopupWindows))
1117 d->hidePopup(
false);
1120void QQuickSearchField::hoverEnterEvent(QHoverEvent *event)
1122 Q_D(QQuickSearchField);
1123 QQuickControl::hoverEnterEvent(event);
1124 QQuickItem *si = d->searchIndicator->indicator();
1125 QQuickItem *ci = d->clearIndicator->indicator();
1126 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1127 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1131void QQuickSearchField::hoverMoveEvent(QHoverEvent *event)
1133 Q_D(QQuickSearchField);
1134 QQuickControl::hoverMoveEvent(event);
1135 QQuickItem *si = d->searchIndicator->indicator();
1136 QQuickItem *ci = d->clearIndicator->indicator();
1137 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1138 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1151void QQuickSearchField::keyPressEvent(QKeyEvent *event)
1153 Q_D(QQuickSearchField);
1155 const auto key = event->key();
1157 if (!d->suggestionModel.isNull() && !d->text.isEmpty()) {
1159 case Qt::Key_Escape:
1161 if (d->isPopupVisible()) {
1162 d->hidePopup(
false);
1168 case Qt::Key_Return:
1170 if (d->isPopupVisible())
1173 emit searchTriggered();
1177 d->decreaseCurrentIndex();
1181 d->increaseCurrentIndex();
1185 if (d->isPopupVisible())
1186 d->setHighlightedIndex(0, Highlight);
1190 if (d->isPopupVisible())
1191 d->setHighlightedIndex(suggestionCount() - 1, Highlight);
1195 QQuickControl::keyPressEvent(event);
1201void QQuickSearchField::classBegin()
1203 Q_D(QQuickSearchField);
1204 QQuickControl::classBegin();
1206 QQmlContext *context = qmlContext(
this);
1208 QQmlEngine::setContextForObject(d->searchIndicator, context);
1209 QQmlEngine::setContextForObject(d->clearIndicator, context);
1213void QQuickSearchField::componentComplete()
1215 Q_D(QQuickSearchField);
1216 QQuickIndicatorButtonPrivate::get(d->searchIndicator)->executeIndicator(
true);
1217 QQuickIndicatorButtonPrivate::get(d->clearIndicator)->executeIndicator(
true);
1218 QQuickControl::componentComplete();
1221 d->executePopup(
true);
1223 if (d->delegateModel && d->ownModel)
1224 static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();
1227void QQuickSearchField::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
1229 Q_D(QQuickSearchField);
1231 oldItem->removeEventFilter(
this);
1232 if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
1233 QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d,
1234 &QQuickSearchFieldPrivate::updateText);
1239 newItem->installEventFilter(
this);
1240 if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
1241 QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d,
1242 &QQuickSearchFieldPrivate::updateText);
1244 #if QT_CONFIG(cursor)
1245 newItem->setCursor(Qt::IBeamCursor);
1250void QQuickSearchField::itemChange(ItemChange change,
const ItemChangeData &data)
1252 Q_D(QQuickSearchField);
1253 QQuickControl::itemChange(change, data);
1254 if (change == ItemVisibleHasChanged && !data.boolValue) {
1255 d->hidePopup(
false);
1256 d->setCurrentItemAtIndex(-1, NoActivate);