Add keybaord shortcut for creating related cards (#2426)

* Extract createCard from actCreateRelatedCard

* Merge related cards and reverse related cards before handling

* Add "Create all related cards" action to a card

* Stop displaying all related tokens if only one token is available

* Add shortcut for Creating all tokens related to selected card

* Extract method for adding related card actions

* Prefer foreach to index based iteration

* Guard against null cards, card menus, or cardInfos

* Remove QRegExp dependency from commonly depended header
This commit is contained in:
Mark McDonald 2017-02-27 02:50:10 -05:00 committed by ctrlaltca
parent c0e7d0c7c7
commit b9cd942308
4 changed files with 114 additions and 53 deletions

View file

@ -24,6 +24,7 @@
#include <QPainter>
#include <QMenu>
#include <QDebug>
#include <QRegExp>
#include "pb/command_change_zone_properties.pb.h"
#include "pb/command_reveal_cards.pb.h"
@ -1095,20 +1096,33 @@ void Player::actCreatePredefinedToken()
void Player::actCreateRelatedCard()
{
// get the clicked card
CardItem * sourceCard = game->getActiveCard();
if(!sourceCard)
return;
// get the target card name
QAction *action = static_cast<QAction *>(sender());
const QString &actionDisplayName = action->text();
createCard(sourceCard, dbNameFromTokenDisplayName(actionDisplayName));
}
// removes p/t from tokens (and leading space))
// Added split for "Token:" due to change in PR fixing #2317
QStringList spaces = action->text().split(tr("Token: "))[1].split(" ");
if (spaces.at(0).indexOf("/") != -1) // Strip space from creatures
spaces.removeFirst();
CardInfo *cardInfo = db->getCard(spaces.join(" "));
void Player::actCreateAllRelatedCards()
{
CardItem * sourceCard = game->getActiveCard();
if(!sourceCard)
return;
QStringList relatedCards = * new QStringList();
relatedCards.append(sourceCard->getInfo()->getRelatedCards());
relatedCards.append(sourceCard->getInfo()->getReverseRelatedCards2Me());
foreach (const QString &tokenName, relatedCards)
{
createCard(sourceCard, dbNameFromTokenDisplayName(tokenName));
}
}
void Player::createCard(const CardItem *sourceCard, const QString &dbCardName) {
CardInfo *cardInfo = db->getCard(dbCardName);
if(!cardInfo)
return;
@ -1177,6 +1191,21 @@ void Player::setCardAttrHelper(const GameEventContext &context, CardItem *card,
}
}
// token names take the form of "<Descriptors> <Power>/<Toughness> <Card Name> " or "<Card Name> ".
// dbName for tokens should take the form of "<Card Name> ".
// trailing whitespace is significant; it is hacked on at the end as an additional identifier in our single key database
QString Player::dbNameFromTokenDisplayName(const QString &tokenName) {
QRegExp tokenNamePattern(".*/\\S+\\s+(.*)");
int index = tokenNamePattern.indexIn(tokenName);
if (index != -1)
{
return tokenNamePattern.capturedTexts()[1];
} else {
return tokenName;
}
}
void Player::eventGameSay(const Event_GameSay &event)
{
emit logSay(this, QString::fromStdString(event.message()));
@ -2286,10 +2315,17 @@ void Player::actPlayFacedown()
void Player::refreshShortcuts()
{
if(shortcutsActive)
{
setShortcutsActive();
foreach (const CardItem *cardItem, table->getCards())
{
updateCardMenu(cardItem);
}
}
}
void Player::updateCardMenu(CardItem *card)
void Player::updateCardMenu(const CardItem *card)
{
QMenu *cardMenu = card->getCardMenu();
QMenu *ptMenu = card->getPTMenu();
@ -2348,26 +2384,8 @@ void Player::updateCardMenu(CardItem *card)
if (card->getFaceDown())
cardMenu->addAction(aPeek);
if(card->getInfo())
{
QStringList relatedCards = card->getInfo()->getRelatedCards();
QStringList reverserelatedCards2Me = card->getInfo()->getReverseRelatedCards2Me();
if(relatedCards.size() || reverserelatedCards2Me.size())
{
cardMenu->addSeparator();
for (int i = 0; i < relatedCards.size(); ++i) {
QAction *a = new QAction(tr("Token: ") + relatedCards.at(i), this);
connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
cardMenu->addAction(a);
}
addRelatedCardActions(card, cardMenu);
for (int i = 0; i < reverserelatedCards2Me.size(); ++i) {
QAction *a = new QAction(tr("Token: ") + reverserelatedCards2Me.at(i), this);
connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
cardMenu->addAction(a);
}
}
}
cardMenu->addSeparator();
cardMenu->addAction(aAttach);
if (card->getAttachedTo())
@ -2395,26 +2413,7 @@ void Player::updateCardMenu(CardItem *card)
cardMenu->addAction(aDrawArrow);
cardMenu->addMenu(moveMenu);
if(card->getInfo())
{
QStringList relatedCards = card->getInfo()->getRelatedCards();
QStringList reverserelatedCards2Me = card->getInfo()->getReverseRelatedCards2Me();
if(relatedCards.size() || reverserelatedCards2Me.size())
{
cardMenu->addSeparator();
for (int i = 0; i < relatedCards.size(); ++i) {
QAction *a = new QAction(tr("Token: ") + relatedCards.at(i), this);
connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
cardMenu->addAction(a);
}
for (int i = 0; i < reverserelatedCards2Me.size(); ++i) {
QAction *a = new QAction(tr("Token: ") + reverserelatedCards2Me.at(i), this);
connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
cardMenu->addAction(a);
}
}
}
addRelatedCardActions(card, cardMenu);
} else {
cardMenu->addAction(aPlay);
cardMenu->addAction(aPlayFacedown);
@ -2425,6 +2424,49 @@ void Player::updateCardMenu(CardItem *card)
}
}
void Player::addRelatedCardActions(const CardItem *card, QMenu *cardMenu) {
if (!card || !cardMenu || !card->getInfo())
{
return;
}
QStringList relatedCards = *new QStringList();
relatedCards.append(card->getInfo()->getRelatedCards());
relatedCards.append(card->getInfo()->getReverseRelatedCards2Me());
switch (relatedCards.length()) {
case 0:
break;
case 1: {
cardMenu->addSeparator();
QAction *createRelatedCards = new QAction(tr("Token: ") + relatedCards.at(0), this);
connect(createRelatedCards, SIGNAL(triggered()), this, SLOT(actCreateAllRelatedCards()));
if (shortcutsActive) {
createRelatedCards->setShortcut(settingsCache->shortcuts().getSingleShortcut("Player/aCreateRelatedTokens"));
}
cardMenu->addAction(createRelatedCards);
break;
}
default: {
cardMenu->addSeparator();
foreach (QString cardName, relatedCards)
{
QAction *createRelated = new QAction(tr("Token: ") + cardName, this);
connect(createRelated, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
cardMenu->addAction(createRelated);
}
QAction *createRelatedCards = new QAction(tr("All tokens"), this);
connect(createRelatedCards, SIGNAL(triggered()), this, SLOT(actCreateAllRelatedCards()));
if (shortcutsActive) {
createRelatedCards->setShortcut(settingsCache->shortcuts().getSingleShortcut("Player/aCreateRelatedTokens"));
}
cardMenu->addAction(createRelatedCards);
break;
}
}
}
void Player::setCardMenu(QMenu *menu)
{
if (aCardMenu)

View file

@ -141,6 +141,7 @@ private slots:
void actOpenDeckInDeckEditor();
void actCreatePredefinedToken();
void actCreateRelatedCard();
void actCreateAllRelatedCards();
void cardMenuAction();
void actCardCounterTrigger();
void actAttach();
@ -209,6 +210,9 @@ private:
PlayerTarget *playerTarget;
void setCardAttrHelper(const GameEventContext &context, CardItem *card, CardAttribute attribute, const QString &avalue, bool allCards);
void addRelatedCardActions(const CardItem *card, QMenu *cardMenu);
void createCard(const CardItem *sourceCard, const QString &dbCardName);
QString dbNameFromTokenDisplayName(const QString &tokenName);
QRectF bRect;
@ -281,7 +285,7 @@ public:
const QMap<int, ArrowItem *> &getArrows() const { return arrows; }
void setCardMenu(QMenu *menu);
QMenu *getCardMenu() const;
void updateCardMenu(CardItem *card);
void updateCardMenu(const CardItem *card);
bool getActive() const { return active; }
void setActive(bool _active);
void setShortcutsActive();
@ -306,6 +310,7 @@ public:
PendingCommand *prepareGameCommand(const QList< const ::google::protobuf::Message * > &cmdList);
void sendGameCommand(PendingCommand *pend);
void sendGameCommand(const google::protobuf::Message &command);
};
#endif

View file

@ -199,6 +199,8 @@ public:
SequenceEdit *Player_aClone;
QLabel *lbl_Player_aCreateToken;
SequenceEdit *Player_aCreateToken;
QLabel *lbl_Player_aCreateRelatedTokens;
SequenceEdit *Player_aCreateRelatedTokens;
QLabel *lbl_Player_aCreateAnotherToken;
SequenceEdit *Player_aCreateAnotherToken;
QLabel *lbl_Player_aSetAnnotation;
@ -1080,25 +1082,35 @@ public:
gridLayout_13->addWidget(Player_aCreateToken, 10, 1, 1, 1);
lbl_Player_aCreateRelatedTokens = new QLabel(groupBox_13);
lbl_Player_aCreateRelatedTokens->setObjectName("lbl_Player_aCreateRelatedTokens");
gridLayout_13->addWidget(lbl_Player_aCreateRelatedTokens, 11, 0, 1, 1);
Player_aCreateRelatedTokens = new SequenceEdit("Player/aCreateRelatedTokens",groupBox_13);
Player_aCreateRelatedTokens->setObjectName("Player_aCreateRelatedTokens");
gridLayout_13->addWidget(Player_aCreateRelatedTokens, 11, 1, 1, 1);
lbl_Player_aCreateAnotherToken = new QLabel(groupBox_13);
lbl_Player_aCreateAnotherToken->setObjectName("lbl_Player_aCreateAnotherToken");
gridLayout_13->addWidget(lbl_Player_aCreateAnotherToken, 11, 0, 1, 1);
gridLayout_13->addWidget(lbl_Player_aCreateAnotherToken, 12, 0, 1, 1);
Player_aCreateAnotherToken = new SequenceEdit("Player/aCreateAnotherToken",groupBox_13);
Player_aCreateAnotherToken->setObjectName("Player_aCreateAnotherToken");
gridLayout_13->addWidget(Player_aCreateAnotherToken, 11, 1, 1, 1);
gridLayout_13->addWidget(Player_aCreateAnotherToken, 12, 1, 1, 1);
lbl_Player_aSetAnnotation = new QLabel(groupBox_13);
lbl_Player_aSetAnnotation->setObjectName("lbl_Player_aSetAnnotation");
gridLayout_13->addWidget(lbl_Player_aSetAnnotation, 12, 0, 1, 1);
gridLayout_13->addWidget(lbl_Player_aSetAnnotation, 13, 0, 1, 1);
Player_aSetAnnotation = new SequenceEdit("Player/aSetAnnotation",groupBox_13);
Player_aSetAnnotation->setObjectName("Player_aSetAnnotation");
gridLayout_13->addWidget(Player_aSetAnnotation, 12, 1, 1, 1);
gridLayout_13->addWidget(Player_aSetAnnotation, 13, 1, 1, 1);
gridLayout_17->addWidget(groupBox_13, 0, 2, 1, 1);
@ -1543,6 +1555,7 @@ public:
lbl_Player_aUnattach->setText(QApplication::translate("shortcutsTab", "Unattach card", 0));
lbl_Player_aClone->setText(QApplication::translate("shortcutsTab", "Clone card", 0));
lbl_Player_aCreateToken->setText(QApplication::translate("shortcutsTab", "Create token", 0));
lbl_Player_aCreateRelatedTokens->setText(QApplication::translate("shortcutsTab", "Create all related tokens", 0));
lbl_Player_aCreateAnotherToken->setText(QApplication::translate("shortcutsTab", "Create another token", 0));
lbl_Player_aSetAnnotation->setText(QApplication::translate("shortcutsTab", "Set annotation", 0));
tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("shortcutsTab", "Phases | P/T | Playing Area", 0));

View file

@ -185,6 +185,7 @@ void ShortcutsSettings::fillDefaultShorcuts()
defaultShortCuts["Player/aClone"] = parseSequenceString("Ctrl+J");
defaultShortCuts["Player/aCreateAnotherToken"] = parseSequenceString("Ctrl+G");
defaultShortCuts["Player/aCreateToken"] = parseSequenceString("Ctrl+T");
defaultShortCuts["Player/aCreateRelatedTokens"] = parseSequenceString("Ctrl+Shift+T");
defaultShortCuts["Player/aDecP"] = parseSequenceString("Ctrl+-");
defaultShortCuts["Player/aDecPT"] = parseSequenceString("Ctrl+Alt+-");
defaultShortCuts["Player/aDecT"] = parseSequenceString("Alt+-");