From a5de633c64d22d4200a9d36ce82b7f2db9ec228a Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:58:29 -0800 Subject: [PATCH] warn if "play top card until" filter expression doesn't match any card in database (#5243) * make FilterString::check const * implement thing --- .../src/dialogs/dlg_move_top_cards_until.cpp | 51 +++++++++++++++++-- .../src/dialogs/dlg_move_top_cards_until.h | 4 +- cockatrice/src/game/filters/filter_string.h | 2 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp index 15293fd8c..c21bbef45 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp @@ -1,5 +1,7 @@ #include "dlg_move_top_cards_until.h" +#include "../game/cards/card_database.h" +#include "../game/cards/card_database_manager.h" #include "../game/filters/filter_string.h" #include "trice_limits.h" @@ -45,14 +47,57 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint setWindowTitle(tr("Put top cards on stack until...")); } +/** + * @brief Checks if a card matching the expr exists in the card database. + * + * @returns true if a card matching the expression exists. + */ +static bool matchExistsInDb(const FilterString &filterString) +{ + const auto cardDatabase = CardDatabaseManager::getInstance(); + const auto allCards = cardDatabase->getCardList(); + + const auto it = std::find_if(allCards.begin(), allCards.end(), + [&filterString](const CardInfoPtr &card) { return filterString.check(card); }); + + return it != allCards.end(); +} + +/** + * @brief Validates that a card matching the expr exists in the card database. + * If no match is found, then pop up a window to warn the user, giving them a chance to back out. + * + * @returns whether to proceed with the action + */ +bool DlgMoveTopCardsUntil::validateMatchExists(const FilterString &filterString) +{ + if (matchExistsInDb(filterString)) { + return true; + } + + const auto msg = tr("No cards matching the search expression exists in the card database. Proceed anyways?"); + const auto res = + QMessageBox::warning(this, tr("Cockatrice"), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (res == QMessageBox::No) { + return false; + } + + return true; +} + void DlgMoveTopCardsUntil::validateAndAccept() { auto movingCardsUntilFilter = FilterString(exprEdit->text()); - if (movingCardsUntilFilter.valid()) { - accept(); - } else { + if (!movingCardsUntilFilter.valid()) { QMessageBox::warning(this, tr("Invalid filter"), movingCardsUntilFilter.error(), QMessageBox::Ok); + return; } + + if (!validateMatchExists(movingCardsUntilFilter)) { + return; + } + + accept(); } QString DlgMoveTopCardsUntil::getExpr() const diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/dialogs/dlg_move_top_cards_until.h index 7b026a942..96ce65baf 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.h +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.h @@ -6,7 +6,8 @@ #include #include #include -#include + +class FilterString; class DlgMoveTopCardsUntil : public QDialog { @@ -18,6 +19,7 @@ class DlgMoveTopCardsUntil : public QDialog QDialogButtonBox *buttonBox; void validateAndAccept(); + bool validateMatchExists(const FilterString &filterString); public: explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, QString expr = QString(), uint numberOfHits = 1); diff --git a/cockatrice/src/game/filters/filter_string.h b/cockatrice/src/game/filters/filter_string.h index 4ef9f3ae0..aabeb015d 100644 --- a/cockatrice/src/game/filters/filter_string.h +++ b/cockatrice/src/game/filters/filter_string.h @@ -26,7 +26,7 @@ class FilterString public: FilterString(); explicit FilterString(const QString &exp); - bool check(const CardData &card) + bool check(const CardData &card) const { return result(card); }