#include "hand_menu.h" #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../../interface/widgets/menus/tearoff_menu.h" #include "../player_graphics_item.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QWidget; HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { auto *actions = player->getLogic()->getPlayerActions(); connect(actions, &PlayerActions::randomHandRevealFailed, this, &HandMenu::onRandomHandRevealFailed); if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aViewHand = new QAction(this); connect(aViewHand, &QAction::triggered, actions, &PlayerActions::actViewHand); addAction(aViewHand); mSortHand = addMenu(QString()); aSortHandByName = new QAction(this); aSortHandByName->setData(CardList::SortByName); aSortHandByType = new QAction(this); aSortHandByType->setData(CardList::SortByMainType); aSortHandByManaValue = new QAction(this); aSortHandByManaValue->setData(CardList::SortByManaValue); connect(aSortHandByType, &QAction::triggered, actions, &PlayerActions::actSortHand); connect(aSortHandByName, &QAction::triggered, actions, &PlayerActions::actSortHand); connect(aSortHandByManaValue, &QAction::triggered, actions, &PlayerActions::actSortHand); mSortHand->addAction(aSortHandByName); mSortHand->addAction(aSortHandByType); mSortHand->addAction(aSortHandByManaValue); } mRevealHand = addMenu(QString()); connect(mRevealHand, &QMenu::aboutToShow, this, &HandMenu::populateRevealHandMenuWithActivePlayers); aRevealHandToAll = new QAction(this); aRevealHandToAll->setData(-1); connect(aRevealHandToAll, &QAction::triggered, this, &HandMenu::onRevealHandTriggered); mRevealRandomHandCard = addMenu(QString()); connect(mRevealRandomHandCard, &QMenu::aboutToShow, this, &HandMenu::populateRevealRandomHandCardMenuWithActivePlayers); aRevealRandomHandCardToAll = new QAction(this); aRevealRandomHandCardToAll->setData(-1); connect(aRevealRandomHandCardToAll, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardTriggered); mRevealRandomHandCards = addMenu(QString()); mRevealRandomHandCards->setObjectName("revealRandomHandCardsMenu"); connect(mRevealRandomHandCards, &QMenu::aboutToShow, this, &HandMenu::populateRevealRandomHandCardsMenuWithActivePlayers); aRevealRandomHandCardsToAll = new QAction(this); aRevealRandomHandCardsToAll->setData(-1); connect(aRevealRandomHandCardsToAll, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardsTriggered); mRevealRandomHandCards->addAction(aRevealRandomHandCardsToAll); // We still need to add these actions to menu here so that the shortcuts are active right away mRevealHand->addAction(aRevealHandToAll); mRevealRandomHandCard->addAction(aRevealRandomHandCardToAll); addSeparator(); aMulligan = new QAction(this); connect(aMulligan, &QAction::triggered, actions, &PlayerActions::actRequestMulliganDialog); addAction(aMulligan); // Mulligan same size aMulliganSame = new QAction(this); connect(aMulliganSame, &QAction::triggered, actions, &PlayerActions::actMulliganSameSize); addAction(aMulliganSame); // Mulligan -1 aMulliganMinusOne = new QAction(this); connect(aMulliganMinusOne, &QAction::triggered, actions, &PlayerActions::actMulliganMinusOne); addAction(aMulliganMinusOne); addSeparator(); mMoveHandMenu = addTearOffMenu(QString()); if (player->getLogic()->getPlayerInfo()->local || player->getLogic()->getPlayerInfo()->judge) { aMoveHandToTopLibrary = new QAction(this); aMoveHandToTopLibrary->setData(QList() << ZoneNames::DECK << 0); aMoveHandToBottomLibrary = new QAction(this); aMoveHandToBottomLibrary->setData(QList() << ZoneNames::DECK << -1); aMoveHandToGrave = new QAction(this); aMoveHandToGrave->setData(QList() << ZoneNames::GRAVE << 0); aMoveHandToRfg = new QAction(this); aMoveHandToRfg->setData(QList() << ZoneNames::EXILE << 0); auto hand = player->getLogic()->getHandZone(); connect(aMoveHandToTopLibrary, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); connect(aMoveHandToBottomLibrary, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); connect(aMoveHandToGrave, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); connect(aMoveHandToRfg, &QAction::triggered, hand, &HandZoneLogic::moveAllToZone); mMoveHandMenu->addAction(aMoveHandToTopLibrary); mMoveHandMenu->addAction(aMoveHandToBottomLibrary); mMoveHandMenu->addSeparator(); mMoveHandMenu->addAction(aMoveHandToGrave); mMoveHandMenu->addSeparator(); mMoveHandMenu->addAction(aMoveHandToRfg); } retranslateUi(); } void HandMenu::retranslateUi() { setTitle(tr("&Hand")); if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) { aViewHand->setText(tr("&View hand")); mSortHand->setTitle(tr("Sort hand by...")); aSortHandByName->setText(tr("Name")); aSortHandByType->setText(tr("Type")); aSortHandByManaValue->setText(tr("Mana Value")); aMulligan->setText(tr("Take &mulligan (Choose hand size)")); aMulliganSame->setText(tr("Take mulligan (Same hand size)")); aMulliganMinusOne->setText(tr("Take mulligan (Hand size - 1)")); mMoveHandMenu->setTitle(tr("&Move hand to...")); aMoveHandToTopLibrary->setText(tr("&Top of library")); aMoveHandToBottomLibrary->setText(tr("&Bottom of library")); aMoveHandToGrave->setText(tr("&Graveyard")); aMoveHandToRfg->setText(tr("&Exile")); mRevealHand->setTitle(tr("&Reveal hand to...")); aRevealHandToAll->setText(tr("All players")); mRevealRandomHandCard->setTitle(tr("Reveal r&andom card to...")); aRevealRandomHandCardToAll->setText(tr("All players")); mRevealRandomHandCards->setTitle(tr("Reveal a chosen number of random cards to...")); aRevealRandomHandCardsToAll->setText(tr("All players")); } } void HandMenu::setShortcutsActive() { ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts(); aViewHand->setShortcuts(shortcuts.getShortcut("Player/aViewHand")); aSortHandByName->setShortcuts(shortcuts.getShortcut("Player/aSortHandByName")); aSortHandByType->setShortcuts(shortcuts.getShortcut("Player/aSortHandByType")); aSortHandByManaValue->setShortcuts(shortcuts.getShortcut("Player/aSortHandByManaValue")); aMulligan->setShortcuts(shortcuts.getShortcut("Player/aMulligan")); aMulliganSame->setShortcuts(shortcuts.getShortcut("Player/aMulliganSame")); aMulliganMinusOne->setShortcuts(shortcuts.getShortcut("Player/aMulliganMinusOne")); aRevealHandToAll->setShortcuts(shortcuts.getShortcut("Player/aRevealHandToAll")); aRevealRandomHandCardToAll->setShortcuts(shortcuts.getShortcut("Player/aRevealRandomHandCardToAll")); } void HandMenu::setShortcutsInactive() { aViewHand->setShortcut(QKeySequence()); aSortHandByName->setShortcut(QKeySequence()); aSortHandByType->setShortcut(QKeySequence()); aSortHandByManaValue->setShortcut(QKeySequence()); aMulligan->setShortcut(QKeySequence()); aRevealHandToAll->setShortcut(QKeySequence()); aRevealRandomHandCardToAll->setShortcut(QKeySequence()); } void HandMenu::populateRevealHandMenuWithActivePlayers() { mRevealHand->clear(); mRevealHand->addAction(aRevealHandToAll); mRevealHand->addSeparator(); const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { if (other == player->getLogic()) { continue; } QAction *a = mRevealHand->addAction(other->getPlayerInfo()->getName()); a->setData(other->getPlayerInfo()->getId()); connect(a, &QAction::triggered, this, &HandMenu::onRevealHandTriggered); } } void HandMenu::populateRevealRandomHandCardMenuWithActivePlayers() { mRevealRandomHandCard->clear(); mRevealRandomHandCard->addAction(aRevealRandomHandCardToAll); mRevealRandomHandCard->addSeparator(); const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { if (other == player->getLogic()) { continue; } QAction *a = mRevealRandomHandCard->addAction(other->getPlayerInfo()->getName()); a->setData(other->getPlayerInfo()->getId()); connect(a, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardTriggered); } } void HandMenu::onRevealHandTriggered() { auto *action = qobject_cast(sender()); if (!action) { return; } const int targetId = action->data().toInt(); player->getLogic()->getPlayerActions()->actRevealHand(targetId); } void HandMenu::onRevealRandomHandCardTriggered() { auto *action = qobject_cast(sender()); if (!action) { return; } const int targetId = action->data().toInt(); player->getLogic()->getPlayerActions()->actRevealRandomHandCard(targetId); } void HandMenu::populateRevealRandomHandCardsMenuWithActivePlayers() { const bool hasCards = !player->getLogic()->getHandZone()->getCards().isEmpty(); mRevealRandomHandCards->clear(); aRevealRandomHandCardsToAll->setEnabled(hasCards); mRevealRandomHandCards->addAction(aRevealRandomHandCardsToAll); mRevealRandomHandCards->addSeparator(); const auto &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); for (auto *other : players) { if (other == player->getLogic()) { continue; } auto *action = mRevealRandomHandCards->addAction(other->getPlayerInfo()->getName()); action->setData(other->getPlayerInfo()->getId()); action->setEnabled(hasCards); connect(action, &QAction::triggered, this, &HandMenu::onRevealRandomHandCardsTriggered); } } void HandMenu::onRevealRandomHandCardsTriggered() { const auto *action = qobject_cast(sender()); const int handSize = player->getLogic()->getHandZone()->getCards().size(); if (!action || handSize == 0) { return; } const int targetId = action->data().toInt(); QPointer actions = player->getLogic()->getPlayerActions(); QPointer client = player->getLogic()->getGame()->getClientForPlayer(player->getLogic()->getPlayerInfo()->getId()); if (!client) { return; } auto *dialog = new QInputDialog(dialogParent()); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setWindowTitle(tr("Reveal Random Hand Cards")); dialog->setLabelText(tr("Number of distinct random cards to reveal to %1:").arg(action->text())); dialog->setInputMode(QInputDialog::IntInput); dialog->setIntRange(1, handSize); dialog->setIntValue(qMin(2, handSize)); connect(this, &QObject::destroyed, dialog, &QDialog::reject); connect(client, &QObject::destroyed, dialog, &QDialog::reject); connect(actions, &QObject::destroyed, dialog, &QDialog::reject); connect(dialog, &QDialog::accepted, this, [dialog, actions, client, targetId] { if (!actions || !client) { return; } actions->actRevealRandomHandCards(targetId, dialog->intValue()); }); dialog->open(); } QWidget *HandMenu::dialogParent() const { if (auto *view = player->scene() ? player->scene()->views().value(0) : nullptr) { return view->window(); } return nullptr; } void HandMenu::onRandomHandRevealFailed(bool unsupported) { const QString text = unsupported ? tr("This server does not support revealing multiple random cards. No cards were revealed.") : tr("The random reveal could not be completed. The hand or recipient may have changed."); auto *message = new QMessageBox(QMessageBox::Warning, tr("Reveal Random Hand Cards"), text, QMessageBox::Ok, dialogParent()); message->setAttribute(Qt::WA_DeleteOnClose); connect(this, &QObject::destroyed, message, &QDialog::reject); connect(player->getLogic()->getPlayerActions(), &QObject::destroyed, message, &QDialog::reject); if (auto *client = player->getLogic()->getGame()->getClientForPlayer(player->getLogic()->getPlayerInfo()->getId())) { connect(client, &QObject::destroyed, message, &QDialog::reject); } message->open(); }