312 Q_Q(QQuickSearchField);
314 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
315 if (!button || !button->isHovered() || !button->isEnabled()
316 || QQuickAbstractButtonPrivate::get(button)->touchId != -1)
319 int index = delegateModel->indexOf(button,
nullptr);
323#if QT_CONFIG(quick_itemview)
324 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
325 itemView->positionViewAtIndex(index, QQuickItemView::Contain);
333 Q_Q(QQuickSearchField);
334 QQuickItem *item = qobject_cast<QQuickItem *>(object);
335 if (item && !item->parentItem()) {
337 item->setParentItem(popup->contentItem());
339 item->setParentItem(q);
340 QQuickItemPrivate::get(item)->setCulled(
true);
343 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object);
345 button->setFocusPolicy(Qt::NoFocus);
346 connect(button, &QQuickAbstractButton::clicked,
this,
347 &QQuickSearchFieldPrivate::itemClicked);
348 connect(button, &QQuickAbstractButton::hoveredChanged,
this,
349 &QQuickSearchFieldPrivate::itemHovered);
446 Q_Q(QQuickSearchField);
451 disconnect(delegateModel, &QQmlInstanceModel::countChanged,
this,
452 &QQuickSearchFieldPrivate::suggestionCountChanged);
453 disconnect(delegateModel, &QQmlInstanceModel::createdItem,
this,
454 &QQuickSearchFieldPrivate::createdItem);
458 delegateModel = suggestionModel.value<QQmlInstanceModel *>();
460 if (!delegateModel && suggestionModel.isValid()) {
461 QQmlDelegateModel *dataModel =
new QQmlDelegateModel(qmlContext(q), q);
462 dataModel->setModel(suggestionModel);
464 if (q->isComponentComplete())
465 dataModel->componentComplete();
472 connect(delegateModel, &QQmlInstanceModel::countChanged,
this,
473 &QQuickSearchFieldPrivate::suggestionCountChanged);
474 connect(delegateModel, &QQmlInstanceModel::createdItem,
this,
475 &QQuickSearchFieldPrivate::createdItem);
478 emit q->delegateModelChanged();
661QQuickSearchField::QQuickSearchField(QQuickItem *parent)
662 : QQuickControl(*(
new QQuickSearchFieldPrivate), parent)
664 Q_D(QQuickSearchField);
665 d->searchIndicator =
new QQuickIndicatorButton(
this);
666 d->clearIndicator =
new QQuickIndicatorButton(
this);
668 setFocusPolicy(Qt::StrongFocus);
669 setFlag(QQuickItem::ItemIsFocusScope);
670 setAcceptedMouseButtons(Qt::LeftButton);
672 setCursor(Qt::ArrowCursor);
678QQuickSearchField::~QQuickSearchField()
680 Q_D(QQuickSearchField);
681 d->removeImplicitSizeListener(d->searchIndicator->indicator());
682 d->removeImplicitSizeListener(d->clearIndicator->indicator());
685 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
686 &QQuickSearchFieldPrivate::popupVisibleChanged);
687 d->hideOldPopup(d->popup);
717void QQuickSearchField::setSuggestionModel(
const QVariant &model)
719 Q_D(QQuickSearchField);
721 QVariant suggestionModel = model;
722 if (suggestionModel.userType() == qMetaTypeId<QJSValue>())
723 suggestionModel = get<QJSValue>(std::move(suggestionModel)).toVariant();
725 if (d->suggestionModel == suggestionModel)
728 d->suggestionModel = suggestionModel;
729 d->createDelegateModel();
730 emit suggestionCountChanged();
731 emit suggestionModelChanged();
926void QQuickSearchField::setPopup(QQuickPopup *popup)
928 Q_D(QQuickSearchField);
929 if (d->popup == popup)
932 if (!d->popup.isExecuting())
936 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::destroyed, d,
937 &QQuickSearchFieldPrivate::popupDestroyed);
938 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
939 &QQuickSearchFieldPrivate::popupVisibleChanged);
940 QQuickSearchFieldPrivate::hideOldPopup(d->popup);
944 QQuickPopupPrivate::get(popup)->allowVerticalFlip =
true;
945 popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
946 QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d,
947 &QQuickSearchFieldPrivate::popupVisibleChanged);
950 QObjectPrivate::connect(popup, &QQuickPopup::destroyed, d,
951 &QQuickSearchFieldPrivate::popupDestroyed);
953#if QT_CONFIG(quick_itemview)
954 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
955 itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);
960 if (!d->popup.isExecuting())
1006bool QQuickSearchField::eventFilter(QObject *object, QEvent *event)
1008 Q_D(QQuickSearchField);
1010 switch (event->type()) {
1011 case QEvent::MouseButtonRelease: {
1012 QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem);
1013 if (input->hasFocus()) {
1014 if (!d->text.isEmpty() && !d->isPopupVisible() && (d->delegateModel && d->delegateModel->count() > 0))
1019 case QEvent::FocusOut: {
1020 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1021 const bool usingPopupWindows =
1022 d->popup ? QQuickPopupPrivate::get(d->popup)->usePopupWindow() :
false;
1023 if (qGuiApp->focusObject() !=
this && !(hasActiveFocus && !usingPopupWindows))
1024 d->hidePopup(
false);
1030 return QQuickControl::eventFilter(object, event);
1033void QQuickSearchField::focusInEvent(QFocusEvent *event)
1035 Q_D(QQuickSearchField);
1036 QQuickControl::focusInEvent(event);
1038 if ((event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason
1039 || event->reason() == Qt::ShortcutFocusReason)
1041 d->contentItem->forceActiveFocus(event->reason());
1044void QQuickSearchField::focusOutEvent(QFocusEvent *event)
1046 Q_D(QQuickSearchField);
1047 QQuickControl::focusOutEvent(event);
1049 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1050 const bool usingPopupWindows = d->popup && QQuickPopupPrivate::get(d->popup)->usePopupWindow();
1052 if (qGuiApp->focusObject() != d->contentItem && !(hasActiveFocus && !usingPopupWindows))
1053 d->hidePopup(
false);
1056void QQuickSearchField::hoverEnterEvent(QHoverEvent *event)
1058 Q_D(QQuickSearchField);
1059 QQuickControl::hoverEnterEvent(event);
1060 QQuickItem *si = d->searchIndicator->indicator();
1061 QQuickItem *ci = d->clearIndicator->indicator();
1062 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1063 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1067void QQuickSearchField::hoverMoveEvent(QHoverEvent *event)
1069 Q_D(QQuickSearchField);
1070 QQuickControl::hoverMoveEvent(event);
1071 QQuickItem *si = d->searchIndicator->indicator();
1072 QQuickItem *ci = d->clearIndicator->indicator();
1073 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1074 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1087void QQuickSearchField::keyPressEvent(QKeyEvent *event)
1089 Q_D(QQuickSearchField);
1091 const auto key = event->key();
1093 if (!d->suggestionModel.isNull() && !d->text.isEmpty()) {
1095 case Qt::Key_Escape:
1097 if (d->isPopupVisible()) {
1098 d->hidePopup(
false);
1104 case Qt::Key_Return:
1106 if (d->isPopupVisible())
1109 emit searchTriggered();
1113 d->decreaseCurrentIndex();
1117 d->increaseCurrentIndex();
1121 if (d->isPopupVisible())
1122 d->setHighlightedIndex(0, Highlight);
1126 if (d->isPopupVisible())
1127 d->setHighlightedIndex(suggestionCount() - 1, Highlight);
1131 QQuickControl::keyPressEvent(event);
1137void QQuickSearchField::classBegin()
1139 Q_D(QQuickSearchField);
1140 QQuickControl::classBegin();
1142 QQmlContext *context = qmlContext(
this);
1144 QQmlEngine::setContextForObject(d->searchIndicator, context);
1145 QQmlEngine::setContextForObject(d->clearIndicator, context);
1149void QQuickSearchField::componentComplete()
1151 Q_D(QQuickSearchField);
1152 QQuickIndicatorButtonPrivate::get(d->searchIndicator)->executeIndicator(
true);
1153 QQuickIndicatorButtonPrivate::get(d->clearIndicator)->executeIndicator(
true);
1154 QQuickControl::componentComplete();
1157 d->executePopup(
true);
1159 if (d->delegateModel && d->ownModel)
1160 static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();
1163void QQuickSearchField::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
1165 Q_D(QQuickSearchField);
1167 oldItem->removeEventFilter(
this);
1168 if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
1169 QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d,
1170 &QQuickSearchFieldPrivate::updateText);
1175 newItem->installEventFilter(
this);
1176 if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
1177 QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d,
1178 &QQuickSearchFieldPrivate::updateText);
1180 #if QT_CONFIG(cursor)
1181 newItem->setCursor(Qt::IBeamCursor);
1186void QQuickSearchField::itemChange(ItemChange change,
const ItemChangeData &data)
1188 Q_D(QQuickSearchField);
1189 QQuickControl::itemChange(change, data);
1190 if (change == ItemVisibleHasChanged && !data.boolValue) {
1191 d->hidePopup(
false);
1192 d->setCurrentItemAtIndex(-1, NoActivate);