[CardSearch] Add card completion popups to chats and search fields (#7089)

* Add card completion popups to chats and search fields

Completes @mention and [[card]] in chat, and card names in the deck
editor, EDHREC, Archidekt, card art rules, and user card settings
searches. Pops up a styled list with mana pips and a card image
preview, flipping the list order when the popup opens above the text
field.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-08-11 18:50:30 +02:00 committed by GitHub
parent a0e76607b5
commit 83fd65b34b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1526 additions and 290 deletions

View file

@ -0,0 +1,52 @@
#include "completer_utils.h"
#include "card_completer_styler.h"
#include <QCompleter>
#include <QLineEdit>
#include <QObject>
#include <QRegularExpression>
#include <QStringListModel>
#include <libcockatrice/models/database/card/card_completer_proxy_model.h>
#include <libcockatrice/models/database/card/card_search_model.h>
#include <libcockatrice/models/database/card_database_display_model.h>
CardCompleterSetup createCardCompleter(CardDatabaseDisplayModel *displayModel, QObject *parent, int maxVisibleItems)
{
auto *searchModel = new CardSearchModel(displayModel, parent);
auto *proxyModel = new CardCompleterProxyModel(parent);
proxyModel->setSourceModel(searchModel);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
auto *completer = new QCompleter(proxyModel, parent);
completer->setCompletionRole(Qt::DisplayRole);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
completer->setMaxVisibleItems(maxVisibleItems);
CardCompleterStyler::apply(completer);
return {searchModel, proxyModel, completer};
}
void connectCardCompleterSearch(QLineEdit *edit, const CardCompleterSetup &setup)
{
QObject::connect(edit, &QLineEdit::textEdited, setup.searchModel, &CardSearchModel::updateSearchResults);
QObject::connect(edit, &QLineEdit::textEdited, setup.completer, [setup](const QString &text) {
setup.proxyModel->setFilterRegularExpression(
QRegularExpression(QRegularExpression::escape(text), QRegularExpression::CaseInsensitiveOption));
if (!text.isEmpty()) {
setup.completer->complete();
}
});
}
QCompleter *createMentionCompleter(QStringListModel *model, QObject *parent)
{
auto *completer = new QCompleter(model, parent);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setMaxVisibleItems(5);
completer->setFilterMode(Qt::MatchStartsWith);
return completer;
}