diff --git a/UI/Qt/LocationEdit.cpp b/UI/Qt/LocationEdit.cpp index 136ffe7e61..7b77360d10 100644 --- a/UI/Qt/LocationEdit.cpp +++ b/UI/Qt/LocationEdit.cpp @@ -256,12 +256,20 @@ LocationEdit::LocationEdit(QWidget* parent) if (!hasFocus()) return; - auto query = current_query(); + auto query = autocomplete_query(); int selected_row = -1; - if (!m_autocomplete_query_without_inline.isNull() && text() == m_autocomplete_query_without_inline) + if (!m_autocomplete_preview_query.isNull()) { + for (size_t i = 0; i < suggestions.size(); ++i) { + if (qstring_from_ak_string(suggestions[i].text) == text()) { + selected_row = static_cast(i); + break; + } + } + } else if (!m_autocomplete_query_without_inline.isNull() && text() == m_autocomplete_query_without_inline) { selected_row = 0; - else + } else { selected_row = apply_inline_autocomplete(suggestions); + } // Do not update the popup while results are still changing. // Intermediate updates are triggered on every keystroke and would @@ -286,22 +294,29 @@ LocationEdit::LocationEdit(QWidget* parent) }; connect(m_autocomplete, &Autocomplete::suggestion_activated, this, [this](QString const& text) { - m_is_applying_inline_autocomplete = true; - setText(text); - m_is_applying_inline_autocomplete = false; + m_autocomplete_preview_query = QString(); + m_current_inline_autocomplete_suggestion.clear(); + set_text_without_inline_autocomplete(text); m_autocomplete->close(); emit returnPressed(); }); connect(m_autocomplete, &Autocomplete::suggestion_highlighted, this, [this](QString const& text) { - auto query = current_query(); - apply_inline_autocomplete_suggestion_text(text, query); + m_has_highlighted_autocomplete_suggestion = true; + auto query = autocomplete_query(); + apply_inline_autocomplete_suggestion_text(text, query, true); }); connect(m_autocomplete, &Autocomplete::did_close, this, [this] { + auto should_preserve_inline_autocomplete = m_should_preserve_inline_autocomplete_on_close; + auto should_restore_query = should_restore_autocomplete_query(); + m_should_preserve_inline_autocomplete_on_close = false; + m_has_highlighted_autocomplete_suggestion = false; m_current_inline_autocomplete_suggestion.clear(); + if (should_preserve_inline_autocomplete) + return; if (!m_autocomplete_query_without_inline.isNull()) { - if (hasSelectedText()) + if (should_restore_query) restore_query(); m_autocomplete_query_without_inline = QString(); return; @@ -330,6 +345,8 @@ LocationEdit::LocationEdit(QWidget* parent) return; m_autocomplete_query_without_inline = QString(); + m_autocomplete_preview_query = QString(); + m_has_highlighted_autocomplete_suggestion = false; if (m_url_is_hidden) m_has_user_edited_hidden_url = true; @@ -460,12 +477,10 @@ void LocationEdit::focusOutEvent(QFocusEvent* event) animate_focus_glow(0); - if (hasSelectedText()) { + if (should_restore_autocomplete_query()) { auto query = current_query(); - m_is_applying_inline_autocomplete = true; - setText(query); + set_text_without_inline_autocomplete(query); setCursorPosition(query.length()); - m_is_applying_inline_autocomplete = false; } auto should_cancel_pending_query = !m_should_skip_autocomplete_cancel_on_focus_out; @@ -512,8 +527,17 @@ void LocationEdit::animate_focus_glow(int target_alpha) void LocationEdit::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Escape) { - if (m_autocomplete->close()) + if (m_autocomplete->is_visible() + && m_autocomplete_query_without_inline.isNull() + && m_autocomplete_preview_query.isNull() + && !m_has_highlighted_autocomplete_suggestion + && hasSelectedText()) { + m_should_preserve_inline_autocomplete_on_close = true; + } + if (m_autocomplete->close()) { + m_autocomplete->cancel_pending_query(); return; + } reset_autocomplete_state(); if (m_url.has_value()) setText(serialized_url()); @@ -532,7 +556,7 @@ void LocationEdit::keyPressEvent(QKeyEvent* event) } if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && m_autocomplete->is_visible()) { - auto query = current_query(); + auto query = autocomplete_query(); if (m_autocomplete_popup_query == query) { activate_selected_autocomplete_suggestion(); event->accept(); @@ -952,6 +976,9 @@ QString LocationEdit::display_url() const QString LocationEdit::current_query() const { + if (!m_autocomplete_preview_query.isNull()) + return m_autocomplete_preview_query; + if (!hasSelectedText()) return text(); int start = selectionStart(); @@ -1070,7 +1097,7 @@ int LocationEdit::apply_inline_autocomplete(Vectorselected_suggestion(); selected.has_value()) { - m_is_applying_inline_autocomplete = true; - setText(qstring_from_ak_string(*selected)); - m_is_applying_inline_autocomplete = false; + m_autocomplete_preview_query = QString(); + m_current_inline_autocomplete_suggestion.clear(); + set_text_without_inline_autocomplete(qstring_from_ak_string(*selected)); } m_autocomplete->close(); emit returnPressed(); @@ -1128,17 +1174,38 @@ void LocationEdit::restore_query() if (text() == query && !hasSelectedText()) return; - m_is_applying_inline_autocomplete = true; - setText(query); + set_text_without_inline_autocomplete(query); setCursorPosition(query.length()); + m_autocomplete_preview_query = QString(); +} + +void LocationEdit::set_text_without_inline_autocomplete(QString const& text) +{ + m_is_applying_inline_autocomplete = true; + setText(text); m_is_applying_inline_autocomplete = false; } +bool LocationEdit::should_restore_autocomplete_query() const +{ + return !m_autocomplete_preview_query.isNull() || !m_current_inline_autocomplete_suggestion.isEmpty(); +} + +QString LocationEdit::autocomplete_query() const +{ + if (!m_autocomplete_query_without_inline.isNull()) + return m_autocomplete_query_without_inline; + return current_query(); +} + void LocationEdit::reset_autocomplete_state() { m_autocomplete_popup_query = QString(); m_autocomplete_query_without_inline = QString(); + m_autocomplete_preview_query = QString(); m_current_inline_autocomplete_suggestion.clear(); + m_has_highlighted_autocomplete_suggestion = false; + m_should_preserve_inline_autocomplete_on_close = false; m_should_skip_autocomplete_cancel_on_focus_out = false; m_pending_autocomplete_activation_query = QString(); m_suppressed_inline_autocomplete_query = QString(); diff --git a/UI/Qt/LocationEdit.h b/UI/Qt/LocationEdit.h index 78590e1469..5356f2bd4f 100644 --- a/UI/Qt/LocationEdit.h +++ b/UI/Qt/LocationEdit.h @@ -73,10 +73,14 @@ private: QString display_url() const; int apply_inline_autocomplete(Vector const&); - bool apply_inline_autocomplete_suggestion_text(QString const& suggestion_text, QString const& query); + bool apply_inline_autocomplete_suggestion_text(QString const& suggestion_text, QString const& query, bool allow_preview = false); void apply_inline_autocomplete_text(QString const& inline_text, QString const& query); + void apply_autocomplete_preview_text(QString const& suggestion_text, QString const& query); void activate_selected_autocomplete_suggestion(); void restore_query(); + void set_text_without_inline_autocomplete(QString const& text); + bool should_restore_autocomplete_query() const; + QString autocomplete_query() const; QString current_query() const; void reset_autocomplete_state(); @@ -99,9 +103,12 @@ private: bool m_is_applying_inline_autocomplete { false }; bool m_should_suppress_inline_autocomplete_on_next_change { false }; + bool m_has_highlighted_autocomplete_suggestion { false }; + bool m_should_preserve_inline_autocomplete_on_close { false }; bool m_should_skip_autocomplete_cancel_on_focus_out { false }; QString m_autocomplete_popup_query; QString m_autocomplete_query_without_inline; + QString m_autocomplete_preview_query; QString m_current_inline_autocomplete_suggestion; QString m_pending_autocomplete_activation_query; QString m_suppressed_inline_autocomplete_query;