mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 00:04:48 -07:00
78 lines
2.2 KiB
C++
78 lines
2.2 KiB
C++
#include "card_search_model.h"
|
|
|
|
#include "../card_database_display_model.h"
|
|
#include "../card_database_model.h"
|
|
|
|
#include <algorithm>
|
|
#include <libcockatrice/utility/levenshtein.h>
|
|
|
|
CardSearchModel::CardSearchModel(CardDatabaseDisplayModel *sourceModel, QObject *parent)
|
|
: QAbstractListModel(parent), sourceModel(sourceModel)
|
|
{
|
|
}
|
|
|
|
int CardSearchModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
Q_UNUSED(parent);
|
|
return searchResults.size();
|
|
}
|
|
|
|
QVariant CardSearchModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid() || index.row() >= searchResults.size()) {
|
|
return QVariant();
|
|
}
|
|
|
|
if (role == Qt::DisplayRole) {
|
|
return searchResults.at(index.row()).card->getName();
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
void CardSearchModel::updateSearchResults(const QString &query)
|
|
{
|
|
beginResetModel();
|
|
searchResults.clear();
|
|
|
|
if (query.isEmpty() || !sourceModel) {
|
|
return;
|
|
}
|
|
|
|
// Set the filter for the display model
|
|
sourceModel->setCardName(query);
|
|
|
|
// Collect matching cards and compute Levenshtein distance
|
|
for (int i = 0; i < sourceModel->rowCount(); ++i) {
|
|
QModelIndex modelIndex = sourceModel->index(i, 0);
|
|
QModelIndex sourceIndex = sourceModel->mapToSource(modelIndex);
|
|
CardDatabaseModel *sourceDbModel = qobject_cast<CardDatabaseModel *>(sourceModel->sourceModel());
|
|
|
|
if (!sourceDbModel || !sourceIndex.isValid()) {
|
|
return;
|
|
}
|
|
|
|
CardInfoPtr card = sourceDbModel->getCard(sourceIndex.row());
|
|
|
|
if (!card) {
|
|
continue;
|
|
}
|
|
|
|
int distance = levenshteinDistance(query.toLower(), card->getName().toLower());
|
|
searchResults.append({card, distance});
|
|
}
|
|
|
|
// Sort by Levenshtein distance (lower distance = better match)
|
|
std::sort(searchResults.begin(), searchResults.end(),
|
|
[](const SearchResult &a, const SearchResult &b) { return a.distance < b.distance; });
|
|
|
|
// Keep only the top 5 results
|
|
if (searchResults.size() > 10) {
|
|
searchResults = searchResults.mid(0, 10);
|
|
}
|
|
|
|
emit dataChanged(index(0, 0), index(rowCount() - 1, 0));
|
|
emit layoutChanged();
|
|
|
|
endResetModel();
|
|
}
|