mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
[Refactor] Decouple DeckFilterString from DeckPreviewWidget (#7104)
* [Refactor] Decouple DeckFilterString from DeckPreviewWidget Took 19 minutes * Use designated initializer Took 24 seconds --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
26fb8622e3
commit
12a5b34e42
3 changed files with 41 additions and 44 deletions
|
|
@ -52,18 +52,14 @@ static void setupParserRules()
|
|||
|
||||
search["Start"] = passthru;
|
||||
search["QueryPartList"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &info) {
|
||||
auto matchesFilter = [&deck, &info](const std::any &query) {
|
||||
return std::any_cast<DeckFilter>(query)(deck, info);
|
||||
};
|
||||
return [=](const DeckSearchData &data) {
|
||||
auto matchesFilter = [&data](const std::any &query) { return std::any_cast<DeckFilter>(query)(data); };
|
||||
return std::all_of(sv.begin(), sv.end(), matchesFilter);
|
||||
};
|
||||
};
|
||||
search["ComplexQueryPart"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &info) {
|
||||
auto matchesFilter = [&deck, &info](const std::any &query) {
|
||||
return std::any_cast<DeckFilter>(query)(deck, info);
|
||||
};
|
||||
return [=](const DeckSearchData &data) {
|
||||
auto matchesFilter = [&data](const std::any &query) { return std::any_cast<DeckFilter>(query)(data); };
|
||||
return std::any_of(sv.begin(), sv.end(), matchesFilter);
|
||||
};
|
||||
};
|
||||
|
|
@ -71,9 +67,7 @@ static void setupParserRules()
|
|||
search["QueryPart"] = passthru;
|
||||
search["NotQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
const auto dependent = std::any_cast<DeckFilter>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &info) -> bool {
|
||||
return !dependent(deck, info);
|
||||
};
|
||||
return [=](const DeckSearchData &data) -> bool { return !dependent(data); };
|
||||
};
|
||||
|
||||
search["String"] = [](const peg::SemanticValues &sv) -> QString {
|
||||
|
|
@ -125,9 +119,9 @@ static void setupParserRules()
|
|||
auto cardFilter = FilterString(std::any_cast<QString>(sv[0]));
|
||||
auto numberMatcher = sv.size() > 1 ? std::any_cast<NumberMatcher>(sv[1]) : [](int count) { return count > 0; };
|
||||
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) -> bool {
|
||||
return [=](const DeckSearchData &data) -> bool {
|
||||
int count = 0;
|
||||
auto cardNodes = deck->deckLoader->getDeck().deckList.getCardNodes();
|
||||
auto cardNodes = data.deck->deckList.getCardNodes();
|
||||
for (auto node : cardNodes) {
|
||||
auto cardInfoPtr = CardDatabaseManager::query()->getCardInfo(node->getName());
|
||||
if (!cardInfoPtr.isNull() && cardFilter.check(cardInfoPtr)) {
|
||||
|
|
@ -146,53 +140,49 @@ static void setupParserRules()
|
|||
|
||||
search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
return deck->deckLoader->getDeck().deckList.getName().contains(name, Qt::CaseInsensitive);
|
||||
return [=](const DeckSearchData &data) {
|
||||
return data.deck->deckList.getName().contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["FileNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
auto filename = QFileInfo(deck->filePath).fileName();
|
||||
return [=](const DeckSearchData &data) {
|
||||
auto filename = QFileInfo(data.filePath).fileName();
|
||||
return filename.contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["PathQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *, const ExtraDeckSearchInfo &info) {
|
||||
return info.relativeFilePath.contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
return [=](const DeckSearchData &data) { return data.relativeFilePath.contains(name, Qt::CaseInsensitive); };
|
||||
};
|
||||
|
||||
search["FormatQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto format = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
auto gameFormat = deck->deckLoader->getDeck().deckList.getGameFormat();
|
||||
return [=](const DeckSearchData &data) {
|
||||
auto gameFormat = data.deck->deckList.getGameFormat();
|
||||
return QString::compare(format, gameFormat, Qt::CaseInsensitive) == 0;
|
||||
};
|
||||
};
|
||||
|
||||
search["CommentQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto value = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
auto comments = deck->deckLoader->getDeck().deckList.getComments();
|
||||
return [=](const DeckSearchData &data) {
|
||||
auto comments = data.deck->deckList.getComments();
|
||||
return comments.contains(value, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
return deck->getDisplayName().contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
return [=](const DeckSearchData &data) { return data.displayName.contains(name, Qt::CaseInsensitive); };
|
||||
};
|
||||
}
|
||||
|
||||
DeckFilterString::DeckFilterString()
|
||||
{
|
||||
filter = [](const DeckPreviewWidget *, const ExtraDeckSearchInfo &) { return false; };
|
||||
filter = [](const DeckSearchData &) { return false; };
|
||||
_error = "Not initialized";
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +195,7 @@ DeckFilterString::DeckFilterString(const QString &expr)
|
|||
_error = QString();
|
||||
|
||||
if (ba.isEmpty()) {
|
||||
filter = [](const DeckPreviewWidget *, const ExtraDeckSearchInfo &) { return true; };
|
||||
filter = [](const DeckSearchData &) { return true; };
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -215,6 +205,6 @@ DeckFilterString::DeckFilterString(const QString &expr)
|
|||
|
||||
if (!search.parse(ba.data(), filter)) {
|
||||
qCInfo(DeckFilterStringLog).nospace() << "DeckFilterString error for " << expr << "; " << qPrintable(_error);
|
||||
filter = [](const DeckPreviewWidget *, const ExtraDeckSearchInfo &) { return false; };
|
||||
filter = [](const DeckSearchData &) { return false; };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef DECK_FILTER_STRING_H
|
||||
#define DECK_FILTER_STRING_H
|
||||
|
||||
#include "../interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h"
|
||||
#include "../interface/deck_loader/loaded_deck.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QString>
|
||||
|
|
@ -16,26 +16,29 @@
|
|||
inline Q_LOGGING_CATEGORY(DeckFilterStringLog, "deck_filter_string");
|
||||
|
||||
/**
|
||||
* Extra info relevant to filtering that isn't present in the DeckPreviewWidget
|
||||
* The data a deck search expression is evaluated against.
|
||||
*
|
||||
* This is a data view rather than a widget pointer, so the same filter
|
||||
* expression can be evaluated against a model or a live widget.
|
||||
*/
|
||||
struct ExtraDeckSearchInfo
|
||||
struct DeckSearchData
|
||||
{
|
||||
/**
|
||||
* The relative filepath starting from the deck folder
|
||||
*/
|
||||
QString relativeFilePath;
|
||||
const LoadedDeck *deck = nullptr; ///< The loaded deck. Must not be null.
|
||||
QString filePath; ///< Absolute path of the deck file.
|
||||
QString displayName; ///< Deck name, or the file name if the deck has no name.
|
||||
QString relativeFilePath; ///< File path relative to the deck folder.
|
||||
};
|
||||
|
||||
typedef std::function<bool(const DeckPreviewWidget *, const ExtraDeckSearchInfo &)> DeckFilter;
|
||||
typedef std::function<bool(const DeckSearchData &data)> DeckFilter;
|
||||
|
||||
class DeckFilterString
|
||||
{
|
||||
public:
|
||||
DeckFilterString();
|
||||
explicit DeckFilterString(const QString &expr);
|
||||
bool check(const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &info) const
|
||||
bool check(const DeckSearchData &data) const
|
||||
{
|
||||
return filter(deck, info);
|
||||
return filter(data);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool valid() const
|
||||
|
|
|
|||
|
|
@ -73,10 +73,14 @@ static QString toRelativeFilepath(const QString &filePath)
|
|||
|
||||
void VisualDeckStorageSearchWidget::filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText)
|
||||
{
|
||||
auto filterString = DeckFilterString(searchText);
|
||||
const auto filterString = DeckFilterString(searchText);
|
||||
|
||||
for (auto widget : widgets) {
|
||||
QString relativeFilePath = toRelativeFilepath(widget->filePath);
|
||||
widget->filteredBySearch = !filterString.check(widget, {relativeFilePath});
|
||||
const DeckSearchData searchData{.deck = &widget->deckLoader->getDeck(),
|
||||
.filePath = widget->filePath,
|
||||
.displayName = widget->getDisplayName(),
|
||||
.relativeFilePath = toRelativeFilepath(widget->filePath)};
|
||||
|
||||
widget->filteredBySearch = !filterString.check(searchData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue