370 Q_Q(QQuickSearchField);
372 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
373 if (!button || !button->isHovered() || !button->isEnabled()
374 || QQuickAbstractButtonPrivate::get(button)->touchId != -1)
381#if QT_CONFIG(quick_itemview)
382 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
383 itemView->positionViewAtIndex(index, QQuickItemView::Contain);
391 Q_Q(QQuickSearchField);
392 QQuickItem *item = qobject_cast<QQuickItem *>(object);
393 if (item && !item->parentItem()) {
395 item->setParentItem(popup->contentItem());
397 item->setParentItem(q);
398 QQuickItemPrivate::get(item)->setCulled(
true);
401 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object);
403 button->setFocusPolicy(Qt::NoFocus);
404 connect(button, &QQuickAbstractButton::clicked,
this,
406 connect(button, &QQuickAbstractButton::hoveredChanged,
this,
504 Q_Q(QQuickSearchField);
509 disconnect(
delegateModel, &QQmlInstanceModel::countChanged,
this,
511 disconnect(
delegateModel, &QQmlInstanceModel::createdItem,
this,
516 delegateModel = suggestionModel.value<QQmlInstanceModel *>();
518 if (!delegateModel && suggestionModel.isValid()) {
519 QQmlDelegateModel *dataModel =
new QQmlDelegateModel(qmlContext(q), q);
520 dataModel->setModel(suggestionModel);
522 if (q->isComponentComplete())
523 dataModel->componentComplete();
530 connect(
delegateModel, &QQmlInstanceModel::countChanged,
this,
532 connect(
delegateModel, &QQmlInstanceModel::createdItem,
this,
536 emit q->delegateModelChanged();
719QQuickSearchField::QQuickSearchField(QQuickItem *parent)
720 : QQuickControl(*(
new QQuickSearchFieldPrivate), parent)
722 Q_D(QQuickSearchField);
723 d->searchIndicator =
new QQuickIndicatorButton(
this);
724 d->clearIndicator =
new QQuickIndicatorButton(
this);
726 setFocusPolicy(Qt::StrongFocus);
727 setFlag(QQuickItem::ItemIsFocusScope);
728 setAcceptedMouseButtons(Qt::LeftButton);
730 setCursor(Qt::ArrowCursor);
736QQuickSearchField::~QQuickSearchField()
738 Q_D(QQuickSearchField);
739 d->removeImplicitSizeListener(d->searchIndicator->indicator());
740 d->removeImplicitSizeListener(d->clearIndicator->indicator());
743 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
744 &QQuickSearchFieldPrivate::popupVisibleChanged);
745 d->hideOldPopup(d->popup);
775void QQuickSearchField::setSuggestionModel(
const QVariant &model)
777 Q_D(QQuickSearchField);
779 QVariant suggestionModel;
780 if (QJSValue *value = get_if<QJSValue>(&suggestionModel))
781 suggestionModel = value->toVariant();
783 suggestionModel = model;
785 if (d->suggestionModel == suggestionModel)
788 d->suggestionModel = suggestionModel;
789 d->createDelegateModel();
790 emit suggestionCountChanged();
791 emit suggestionModelChanged();
1009void QQuickSearchField::setPopup(QQuickPopup *popup)
1011 Q_D(QQuickSearchField);
1012 if (d->popup == popup)
1015 if (!d->popup.isExecuting())
1019 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::destroyed, d,
1020 &QQuickSearchFieldPrivate::popupDestroyed);
1021 QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d,
1022 &QQuickSearchFieldPrivate::popupVisibleChanged);
1023 QQuickSearchFieldPrivate::hideOldPopup(d->popup);
1027 QQuickPopupPrivate::get(popup)->allowVerticalFlip =
true;
1028 popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
1029 QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d,
1030 &QQuickSearchFieldPrivate::popupVisibleChanged);
1033 QObjectPrivate::connect(popup, &QQuickPopup::destroyed, d,
1034 &QQuickSearchFieldPrivate::popupDestroyed);
1036#if QT_CONFIG(quick_itemview)
1037 if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
1038 itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);
1043 if (!d->popup.isExecuting())
1044 emit popupChanged();
1112bool QQuickSearchField::eventFilter(QObject *object, QEvent *event)
1114 Q_D(QQuickSearchField);
1116 switch (event->type()) {
1117 case QEvent::MouseButtonRelease: {
1118 QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem);
1119 if (input->hasFocus()) {
1120 if (!d->text.isEmpty() && !d->isPopupVisible() && (d->delegateModel && d->delegateModel->count() > 0))
1125 case QEvent::FocusOut: {
1126 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1127 const bool usingPopupWindows =
1128 d->popup ? QQuickPopupPrivate::get(d->popup)->usePopupWindow() :
false;
1129 if (qGuiApp->focusObject() !=
this && !(hasActiveFocus && !usingPopupWindows))
1130 d->hidePopup(
false);
1136 return QQuickControl::eventFilter(object, event);
1139void QQuickSearchField::focusInEvent(QFocusEvent *event)
1141 Q_D(QQuickSearchField);
1142 QQuickControl::focusInEvent(event);
1144 if (!d->contentItem)
1147 const auto reason = event->reason();
1149 case Qt::TabFocusReason:
1150 case Qt::BacktabFocusReason:
1151 case Qt::ShortcutFocusReason:
1152 case Qt::OtherFocusReason:
1153 if (reason != Qt::OtherFocusReason || !d->isPopupVisible())
1154 d->contentItem->forceActiveFocus(reason);
1161void QQuickSearchField::focusOutEvent(QFocusEvent *event)
1163 Q_D(QQuickSearchField);
1164 QQuickControl::focusOutEvent(event);
1166 const bool hasActiveFocus = d->popup && d->popup->hasActiveFocus();
1167 const bool usingPopupWindows = d->popup && QQuickPopupPrivate::get(d->popup)->usePopupWindow();
1169 if (qGuiApp->focusObject() != d->contentItem && !(hasActiveFocus && !usingPopupWindows))
1170 d->hidePopup(
false);
1173void QQuickSearchField::hoverEnterEvent(QHoverEvent *event)
1175 Q_D(QQuickSearchField);
1176 QQuickControl::hoverEnterEvent(event);
1177 QQuickItem *si = d->searchIndicator->indicator();
1178 QQuickItem *ci = d->clearIndicator->indicator();
1179 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1180 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1184void QQuickSearchField::hoverMoveEvent(QHoverEvent *event)
1186 Q_D(QQuickSearchField);
1187 QQuickControl::hoverMoveEvent(event);
1188 QQuickItem *si = d->searchIndicator->indicator();
1189 QQuickItem *ci = d->clearIndicator->indicator();
1190 d->searchIndicator->setHovered(si && si->isEnabled() && si->contains(mapToItem(si, event->position())));
1191 d->clearIndicator->setHovered(ci && ci->isEnabled() && ci->contains(mapToItem(ci, event->position())));
1204void QQuickSearchField::keyPressEvent(QKeyEvent *event)
1206 Q_D(QQuickSearchField);
1208 const auto key = event->key();
1210 if (!d->suggestionModel.isNull() && !d->text.isEmpty()) {
1212 case Qt::Key_Escape:
1214 if (d->isPopupVisible()) {
1215 d->hidePopup(
false);
1221 case Qt::Key_Return:
1223 if (d->isPopupVisible())
1226 emit searchTriggered();
1230 d->decreaseCurrentIndex();
1234 d->increaseCurrentIndex();
1238 if (d->isPopupVisible())
1239 d->setHighlightedIndex(0, Highlight);
1243 if (d->isPopupVisible())
1244 d->setHighlightedIndex(suggestionCount() - 1, Highlight);
1248 QQuickControl::keyPressEvent(event);
1254void QQuickSearchField::classBegin()
1256 Q_D(QQuickSearchField);
1257 QQuickControl::classBegin();
1259 QQmlContext *context = qmlContext(
this);
1261 QQmlEngine::setContextForObject(d->searchIndicator, context);
1262 QQmlEngine::setContextForObject(d->clearIndicator, context);
1266void QQuickSearchField::componentComplete()
1268 Q_D(QQuickSearchField);
1269 QQuickIndicatorButtonPrivate::get(d->searchIndicator)->executeIndicator(
true);
1270 QQuickIndicatorButtonPrivate::get(d->clearIndicator)->executeIndicator(
true);
1271 QQuickControl::componentComplete();
1274 d->executePopup(
true);
1276 if (d->delegateModel && d->ownModel)
1277 static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();
1280void QQuickSearchField::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
1282 Q_D(QQuickSearchField);
1284 oldItem->removeEventFilter(
this);
1285 if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
1286 QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d,
1287 &QQuickSearchFieldPrivate::updateText);
1292 newItem->installEventFilter(
this);
1293 if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
1294 QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d,
1295 &QQuickSearchFieldPrivate::updateText);
1297 #if QT_CONFIG(cursor)
1298 newItem->setCursor(Qt::IBeamCursor);
1303void QQuickSearchField::itemChange(ItemChange change,
const ItemChangeData &data)
1305 Q_D(QQuickSearchField);
1306 QQuickControl::itemChange(change, data);
1307 if (change == ItemVisibleHasChanged && !data.boolValue) {
1308 d->hidePopup(
false);
1309 d->setCurrentItemAtIndex(-1, NoActivate);