Rework of the card database, xml format and oracle parser (#3511)
* CardDB: merge all card properties in a new structure * Pre Json parser changes * Cockatrice: use qt's builtin json support * Move qt-json src dir from cockatrice to oracle * Add dummy cockatricexml4 parser (yet to be implemented) * Implement a new parser and xml format * cockatricexml4: new xml parser following the "generic properties hash" pattern; * oracleimporter: refactor the parsing code to better adapt to cockatricexml4; rewrote split cards parsing * carddb: change "colors" from a stringlist to a string * carddb: move the getMainCardType() method to the cockatricexml3 parser * * CardInfo: show all properties (stil missing: nice name + translation) * Rework the "add related card" feature so that it doesn't change the card name in the carddb Also, fix token count display * Picture loader: Added support for transform cards * Fix side information for flip cards Mtgjson uses side a/b for flip cards, while scryfall doesn't * Pictureloader: dynamic tag resolution from card properties Examples old => new * !cardid! => !set:muid! * !uuid! => !set:uuid! * !collectornumber! => !set:num! New examples: * !prop:type! * !prop:manacost! * Start moving mtg-related property names to a specific file * Clangify * Fix tests * Make gcc an happy puppy * Revert "Make gcc an happy puppy" This reverts commit 446ec5f27516c4d3b32dbfc79557f4827c5c5bdf. * Some gcc fixes * Share set list between different db parsers, so they won't overwrite one each other * All glory to the hypnoclangifier! * Fix test compilation * Cleanup edited files in the prior PR. (#3519) * Cleanup edited files in the prior PR. Signed-off-by: Zach Halpern <ZaHalpern+github@gmail.com> * Fix includes Signed-off-by: Zach Halpern <ZaHalpern+github@gmail.com> * Update carddatabase.h
This commit is contained in:
parent
19180243aa
commit
ed70099e36
44 changed files with 1814 additions and 1360 deletions
|
@ -12,11 +12,11 @@ include=("common" \
|
|||
"cockatrice/src" \
|
||||
"oracle/src" \
|
||||
"servatrice/src")
|
||||
exclude=("cockatrice/src/qt-json" \
|
||||
"servatrice/src/smtp" \
|
||||
exclude=("servatrice/src/smtp" \
|
||||
"common/sfmt" \
|
||||
"oracle/src/zip" \
|
||||
"oracle/src/lzma")
|
||||
"oracle/src/lzma" \
|
||||
"oracle/src/qt-json")
|
||||
exts=("cpp" "h")
|
||||
cf_cmd="clang-format"
|
||||
branch="origin/master"
|
||||
|
|
|
@ -100,7 +100,6 @@ SET(cockatrice_SOURCES
|
|||
src/localserver.cpp
|
||||
src/localserverinterface.cpp
|
||||
src/localclient.cpp
|
||||
src/qt-json/json.cpp
|
||||
src/soundengine.cpp
|
||||
src/pending_command.cpp
|
||||
src/pictureloader.cpp
|
||||
|
@ -121,7 +120,9 @@ SET(cockatrice_SOURCES
|
|||
src/userconnection_information.cpp
|
||||
src/spoilerbackgroundupdater.cpp
|
||||
src/handle_public_servers.cpp
|
||||
src/carddbparser/carddatabaseparser.cpp
|
||||
src/carddbparser/cockatricexml3.cpp
|
||||
src/carddbparser/cockatricexml4.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "carddatabase.h"
|
||||
#include "carddbparser/cockatricexml3.h"
|
||||
#include "carddbparser/cockatricexml4.h"
|
||||
#include "game_specific_terms.h"
|
||||
#include "pictureloader.h"
|
||||
#include "settingscache.h"
|
||||
#include "spoilerbackgroundupdater.h"
|
||||
|
@ -207,31 +209,23 @@ void SetList::guessSortKeys()
|
|||
}
|
||||
}
|
||||
|
||||
CardInfoPerSet::CardInfoPerSet(const CardSetPtr &_set) : set(_set)
|
||||
{
|
||||
}
|
||||
|
||||
CardInfo::CardInfo(const QString &_name,
|
||||
bool _isToken,
|
||||
const QString &_manacost,
|
||||
const QString &_cmc,
|
||||
const QString &_cardtype,
|
||||
const QString &_powtough,
|
||||
const QString &_text,
|
||||
const QStringList &_colors,
|
||||
bool _isToken,
|
||||
QVariantHash _properties,
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
bool _upsideDownArt,
|
||||
const QString &_loyalty,
|
||||
CardInfoPerSetMap _sets,
|
||||
bool _cipt,
|
||||
int _tableRow,
|
||||
const SetList &_sets,
|
||||
const QStringMap &_customPicURLs,
|
||||
MuidMap _muIds,
|
||||
QStringMap _uuIds,
|
||||
QStringMap _collectorNumbers,
|
||||
QStringMap _rarities)
|
||||
: name(_name), isToken(_isToken), sets(_sets), manacost(_manacost), cmc(_cmc), cardtype(_cardtype),
|
||||
powtough(_powtough), text(_text), colors(_colors), relatedCards(_relatedCards),
|
||||
reverseRelatedCards(_reverseRelatedCards), setsNames(), upsideDownArt(_upsideDownArt), loyalty(_loyalty),
|
||||
customPicURLs(_customPicURLs), muIds(std::move(_muIds)), uuIds(std::move(_uuIds)),
|
||||
collectorNumbers(std::move(_collectorNumbers)), rarities(std::move(_rarities)), cipt(_cipt), tableRow(_tableRow)
|
||||
bool _upsideDownArt)
|
||||
: name(_name), text(_text), isToken(_isToken), properties(std::move(_properties)), relatedCards(_relatedCards),
|
||||
reverseRelatedCards(_reverseRelatedCards), sets(std::move(_sets)), cipt(_cipt), tableRow(_tableRow),
|
||||
upsideDownArt(_upsideDownArt)
|
||||
{
|
||||
pixmapCacheKey = QLatin1String("card_") + name;
|
||||
simpleName = CardInfo::simplifyName(name);
|
||||
|
@ -245,77 +239,27 @@ CardInfo::~CardInfo()
|
|||
}
|
||||
|
||||
CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||
bool _isToken,
|
||||
const QString &_manacost,
|
||||
const QString &_cmc,
|
||||
const QString &_cardtype,
|
||||
const QString &_powtough,
|
||||
const QString &_text,
|
||||
const QStringList &_colors,
|
||||
bool _isToken,
|
||||
QVariantHash _properties,
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
bool _upsideDownArt,
|
||||
const QString &_loyalty,
|
||||
CardInfoPerSetMap _sets,
|
||||
bool _cipt,
|
||||
int _tableRow,
|
||||
const SetList &_sets,
|
||||
const QStringMap &_customPicURLs,
|
||||
MuidMap _muIds,
|
||||
QStringMap _uuIds,
|
||||
QStringMap _collectorNumbers,
|
||||
QStringMap _rarities)
|
||||
bool _upsideDownArt)
|
||||
{
|
||||
CardInfoPtr ptr(new CardInfo(_name, _isToken, _manacost, _cmc, _cardtype, _powtough, _text, _colors, _relatedCards,
|
||||
_reverseRelatedCards, _upsideDownArt, _loyalty, _cipt, _tableRow, _sets,
|
||||
_customPicURLs, std::move(_muIds), std::move(_uuIds), std::move(_collectorNumbers),
|
||||
std::move(_rarities)));
|
||||
CardInfoPtr ptr(new CardInfo(_name, _text, _isToken, std::move(_properties), _relatedCards, _reverseRelatedCards,
|
||||
_sets, _cipt, _tableRow, _upsideDownArt));
|
||||
ptr->setSmartPointer(ptr);
|
||||
|
||||
for (int i = 0; i < _sets.size(); i++) {
|
||||
_sets[i]->append(ptr);
|
||||
for (const CardInfoPerSet &set : _sets) {
|
||||
set.getPtr()->append(ptr);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
QString CardInfo::getMainCardType() const
|
||||
{
|
||||
QString result = getCardType();
|
||||
/*
|
||||
Legendary Artifact Creature - Golem
|
||||
Instant // Instant
|
||||
*/
|
||||
|
||||
int pos;
|
||||
if ((pos = result.indexOf('-')) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
if ((pos = result.indexOf("—")) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
if ((pos = result.indexOf("//")) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
result = result.simplified();
|
||||
/*
|
||||
Legendary Artifact Creature
|
||||
Instant
|
||||
*/
|
||||
|
||||
if ((pos = result.lastIndexOf(' ')) != -1) {
|
||||
result = result.mid(pos + 1);
|
||||
}
|
||||
/*
|
||||
Creature
|
||||
Instant
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CardInfo::getCorrectedName() const
|
||||
{
|
||||
QString result = name;
|
||||
|
@ -323,26 +267,21 @@ QString CardInfo::getCorrectedName() const
|
|||
return result.remove(" // ").remove(':').remove('"').remove('?').replace('/', ' ');
|
||||
}
|
||||
|
||||
void CardInfo::addToSet(CardSetPtr set)
|
||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
||||
{
|
||||
if (set.isNull()) {
|
||||
qDebug() << "addToSet(nullptr)";
|
||||
return;
|
||||
}
|
||||
|
||||
set->append(smartThis);
|
||||
sets << set;
|
||||
_set->append(smartThis);
|
||||
sets.insert(_set->getShortName(), _info);
|
||||
|
||||
refreshCachedSetNames();
|
||||
}
|
||||
|
||||
void CardInfo::refreshCachedSetNames()
|
||||
{
|
||||
// update the cached list of set names
|
||||
QStringList setList;
|
||||
for (int i = 0; i < sets.size(); i++) {
|
||||
if (sets[i]->getEnabled()) {
|
||||
setList << sets[i]->getShortName();
|
||||
// update the cached list of set names
|
||||
for (const auto &set : sets) {
|
||||
if (set.getPtr()->getEnabled()) {
|
||||
setList << set.getPtr()->getShortName();
|
||||
}
|
||||
}
|
||||
setsNames = setList.join(", ");
|
||||
|
@ -371,11 +310,12 @@ QString CardInfo::simplifyName(const QString &name)
|
|||
|
||||
const QChar CardInfo::getColorChar() const
|
||||
{
|
||||
QString colors = getColors();
|
||||
switch (colors.size()) {
|
||||
case 0:
|
||||
return QChar();
|
||||
case 1:
|
||||
return colors.first().isEmpty() ? QChar() : colors.first().at(0);
|
||||
return colors.at(0);
|
||||
default:
|
||||
return QChar('m');
|
||||
}
|
||||
|
@ -388,6 +328,7 @@ CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoa
|
|||
|
||||
// add new parsers here
|
||||
availableParsers << new CockatriceXml3Parser;
|
||||
availableParsers << new CockatriceXml4Parser;
|
||||
|
||||
for (auto &parser : availableParsers) {
|
||||
connect(parser, SIGNAL(addCard(CardInfoPtr)), this, SLOT(addCard(CardInfoPtr)), Qt::DirectConnection);
|
||||
|
@ -419,9 +360,7 @@ void CardDatabase::clear()
|
|||
simpleNameCards.clear();
|
||||
|
||||
sets.clear();
|
||||
for (auto parser : availableParsers) {
|
||||
parser->clearSetlist();
|
||||
}
|
||||
ICardDatabaseParser::clearSetlist();
|
||||
|
||||
loadStatus = NotLoaded;
|
||||
|
||||
|
@ -438,13 +377,8 @@ void CardDatabase::addCard(CardInfoPtr card)
|
|||
// if card already exists just add the new set property
|
||||
if (cards.contains(card->getName())) {
|
||||
CardInfoPtr sameCard = cards[card->getName()];
|
||||
for (auto set : card->getSets()) {
|
||||
QString setName = set->getCorrectedShortName();
|
||||
sameCard->setSet(set);
|
||||
sameCard->setMuId(setName, card->getMuId(setName));
|
||||
sameCard->setUuId(setName, card->getUuId(setName));
|
||||
sameCard->setRarity(setName, card->getRarity(setName));
|
||||
sameCard->setSetNumber(setName, card->getCollectorNumber(setName));
|
||||
for (const CardInfoPerSet &set : card->getSets()) {
|
||||
sameCard->addToSet(set.getPtr(), set);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -585,7 +519,7 @@ LoadStatus CardDatabase::loadCardDatabases()
|
|||
|
||||
// load custom card databases
|
||||
QDir dir(settingsCache->getCustomCardDatabasePath());
|
||||
for (QString fileName :
|
||||
for (const QString &fileName :
|
||||
dir.entryList(QStringList("*.xml"), QDir::Files | QDir::Readable, QDir::Name | QDir::IgnoreCase)) {
|
||||
loadCardDatabase(dir.absoluteFilePath(fileName));
|
||||
}
|
||||
|
@ -617,20 +551,13 @@ void CardDatabase::refreshCachedReverseRelatedCards()
|
|||
continue;
|
||||
}
|
||||
|
||||
QString relatedCardName;
|
||||
if (card->getPowTough().size() > 0) {
|
||||
relatedCardName = card->getPowTough() + " " + card->getName(); // "n/n name"
|
||||
} else {
|
||||
relatedCardName = card->getName(); // "name"
|
||||
}
|
||||
|
||||
foreach (CardRelation *cardRelation, card->getReverseRelatedCards()) {
|
||||
const QString &targetCard = cardRelation->getName();
|
||||
if (!cards.contains(targetCard)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *newCardRelation = new CardRelation(relatedCardName, cardRelation->getDoesAttach(),
|
||||
auto *newCardRelation = new CardRelation(card->getName(), cardRelation->getDoesAttach(),
|
||||
cardRelation->getIsCreateAllExclusion(),
|
||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount());
|
||||
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
||||
|
@ -638,23 +565,6 @@ void CardDatabase::refreshCachedReverseRelatedCards()
|
|||
}
|
||||
}
|
||||
|
||||
QStringList CardDatabase::getAllColors() const
|
||||
{
|
||||
QSet<QString> colors;
|
||||
QHashIterator<QString, CardInfoPtr> cardIterator(cards);
|
||||
while (cardIterator.hasNext()) {
|
||||
const QStringList &cardColors = cardIterator.next().value()->getColors();
|
||||
if (cardColors.isEmpty()) {
|
||||
colors.insert("X");
|
||||
} else {
|
||||
for (int i = 0; i < cardColors.size(); ++i) {
|
||||
colors.insert(cardColors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return colors.toList();
|
||||
}
|
||||
|
||||
QStringList CardDatabase::getAllMainCardTypes() const
|
||||
{
|
||||
QSet<QString> types;
|
||||
|
@ -720,8 +630,8 @@ bool CardDatabase::saveCustomTokensToFile()
|
|||
tmpSets.insert(CardDatabase::TOKENS_SETNAME, customTokensSet);
|
||||
|
||||
CardNameMap tmpCards;
|
||||
for (CardInfoPtr card : cards) {
|
||||
if (card->getSets().contains(customTokensSet)) {
|
||||
for (const CardInfoPtr &card : cards) {
|
||||
if (card->getSets().contains(CardDatabase::TOKENS_SETNAME)) {
|
||||
tmpCards.insert(card->getName(), card);
|
||||
}
|
||||
}
|
||||
|
@ -747,3 +657,45 @@ void CardInfo::resetReverseRelatedCards2Me()
|
|||
}
|
||||
reverseRelatedCardsToMe = QList<CardRelation *>();
|
||||
}
|
||||
|
||||
// Back-compatibility methods. Remove ASAP
|
||||
const QString CardInfo::getCardType() const
|
||||
{
|
||||
return getProperty(Mtg::CardType);
|
||||
}
|
||||
void CardInfo::setCardType(const QString &value)
|
||||
{
|
||||
setProperty(Mtg::CardType, value);
|
||||
}
|
||||
const QString CardInfo::getCmc() const
|
||||
{
|
||||
return getProperty(Mtg::ConvertedManaCost);
|
||||
}
|
||||
const QString CardInfo::getColors() const
|
||||
{
|
||||
return getProperty(Mtg::Colors);
|
||||
}
|
||||
void CardInfo::setColors(const QString &value)
|
||||
{
|
||||
setProperty(Mtg::Colors, value);
|
||||
}
|
||||
const QString CardInfo::getLoyalty() const
|
||||
{
|
||||
return getProperty(Mtg::Loyalty);
|
||||
}
|
||||
const QString CardInfo::getMainCardType() const
|
||||
{
|
||||
return getProperty(Mtg::MainCardType);
|
||||
}
|
||||
const QString CardInfo::getManaCost() const
|
||||
{
|
||||
return getProperty(Mtg::ManaCost);
|
||||
}
|
||||
const QString CardInfo::getPowTough() const
|
||||
{
|
||||
return getProperty(Mtg::PowTough);
|
||||
}
|
||||
void CardInfo::setPowTough(const QString &value)
|
||||
{
|
||||
setProperty(Mtg::PowTough, value);
|
||||
}
|
|
@ -9,10 +9,13 @@
|
|||
#include <QMetaType>
|
||||
#include <QSharedPointer>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
#include <utility>
|
||||
|
||||
class CardDatabase;
|
||||
class CardInfo;
|
||||
class CardInfoPerSet;
|
||||
class CardSet;
|
||||
class CardRelation;
|
||||
class ICardDatabaseParser;
|
||||
|
@ -21,6 +24,7 @@ typedef QMap<QString, QString> QStringMap;
|
|||
typedef QMap<QString, int> MuidMap;
|
||||
typedef QSharedPointer<CardInfo> CardInfoPtr;
|
||||
typedef QSharedPointer<CardSet> CardSetPtr;
|
||||
typedef QMap<QString, CardInfoPerSet> CardInfoPerSetMap;
|
||||
|
||||
Q_DECLARE_METATYPE(CardInfoPtr)
|
||||
|
||||
|
@ -112,178 +116,162 @@ public:
|
|||
QStringList getUnknownSetsNames();
|
||||
};
|
||||
|
||||
class CardInfoPerSet
|
||||
{
|
||||
public:
|
||||
explicit CardInfoPerSet(const CardSetPtr &_set = QSharedPointer<CardSet>(nullptr));
|
||||
~CardInfoPerSet() = default;
|
||||
|
||||
private:
|
||||
CardSetPtr set;
|
||||
// per-set card properties;
|
||||
QVariantHash properties;
|
||||
|
||||
public:
|
||||
const CardSetPtr getPtr() const
|
||||
{
|
||||
return set;
|
||||
}
|
||||
const QStringList getProperties() const
|
||||
{
|
||||
return properties.keys();
|
||||
}
|
||||
const QString getProperty(const QString &propertyName) const
|
||||
{
|
||||
return properties.value(propertyName).toString();
|
||||
}
|
||||
void setProperty(const QString &_name, const QString &_value)
|
||||
{
|
||||
properties.insert(_name, _value);
|
||||
}
|
||||
};
|
||||
|
||||
class CardInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
CardInfoPtr smartThis;
|
||||
// The card name
|
||||
QString name;
|
||||
|
||||
/*
|
||||
* The name without punctuation or capitalization, for better card tag name
|
||||
* recognition.
|
||||
*/
|
||||
// The name without punctuation or capitalization, for better card name recognition.
|
||||
QString simpleName;
|
||||
|
||||
bool isToken;
|
||||
SetList sets;
|
||||
QString manacost;
|
||||
QString cmc;
|
||||
QString cardtype;
|
||||
QString powtough;
|
||||
// The key used to identify this card in the cache
|
||||
QString pixmapCacheKey;
|
||||
// card text
|
||||
QString text;
|
||||
QStringList colors;
|
||||
|
||||
// whether this is not a "real" card but a token
|
||||
bool isToken;
|
||||
// basic card properties; common for all the sets
|
||||
QVariantHash properties;
|
||||
// the cards i'm related to
|
||||
QList<CardRelation *> relatedCards;
|
||||
|
||||
// the card i'm reverse-related to
|
||||
QList<CardRelation *> reverseRelatedCards;
|
||||
|
||||
// the cards thare are reverse-related to me
|
||||
QList<CardRelation *> reverseRelatedCardsToMe;
|
||||
|
||||
// card sets
|
||||
CardInfoPerSetMap sets;
|
||||
// cached set names
|
||||
QString setsNames;
|
||||
|
||||
bool upsideDownArt;
|
||||
QString loyalty;
|
||||
QStringMap customPicURLs;
|
||||
MuidMap muIds;
|
||||
QStringMap uuIds;
|
||||
QStringMap collectorNumbers;
|
||||
QStringMap rarities;
|
||||
// positioning properties; used by UI
|
||||
bool cipt;
|
||||
int tableRow;
|
||||
QString pixmapCacheKey;
|
||||
bool upsideDownArt;
|
||||
|
||||
public:
|
||||
explicit CardInfo(const QString &_name = QString(),
|
||||
bool _isToken = false,
|
||||
const QString &_manacost = QString(),
|
||||
const QString &_cmc = QString(),
|
||||
const QString &_cardtype = QString(),
|
||||
const QString &_powtough = QString(),
|
||||
const QString &_text = QString(),
|
||||
const QStringList &_colors = QStringList(),
|
||||
bool _isToken = false,
|
||||
QVariantHash _properties = QVariantHash(),
|
||||
const QList<CardRelation *> &_relatedCards = QList<CardRelation *>(),
|
||||
const QList<CardRelation *> &_reverseRelatedCards = QList<CardRelation *>(),
|
||||
bool _upsideDownArt = false,
|
||||
const QString &_loyalty = QString(),
|
||||
CardInfoPerSetMap _sets = CardInfoPerSetMap(),
|
||||
bool _cipt = false,
|
||||
int _tableRow = 0,
|
||||
const SetList &_sets = SetList(),
|
||||
const QStringMap &_customPicURLs = QStringMap(),
|
||||
MuidMap _muids = MuidMap(),
|
||||
QStringMap _uuIds = QStringMap(),
|
||||
QStringMap _collectorNumbers = QStringMap(),
|
||||
QStringMap _rarities = QStringMap());
|
||||
bool _upsideDownArt = false);
|
||||
~CardInfo() override;
|
||||
|
||||
static CardInfoPtr newInstance(const QString &_name = QString(),
|
||||
bool _isToken = false,
|
||||
const QString &_manacost = QString(),
|
||||
const QString &_cmc = QString(),
|
||||
const QString &_cardtype = QString(),
|
||||
const QString &_powtough = QString(),
|
||||
const QString &_text = QString(),
|
||||
const QStringList &_colors = QStringList(),
|
||||
bool _isToken = false,
|
||||
QVariantHash _properties = QVariantHash(),
|
||||
const QList<CardRelation *> &_relatedCards = QList<CardRelation *>(),
|
||||
const QList<CardRelation *> &_reverseRelatedCards = QList<CardRelation *>(),
|
||||
bool _upsideDownArt = false,
|
||||
const QString &_loyalty = QString(),
|
||||
CardInfoPerSetMap _sets = CardInfoPerSetMap(),
|
||||
bool _cipt = false,
|
||||
int _tableRow = 0,
|
||||
const SetList &_sets = SetList(),
|
||||
const QStringMap &_customPicURLs = QStringMap(),
|
||||
MuidMap _muids = MuidMap(),
|
||||
QStringMap _uuIds = QStringMap(),
|
||||
QStringMap _collectorNumbers = QStringMap(),
|
||||
QStringMap _rarities = QStringMap());
|
||||
bool _upsideDownArt = false);
|
||||
|
||||
void setSmartPointer(CardInfoPtr _ptr)
|
||||
{
|
||||
smartThis = _ptr;
|
||||
smartThis = std::move(_ptr);
|
||||
}
|
||||
|
||||
// basic properties
|
||||
inline const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
inline const QString &getSetsNames() const
|
||||
{
|
||||
return setsNames;
|
||||
}
|
||||
const QString &getSimpleName() const
|
||||
{
|
||||
return simpleName;
|
||||
}
|
||||
bool getIsToken() const
|
||||
{
|
||||
return isToken;
|
||||
}
|
||||
const SetList &getSets() const
|
||||
{
|
||||
return sets;
|
||||
}
|
||||
inline const QString &getManaCost() const
|
||||
{
|
||||
return manacost;
|
||||
}
|
||||
inline const QString &getCmc() const
|
||||
{
|
||||
return cmc;
|
||||
}
|
||||
inline const QString &getCardType() const
|
||||
{
|
||||
return cardtype;
|
||||
}
|
||||
inline const QString &getPowTough() const
|
||||
{
|
||||
return powtough;
|
||||
}
|
||||
const QString &getText() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
const QString &getPixmapCacheKey() const
|
||||
{
|
||||
return pixmapCacheKey;
|
||||
}
|
||||
const QString &getLoyalty() const
|
||||
|
||||
const QString &getText() const
|
||||
{
|
||||
return loyalty;
|
||||
}
|
||||
bool getCipt() const
|
||||
{
|
||||
return cipt;
|
||||
}
|
||||
// void setManaCost(const QString &_manaCost) { manacost = _manaCost; emit cardInfoChanged(smartThis); }
|
||||
// void setCmc(const QString &_cmc) { cmc = _cmc; emit cardInfoChanged(smartThis); }
|
||||
void setCardType(const QString &_cardType)
|
||||
{
|
||||
cardtype = _cardType;
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
void setPowTough(const QString &_powTough)
|
||||
{
|
||||
powtough = _powTough;
|
||||
emit cardInfoChanged(smartThis);
|
||||
return text;
|
||||
}
|
||||
void setText(const QString &_text)
|
||||
{
|
||||
text = _text;
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
void setColors(const QStringList &_colors)
|
||||
|
||||
bool getIsToken() const
|
||||
{
|
||||
colors = _colors;
|
||||
return isToken;
|
||||
}
|
||||
const QStringList getProperties() const
|
||||
{
|
||||
return properties.keys();
|
||||
}
|
||||
const QString getProperty(const QString &propertyName) const
|
||||
{
|
||||
return properties.value(propertyName).toString();
|
||||
}
|
||||
void setProperty(const QString &_name, const QString &_value)
|
||||
{
|
||||
properties.insert(_name, _value);
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
const QChar getColorChar() const;
|
||||
const QStringList &getColors() const
|
||||
const CardInfoPerSetMap &getSets() const
|
||||
{
|
||||
return colors;
|
||||
return sets;
|
||||
}
|
||||
const QString &getSetsNames() const
|
||||
{
|
||||
return setsNames;
|
||||
}
|
||||
const QString getSetProperty(const QString &setName, const QString &propertyName) const
|
||||
{
|
||||
if (!sets.contains(setName))
|
||||
return "";
|
||||
return sets[setName].getProperty(propertyName);
|
||||
}
|
||||
void setSetProperty(const QString &setName, const QString &_name, const QString &_value)
|
||||
{
|
||||
if (!sets.contains(setName))
|
||||
return;
|
||||
|
||||
sets[setName].setProperty(_name, _value);
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
|
||||
// related cards
|
||||
const QList<CardRelation *> &getRelatedCards() const
|
||||
{
|
||||
return relatedCards;
|
||||
|
@ -301,36 +289,12 @@ public:
|
|||
{
|
||||
reverseRelatedCardsToMe.append(cardRelation);
|
||||
}
|
||||
bool getUpsideDownArt() const
|
||||
|
||||
// positioning
|
||||
bool getCipt() const
|
||||
{
|
||||
return upsideDownArt;
|
||||
return cipt;
|
||||
}
|
||||
QString getCustomPicURL(const QString &set) const
|
||||
{
|
||||
return customPicURLs.value(set);
|
||||
}
|
||||
int getMuId(const QString &set) const
|
||||
{
|
||||
return muIds.value(set);
|
||||
}
|
||||
QString getUuId(const QString &set) const
|
||||
{
|
||||
return uuIds.value(set);
|
||||
}
|
||||
QString getCollectorNumber(const QString &set) const
|
||||
{
|
||||
return collectorNumbers.value(set);
|
||||
}
|
||||
QString getRarity(const QString &set) const
|
||||
{
|
||||
return rarities.value(set);
|
||||
}
|
||||
QStringMap getRarities() const
|
||||
{
|
||||
return rarities;
|
||||
}
|
||||
QString getMainCardType() const;
|
||||
QString getCorrectedName() const;
|
||||
int getTableRow() const
|
||||
{
|
||||
return tableRow;
|
||||
|
@ -339,31 +303,31 @@ public:
|
|||
{
|
||||
tableRow = _tableRow;
|
||||
}
|
||||
// void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(smartThis); }
|
||||
// void setCustomPicURL(const QString &_set, const QString &_customPicURL) { customPicURLs.insert(_set,
|
||||
// _customPicURL); }
|
||||
void setSet(const CardSetPtr &_set)
|
||||
bool getUpsideDownArt() const
|
||||
{
|
||||
sets.append(_set);
|
||||
refreshCachedSetNames();
|
||||
return upsideDownArt;
|
||||
}
|
||||
void setMuId(const QString &_set, const int &_muId)
|
||||
const QChar getColorChar() const;
|
||||
|
||||
// Back-compatibility methods. Remove ASAP
|
||||
const QString getCardType() const;
|
||||
void setCardType(const QString &value);
|
||||
const QString getCmc() const;
|
||||
const QString getColors() const;
|
||||
void setColors(const QString &value);
|
||||
const QString getLoyalty() const;
|
||||
const QString getMainCardType() const;
|
||||
const QString getManaCost() const;
|
||||
const QString getPowTough() const;
|
||||
void setPowTough(const QString &value);
|
||||
|
||||
// methods using per-set properties
|
||||
QString getCustomPicURL(const QString &set) const
|
||||
{
|
||||
muIds.insert(_set, _muId);
|
||||
return getSetProperty(set, "picurl");
|
||||
}
|
||||
void setUuId(const QString &_set, const QString &_uuId)
|
||||
{
|
||||
uuIds.insert(_set, _uuId);
|
||||
}
|
||||
void setSetNumber(const QString &_set, const QString &_setNumber)
|
||||
{
|
||||
collectorNumbers.insert(_set, _setNumber);
|
||||
}
|
||||
void setRarity(const QString &_set, const QString &_setNumber)
|
||||
{
|
||||
rarities.insert(_set, _setNumber);
|
||||
}
|
||||
void addToSet(CardSetPtr set);
|
||||
QString getCorrectedName() const;
|
||||
void addToSet(const CardSetPtr &_set, CardInfoPerSet _info = CardInfoPerSet());
|
||||
void emitPixmapUpdated()
|
||||
{
|
||||
emit pixmapUpdated();
|
||||
|
@ -450,7 +414,6 @@ public:
|
|||
SetList getSetList() const;
|
||||
LoadStatus loadFromFile(const QString &fileName);
|
||||
bool saveCustomTokensToFile();
|
||||
QStringList getAllColors() const;
|
||||
QStringList getAllMainCardTypes() const;
|
||||
LoadStatus getLoadStatus() const
|
||||
{
|
||||
|
|
|
@ -14,9 +14,7 @@ CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromE
|
|||
cardDatabaseEnabledSetsChanged();
|
||||
}
|
||||
|
||||
CardDatabaseModel::~CardDatabaseModel()
|
||||
{
|
||||
}
|
||||
CardDatabaseModel::~CardDatabaseModel() = default;
|
||||
|
||||
QMap<wchar_t, wchar_t> CardDatabaseDisplayModel::characterTranslation = {{L'“', L'\"'},
|
||||
{L'”', L'\"'},
|
||||
|
@ -53,7 +51,7 @@ QVariant CardDatabaseModel::data(const QModelIndex &index, int role) const
|
|||
case PTColumn:
|
||||
return card->getPowTough();
|
||||
case ColorColumn:
|
||||
return card->getColors().join("");
|
||||
return card->getColors();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -97,8 +95,8 @@ bool CardDatabaseModel::checkCardHasAtLeastOneEnabledSet(CardInfoPtr card)
|
|||
if (!showOnlyCardsFromEnabledSets)
|
||||
return true;
|
||||
|
||||
for (CardSetPtr set : card->getSets()) {
|
||||
if (set->getEnabled())
|
||||
for (const auto &set : card->getSets()) {
|
||||
if (set.getPtr()->getEnabled())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,12 @@ public:
|
|||
{
|
||||
SortRole = Qt::UserRole
|
||||
};
|
||||
CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromEnabledSets, QObject *parent = 0);
|
||||
~CardDatabaseModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromEnabledSets, QObject *parent = nullptr);
|
||||
~CardDatabaseModel() override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
CardDatabase *getDatabase() const
|
||||
{
|
||||
return db;
|
||||
|
@ -77,7 +77,7 @@ private:
|
|||
static QMap<wchar_t, wchar_t> characterTranslation;
|
||||
|
||||
public:
|
||||
CardDatabaseDisplayModel(QObject *parent = 0);
|
||||
explicit CardDatabaseDisplayModel(QObject *parent = nullptr);
|
||||
void setFilterTree(FilterTree *filterTree);
|
||||
void setIsToken(FilterBool _isToken)
|
||||
{
|
||||
|
@ -119,15 +119,15 @@ public:
|
|||
invalidate();
|
||||
}
|
||||
void clearFilterAll();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
static int lessThanNumerically(const QString &left, const QString &right);
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool rowMatchesCardName(CardInfoPtr info) const;
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
private slots:
|
||||
void filterTreeChanged();
|
||||
/** Will translate all undesirable characters in DIRTYNAME according to the TABLE. */
|
||||
|
@ -138,11 +138,11 @@ class TokenDisplayModel : public CardDatabaseDisplayModel
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TokenDisplayModel(QObject *parent = 0);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
explicit TokenDisplayModel(QObject *parent = nullptr);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
27
cockatrice/src/carddbparser/carddatabaseparser.cpp
Normal file
27
cockatrice/src/carddbparser/carddatabaseparser.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "carddatabaseparser.h"
|
||||
|
||||
SetNameMap ICardDatabaseParser::sets;
|
||||
|
||||
void ICardDatabaseParser::clearSetlist()
|
||||
{
|
||||
sets.clear();
|
||||
}
|
||||
|
||||
CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
|
||||
const QString &longName,
|
||||
const QString &setType,
|
||||
const QDate &releaseDate)
|
||||
{
|
||||
if (sets.contains(setName)) {
|
||||
return sets.value(setName);
|
||||
}
|
||||
|
||||
CardSetPtr newSet = CardSet::newInstance(setName);
|
||||
newSet->setLongName(longName);
|
||||
newSet->setSetType(setType);
|
||||
newSet->setReleaseDate(releaseDate);
|
||||
|
||||
sets.insert(setName, newSet);
|
||||
emit addSet(newSet);
|
||||
return newSet;
|
||||
}
|
|
@ -9,15 +9,27 @@
|
|||
class ICardDatabaseParser : public QObject
|
||||
{
|
||||
public:
|
||||
virtual ~ICardDatabaseParser()
|
||||
{
|
||||
}
|
||||
~ICardDatabaseParser() override = default;
|
||||
|
||||
virtual bool getCanParseFile(const QString &name, QIODevice &device) = 0;
|
||||
virtual void parseFile(QIODevice &device) = 0;
|
||||
virtual bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) = 0;
|
||||
virtual void clearSetlist() = 0;
|
||||
static void clearSetlist();
|
||||
|
||||
protected:
|
||||
/*
|
||||
* A cached list of the available sets, needed to cross-reference sets from cards.
|
||||
* Shared between all parsers
|
||||
*/
|
||||
static SetNameMap sets;
|
||||
|
||||
CardSetPtr internalAddSet(const QString &setName,
|
||||
const QString &longName = "",
|
||||
const QString &setType = "",
|
||||
const QDate &releaseDate = QDate());
|
||||
signals:
|
||||
virtual void addCard(CardInfoPtr card) = 0;
|
||||
virtual void addSet(CardSetPtr set) = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(ICardDatabaseParser, "ICardDatabaseParser")
|
||||
|
|
|
@ -61,30 +61,6 @@ void CockatriceXml3Parser::parseFile(QIODevice &device)
|
|||
}
|
||||
}
|
||||
|
||||
CardSetPtr CockatriceXml3Parser::internalAddSet(const QString &setName,
|
||||
const QString &longName,
|
||||
const QString &setType,
|
||||
const QDate &releaseDate)
|
||||
{
|
||||
if (sets.contains(setName)) {
|
||||
return sets.value(setName);
|
||||
}
|
||||
|
||||
CardSetPtr newSet = CardSet::newInstance(setName);
|
||||
newSet->setLongName(longName);
|
||||
newSet->setSetType(setType);
|
||||
newSet->setReleaseDate(releaseDate);
|
||||
|
||||
sets.insert(setName, newSet);
|
||||
emit addSet(newSet);
|
||||
return newSet;
|
||||
}
|
||||
|
||||
void CockatriceXml3Parser::clearSetlist()
|
||||
{
|
||||
sets.clear();
|
||||
}
|
||||
|
||||
void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
while (!xml.atEnd()) {
|
||||
|
@ -120,6 +96,44 @@ void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
|||
}
|
||||
}
|
||||
|
||||
QString CockatriceXml3Parser::getMainCardType(QString &type)
|
||||
{
|
||||
QString result = type;
|
||||
/*
|
||||
Legendary Artifact Creature - Golem
|
||||
Instant // Instant
|
||||
*/
|
||||
|
||||
int pos;
|
||||
if ((pos = result.indexOf('-')) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
if ((pos = result.indexOf("—")) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
if ((pos = result.indexOf("//")) != -1) {
|
||||
result.remove(pos, result.length());
|
||||
}
|
||||
|
||||
result = result.simplified();
|
||||
/*
|
||||
Legendary Artifact Creature
|
||||
Instant
|
||||
*/
|
||||
|
||||
if ((pos = result.lastIndexOf(' ')) != -1) {
|
||||
result = result.mid(pos + 1);
|
||||
}
|
||||
/*
|
||||
Creature
|
||||
Instant
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
while (!xml.atEnd()) {
|
||||
|
@ -128,59 +142,77 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||
}
|
||||
|
||||
if (xml.name() == "card") {
|
||||
QString name, manacost, cmc, type, pt, text, loyalty;
|
||||
QStringList colors;
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
QString colors = QString("");
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
QStringMap customPicURLs;
|
||||
MuidMap muids;
|
||||
QStringMap uuids, collectorNumbers, rarities;
|
||||
SetList sets;
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
bool upsideDown = false;
|
||||
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
// variable - assigned properties
|
||||
if (xml.name() == "name") {
|
||||
name = xml.readElementText();
|
||||
} else if (xml.name() == "manacost") {
|
||||
manacost = xml.readElementText();
|
||||
} else if (xml.name() == "cmc") {
|
||||
cmc = xml.readElementText();
|
||||
} else if (xml.name() == "type") {
|
||||
type = xml.readElementText();
|
||||
} else if (xml.name() == "pt") {
|
||||
pt = xml.readElementText();
|
||||
} else if (xml.name() == "text") {
|
||||
text = xml.readElementText();
|
||||
} else if (xml.name() == "color") {
|
||||
colors.append(xml.readElementText());
|
||||
} else if (xml.name() == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText().toInt());
|
||||
// generic properties
|
||||
} else if (xml.name() == "manacost") {
|
||||
properties.insert("manacost", xml.readElementText());
|
||||
} else if (xml.name() == "cmc") {
|
||||
properties.insert("cmc", xml.readElementText());
|
||||
} else if (xml.name() == "type") {
|
||||
QString type = xml.readElementText();
|
||||
properties.insert("type", type);
|
||||
properties.insert("maintype", getMainCardType(type));
|
||||
} else if (xml.name() == "pt") {
|
||||
properties.insert("pt", xml.readElementText());
|
||||
} else if (xml.name() == "loyalty") {
|
||||
properties.insert("loyalty", xml.readElementText());
|
||||
// positioning info
|
||||
} else if (xml.name() == "tablerow") {
|
||||
tableRow = xml.readElementText().toInt();
|
||||
} else if (xml.name() == "cipt") {
|
||||
cipt = (xml.readElementText() == "1");
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
upsideDown = (xml.readElementText() == "1");
|
||||
// sets
|
||||
} else if (xml.name() == "set") {
|
||||
// NOTE: attributes must be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText();
|
||||
sets.append(internalAddSet(setName));
|
||||
CardInfoPerSet setInfo(internalAddSet(setName));
|
||||
if (attrs.hasAttribute("muId")) {
|
||||
muids[setName] = attrs.value("muId").toString().toInt();
|
||||
setInfo.setProperty("muid", attrs.value("muId").toString());
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("muId")) {
|
||||
uuids[setName] = attrs.value("uuId").toString();
|
||||
setInfo.setProperty("uuid", attrs.value("uuId").toString());
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("picURL")) {
|
||||
customPicURLs[setName] = attrs.value("picURL").toString();
|
||||
setInfo.setProperty("picurl", attrs.value("picURL").toString());
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("num")) {
|
||||
collectorNumbers[setName] = attrs.value("num").toString();
|
||||
setInfo.setProperty("num", attrs.value("num").toString());
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("rarity")) {
|
||||
rarities[setName] = attrs.value("rarity").toString();
|
||||
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
||||
}
|
||||
} else if (xml.name() == "color") {
|
||||
colors << xml.readElementText();
|
||||
sets.insert(setName, setInfo);
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
|
@ -217,16 +249,6 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (xml.name() == "tablerow") {
|
||||
tableRow = xml.readElementText().toInt();
|
||||
} else if (xml.name() == "cipt") {
|
||||
cipt = (xml.readElementText() == "1");
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
upsideDown = (xml.readElementText() == "1");
|
||||
} else if (xml.name() == "loyalty") {
|
||||
loyalty = xml.readElementText();
|
||||
} else if (xml.name() == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText().toInt());
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
|
@ -234,9 +256,9 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||
}
|
||||
}
|
||||
|
||||
CardInfoPtr newCard = CardInfo::newInstance(
|
||||
name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, reverseRelatedCards, upsideDown,
|
||||
loyalty, cipt, tableRow, sets, customPicURLs, muids, uuids, collectorNumbers, rarities);
|
||||
properties.insert("colors", colors);
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
|
@ -266,38 +288,60 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||
return xml;
|
||||
}
|
||||
|
||||
xml.writeStartElement("card");
|
||||
xml.writeTextElement("name", info->getName());
|
||||
|
||||
const SetList &sets = info->getSets();
|
||||
QString tmpString;
|
||||
QString tmpSet;
|
||||
for (int i = 0; i < sets.size(); i++) {
|
||||
xml.writeStartElement("set");
|
||||
|
||||
tmpSet = sets[i]->getShortName();
|
||||
xml.writeAttribute("rarity", info->getRarity(tmpSet));
|
||||
xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet)));
|
||||
xml.writeAttribute("uuId", info->getUuId(tmpSet));
|
||||
xml.writeStartElement("card");
|
||||
|
||||
tmpString = info->getCollectorNumber(tmpSet);
|
||||
if (!tmpString.isEmpty()) {
|
||||
xml.writeAttribute("num", info->getCollectorNumber(tmpSet));
|
||||
// variable - assigned properties
|
||||
xml.writeTextElement("name", info->getName());
|
||||
xml.writeTextElement("text", info->getText());
|
||||
if (info->getIsToken()) {
|
||||
xml.writeTextElement("token", "1");
|
||||
}
|
||||
|
||||
tmpString = info->getCustomPicURL(tmpSet);
|
||||
// generic properties
|
||||
xml.writeTextElement("manacost", info->getProperty("manacost"));
|
||||
xml.writeTextElement("cmc", info->getProperty("cmc"));
|
||||
xml.writeTextElement("type", info->getProperty("type"));
|
||||
|
||||
int colorSize = info->getColors().size();
|
||||
for (int i = 0; i < colorSize; ++i) {
|
||||
xml.writeTextElement("color", info->getColors().at(i));
|
||||
}
|
||||
|
||||
tmpString = info->getProperty("pt");
|
||||
if (!tmpString.isEmpty()) {
|
||||
xml.writeTextElement("pt", tmpString);
|
||||
}
|
||||
|
||||
tmpString = info->getProperty("loyalty");
|
||||
if (!tmpString.isEmpty()) {
|
||||
xml.writeTextElement("loyalty", tmpString);
|
||||
}
|
||||
|
||||
// sets
|
||||
const CardInfoPerSetMap sets = info->getSets();
|
||||
for (CardInfoPerSet set : sets) {
|
||||
xml.writeStartElement("set");
|
||||
xml.writeAttribute("rarity", set.getProperty("rarity"));
|
||||
xml.writeAttribute("muId", set.getProperty("muid"));
|
||||
xml.writeAttribute("uuId", set.getProperty("uuid"));
|
||||
|
||||
tmpString = set.getProperty("num");
|
||||
if (!tmpString.isEmpty()) {
|
||||
xml.writeAttribute("num", tmpString);
|
||||
}
|
||||
|
||||
tmpString = set.getProperty("picurl");
|
||||
if (!tmpString.isEmpty()) {
|
||||
xml.writeAttribute("picURL", tmpString);
|
||||
}
|
||||
|
||||
xml.writeCharacters(tmpSet);
|
||||
xml.writeCharacters(set.getPtr()->getShortName());
|
||||
xml.writeEndElement();
|
||||
}
|
||||
const QStringList &colors = info->getColors();
|
||||
for (int i = 0; i < colors.size(); i++) {
|
||||
xml.writeTextElement("color", colors[i]);
|
||||
}
|
||||
|
||||
// related cards
|
||||
const QList<CardRelation *> related = info->getRelatedCards();
|
||||
for (auto i : related) {
|
||||
xml.writeStartElement("related");
|
||||
|
@ -343,23 +387,12 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||
xml.writeCharacters(i->getName());
|
||||
xml.writeEndElement();
|
||||
}
|
||||
xml.writeTextElement("manacost", info->getManaCost());
|
||||
xml.writeTextElement("cmc", info->getCmc());
|
||||
xml.writeTextElement("type", info->getCardType());
|
||||
if (!info->getPowTough().isEmpty()) {
|
||||
xml.writeTextElement("pt", info->getPowTough());
|
||||
}
|
||||
|
||||
// positioning
|
||||
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
||||
xml.writeTextElement("text", info->getText());
|
||||
if (info->getMainCardType() == "Planeswalker") {
|
||||
xml.writeTextElement("loyalty", info->getLoyalty());
|
||||
}
|
||||
if (info->getCipt()) {
|
||||
xml.writeTextElement("cipt", "1");
|
||||
}
|
||||
if (info->getIsToken()) {
|
||||
xml.writeTextElement("token", "1");
|
||||
}
|
||||
if (info->getUpsideDownArt()) {
|
||||
xml.writeTextElement("upsidedown", "1");
|
||||
}
|
||||
|
|
|
@ -11,27 +11,18 @@ class CockatriceXml3Parser : public ICardDatabaseParser
|
|||
Q_INTERFACES(ICardDatabaseParser)
|
||||
public:
|
||||
CockatriceXml3Parser() = default;
|
||||
~CockatriceXml3Parser() = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device);
|
||||
void parseFile(QIODevice &device);
|
||||
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName);
|
||||
void clearSetlist();
|
||||
~CockatriceXml3Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) override;
|
||||
|
||||
private:
|
||||
/*
|
||||
* A cached list of the available sets, needed to cross-reference sets from cards.
|
||||
*/
|
||||
SetNameMap sets;
|
||||
|
||||
CardSetPtr internalAddSet(const QString &setName,
|
||||
const QString &longName = "",
|
||||
const QString &setType = "",
|
||||
const QDate &releaseDate = QDate());
|
||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||
QString getMainCardType(QString &type);
|
||||
signals:
|
||||
void addCard(CardInfoPtr card);
|
||||
void addSet(CardSetPtr set);
|
||||
void addCard(CardInfoPtr card) override;
|
||||
void addSet(CardSetPtr set) override;
|
||||
};
|
||||
|
||||
#endif
|
362
cockatrice/src/carddbparser/cockatricexml4.cpp
Normal file
362
cockatrice/src/carddbparser/cockatricexml4.cpp
Normal file
|
@ -0,0 +1,362 @@
|
|||
#include "cockatricexml4.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#define COCKATRICE_XML4_TAGNAME "cockatrice_carddatabase"
|
||||
#define COCKATRICE_XML4_TAGVER 4
|
||||
|
||||
bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &device)
|
||||
{
|
||||
qDebug() << "[CockatriceXml4Parser] Trying to parse: " << fileName;
|
||||
|
||||
if (!fileName.endsWith(".xml", Qt::CaseInsensitive)) {
|
||||
qDebug() << "[CockatriceXml4Parser] Parsing failed: wrong extension";
|
||||
return false;
|
||||
}
|
||||
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name() == COCKATRICE_XML4_TAGNAME) {
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version == COCKATRICE_XML4_TAGVER) {
|
||||
return true;
|
||||
} else {
|
||||
qDebug() << "[CockatriceXml4Parser] Parsing failed: wrong version" << version;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
qDebug() << "[CockatriceXml4Parser] Parsing failed: wrong element tag" << xml.name();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CockatriceXml4Parser::parseFile(QIODevice &device)
|
||||
{
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "sets") {
|
||||
loadSetsFromXml(xml);
|
||||
} else if (xml.name() == "cards") {
|
||||
loadCardsFromXml(xml);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "name") {
|
||||
shortName = xml.readElementText();
|
||||
} else if (xml.name() == "longname") {
|
||||
longName = xml.readElementText();
|
||||
} else if (xml.name() == "settype") {
|
||||
setType = xml.readElementText();
|
||||
} else if (xml.name() == "releasedate") {
|
||||
releaseDate = QDate::fromString(xml.readElementText(), Qt::ISODate);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
internalAddSet(shortName, longName, setType, releaseDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariantHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
QVariantHash properties = QVariantHash();
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() != "") {
|
||||
properties.insert(xml.name().toString(), xml.readElementText());
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "card") {
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
bool upsideDown = false;
|
||||
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
// variable - assigned properties
|
||||
if (xml.name() == "name") {
|
||||
name = xml.readElementText();
|
||||
} else if (xml.name() == "text") {
|
||||
text = xml.readElementText();
|
||||
} else if (xml.name() == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText().toInt());
|
||||
// generic properties
|
||||
} else if (xml.name() == "prop") {
|
||||
properties = loadCardPropertiesFromXml(xml);
|
||||
// positioning info
|
||||
} else if (xml.name() == "tablerow") {
|
||||
tableRow = xml.readElementText().toInt();
|
||||
} else if (xml.name() == "cipt") {
|
||||
cipt = (xml.readElementText() == "1");
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
upsideDown = (xml.readElementText() == "1");
|
||||
// sets
|
||||
} else if (xml.name() == "set") {
|
||||
// NOTE: attributes but be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText();
|
||||
CardInfoPerSet setInfo(internalAddSet(setName));
|
||||
for (QXmlStreamAttribute attr : attrs) {
|
||||
setInfo.setProperty(attr.name().toString(), attr.value().toString());
|
||||
}
|
||||
sets.insert(setName, setInfo);
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
int count = 1;
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString cardName = xml.readElementText();
|
||||
if (attrs.hasAttribute("count")) {
|
||||
if (attrs.value("count").toString().indexOf("x=") == 0) {
|
||||
variable = true;
|
||||
count = attrs.value("count").toString().remove(0, 2).toInt();
|
||||
} else if (attrs.value("count").toString().indexOf("x") == 0) {
|
||||
variable = true;
|
||||
} else {
|
||||
count = attrs.value("count").toString().toInt();
|
||||
}
|
||||
|
||||
if (count < 1) {
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("attach")) {
|
||||
attach = true;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("exclude")) {
|
||||
exclude = true;
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xml.name() == "reverse-related") {
|
||||
reverseRelatedCards << relation;
|
||||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSetPtr &set)
|
||||
{
|
||||
if (set.isNull()) {
|
||||
qDebug() << "&operator<< set is nullptr";
|
||||
return xml;
|
||||
}
|
||||
|
||||
xml.writeStartElement("set");
|
||||
xml.writeTextElement("name", set->getShortName());
|
||||
xml.writeTextElement("longname", set->getLongName());
|
||||
xml.writeTextElement("settype", set->getSetType());
|
||||
xml.writeTextElement("releasedate", set->getReleaseDate().toString(Qt::ISODate));
|
||||
xml.writeEndElement();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &info)
|
||||
{
|
||||
if (info.isNull()) {
|
||||
qDebug() << "operator<< info is nullptr";
|
||||
return xml;
|
||||
}
|
||||
|
||||
QString tmpString;
|
||||
|
||||
xml.writeStartElement("card");
|
||||
|
||||
// variable - assigned properties
|
||||
xml.writeTextElement("name", info->getName());
|
||||
xml.writeTextElement("text", info->getText());
|
||||
if (info->getIsToken()) {
|
||||
xml.writeTextElement("token", "1");
|
||||
}
|
||||
|
||||
// generic properties
|
||||
xml.writeStartElement("prop");
|
||||
for (QString propName : info->getProperties()) {
|
||||
xml.writeTextElement(propName, info->getProperty(propName));
|
||||
}
|
||||
xml.writeEndElement();
|
||||
|
||||
// sets
|
||||
for (CardInfoPerSet set : info->getSets()) {
|
||||
xml.writeStartElement("set");
|
||||
for (QString propName : set.getProperties()) {
|
||||
xml.writeAttribute(propName, set.getProperty(propName));
|
||||
}
|
||||
|
||||
xml.writeCharacters(set.getPtr()->getShortName());
|
||||
xml.writeEndElement();
|
||||
}
|
||||
|
||||
// related cards
|
||||
const QList<CardRelation *> related = info->getRelatedCards();
|
||||
for (auto i : related) {
|
||||
xml.writeStartElement("related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", "attach");
|
||||
}
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
} else {
|
||||
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
||||
}
|
||||
} else if (1 != i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
||||
}
|
||||
xml.writeCharacters(i->getName());
|
||||
xml.writeEndElement();
|
||||
}
|
||||
const QList<CardRelation *> reverseRelated = info->getReverseRelatedCards();
|
||||
for (auto i : reverseRelated) {
|
||||
xml.writeStartElement("reverse-related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", "attach");
|
||||
}
|
||||
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
} else {
|
||||
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
||||
}
|
||||
} else if (1 != i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
||||
}
|
||||
xml.writeCharacters(i->getName());
|
||||
xml.writeEndElement();
|
||||
}
|
||||
|
||||
// positioning
|
||||
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
||||
if (info->getCipt()) {
|
||||
xml.writeTextElement("cipt", "1");
|
||||
}
|
||||
if (info->getUpsideDownArt()) {
|
||||
xml.writeTextElement("upsidedown", "1");
|
||||
}
|
||||
|
||||
xml.writeEndElement(); // card
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool CockatriceXml4Parser::saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QXmlStreamWriter xml(&file);
|
||||
|
||||
xml.setAutoFormatting(true);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement(COCKATRICE_XML4_TAGNAME);
|
||||
xml.writeAttribute("version", QString::number(COCKATRICE_XML4_TAGVER));
|
||||
|
||||
if (sets.count() > 0) {
|
||||
xml.writeStartElement("sets");
|
||||
for (CardSetPtr set : sets) {
|
||||
xml << set;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
}
|
||||
|
||||
if (cards.count() > 0) {
|
||||
xml.writeStartElement("cards");
|
||||
for (CardInfoPtr card : cards) {
|
||||
xml << card;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
}
|
||||
|
||||
xml.writeEndElement(); // cockatrice_carddatabase
|
||||
xml.writeEndDocument();
|
||||
|
||||
return true;
|
||||
}
|
28
cockatrice/src/carddbparser/cockatricexml4.h
Normal file
28
cockatrice/src/carddbparser/cockatricexml4.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef COCKATRICE_XML4_H
|
||||
#define COCKATRICE_XML4_H
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include "carddatabaseparser.h"
|
||||
|
||||
class CockatriceXml4Parser : public ICardDatabaseParser
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ICardDatabaseParser)
|
||||
public:
|
||||
CockatriceXml4Parser() = default;
|
||||
~CockatriceXml4Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) override;
|
||||
|
||||
private:
|
||||
QVariantHash loadCardPropertiesFromXml(QXmlStreamReader &xml);
|
||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||
signals:
|
||||
void addCard(CardInfoPtr card) override;
|
||||
void addSet(CardSetPtr set) override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,3 +1,5 @@
|
|||
#include <utility>
|
||||
|
||||
#include "cardframe.h"
|
||||
|
||||
#include "cardinfopicture.h"
|
||||
|
@ -16,6 +18,7 @@ CardFrame::CardFrame(const QString &cardName, QWidget *parent) : QTabWidget(pare
|
|||
pic->setObjectName("pic");
|
||||
text = new CardInfoText();
|
||||
text->setObjectName("text");
|
||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
||||
|
||||
tab1 = new QWidget(this);
|
||||
tab2 = new QWidget(this);
|
||||
|
@ -93,10 +96,10 @@ void CardFrame::setCard(CardInfoPtr card)
|
|||
disconnect(info.data(), nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
info = card;
|
||||
info = std::move(card);
|
||||
|
||||
if (info) {
|
||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clear()));
|
||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clearCard()));
|
||||
}
|
||||
|
||||
text->setCard(info);
|
||||
|
@ -115,7 +118,7 @@ void CardFrame::setCard(AbstractCardItem *card)
|
|||
}
|
||||
}
|
||||
|
||||
void CardFrame::clear()
|
||||
void CardFrame::clearCard()
|
||||
{
|
||||
setCard((CardInfoPtr) nullptr);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public slots:
|
|||
void setCard(CardInfoPtr card);
|
||||
void setCard(const QString &cardName);
|
||||
void setCard(AbstractCardItem *card);
|
||||
void clear();
|
||||
void clearCard();
|
||||
void setViewMode(int mode);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,137 +1,83 @@
|
|||
#include "cardinfotext.h"
|
||||
|
||||
#include "carditem.h"
|
||||
#include "game_specific_terms.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
|
||||
CardInfoText::CardInfoText(QWidget *parent) : QFrame(parent), info(nullptr)
|
||||
{
|
||||
nameLabel1 = new QLabel;
|
||||
nameLabel2 = new QLabel;
|
||||
nameLabel2->setWordWrap(true);
|
||||
nameLabel2->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
manacostLabel1 = new QLabel;
|
||||
manacostLabel2 = new QLabel;
|
||||
manacostLabel2->setWordWrap(true);
|
||||
manacostLabel2->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
colorLabel1 = new QLabel;
|
||||
colorLabel2 = new QLabel;
|
||||
colorLabel2->setWordWrap(true);
|
||||
colorLabel2->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
cardtypeLabel1 = new QLabel;
|
||||
cardtypeLabel2 = new QLabel;
|
||||
cardtypeLabel2->setWordWrap(true);
|
||||
cardtypeLabel2->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
powtoughLabel1 = new QLabel;
|
||||
powtoughLabel2 = new QLabel;
|
||||
powtoughLabel2->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
loyaltyLabel1 = new QLabel;
|
||||
loyaltyLabel2 = new QLabel;
|
||||
loyaltyLabel1->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
nameLabel = new QLabel;
|
||||
nameLabel->setOpenExternalLinks(false);
|
||||
connect(nameLabel, SIGNAL(linkActivated(const QString &)), this, SIGNAL(linkActivated(const QString &)));
|
||||
|
||||
textLabel = new QTextEdit();
|
||||
textLabel->setReadOnly(true);
|
||||
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
int row = 0;
|
||||
grid->addWidget(nameLabel1, row, 0);
|
||||
grid->addWidget(nameLabel2, row++, 1);
|
||||
grid->addWidget(manacostLabel1, row, 0);
|
||||
grid->addWidget(manacostLabel2, row++, 1);
|
||||
grid->addWidget(colorLabel1, row, 0);
|
||||
grid->addWidget(colorLabel2, row++, 1);
|
||||
grid->addWidget(cardtypeLabel1, row, 0);
|
||||
grid->addWidget(cardtypeLabel2, row++, 1);
|
||||
grid->addWidget(powtoughLabel1, row, 0);
|
||||
grid->addWidget(powtoughLabel2, row++, 1);
|
||||
grid->addWidget(loyaltyLabel1, row, 0);
|
||||
grid->addWidget(loyaltyLabel2, row++, 1);
|
||||
grid->addWidget(textLabel, row, 0, -1, 2);
|
||||
grid->setRowStretch(row, 1);
|
||||
grid->addWidget(nameLabel, 0, 0);
|
||||
grid->addWidget(textLabel, 1, 0, -1, 2);
|
||||
grid->setRowStretch(1, 1);
|
||||
grid->setColumnStretch(1, 1);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
// Reset every label which is optionally hidden
|
||||
void CardInfoText::resetLabels()
|
||||
{
|
||||
nameLabel1->show();
|
||||
nameLabel2->show();
|
||||
manacostLabel1->show();
|
||||
manacostLabel2->show();
|
||||
colorLabel1->show();
|
||||
colorLabel2->show();
|
||||
cardtypeLabel1->show();
|
||||
cardtypeLabel2->show();
|
||||
powtoughLabel1->show();
|
||||
powtoughLabel2->show();
|
||||
loyaltyLabel1->show();
|
||||
loyaltyLabel2->show();
|
||||
textLabel->show();
|
||||
}
|
||||
|
||||
void CardInfoText::setCard(CardInfoPtr card)
|
||||
{
|
||||
if (card) {
|
||||
resetLabels();
|
||||
nameLabel2->setText(card->getName());
|
||||
if (!card->getManaCost().isEmpty()) {
|
||||
manacostLabel2->setText(card->getManaCost());
|
||||
} else {
|
||||
manacostLabel1->hide();
|
||||
manacostLabel2->hide();
|
||||
if (card == nullptr) {
|
||||
nameLabel->setText("");
|
||||
textLabel->setText("");
|
||||
return;
|
||||
}
|
||||
if (!card->getColors().isEmpty()) {
|
||||
colorLabel2->setText(card->getColors().join(""));
|
||||
} else {
|
||||
colorLabel2->setText("Colorless");
|
||||
|
||||
QString text = "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
text += QString("<tr><td>%1</td><td width=\"5\"></td><td>%2</td></tr>")
|
||||
.arg(tr("Name:"), card->getName().toHtmlEscaped());
|
||||
|
||||
QStringList cardProps = card->getProperties();
|
||||
foreach (QString key, cardProps) {
|
||||
QString keyText = Mtg::getNicePropertyName(key).toHtmlEscaped() + ":";
|
||||
text +=
|
||||
QString("<tr><td>%1</td><td></td><td>%2</td></tr>").arg(keyText, card->getProperty(key).toHtmlEscaped());
|
||||
}
|
||||
cardtypeLabel2->setText(card->getCardType());
|
||||
if (!card->getPowTough().isEmpty()) {
|
||||
powtoughLabel2->setText(card->getPowTough());
|
||||
} else {
|
||||
powtoughLabel1->hide();
|
||||
powtoughLabel2->hide();
|
||||
|
||||
auto relatedCards = card->getRelatedCards();
|
||||
auto reverserelatedCards2Me = card->getReverseRelatedCards2Me();
|
||||
if (relatedCards.size() || reverserelatedCards2Me.size()) {
|
||||
text += QString("<tr><td>%1</td><td width=\"5\"></td><td>").arg(tr("Related cards:"));
|
||||
|
||||
for (int i = 0; i < relatedCards.size(); ++i) {
|
||||
QString tmp = relatedCards.at(i)->getName().toHtmlEscaped();
|
||||
text += "<a href=\"" + tmp + "\">" + tmp + "</a><br>";
|
||||
}
|
||||
if (!card->getLoyalty().isEmpty()) {
|
||||
loyaltyLabel2->setText(card->getLoyalty());
|
||||
} else {
|
||||
loyaltyLabel1->hide();
|
||||
loyaltyLabel2->hide();
|
||||
|
||||
for (int i = 0; i < reverserelatedCards2Me.size(); ++i) {
|
||||
QString tmp = reverserelatedCards2Me.at(i)->getName().toHtmlEscaped();
|
||||
text += "<a href=\"" + tmp + "\">" + tmp + "</a><br>";
|
||||
}
|
||||
|
||||
text += "</td></tr>";
|
||||
}
|
||||
|
||||
text += "</table>";
|
||||
nameLabel->setText(text);
|
||||
textLabel->setText(card->getText());
|
||||
} else {
|
||||
nameLabel1->hide();
|
||||
nameLabel2->hide();
|
||||
manacostLabel1->hide();
|
||||
manacostLabel2->hide();
|
||||
colorLabel1->hide();
|
||||
colorLabel2->hide();
|
||||
cardtypeLabel1->hide();
|
||||
cardtypeLabel2->hide();
|
||||
powtoughLabel1->hide();
|
||||
powtoughLabel2->hide();
|
||||
loyaltyLabel1->hide();
|
||||
loyaltyLabel2->hide();
|
||||
textLabel->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void CardInfoText::setInvalidCardName(const QString &cardName)
|
||||
{
|
||||
nameLabel1->setText(tr("Unknown card:"));
|
||||
nameLabel1->show();
|
||||
nameLabel2->setText(cardName);
|
||||
nameLabel2->show();
|
||||
nameLabel->setText(tr("Unknown card:") + " " + cardName);
|
||||
textLabel->setText("");
|
||||
}
|
||||
|
||||
void CardInfoText::retranslateUi()
|
||||
{
|
||||
nameLabel1->setText(tr("Name:"));
|
||||
manacostLabel1->setText(tr("Mana cost:"));
|
||||
colorLabel1->setText(tr("Color(s):"));
|
||||
cardtypeLabel1->setText(tr("Card type:"));
|
||||
powtoughLabel1->setText(tr("P / T:"));
|
||||
loyaltyLabel1->setText(tr("Loyalty:"));
|
||||
/*
|
||||
* There's no way we can really translate the text currently being rendered.
|
||||
* The best we can do is invalidate the current text.
|
||||
*/
|
||||
setInvalidCardName("");
|
||||
}
|
||||
|
|
|
@ -12,23 +12,17 @@ class CardInfoText : public QFrame
|
|||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QLabel *nameLabel1, *nameLabel2;
|
||||
QLabel *manacostLabel1, *manacostLabel2;
|
||||
QLabel *colorLabel1, *colorLabel2;
|
||||
QLabel *cardtypeLabel1, *cardtypeLabel2;
|
||||
QLabel *powtoughLabel1, *powtoughLabel2;
|
||||
QLabel *loyaltyLabel1, *loyaltyLabel2;
|
||||
QLabel *nameLabel;
|
||||
QTextEdit *textLabel;
|
||||
|
||||
CardInfoPtr info;
|
||||
|
||||
void resetLabels();
|
||||
|
||||
public:
|
||||
CardInfoText(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
void setInvalidCardName(const QString &cardName);
|
||||
|
||||
signals:
|
||||
void linkActivated(const QString &link);
|
||||
public slots:
|
||||
void setCard(CardInfoPtr card);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "cardinfowidget.h"
|
||||
#include <utility>
|
||||
|
||||
#include "cardinfopicture.h"
|
||||
#include "cardinfotext.h"
|
||||
#include "cardinfowidget.h"
|
||||
#include "carditem.h"
|
||||
#include "main.h"
|
||||
#include <QDesktopWidget>
|
||||
|
@ -14,8 +16,9 @@ CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::Win
|
|||
pic->setObjectName("pic");
|
||||
text = new CardInfoText();
|
||||
text->setObjectName("text");
|
||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
auto *layout = new QVBoxLayout();
|
||||
layout->setObjectName("layout");
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
|
@ -26,7 +29,7 @@ CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::Win
|
|||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
QDesktopWidget desktopWidget;
|
||||
int pixmapHeight = desktopWidget.screenGeometry().height() / 3;
|
||||
int pixmapWidth = pixmapHeight / aspectRatio;
|
||||
int pixmapWidth = static_cast<int>(pixmapHeight / aspectRatio);
|
||||
pic->setFixedWidth(pixmapWidth);
|
||||
pic->setFixedHeight(pixmapHeight);
|
||||
setFixedWidth(pixmapWidth + 150);
|
||||
|
@ -41,7 +44,7 @@ void CardInfoWidget::setCard(CardInfoPtr card)
|
|||
{
|
||||
if (info)
|
||||
disconnect(info.data(), nullptr, this, nullptr);
|
||||
info = card;
|
||||
info = std::move(card);
|
||||
if (info)
|
||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clear()));
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ private:
|
|||
CardInfoText *text;
|
||||
|
||||
public:
|
||||
CardInfoWidget(const QString &cardName, QWidget *parent = 0, Qt::WindowFlags f = 0);
|
||||
explicit CardInfoWidget(const QString &cardName, QWidget *parent = nullptr, Qt::WindowFlags f = nullptr);
|
||||
|
||||
public slots:
|
||||
void setCard(CardInfoPtr card);
|
||||
|
|
|
@ -322,9 +322,7 @@ QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneN
|
|||
// This is usually called from tab_deck_editor
|
||||
// So we'll create a new CardInfo with the name
|
||||
// and default values for all fields
|
||||
info = CardInfo::newInstance(cardName, false, nullptr, nullptr, "unknown", nullptr, nullptr, QStringList(),
|
||||
QList<CardRelation *>(), QList<CardRelation *>(), false, 0, false, 0,
|
||||
SetList(), QStringMap(), MuidMap(), QStringMap(), QStringMap(), QStringMap());
|
||||
info = CardInfo::newInstance(cardName);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
class DeckLoader;
|
||||
class CardDatabase;
|
||||
class QProgressDialog;
|
||||
class QPrinter;
|
||||
class QTextCursor;
|
||||
|
||||
|
@ -21,19 +20,19 @@ public:
|
|||
: AbstractDecklistCardNode(_parent), dataNode(_dataNode)
|
||||
{
|
||||
}
|
||||
int getNumber() const
|
||||
int getNumber() const override
|
||||
{
|
||||
return dataNode->getNumber();
|
||||
}
|
||||
void setNumber(int _number)
|
||||
void setNumber(int _number) override
|
||||
{
|
||||
dataNode->setNumber(_number);
|
||||
}
|
||||
QString getName() const
|
||||
QString getName() const override
|
||||
{
|
||||
return dataNode->getName();
|
||||
}
|
||||
void setName(const QString &_name)
|
||||
void setName(const QString &_name) override
|
||||
{
|
||||
dataNode->setName(_name);
|
||||
}
|
||||
|
@ -54,20 +53,20 @@ signals:
|
|||
void deckHashChanged();
|
||||
|
||||
public:
|
||||
DeckListModel(QObject *parent = 0);
|
||||
~DeckListModel();
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
bool removeRows(int row, int count, const QModelIndex &parent);
|
||||
explicit DeckListModel(QObject *parent = nullptr);
|
||||
~DeckListModel() override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent) override;
|
||||
QModelIndex findCard(const QString &cardName, const QString &zoneName) const;
|
||||
QModelIndex addCard(const QString &cardName, const QString &zoneName, bool abAddAnyway = false);
|
||||
void sort(int column, Qt::SortOrder order);
|
||||
void sort(int column, Qt::SortOrder order) override;
|
||||
void cleanList();
|
||||
DeckLoader *getDeckList() const
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <QTreeView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(0)
|
||||
DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nullptr)
|
||||
{
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit;
|
||||
|
@ -46,7 +46,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(0)
|
|||
annotationLabel->setBuddy(annotationEdit);
|
||||
connect(annotationEdit, SIGNAL(textChanged(QString)), this, SLOT(annotationChanged(QString)));
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
auto *grid = new QGridLayout;
|
||||
grid->addWidget(nameLabel, 0, 0);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(colorLabel, 1, 0);
|
||||
|
@ -89,15 +89,15 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(0)
|
|||
aRemoveToken->setIcon(QPixmap("theme:icons/decrement"));
|
||||
connect(aRemoveToken, SIGNAL(triggered()), this, SLOT(actRemoveToken()));
|
||||
|
||||
QToolBar *databaseToolBar = new QToolBar;
|
||||
auto *databaseToolBar = new QToolBar;
|
||||
databaseToolBar->addAction(aAddToken);
|
||||
databaseToolBar->addAction(aRemoveToken);
|
||||
|
||||
QVBoxLayout *leftVBox = new QVBoxLayout;
|
||||
auto *leftVBox = new QVBoxLayout;
|
||||
leftVBox->addWidget(chooseTokenView);
|
||||
leftVBox->addWidget(databaseToolBar);
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout;
|
||||
auto *hbox = new QHBoxLayout;
|
||||
hbox->addLayout(leftVBox);
|
||||
hbox->addWidget(tokenDataGroupBox);
|
||||
|
||||
|
@ -105,7 +105,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(0)
|
|||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(hbox);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
|
@ -154,9 +154,10 @@ void DlgEditTokens::actAddToken()
|
|||
}
|
||||
} while (askAgain);
|
||||
|
||||
CardInfoPtr card = CardInfo::newInstance(name, true);
|
||||
card->addToSet(databaseModel->getDatabase()->getSet(CardDatabase::TOKENS_SETNAME));
|
||||
CardInfoPtr card = CardInfo::newInstance(name, "", true);
|
||||
card->setCardType("Token");
|
||||
card->addToSet(databaseModel->getDatabase()->getSet(CardDatabase::TOKENS_SETNAME));
|
||||
|
||||
databaseModel->getDatabase()->addCard(card);
|
||||
}
|
||||
|
||||
|
@ -172,7 +173,7 @@ void DlgEditTokens::actRemoveToken()
|
|||
void DlgEditTokens::colorChanged(int colorIndex)
|
||||
{
|
||||
if (currentCard)
|
||||
currentCard->setColors(QStringList() << QString(colorEdit->itemData(colorIndex).toChar()));
|
||||
currentCard->setColors(QString(colorEdit->itemData(colorIndex).toChar()));
|
||||
}
|
||||
|
||||
void DlgEditTokens::ptChanged(const QString &_pt)
|
||||
|
|
|
@ -35,7 +35,7 @@ private:
|
|||
QTreeView *chooseTokenView;
|
||||
|
||||
public:
|
||||
DlgEditTokens(QWidget *parent = nullptr);
|
||||
explicit DlgEditTokens(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -187,12 +187,9 @@ bool FilterItem::acceptColor(const CardInfoPtr info) const
|
|||
*/
|
||||
int match_count = 0;
|
||||
for (auto &it : converted_term) {
|
||||
for (auto i = info->getColors().constBegin(); i != info->getColors().constEnd(); i++) {
|
||||
if ((*i).contains(it, Qt::CaseInsensitive)) {
|
||||
if (info->getColors().contains(it, Qt::CaseInsensitive))
|
||||
match_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match_count == converted_term.length();
|
||||
}
|
||||
|
@ -205,9 +202,9 @@ bool FilterItem::acceptText(const CardInfoPtr info) const
|
|||
bool FilterItem::acceptSet(const CardInfoPtr info) const
|
||||
{
|
||||
bool status = false;
|
||||
for (auto i = info->getSets().constBegin(); i != info->getSets().constEnd(); i++) {
|
||||
if ((*i)->getShortName().compare(term, Qt::CaseInsensitive) == 0 ||
|
||||
(*i)->getLongName().compare(term, Qt::CaseInsensitive) == 0) {
|
||||
for (const auto &set : info->getSets()) {
|
||||
if (set.getPtr()->getShortName().compare(term, Qt::CaseInsensitive) == 0 ||
|
||||
set.getPtr()->getLongName().compare(term, Qt::CaseInsensitive) == 0) {
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
|
@ -299,7 +296,7 @@ bool FilterItem::acceptRarity(const CardInfoPtr info) const
|
|||
|
||||
/*
|
||||
* The purpose of this loop is to only apply one of the replacement
|
||||
* policies and then escape. If we attempt to layer them ontop of
|
||||
* policies and then escape. If we attempt to layer them on top of
|
||||
* each other, we will get awkward results (i.e. comythic rare mythic rareon)
|
||||
* Conditional statement will exit once a case is successful in
|
||||
* replacement OR we go through all possible cases.
|
||||
|
@ -334,8 +331,8 @@ bool FilterItem::acceptRarity(const CardInfoPtr info) const
|
|||
}
|
||||
}
|
||||
|
||||
for (const QString &rareLevel : info->getRarities()) {
|
||||
if (rareLevel.compare(converted_term, Qt::CaseInsensitive) == 0) {
|
||||
for (const auto &set : info->getSets()) {
|
||||
if (set.getProperty("rarity").compare(converted_term, Qt::CaseInsensitive) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
|
||||
#ifndef FILTERTREE_H
|
||||
#define FILTERTREE_H
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "cardfilter.h"
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "cardfilter.h"
|
||||
#include <utility>
|
||||
|
||||
class FilterTreeNode
|
||||
{
|
||||
|
@ -33,11 +35,11 @@ public:
|
|||
}
|
||||
virtual FilterTreeNode *parent() const
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
virtual FilterTreeNode *nodeAt(int /* i */) const
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
virtual void deleteAt(int /* i */)
|
||||
{
|
||||
|
@ -52,7 +54,7 @@ public:
|
|||
}
|
||||
virtual int index() const
|
||||
{
|
||||
return (parent() != NULL) ? parent()->childIndex(this) : -1;
|
||||
return (parent() != nullptr) ? parent()->childIndex(this) : -1;
|
||||
}
|
||||
virtual const QString text() const
|
||||
{
|
||||
|
@ -64,27 +66,27 @@ public:
|
|||
}
|
||||
virtual void nodeChanged() const
|
||||
{
|
||||
if (parent() != NULL)
|
||||
if (parent() != nullptr)
|
||||
parent()->nodeChanged();
|
||||
}
|
||||
virtual void preInsertChild(const FilterTreeNode *p, int i) const
|
||||
{
|
||||
if (parent() != NULL)
|
||||
if (parent() != nullptr)
|
||||
parent()->preInsertChild(p, i);
|
||||
}
|
||||
virtual void postInsertChild(const FilterTreeNode *p, int i) const
|
||||
{
|
||||
if (parent() != NULL)
|
||||
if (parent() != nullptr)
|
||||
parent()->postInsertChild(p, i);
|
||||
}
|
||||
virtual void preRemoveChild(const FilterTreeNode *p, int i) const
|
||||
{
|
||||
if (parent() != NULL)
|
||||
if (parent() != nullptr)
|
||||
parent()->preRemoveChild(p, i);
|
||||
}
|
||||
virtual void postRemoveChild(const FilterTreeNode *p, int i) const
|
||||
{
|
||||
if (parent() != NULL)
|
||||
if (parent() != nullptr)
|
||||
parent()->postRemoveChild(p, i);
|
||||
}
|
||||
};
|
||||
|
@ -96,13 +98,13 @@ protected:
|
|||
|
||||
public:
|
||||
virtual ~FilterTreeBranch();
|
||||
FilterTreeNode *nodeAt(int i) const;
|
||||
void deleteAt(int i);
|
||||
int childCount() const
|
||||
FilterTreeNode *nodeAt(int i) const override;
|
||||
void deleteAt(int i) override;
|
||||
int childCount() const override
|
||||
{
|
||||
return childNodes.size();
|
||||
}
|
||||
int childIndex(const FilterTreeNode *node) const;
|
||||
int childIndex(const FilterTreeNode *node) const override;
|
||||
};
|
||||
|
||||
class FilterItemList;
|
||||
|
@ -121,8 +123,8 @@ public:
|
|||
}
|
||||
const FilterItemList *findTypeList(CardFilter::Type type) const;
|
||||
FilterItemList *typeList(CardFilter::Type type);
|
||||
FilterTreeNode *parent() const;
|
||||
const QString text() const
|
||||
FilterTreeNode *parent() const override;
|
||||
const QString text() const override
|
||||
{
|
||||
return CardFilter::attrName(attr);
|
||||
}
|
||||
|
@ -144,21 +146,21 @@ public:
|
|||
{
|
||||
return p->attr;
|
||||
}
|
||||
FilterTreeNode *parent() const
|
||||
FilterTreeNode *parent() const override
|
||||
{
|
||||
return p;
|
||||
}
|
||||
int termIndex(const QString &term) const;
|
||||
FilterTreeNode *termNode(const QString &term);
|
||||
const QString text() const
|
||||
const QString text() const override
|
||||
{
|
||||
return CardFilter::typeName(type);
|
||||
}
|
||||
|
||||
bool testTypeAnd(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeAndNot(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeOr(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeOrNot(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeAnd(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeAndNot(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeOr(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool testTypeOrNot(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
};
|
||||
|
||||
class FilterItem : public FilterTreeNode
|
||||
|
@ -169,10 +171,10 @@ private:
|
|||
public:
|
||||
const QString term;
|
||||
|
||||
FilterItem(QString trm, FilterItemList *parent) : p(parent), term(trm)
|
||||
FilterItem(QString trm, FilterItemList *parent) : p(parent), term(std::move(trm))
|
||||
{
|
||||
}
|
||||
virtual ~FilterItem(){};
|
||||
virtual ~FilterItem() = default;
|
||||
|
||||
CardFilter::Attr attr() const
|
||||
{
|
||||
|
@ -182,30 +184,30 @@ public:
|
|||
{
|
||||
return p->type;
|
||||
}
|
||||
FilterTreeNode *parent() const
|
||||
FilterTreeNode *parent() const override
|
||||
{
|
||||
return p;
|
||||
}
|
||||
const QString text() const
|
||||
const QString text() const override
|
||||
{
|
||||
return term;
|
||||
}
|
||||
bool isLeaf() const
|
||||
bool isLeaf() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acceptName(const CardInfoPtr info) const;
|
||||
bool acceptType(const CardInfoPtr info) const;
|
||||
bool acceptColor(const CardInfoPtr info) const;
|
||||
bool acceptText(const CardInfoPtr info) const;
|
||||
bool acceptSet(const CardInfoPtr info) const;
|
||||
bool acceptManaCost(const CardInfoPtr info) const;
|
||||
bool acceptCmc(const CardInfoPtr info) const;
|
||||
bool acceptPowerToughness(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool acceptLoyalty(const CardInfoPtr info) const;
|
||||
bool acceptRarity(const CardInfoPtr info) const;
|
||||
bool acceptCardAttr(const CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool acceptName(CardInfoPtr info) const;
|
||||
bool acceptType(CardInfoPtr info) const;
|
||||
bool acceptColor(CardInfoPtr info) const;
|
||||
bool acceptText(CardInfoPtr info) const;
|
||||
bool acceptSet(CardInfoPtr info) const;
|
||||
bool acceptManaCost(CardInfoPtr info) const;
|
||||
bool acceptCmc(CardInfoPtr info) const;
|
||||
bool acceptPowerToughness(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool acceptLoyalty(CardInfoPtr info) const;
|
||||
bool acceptRarity(CardInfoPtr info) const;
|
||||
bool acceptCardAttr(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
bool relationCheck(int cardInfo) const;
|
||||
};
|
||||
|
||||
|
@ -224,47 +226,47 @@ private:
|
|||
LogicMap *attrLogicMap(CardFilter::Attr attr);
|
||||
FilterItemList *attrTypeList(CardFilter::Attr attr, CardFilter::Type type);
|
||||
|
||||
bool testAttr(const CardInfoPtr info, const LogicMap *lm) const;
|
||||
bool testAttr(CardInfoPtr info, const LogicMap *lm) const;
|
||||
|
||||
void nodeChanged() const
|
||||
void nodeChanged() const override
|
||||
{
|
||||
emit changed();
|
||||
}
|
||||
void preInsertChild(const FilterTreeNode *p, int i) const
|
||||
void preInsertChild(const FilterTreeNode *p, int i) const override
|
||||
{
|
||||
emit preInsertRow(p, i);
|
||||
}
|
||||
void postInsertChild(const FilterTreeNode *p, int i) const
|
||||
void postInsertChild(const FilterTreeNode *p, int i) const override
|
||||
{
|
||||
emit postInsertRow(p, i);
|
||||
}
|
||||
void preRemoveChild(const FilterTreeNode *p, int i) const
|
||||
void preRemoveChild(const FilterTreeNode *p, int i) const override
|
||||
{
|
||||
emit preRemoveRow(p, i);
|
||||
}
|
||||
void postRemoveChild(const FilterTreeNode *p, int i) const
|
||||
void postRemoveChild(const FilterTreeNode *p, int i) const override
|
||||
{
|
||||
emit postRemoveRow(p, i);
|
||||
}
|
||||
|
||||
public:
|
||||
FilterTree();
|
||||
~FilterTree();
|
||||
~FilterTree() override;
|
||||
int findTermIndex(CardFilter::Attr attr, CardFilter::Type type, const QString &term);
|
||||
int findTermIndex(const CardFilter *f);
|
||||
FilterTreeNode *termNode(CardFilter::Attr attr, CardFilter::Type type, const QString &term);
|
||||
FilterTreeNode *termNode(const CardFilter *f);
|
||||
FilterTreeNode *attrTypeNode(CardFilter::Attr attr, CardFilter::Type type);
|
||||
const QString text() const
|
||||
const QString text() const override
|
||||
{
|
||||
return QString("root");
|
||||
}
|
||||
int index() const
|
||||
int index() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool acceptsCard(const CardInfoPtr info) const;
|
||||
bool acceptsCard(CardInfoPtr info) const;
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
|
49
cockatrice/src/game_specific_terms.h
Normal file
49
cockatrice/src/game_specific_terms.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef GAME_SPECIFIC_TERMS_H
|
||||
#define GAME_SPECIFIC_TERMS_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
/*
|
||||
* Collection of traslatable property names used in games,
|
||||
* so we can use Game::Property instead of hardcoding strings.
|
||||
* Note: Mtg = "Maybe that game"
|
||||
*/
|
||||
|
||||
namespace Mtg
|
||||
{
|
||||
QString const CardType("type");
|
||||
QString const ConvertedManaCost("cmc");
|
||||
QString const Colors("colors");
|
||||
QString const Loyalty("loyalty");
|
||||
QString const MainCardType("maintype");
|
||||
QString const ManaCost("manacost");
|
||||
QString const PowTough("pt");
|
||||
QString const Side("side");
|
||||
QString const Layout("layout");
|
||||
|
||||
inline static const QString getNicePropertyName(QString key)
|
||||
{
|
||||
if (key == CardType)
|
||||
return QCoreApplication::translate("Mtg", "Card type");
|
||||
if (key == ConvertedManaCost)
|
||||
return QCoreApplication::translate("Mtg", "Converted mana cost");
|
||||
if (key == Colors)
|
||||
return QCoreApplication::translate("Mtg", "Color(s)");
|
||||
if (key == Loyalty)
|
||||
return QCoreApplication::translate("Mtg", "Loyalty");
|
||||
if (key == MainCardType)
|
||||
return QCoreApplication::translate("Mtg", "Main card type");
|
||||
if (key == ManaCost)
|
||||
return QCoreApplication::translate("Mtg", "Mana cost");
|
||||
if (key == PowTough)
|
||||
return QCoreApplication::translate("Mtg", "P / T");
|
||||
if (key == Side)
|
||||
return QCoreApplication::translate("Mtg", "Side");
|
||||
if (key == Layout)
|
||||
return QCoreApplication::translate("Mtg", "Layout");
|
||||
return key;
|
||||
}
|
||||
}; // namespace Mtg
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
#include "handle_public_servers.h"
|
||||
#include "qt-json/json.h"
|
||||
#include "settingscache.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
@ -31,19 +31,16 @@ void HandlePublicServers::actFinishParsingDownloadedData()
|
|||
savedHostList = uci.getServerInfo();
|
||||
|
||||
// Downloaded data from GitHub
|
||||
bool jsonSuccessful;
|
||||
QString jsonData = QString(reply->readAll());
|
||||
|
||||
auto jsonMap = QtJson::Json::parse(jsonData, jsonSuccessful).toMap();
|
||||
|
||||
if (jsonSuccessful) {
|
||||
QJsonParseError parseError{};
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
if (parseError.error == QJsonParseError::NoError) {
|
||||
QVariantMap jsonMap = jsonResponse.toVariant().toMap();
|
||||
updateServerINISettings(jsonMap);
|
||||
} else {
|
||||
qDebug() << "[PUBLIC SERVER HANDLER]"
|
||||
<< "JSON Parsing Error";
|
||||
<< "JSON Parsing Error:" << parseError.errorString();
|
||||
emit sigPublicServersDownloadedUnsuccessfully(errorCode);
|
||||
}
|
||||
|
||||
} else {
|
||||
qDebug() << "[PUBLIC SERVER HANDLER]"
|
||||
<< "Error Downloading Public Servers" << errorCode;
|
||||
|
|
|
@ -30,7 +30,9 @@ PictureToLoad::PictureToLoad(CardInfoPtr _card) : card(std::move(_card))
|
|||
urlTemplates = settingsCache->downloads().getAllURLs();
|
||||
|
||||
if (card) {
|
||||
sortedSets = card->getSets();
|
||||
for (const auto &set : card->getSets()) {
|
||||
sortedSets << set.getPtr();
|
||||
}
|
||||
qSort(sortedSets.begin(), sortedSets.end(), SetDownloadPriorityComparator());
|
||||
// The first time called, nextSet will also populate the Urls for the first set.
|
||||
nextSet();
|
||||
|
@ -240,28 +242,50 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
|
|||
CardSetPtr set = getCurrentSet();
|
||||
|
||||
QMap<QString, QString> transformMap = QMap<QString, QString>();
|
||||
|
||||
// name
|
||||
transformMap["!name!"] = card->getName();
|
||||
transformMap["!name_lower!"] = card->getName().toLower();
|
||||
transformMap["!corrected_name!"] = card->getCorrectedName();
|
||||
transformMap["!corrected_name_lower!"] = card->getCorrectedName().toLower();
|
||||
|
||||
// card properties
|
||||
QRegExp rxCardProp("!prop:([^!]+)!");
|
||||
int pos = 0;
|
||||
while ((pos = rxCardProp.indexIn(transformedUrl, pos)) != -1) {
|
||||
QString propertyName = rxCardProp.cap(1);
|
||||
pos += rxCardProp.matchedLength();
|
||||
QString propertyValue = card->getProperty(propertyName);
|
||||
if (propertyValue.isEmpty()) {
|
||||
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
|
||||
<< "]: Requested property (" << propertyName << ") for Url template (" << urlTemplate
|
||||
<< ") is not available";
|
||||
return QString();
|
||||
} else {
|
||||
transformMap["!prop:" + propertyName + "!"] = propertyValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (set) {
|
||||
transformMap["!cardid!"] = QString::number(card->getMuId(set->getShortName()));
|
||||
transformMap["!uuid!"] = card->getUuId(set->getShortName());
|
||||
transformMap["!collectornumber!"] = card->getCollectorNumber(set->getShortName());
|
||||
transformMap["!setcode!"] = set->getShortName();
|
||||
transformMap["!setcode_lower!"] = set->getShortName().toLower();
|
||||
transformMap["!setname!"] = set->getLongName();
|
||||
transformMap["!setname_lower!"] = set->getLongName().toLower();
|
||||
|
||||
QRegExp rxSetProp("!set:([^!]+)!");
|
||||
pos = 0; // Defined above
|
||||
while ((pos = rxSetProp.indexIn(transformedUrl, pos)) != -1) {
|
||||
QString propertyName = rxSetProp.cap(1);
|
||||
pos += rxSetProp.matchedLength();
|
||||
QString propertyValue = card->getSetProperty(set->getShortName(), propertyName);
|
||||
if (propertyValue.isEmpty()) {
|
||||
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
|
||||
<< "]: Requested set property (" << propertyName << ") for Url template (" << urlTemplate
|
||||
<< ") is not available";
|
||||
return QString();
|
||||
} else {
|
||||
transformMap["!cardid!"] = QString();
|
||||
transformMap["!uuid!"] = QString();
|
||||
transformMap["!collectornumber!"] = QString();
|
||||
transformMap["!setcode!"] = QString();
|
||||
transformMap["!setcode_lower!"] = QString();
|
||||
transformMap["!setname!"] = QString();
|
||||
transformMap["!setname_lower!"] = QString();
|
||||
transformMap["!set:" + propertyName + "!"] = propertyValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString &prop : transformMap.keys()) {
|
||||
|
@ -483,7 +507,7 @@ void PictureLoader::getPixmap(QPixmap &pixmap, CardInfoPtr card, QSize size)
|
|||
return;
|
||||
}
|
||||
|
||||
// search for an exact size copy of the picure in cache
|
||||
// search for an exact size copy of the picture in cache
|
||||
QString key = card->getPixmapCacheKey();
|
||||
QString sizeKey = key + QLatin1Char('_') + QString::number(size.width()) + QString::number(size.height());
|
||||
if (QPixmapCache::find(sizeKey, &pixmap))
|
||||
|
|
|
@ -94,7 +94,7 @@ void PlayerArea::setSize(qreal width, qreal height)
|
|||
Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_parent)
|
||||
: QObject(_parent), game(_parent), shortcutsActive(false), defaultNumberTopCards(1),
|
||||
defaultNumberTopCardsToPlaceBelow(1), lastTokenDestroy(true), lastTokenTableRow(0), id(_id), active(false),
|
||||
local(_local), mirrored(false), handVisible(false), conceded(false), dialogSemaphore(false), deck(0)
|
||||
local(_local), mirrored(false), handVisible(false), conceded(false), dialogSemaphore(false), deck(nullptr)
|
||||
{
|
||||
userInfo = new ServerInfo_User;
|
||||
userInfo->CopyFrom(info);
|
||||
|
@ -115,7 +115,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_pare
|
|||
|
||||
qreal h = deck->boundingRect().width() + 5;
|
||||
|
||||
HandCounter *handCounter = new HandCounter(playerArea);
|
||||
auto *handCounter = new HandCounter(playerArea);
|
||||
handCounter->setPos(base + QPointF(0, h + 10));
|
||||
qreal h2 = handCounter->boundingRect().height();
|
||||
|
||||
|
@ -279,8 +279,8 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_pare
|
|||
libraryMenu->addAction(aOpenDeckInDeckEditor);
|
||||
deck->setMenu(libraryMenu, aDrawCard);
|
||||
} else {
|
||||
handMenu = 0;
|
||||
libraryMenu = 0;
|
||||
handMenu = nullptr;
|
||||
libraryMenu = nullptr;
|
||||
}
|
||||
|
||||
graveMenu = playerMenu->addMenu(QString());
|
||||
|
@ -356,19 +356,19 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_pare
|
|||
playerMenu->addSeparator();
|
||||
playerMenu->addAction(aCardMenu);
|
||||
|
||||
for (int i = 0; i < playerLists.size(); ++i) {
|
||||
QAction *newAction = playerLists[i]->addAction(QString());
|
||||
for (auto &playerList : playerLists) {
|
||||
QAction *newAction = playerList->addAction(QString());
|
||||
newAction->setData(-1);
|
||||
connect(newAction, SIGNAL(triggered()), this, SLOT(playerListActionTriggered()));
|
||||
allPlayersActions.append(newAction);
|
||||
playerLists[i]->addSeparator();
|
||||
playerList->addSeparator();
|
||||
}
|
||||
} else {
|
||||
countersMenu = 0;
|
||||
sbMenu = 0;
|
||||
aCreateAnotherToken = 0;
|
||||
createPredefinedTokenMenu = 0;
|
||||
aCardMenu = 0;
|
||||
countersMenu = nullptr;
|
||||
sbMenu = nullptr;
|
||||
aCreateAnotherToken = nullptr;
|
||||
createPredefinedTokenMenu = nullptr;
|
||||
aCardMenu = nullptr;
|
||||
}
|
||||
|
||||
aTap = new QAction(this);
|
||||
|
@ -436,11 +436,11 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_pare
|
|||
connect(aPlayFacedown, SIGNAL(triggered()), this, SLOT(actPlayFacedown()));
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
QAction *tempAddCounter = new QAction(this);
|
||||
auto *tempAddCounter = new QAction(this);
|
||||
tempAddCounter->setData(9 + i * 1000);
|
||||
QAction *tempRemoveCounter = new QAction(this);
|
||||
auto *tempRemoveCounter = new QAction(this);
|
||||
tempRemoveCounter->setData(10 + i * 1000);
|
||||
QAction *tempSetCounter = new QAction(this);
|
||||
auto *tempSetCounter = new QAction(this);
|
||||
tempSetCounter->setData(11 + i * 1000);
|
||||
aAddCounter.append(tempAddCounter);
|
||||
aRemoveCounter.append(tempRemoveCounter);
|
||||
|
@ -451,8 +451,8 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_pare
|
|||
}
|
||||
|
||||
const QList<Player *> &players = game->getPlayers().values();
|
||||
for (int i = 0; i < players.size(); ++i)
|
||||
addPlayer(players[i]);
|
||||
for (auto player : players)
|
||||
addPlayer(player);
|
||||
|
||||
rearrangeZones();
|
||||
retranslateUi();
|
||||
|
@ -494,8 +494,8 @@ void Player::addPlayer(Player *player)
|
|||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < playerLists.size(); ++i) {
|
||||
QAction *newAction = playerLists[i]->addAction(player->getName());
|
||||
for (auto &playerList : playerLists) {
|
||||
QAction *newAction = playerList->addAction(player->getName());
|
||||
newAction->setData(player->getId());
|
||||
connect(newAction, SIGNAL(triggered()), this, SLOT(playerListActionTriggered()));
|
||||
}
|
||||
|
@ -507,20 +507,20 @@ void Player::removePlayer(Player *player)
|
|||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < playerLists.size(); ++i) {
|
||||
QList<QAction *> actionList = playerLists[i]->actions();
|
||||
for (int j = 0; j < actionList.size(); ++j)
|
||||
if (actionList[j]->data().toInt() == player->getId()) {
|
||||
playerLists[i]->removeAction(actionList[j]);
|
||||
actionList[j]->deleteLater();
|
||||
for (auto &playerList : playerLists) {
|
||||
QList<QAction *> actionList = playerList->actions();
|
||||
for (auto &j : actionList)
|
||||
if (j->data().toInt() == player->getId()) {
|
||||
playerList->removeAction(j);
|
||||
j->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::playerListActionTriggered()
|
||||
{
|
||||
QAction *action = static_cast<QAction *>(sender());
|
||||
QMenu *menu = static_cast<QMenu *>(action->parentWidget());
|
||||
auto *action = static_cast<QAction *>(sender());
|
||||
auto *menu = static_cast<QMenu *>(action->parentWidget());
|
||||
|
||||
Command_RevealCards cmd;
|
||||
const int otherPlayerId = action->data().toInt();
|
||||
|
@ -533,9 +533,9 @@ void Player::playerListActionTriggered()
|
|||
} else if (menu == mRevealTopCard) {
|
||||
int decksize = zones.value("deck")->getCards().size();
|
||||
bool ok;
|
||||
int number =
|
||||
QInputDialog::getInt(0, tr("Reveal top cards of library"), tr("Number of cards: (max. %1)").arg(decksize),
|
||||
defaultNumberTopCards, 1, decksize, 1, &ok);
|
||||
int number = QInputDialog::getInt(nullptr, tr("Reveal top cards of library"),
|
||||
tr("Number of cards: (max. %1)").arg(decksize), defaultNumberTopCards, 1,
|
||||
decksize, 1, &ok);
|
||||
if (ok) {
|
||||
cmd.set_zone_name("deck");
|
||||
cmd.set_top_cards(number);
|
||||
|
@ -692,8 +692,8 @@ void Player::retranslateUi()
|
|||
|
||||
aCardMenu->setText(tr("C&ard"));
|
||||
|
||||
for (int i = 0; i < allPlayersActions.size(); ++i)
|
||||
allPlayersActions[i]->setText(tr("&All players"));
|
||||
for (auto &allPlayersAction : allPlayersActions)
|
||||
allPlayersAction->setText(tr("&All players"));
|
||||
}
|
||||
|
||||
aPlay->setText(tr("&Play"));
|
||||
|
@ -904,8 +904,8 @@ void Player::actViewLibrary()
|
|||
void Player::actViewTopCards()
|
||||
{
|
||||
bool ok;
|
||||
int number = QInputDialog::getInt(0, tr("View top cards of library"), tr("Number of cards:"), defaultNumberTopCards,
|
||||
1, 2000000000, 1, &ok);
|
||||
int number = QInputDialog::getInt(nullptr, tr("View top cards of library"), tr("Number of cards:"),
|
||||
defaultNumberTopCards, 1, 2000000000, 1, &ok);
|
||||
if (ok) {
|
||||
defaultNumberTopCards = number;
|
||||
static_cast<GameScene *>(scene())->toggleZoneView(this, "deck", number);
|
||||
|
@ -934,7 +934,7 @@ void Player::actViewGraveyard()
|
|||
void Player::actRevealRandomGraveyardCard()
|
||||
{
|
||||
Command_RevealCards cmd;
|
||||
QAction *action = dynamic_cast<QAction *>(sender());
|
||||
auto *action = dynamic_cast<QAction *>(sender());
|
||||
const int otherPlayerId = action->data().toInt();
|
||||
if (otherPlayerId != -1) {
|
||||
cmd.set_player_id(otherPlayerId);
|
||||
|
@ -973,10 +973,10 @@ void Player::actMulligan()
|
|||
|
||||
void Player::actDrawCards()
|
||||
{
|
||||
int number = QInputDialog::getInt(0, tr("Draw cards"), tr("Number:"));
|
||||
int number = QInputDialog::getInt(nullptr, tr("Draw cards"), tr("Number:"));
|
||||
if (number) {
|
||||
Command_DrawCards cmd;
|
||||
cmd.set_number(number);
|
||||
cmd.set_number(static_cast<google::protobuf::uint32>(number));
|
||||
sendGameCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
@ -988,7 +988,7 @@ void Player::actUndoDraw()
|
|||
|
||||
void Player::actMoveTopCardToGrave()
|
||||
{
|
||||
if (zones.value("deck")->getCards().size() == 0) {
|
||||
if (zones.value("deck")->getCards().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1005,7 +1005,7 @@ void Player::actMoveTopCardToGrave()
|
|||
|
||||
void Player::actMoveTopCardToExile()
|
||||
{
|
||||
if (zones.value("deck")->getCards().size() == 0) {
|
||||
if (zones.value("deck")->getCards().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1022,7 @@ void Player::actMoveTopCardToExile()
|
|||
|
||||
void Player::actMoveTopCardsToGrave()
|
||||
{
|
||||
int number = QInputDialog::getInt(0, tr("Move top cards to grave"), tr("Number:"));
|
||||
int number = QInputDialog::getInt(nullptr, tr("Move top cards to grave"), tr("Number:"));
|
||||
if (!number) {
|
||||
return;
|
||||
}
|
||||
|
@ -1048,7 +1048,7 @@ void Player::actMoveTopCardsToGrave()
|
|||
|
||||
void Player::actMoveTopCardsToExile()
|
||||
{
|
||||
int number = QInputDialog::getInt(0, tr("Move top cards to exile"), tr("Number:"));
|
||||
int number = QInputDialog::getInt(nullptr, tr("Move top cards to exile"), tr("Number:"));
|
||||
if (!number) {
|
||||
return;
|
||||
}
|
||||
|
@ -1131,7 +1131,7 @@ void Player::actRollDie()
|
|||
1000, 1, &ok);
|
||||
if (ok) {
|
||||
Command_RollDie cmd;
|
||||
cmd.set_sides(sides);
|
||||
cmd.set_sides(static_cast<google::protobuf::uint32>(sides));
|
||||
sendGameCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
@ -1148,7 +1148,7 @@ void Player::actCreateToken()
|
|||
CardInfoPtr correctedCard = db->getCardBySimpleName(lastTokenName);
|
||||
if (correctedCard) {
|
||||
lastTokenName = correctedCard->getName();
|
||||
lastTokenTableRow = table->clampValidTableRow(2 - correctedCard->getTableRow());
|
||||
lastTokenTableRow = TableZone::clampValidTableRow(2 - correctedCard->getTableRow());
|
||||
if (lastTokenPT.isEmpty()) {
|
||||
lastTokenPT = correctedCard->getPowTough();
|
||||
}
|
||||
|
@ -1182,7 +1182,7 @@ void Player::actCreateAnotherToken()
|
|||
|
||||
void Player::actCreatePredefinedToken()
|
||||
{
|
||||
QAction *action = static_cast<QAction *>(sender());
|
||||
auto *action = static_cast<QAction *>(sender());
|
||||
CardInfoPtr cardInfo = db->getCard(action->text());
|
||||
if (!cardInfo) {
|
||||
return;
|
||||
|
@ -1199,7 +1199,7 @@ void Player::actCreateRelatedCard()
|
|||
if (!sourceCard) {
|
||||
return;
|
||||
}
|
||||
QAction *action = static_cast<QAction *>(sender());
|
||||
auto *action = static_cast<QAction *>(sender());
|
||||
// If there is a better way of passing a CardRelation through a QAction, please add it here.
|
||||
QList<CardRelation *> relatedCards = QList<CardRelation *>();
|
||||
relatedCards.append(sourceCard->getInfo()->getRelatedCards());
|
||||
|
@ -1211,7 +1211,7 @@ void Player::actCreateRelatedCard()
|
|||
* then let's allow it to be created via "create another token"
|
||||
*/
|
||||
if (createRelatedFromRelation(sourceCard, cardRelation) && cardRelation->getCanCreateAnother()) {
|
||||
CardInfoPtr cardInfo = db->getCard(dbNameFromTokenDisplayName(cardRelation->getName()));
|
||||
CardInfoPtr cardInfo = db->getCard(cardRelation->getName());
|
||||
setLastToken(cardInfo);
|
||||
}
|
||||
}
|
||||
|
@ -1257,7 +1257,7 @@ void Player::actCreateAllRelatedCards()
|
|||
case 0: // else if nonExcludedRelatedCards == 0
|
||||
for (CardRelation *cardRelationAll : relatedCards) {
|
||||
if (!cardRelationAll->getDoesAttach() && !cardRelationAll->getIsVariable()) {
|
||||
dbName = dbNameFromTokenDisplayName(cardRelationAll->getName());
|
||||
dbName = cardRelationAll->getName();
|
||||
for (int i = 0; i < cardRelationAll->getDefaultCount(); ++i) {
|
||||
createCard(sourceCard, dbName);
|
||||
}
|
||||
|
@ -1271,7 +1271,7 @@ void Player::actCreateAllRelatedCards()
|
|||
default: // else
|
||||
for (CardRelation *cardRelationNotExcluded : nonExcludedRelatedCards) {
|
||||
if (!cardRelationNotExcluded->getDoesAttach() && !cardRelationNotExcluded->getIsVariable()) {
|
||||
dbName = dbNameFromTokenDisplayName(cardRelationNotExcluded->getName());
|
||||
dbName = cardRelationNotExcluded->getName();
|
||||
for (int i = 0; i < cardRelationNotExcluded->getDefaultCount(); ++i) {
|
||||
createCard(sourceCard, dbName);
|
||||
}
|
||||
|
@ -1290,7 +1290,7 @@ void Player::actCreateAllRelatedCards()
|
|||
* then assign the first to the "Create another" shortcut.
|
||||
*/
|
||||
if (cardRelation != nullptr && cardRelation->getCanCreateAnother()) {
|
||||
CardInfoPtr cardInfo = db->getCard(dbNameFromTokenDisplayName(cardRelation->getName()));
|
||||
CardInfoPtr cardInfo = db->getCard(cardRelation->getName());
|
||||
setLastToken(cardInfo);
|
||||
}
|
||||
}
|
||||
|
@ -1300,12 +1300,12 @@ bool Player::createRelatedFromRelation(const CardItem *sourceCard, const CardRel
|
|||
if (sourceCard == nullptr || cardRelation == nullptr) {
|
||||
return false;
|
||||
}
|
||||
QString dbName = dbNameFromTokenDisplayName(cardRelation->getName());
|
||||
QString dbName = cardRelation->getName();
|
||||
if (cardRelation->getIsVariable()) {
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
int count = QInputDialog::getInt(0, tr("Create tokens"), tr("Number:"), cardRelation->getDefaultCount(), 1,
|
||||
MAX_TOKENS_PER_DIALOG, 1, &ok);
|
||||
int count = QInputDialog::getInt(nullptr, tr("Create tokens"), tr("Number:"), cardRelation->getDefaultCount(),
|
||||
1, MAX_TOKENS_PER_DIALOG, 1, &ok);
|
||||
dialogSemaphore = false;
|
||||
if (!ok) {
|
||||
return false;
|
||||
|
@ -1337,19 +1337,22 @@ void Player::createCard(const CardItem *sourceCard, const QString &dbCardName, b
|
|||
|
||||
// get the target token's location
|
||||
// TODO: Define this QPoint into its own function along with the one below
|
||||
QPoint gridPoint = QPoint(-1, table->clampValidTableRow(2 - cardInfo->getTableRow()));
|
||||
QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - cardInfo->getTableRow()));
|
||||
|
||||
// create the token for the related card
|
||||
Command_CreateToken cmd;
|
||||
cmd.set_zone("table");
|
||||
cmd.set_card_name(cardInfo->getName().toStdString());
|
||||
if (cardInfo->getColors().length() > 1) // Multicoloured
|
||||
{
|
||||
cmd.set_color("m");
|
||||
} else if (cardInfo->getColors().isEmpty()) {
|
||||
switch (cardInfo->getColors().size()) {
|
||||
case 0:
|
||||
cmd.set_color("");
|
||||
} else {
|
||||
cmd.set_color(cardInfo->getColors().first().toLower().toStdString());
|
||||
break;
|
||||
case 1:
|
||||
cmd.set_color("m");
|
||||
break;
|
||||
default:
|
||||
cmd.set_color(cardInfo->getColors().left(1).toLower().toStdString());
|
||||
break;
|
||||
}
|
||||
|
||||
cmd.set_pt(cardInfo->getPowTough().toStdString());
|
||||
|
@ -1377,7 +1380,7 @@ void Player::createAttachedCard(const CardItem *sourceCard, const QString &dbCar
|
|||
|
||||
void Player::actSayMessage()
|
||||
{
|
||||
QAction *a = qobject_cast<QAction *>(sender());
|
||||
auto *a = qobject_cast<QAction *>(sender());
|
||||
Command_GameSay cmd;
|
||||
cmd.set_message(a->text().toStdString());
|
||||
sendGameCommand(cmd);
|
||||
|
@ -1436,22 +1439,6 @@ void Player::setCardAttrHelper(const GameEventContext &context,
|
|||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
QRegularExpression tokenNamePattern(".*/\\S+\\s+(.*)");
|
||||
QRegularExpressionMatch match = tokenNamePattern.match(tokenName);
|
||||
if (match.hasMatch()) {
|
||||
return match.captured(1);
|
||||
} else if (tokenName.indexOf(tr("Token: ")) != -1) {
|
||||
return tokenName.mid(tr("Token: ").length());
|
||||
} else {
|
||||
return tokenName;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::eventGameSay(const Event_GameSay &event)
|
||||
{
|
||||
emit logSay(this, QString::fromStdString(event.message()));
|
||||
|
@ -1481,8 +1468,8 @@ void Player::eventCreateArrow(const Event_CreateArrow &event)
|
|||
return;
|
||||
}
|
||||
|
||||
CardItem *startCard = static_cast<CardItem *>(arrow->getStartItem());
|
||||
CardItem *targetCard = qgraphicsitem_cast<CardItem *>(arrow->getTargetItem());
|
||||
auto *startCard = static_cast<CardItem *>(arrow->getStartItem());
|
||||
auto *targetCard = qgraphicsitem_cast<CardItem *>(arrow->getTargetItem());
|
||||
if (targetCard) {
|
||||
emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), targetCard->getOwner(),
|
||||
targetCard->getName(), false);
|
||||
|
@ -1536,7 +1523,7 @@ void Player::eventSetCardAttr(const Event_SetCardAttr &event, const GameEventCon
|
|||
true);
|
||||
}
|
||||
if (event.attribute() == AttrTapped) {
|
||||
emit logSetTapped(this, 0, event.attr_value() == "1");
|
||||
emit logSetTapped(this, nullptr, event.attr_value() == "1");
|
||||
}
|
||||
} else {
|
||||
CardItem *card = zone->getCard(event.card_id(), QString());
|
||||
|
@ -1654,7 +1641,7 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &
|
|||
|
||||
if (card->getAttachedTo() && (startZone != targetZone)) {
|
||||
CardItem *parentCard = card->getAttachedTo();
|
||||
card->setAttachedTo(0);
|
||||
card->setAttachedTo(nullptr);
|
||||
parentCard->getZone()->reorganizeCards();
|
||||
}
|
||||
|
||||
|
@ -1667,8 +1654,8 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &
|
|||
card->setHovered(false);
|
||||
|
||||
const QList<CardItem *> &attachedCards = card->getAttachedCards();
|
||||
for (int i = 0; i < attachedCards.size(); ++i) {
|
||||
attachedCards[i]->setParentItem(targetZone);
|
||||
for (auto attachedCard : attachedCards) {
|
||||
attachedCard->setParentItem(targetZone);
|
||||
}
|
||||
|
||||
if (startZone->getPlayer() != targetZone->getPlayer()) {
|
||||
|
@ -1704,8 +1691,8 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < arrowsToDelete.size(); ++i) {
|
||||
arrowsToDelete[i]->delArrow();
|
||||
for (auto &i : arrowsToDelete) {
|
||||
i->delArrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1738,8 +1725,8 @@ void Player::eventDestroyCard(const Event_DestroyCard &event)
|
|||
|
||||
QList<CardItem *> attachedCards = card->getAttachedCards();
|
||||
// This list is always empty except for buggy server implementations.
|
||||
for (int i = 0; i < attachedCards.size(); ++i) {
|
||||
attachedCards[i]->setAttachedTo(0);
|
||||
for (auto &attachedCard : attachedCards) {
|
||||
attachedCard->setAttachedTo(0);
|
||||
}
|
||||
|
||||
emit logDestroyCard(this, card->getName());
|
||||
|
@ -1750,9 +1737,9 @@ void Player::eventDestroyCard(const Event_DestroyCard &event)
|
|||
void Player::eventAttachCard(const Event_AttachCard &event)
|
||||
{
|
||||
const QMap<int, Player *> &playerList = game->getPlayers();
|
||||
Player *targetPlayer = 0;
|
||||
CardZone *targetZone = 0;
|
||||
CardItem *targetCard = 0;
|
||||
Player *targetPlayer = nullptr;
|
||||
CardZone *targetZone = nullptr;
|
||||
CardItem *targetCard = nullptr;
|
||||
if (event.has_target_player_id()) {
|
||||
targetPlayer = playerList.value(event.target_player_id(), 0);
|
||||
if (targetPlayer) {
|
||||
|
@ -1823,7 +1810,7 @@ void Player::eventRevealCards(const Event_RevealCards &event)
|
|||
if (!zone) {
|
||||
return;
|
||||
}
|
||||
Player *otherPlayer = 0;
|
||||
Player *otherPlayer = nullptr;
|
||||
if (event.has_other_player_id()) {
|
||||
otherPlayer = game->getPlayers().value(event.other_player_id());
|
||||
if (!otherPlayer) {
|
||||
|
@ -1843,14 +1830,14 @@ void Player::eventRevealCards(const Event_RevealCards &event)
|
|||
}
|
||||
|
||||
if (peeking) {
|
||||
for (int i = 0; i < cardList.size(); ++i) {
|
||||
QString cardName = QString::fromStdString(cardList.at(i)->name());
|
||||
CardItem *card = zone->getCard(cardList.at(i)->id(), QString());
|
||||
for (auto i : cardList) {
|
||||
QString cardName = QString::fromStdString(i->name());
|
||||
CardItem *card = zone->getCard(i->id(), QString());
|
||||
if (!card) {
|
||||
continue;
|
||||
}
|
||||
card->setName(cardName);
|
||||
emit logRevealCards(this, zone, cardList.at(i)->id(), cardName, this, true);
|
||||
emit logRevealCards(this, zone, i->id(), cardName, this, true);
|
||||
}
|
||||
} else {
|
||||
bool showZoneView = true;
|
||||
|
@ -1953,7 +1940,7 @@ void Player::processGameEvent(GameEvent::GameEventType type, const GameEvent &ev
|
|||
}
|
||||
}
|
||||
|
||||
void Player::setActive(bool _active)
|
||||
void Player::setActivePlayer(bool _active)
|
||||
{
|
||||
active = _active;
|
||||
table->setActive(active);
|
||||
|
@ -2073,7 +2060,7 @@ void Player::playCard(CardItem *card, bool faceDown, bool tapped)
|
|||
cmd.set_y(0);
|
||||
} else {
|
||||
int tableRow = faceDown ? 2 : info->getTableRow();
|
||||
QPoint gridPoint = QPoint(-1, table->clampValidTableRow(2 - tableRow));
|
||||
QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - tableRow));
|
||||
cardToMove->set_face_down(faceDown);
|
||||
cardToMove->set_pt(info->getPowTough().toStdString());
|
||||
cardToMove->set_tapped(faceDown ? false : tapped);
|
||||
|
@ -2116,7 +2103,7 @@ AbstractCounter *Player::addCounter(int counterId, const QString &name, QColor c
|
|||
{
|
||||
qDebug() << "addCounter:" << getName() << counterId << name;
|
||||
if (counters.contains(counterId)) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AbstractCounter *ctr;
|
||||
|
@ -2163,25 +2150,25 @@ ArrowItem *Player::addArrow(const ServerInfo_Arrow &arrow)
|
|||
Player *startPlayer = playerList.value(arrow.start_player_id(), 0);
|
||||
Player *targetPlayer = playerList.value(arrow.target_player_id(), 0);
|
||||
if (!startPlayer || !targetPlayer) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(arrow.start_zone()), 0);
|
||||
CardZone *targetZone = 0;
|
||||
CardZone *targetZone = nullptr;
|
||||
if (arrow.has_target_zone()) {
|
||||
targetZone = targetPlayer->getZones().value(QString::fromStdString(arrow.target_zone()), 0);
|
||||
}
|
||||
if (!startZone || (!targetZone && arrow.has_target_zone())) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CardItem *startCard = startZone->getCard(arrow.start_card_id(), QString());
|
||||
CardItem *targetCard = 0;
|
||||
CardItem *targetCard = nullptr;
|
||||
if (targetZone) {
|
||||
targetCard = targetZone->getCard(arrow.target_card_id(), QString());
|
||||
}
|
||||
if (!startCard || (!targetCard && arrow.has_target_card_id())) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (targetCard) {
|
||||
|
@ -2194,7 +2181,7 @@ ArrowItem *Player::addArrow(const ServerInfo_Arrow &arrow)
|
|||
|
||||
ArrowItem *Player::addArrow(int arrowId, CardItem *startCard, ArrowTarget *targetItem, const QColor &color)
|
||||
{
|
||||
ArrowItem *arrow = new ArrowItem(this, arrowId, startCard, targetItem, color);
|
||||
auto *arrow = new ArrowItem(this, arrowId, startCard, targetItem, color);
|
||||
arrows.insert(arrowId, arrow);
|
||||
scene()->addItem(arrow);
|
||||
return arrow;
|
||||
|
@ -2295,7 +2282,7 @@ bool Player::clearCardsToDelete()
|
|||
void Player::actMoveCardXCardsFromTop()
|
||||
{
|
||||
bool ok;
|
||||
int number = QInputDialog::getInt(0, tr("Place card X cards from top of library"),
|
||||
int number = QInputDialog::getInt(nullptr, tr("Place card X cards from top of library"),
|
||||
tr("How many cards from the top of the deck should this card be placed:"),
|
||||
defaultNumberTopCardsToPlaceBelow, 1, 2000000000, 1, &ok);
|
||||
number--;
|
||||
|
@ -2325,7 +2312,7 @@ void Player::actMoveCardXCardsFromTop()
|
|||
int startPlayerId = cardList[0]->getZone()->getPlayer()->getId();
|
||||
QString startZone = cardList[0]->getZone()->getName();
|
||||
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2344,7 +2331,7 @@ void Player::actMoveCardXCardsFromTop()
|
|||
|
||||
void Player::cardMenuAction()
|
||||
{
|
||||
QAction *a = dynamic_cast<QAction *>(sender());
|
||||
auto *a = dynamic_cast<QAction *>(sender());
|
||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
||||
QList<CardItem *> cardList;
|
||||
while (!sel.isEmpty()) {
|
||||
|
@ -2353,14 +2340,13 @@ void Player::cardMenuAction()
|
|||
|
||||
QList<const ::google::protobuf::Message *> commandList;
|
||||
if (a->data().toInt() <= (int)cmClone) {
|
||||
for (int i = 0; i < cardList.size(); ++i) {
|
||||
CardItem *card = cardList[i];
|
||||
for (auto card : cardList) {
|
||||
switch (static_cast<CardMenuActionType>(a->data().toInt())) {
|
||||
// Leaving both for compatibility with server
|
||||
case cmUntap:
|
||||
// fallthrough
|
||||
case cmTap: {
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_attribute(AttrTapped);
|
||||
|
@ -2369,7 +2355,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmDoesntUntap: {
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_attribute(AttrDoesntUntap);
|
||||
|
@ -2378,7 +2364,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmFlip: {
|
||||
Command_FlipCard *cmd = new Command_FlipCard;
|
||||
auto *cmd = new Command_FlipCard;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_face_down(!card->getFaceDown());
|
||||
|
@ -2392,7 +2378,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmPeek: {
|
||||
Command_RevealCards *cmd = new Command_RevealCards;
|
||||
auto *cmd = new Command_RevealCards;
|
||||
cmd->set_zone_name(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_player_id(id);
|
||||
|
@ -2400,7 +2386,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmClone: {
|
||||
Command_CreateToken *cmd = new Command_CreateToken;
|
||||
auto *cmd = new Command_CreateToken;
|
||||
cmd->set_zone("table");
|
||||
cmd->set_card_name(card->getName().toStdString());
|
||||
cmd->set_color(card->getColor().toStdString());
|
||||
|
@ -2418,15 +2404,15 @@ void Player::cardMenuAction()
|
|||
}
|
||||
} else {
|
||||
ListOfCardsToMove idList;
|
||||
for (int i = 0; i < cardList.size(); ++i) {
|
||||
idList.add_card()->set_card_id(cardList[i]->getId());
|
||||
for (auto &i : cardList) {
|
||||
idList.add_card()->set_card_id(i->getId());
|
||||
}
|
||||
int startPlayerId = cardList[0]->getZone()->getPlayer()->getId();
|
||||
QString startZone = cardList[0]->getZone()->getName();
|
||||
|
||||
switch (static_cast<CardMenuActionType>(a->data().toInt())) {
|
||||
case cmMoveToTopLibrary: {
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2438,7 +2424,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmMoveToBottomLibrary: {
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2450,7 +2436,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmMoveToHand: {
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2462,7 +2448,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmMoveToGraveyard: {
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2474,7 +2460,7 @@ void Player::cardMenuAction()
|
|||
break;
|
||||
}
|
||||
case cmMoveToExile: {
|
||||
Command_MoveCard *cmd = new Command_MoveCard;
|
||||
auto *cmd = new Command_MoveCard;
|
||||
cmd->set_start_player_id(startPlayerId);
|
||||
cmd->set_start_zone(startZone.toStdString());
|
||||
cmd->mutable_cards_to_move()->CopyFrom(idList);
|
||||
|
@ -2505,8 +2491,8 @@ void Player::actIncPT(int deltaP, int deltaT)
|
|||
QList<const ::google::protobuf::Message *> commandList;
|
||||
QListIterator<QGraphicsItem *> j(scene()->selectedItems());
|
||||
while (j.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(j.next());
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *card = static_cast<CardItem *>(j.next());
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_attribute(AttrPT);
|
||||
|
@ -2527,12 +2513,12 @@ void Player::actResetPT()
|
|||
QList<const ::google::protobuf::Message *> commandList;
|
||||
QListIterator<QGraphicsItem *> selected(scene()->selectedItems());
|
||||
while (selected.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(selected.next());
|
||||
auto *card = static_cast<CardItem *>(selected.next());
|
||||
CardInfoPtr info = card->getInfo();
|
||||
if (!info) {
|
||||
continue;
|
||||
}
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
QString zoneName = card->getZone()->getName();
|
||||
cmd->set_zone(zoneName.toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
|
@ -2556,15 +2542,15 @@ void Player::actSetPT()
|
|||
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
if (!card->getPT().isEmpty()) {
|
||||
oldPT = card->getPT();
|
||||
}
|
||||
}
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
QString pt = QInputDialog::getText(0, tr("Set power/toughness"), tr("Please enter the new PT:"), QLineEdit::Normal,
|
||||
oldPT, &ok);
|
||||
QString pt = QInputDialog::getText(nullptr, tr("Set power/toughness"), tr("Please enter the new PT:"),
|
||||
QLineEdit::Normal, oldPT, &ok);
|
||||
dialogSemaphore = false;
|
||||
if (clearCardsToDelete()) {
|
||||
return;
|
||||
|
@ -2576,8 +2562,8 @@ void Player::actSetPT()
|
|||
QList<const ::google::protobuf::Message *> commandList;
|
||||
QListIterator<QGraphicsItem *> j(scene()->selectedItems());
|
||||
while (j.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(j.next());
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *card = static_cast<CardItem *>(j.next());
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_attribute(AttrPT);
|
||||
|
@ -2636,7 +2622,7 @@ void Player::actSetAnnotation()
|
|||
QString oldAnnotation;
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
if (!card->getAnnotation().isEmpty()) {
|
||||
oldAnnotation = card->getAnnotation();
|
||||
}
|
||||
|
@ -2644,7 +2630,7 @@ void Player::actSetAnnotation()
|
|||
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
QString annotation = QInputDialog::getText(0, tr("Set annotation"), tr("Please enter the new annotation:"),
|
||||
QString annotation = QInputDialog::getText(nullptr, tr("Set annotation"), tr("Please enter the new annotation:"),
|
||||
QLineEdit::Normal, oldAnnotation, &ok);
|
||||
dialogSemaphore = false;
|
||||
if (clearCardsToDelete()) {
|
||||
|
@ -2657,8 +2643,8 @@ void Player::actSetAnnotation()
|
|||
QList<const ::google::protobuf::Message *> commandList;
|
||||
i.toFront();
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
auto *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_attribute(AttrAnnotation);
|
||||
|
@ -2674,7 +2660,7 @@ void Player::actAttach()
|
|||
return;
|
||||
}
|
||||
|
||||
ArrowAttachItem *arrow = new ArrowAttachItem(game->getActiveCard());
|
||||
auto *arrow = new ArrowAttachItem(game->getActiveCard());
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
}
|
||||
|
@ -2693,16 +2679,16 @@ void Player::actUnattach()
|
|||
|
||||
void Player::actCardCounterTrigger()
|
||||
{
|
||||
QAction *action = static_cast<QAction *>(sender());
|
||||
auto *action = static_cast<QAction *>(sender());
|
||||
int counterId = action->data().toInt() / 1000;
|
||||
QList<const ::google::protobuf::Message *> commandList;
|
||||
switch (action->data().toInt() % 1000) { // TODO: define case numbers
|
||||
case 9: {
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
if (card->getCounters().value(counterId, 0) < MAX_COUNTERS_ON_CARD) {
|
||||
Command_SetCardCounter *cmd = new Command_SetCardCounter;
|
||||
auto *cmd = new Command_SetCardCounter;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_counter_id(counterId);
|
||||
|
@ -2715,9 +2701,9 @@ void Player::actCardCounterTrigger()
|
|||
case 10: {
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
if (card->getCounters().value(counterId, 0)) {
|
||||
Command_SetCardCounter *cmd = new Command_SetCardCounter;
|
||||
auto *cmd = new Command_SetCardCounter;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_counter_id(counterId);
|
||||
|
@ -2730,7 +2716,8 @@ void Player::actCardCounterTrigger()
|
|||
case 11: {
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
int number = QInputDialog::getInt(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok);
|
||||
int number =
|
||||
QInputDialog::getInt(nullptr, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok);
|
||||
dialogSemaphore = false;
|
||||
if (clearCardsToDelete() || !ok) {
|
||||
return;
|
||||
|
@ -2738,8 +2725,8 @@ void Player::actCardCounterTrigger()
|
|||
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *card = static_cast<CardItem *>(i.next());
|
||||
Command_SetCardCounter *cmd = new Command_SetCardCounter;
|
||||
auto *card = static_cast<CardItem *>(i.next());
|
||||
auto *cmd = new Command_SetCardCounter;
|
||||
cmd->set_zone(card->getZone()->getName().toStdString());
|
||||
cmd->set_card_id(card->getId());
|
||||
cmd->set_counter_id(counterId);
|
||||
|
@ -2964,16 +2951,25 @@ void Player::addRelatedCardActions(const CardItem *card, QMenu *cardMenu)
|
|||
int index = 0;
|
||||
QAction *createRelatedCards = nullptr;
|
||||
for (const CardRelation *cardRelation : relatedCards) {
|
||||
QString cardName = cardRelation->getName();
|
||||
CardInfoPtr relatedCard = db->getCard(cardRelation->getName());
|
||||
if (relatedCard == nullptr)
|
||||
continue;
|
||||
QString relatedCardName;
|
||||
if (relatedCard->getPowTough().size() > 0) {
|
||||
relatedCardName = relatedCard->getPowTough() + " " + relatedCard->getName(); // "n/n name"
|
||||
} else {
|
||||
relatedCardName = relatedCard->getName(); // "name"
|
||||
}
|
||||
|
||||
QString text = tr("Token: ");
|
||||
if (cardRelation->getDoesAttach()) {
|
||||
text += tr("Attach to ") + "\"" + cardName + "\"";
|
||||
text += tr("Attach to ") + "\"" + relatedCardName + "\"";
|
||||
} else if (cardRelation->getIsVariable()) {
|
||||
text += "X " + cardName;
|
||||
text += "X " + relatedCardName;
|
||||
} else if (cardRelation->getDefaultCount() != 1) {
|
||||
text += QString(cardRelation->getDefaultCount()) + "x " + cardName;
|
||||
text += QString::number(cardRelation->getDefaultCount()) + "x " + relatedCardName;
|
||||
} else {
|
||||
text += cardName;
|
||||
text += relatedCardName;
|
||||
}
|
||||
|
||||
if (createRelatedCards == nullptr) {
|
||||
|
@ -2985,7 +2981,7 @@ void Player::addRelatedCardActions(const CardItem *card, QMenu *cardMenu)
|
|||
}
|
||||
}
|
||||
|
||||
QAction *createRelated = new QAction(text, this);
|
||||
auto *createRelated = new QAction(text, this);
|
||||
createRelated->setData(QVariant(index++));
|
||||
connect(createRelated, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
|
||||
cardMenu->addAction(createRelated);
|
||||
|
@ -3010,7 +3006,7 @@ QMenu *Player::getCardMenu() const
|
|||
if (aCardMenu) {
|
||||
return aCardMenu->menu();
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString Player::getName() const
|
||||
|
@ -3055,7 +3051,7 @@ void Player::setMirrored(bool _mirrored)
|
|||
|
||||
void Player::processSceneSizeChange(int newPlayerWidth)
|
||||
{
|
||||
// Extend table (and hand, if horizontal) to accomodate the new player width.
|
||||
// Extend table (and hand, if horizontal) to accommodate the new player width.
|
||||
qreal tableWidth = newPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width();
|
||||
if (!settingsCache->getHorizontalHand()) {
|
||||
tableWidth -= hand->boundingRect().width();
|
||||
|
@ -3072,10 +3068,10 @@ void Player::setLastToken(CardInfoPtr cardInfo)
|
|||
}
|
||||
|
||||
lastTokenName = cardInfo->getName();
|
||||
lastTokenColor = cardInfo->getColors().isEmpty() ? QString() : cardInfo->getColors().first().toLower();
|
||||
lastTokenColor = cardInfo->getColors().isEmpty() ? QString() : cardInfo->getColors().left(1).toLower();
|
||||
lastTokenPT = cardInfo->getPowTough();
|
||||
lastTokenAnnotation = settingsCache->getAnnotateTokens() ? cardInfo->getText() : "";
|
||||
lastTokenTableRow = table->clampValidTableRow(2 - cardInfo->getTableRow());
|
||||
lastTokenTableRow = TableZone::clampValidTableRow(2 - cardInfo->getTableRow());
|
||||
lastTokenDestroy = true;
|
||||
aCreateAnotherToken->setText(tr("C&reate another %1 token").arg(lastTokenName));
|
||||
aCreateAnotherToken->setEnabled(true);
|
||||
|
|
|
@ -79,17 +79,17 @@ public:
|
|||
{
|
||||
Type = typeOther
|
||||
};
|
||||
int type() const
|
||||
int type() const override
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
PlayerArea(QGraphicsItem *parent = 0);
|
||||
QRectF boundingRect() const
|
||||
explicit PlayerArea(QGraphicsItem *parent = nullptr);
|
||||
QRectF boundingRect() const override
|
||||
{
|
||||
return bRect;
|
||||
}
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void setSize(qreal width, qreal height);
|
||||
};
|
||||
|
@ -251,7 +251,6 @@ private:
|
|||
void createCard(const CardItem *sourceCard, const QString &dbCardName, bool attach = false);
|
||||
void createAttachedCard(const CardItem *sourceCard, const QString &dbCardName);
|
||||
bool createRelatedFromRelation(const CardItem *sourceCard, const CardRelation *cardRelation);
|
||||
QString dbNameFromTokenDisplayName(const QString &tokenName);
|
||||
|
||||
QRectF bRect;
|
||||
|
||||
|
@ -308,12 +307,12 @@ public:
|
|||
{
|
||||
Type = typeOther
|
||||
};
|
||||
int type() const
|
||||
int type() const override
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void playCard(CardItem *c, bool faceDown, bool tapped);
|
||||
void addCard(CardItem *c);
|
||||
|
@ -336,7 +335,7 @@ public:
|
|||
}
|
||||
|
||||
Player(const ServerInfo_User &info, int _id, bool _local, TabGame *_parent);
|
||||
~Player();
|
||||
~Player() override;
|
||||
void retranslateUi();
|
||||
void clear();
|
||||
TabGame *getGame() const
|
||||
|
@ -380,7 +379,7 @@ public:
|
|||
{
|
||||
return active;
|
||||
}
|
||||
void setActive(bool _active);
|
||||
void setActivePlayer(bool _active);
|
||||
void setShortcutsActive();
|
||||
void setShortcutsInactive();
|
||||
void updateZones();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "releasechannel.h"
|
||||
#include "qt-json/json.h"
|
||||
#include "version_string.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
|
@ -93,21 +92,20 @@ QString StableReleaseChannel::getReleaseChannelUrl() const
|
|||
|
||||
void StableReleaseChannel::releaseListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
QJsonParseError parseError{};
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the release update server:" << tmp;
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the release update server.";
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap resultMap = jsonResponse.toVariant().toMap();
|
||||
if (!(resultMap.contains("name") && resultMap.contains("html_url") && resultMap.contains("tag_name") &&
|
||||
resultMap.contains("published_at"))) {
|
||||
qWarning() << "Invalid received from the release update server:" << tmp;
|
||||
qWarning() << "Invalid received from the release update server.";
|
||||
emit error(tr("Invalid reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
@ -145,7 +143,7 @@ void StableReleaseChannel::releaseListFinished()
|
|||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
qDebug() << "Got reply from release server, size=" << tmp.size() << "name=" << lastRelease->getName()
|
||||
qDebug() << "Got reply from release server, name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl() << "date=" << lastRelease->getPublishDate()
|
||||
<< "url=" << lastRelease->getDownloadUrl();
|
||||
|
||||
|
@ -158,26 +156,25 @@ void StableReleaseChannel::releaseListFinished()
|
|||
|
||||
void StableReleaseChannel::tagListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
QJsonParseError parseError{};
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the tag update server:" << tmp;
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the tag update server.";
|
||||
emit error(tr("No reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap resultMap = jsonResponse.toVariant().toMap();
|
||||
if (!(resultMap.contains("object") && resultMap["object"].toMap().contains("sha"))) {
|
||||
qWarning() << "Invalid received from the tag update server:" << tmp;
|
||||
qWarning() << "Invalid received from the tag update server.";
|
||||
emit error(tr("Invalid reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
lastRelease->setCommitHash(resultMap["object"].toMap()["sha"].toString());
|
||||
qDebug() << "Got reply from tag server, size=" << tmp.size() << "commit=" << lastRelease->getCommitHash();
|
||||
qDebug() << "Got reply from tag server, commit=" << lastRelease->getCommitHash();
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
|
@ -190,7 +187,6 @@ void StableReleaseChannel::tagListFinished()
|
|||
void StableReleaseChannel::fileListFinished()
|
||||
{
|
||||
// Only implemented to satisfy interface
|
||||
return;
|
||||
}
|
||||
|
||||
QString BetaReleaseChannel::getManualDownloadUrl() const
|
||||
|
@ -210,7 +206,7 @@ QString BetaReleaseChannel::getReleaseChannelUrl() const
|
|||
|
||||
void BetaReleaseChannel::releaseListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
QByteArray jsonData = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
|
@ -224,7 +220,7 @@ void BetaReleaseChannel::releaseListFinished()
|
|||
*/
|
||||
QVariantMap resultMap = array.at(0).toObject().toVariantMap();
|
||||
|
||||
if (array.size() == 0 || resultMap.size() == 0) {
|
||||
if (array.empty() || resultMap.empty()) {
|
||||
qWarning() << "No reply received from the release update server:" << QString(jsonData);
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
|
@ -262,18 +258,17 @@ void BetaReleaseChannel::releaseListFinished()
|
|||
|
||||
void BetaReleaseChannel::fileListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
QByteArray jsonData = reply->readAll();
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
QJsonParseError parseError{};
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
bool ok;
|
||||
|
||||
QVariantList resultList = QtJson::Json::parse(jsonData, ok).toList();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the file update server:" << QString(jsonData);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the file update server.";
|
||||
emit error(tr("No reply received from the file update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantList resultList = jsonResponse.toVariant().toList();
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
#include <utility>
|
||||
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
|
@ -15,8 +16,8 @@ class Release
|
|||
friend class BetaReleaseChannel;
|
||||
|
||||
public:
|
||||
Release(){};
|
||||
~Release(){};
|
||||
Release() = default;
|
||||
~Release() = default;
|
||||
|
||||
private:
|
||||
QString name, descriptionUrl, downloadUrl, commitHash;
|
||||
|
@ -26,20 +27,20 @@ private:
|
|||
protected:
|
||||
void setName(QString _name)
|
||||
{
|
||||
name = _name;
|
||||
name = std::move(_name);
|
||||
}
|
||||
void setDescriptionUrl(QString _descriptionUrl)
|
||||
{
|
||||
descriptionUrl = _descriptionUrl;
|
||||
descriptionUrl = std::move(_descriptionUrl);
|
||||
}
|
||||
void setDownloadUrl(QString _downloadUrl)
|
||||
{
|
||||
downloadUrl = _downloadUrl;
|
||||
downloadUrl = std::move(_downloadUrl);
|
||||
compatibleVersionFound = true;
|
||||
}
|
||||
void setCommitHash(QString _commitHash)
|
||||
{
|
||||
commitHash = _commitHash;
|
||||
commitHash = std::move(_commitHash);
|
||||
}
|
||||
void setPublishDate(QDate _publishDate)
|
||||
{
|
||||
|
@ -78,7 +79,7 @@ class ReleaseChannel : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
ReleaseChannel();
|
||||
~ReleaseChannel();
|
||||
~ReleaseChannel() override;
|
||||
|
||||
protected:
|
||||
// shared by all instances
|
||||
|
@ -116,33 +117,41 @@ class StableReleaseChannel : public ReleaseChannel
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StableReleaseChannel(){};
|
||||
~StableReleaseChannel(){};
|
||||
virtual QString getManualDownloadUrl() const;
|
||||
virtual QString getName() const;
|
||||
StableReleaseChannel() = default;
|
||||
~StableReleaseChannel() override = default;
|
||||
|
||||
QString getManualDownloadUrl() const override;
|
||||
|
||||
QString getName() const override;
|
||||
|
||||
protected:
|
||||
virtual QString getReleaseChannelUrl() const;
|
||||
QString getReleaseChannelUrl() const override;
|
||||
protected slots:
|
||||
virtual void releaseListFinished();
|
||||
|
||||
void releaseListFinished() override;
|
||||
void tagListFinished();
|
||||
virtual void fileListFinished();
|
||||
|
||||
void fileListFinished() override;
|
||||
};
|
||||
|
||||
class BetaReleaseChannel : public ReleaseChannel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BetaReleaseChannel(){};
|
||||
~BetaReleaseChannel(){};
|
||||
virtual QString getManualDownloadUrl() const;
|
||||
virtual QString getName() const;
|
||||
BetaReleaseChannel() = default;
|
||||
~BetaReleaseChannel() override = default;
|
||||
|
||||
QString getManualDownloadUrl() const override;
|
||||
|
||||
QString getName() const override;
|
||||
|
||||
protected:
|
||||
virtual QString getReleaseChannelUrl() const;
|
||||
QString getReleaseChannelUrl() const override;
|
||||
protected slots:
|
||||
virtual void releaseListFinished();
|
||||
virtual void fileListFinished();
|
||||
|
||||
void releaseListFinished() override;
|
||||
|
||||
void fileListFinished() override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -29,9 +29,9 @@ QStringList DownloadSettings::getAllURLs()
|
|||
void DownloadSettings::populateDefaultURLs()
|
||||
{
|
||||
downloadURLs.clear();
|
||||
downloadURLs.append("https://api.scryfall.com/cards/!uuid!?format=image");
|
||||
downloadURLs.append("https://api.scryfall.com/cards/multiverse/!cardid!?format=image");
|
||||
downloadURLs.append("http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card");
|
||||
downloadURLs.append("https://api.scryfall.com/cards/!set:uuid!?format=image&face=!prop:side!");
|
||||
downloadURLs.append("https://api.scryfall.com/cards/multiverse/!set:muid!?format=image");
|
||||
downloadURLs.append("http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!set:muid!&type=card");
|
||||
downloadURLs.append("http://gatherer.wizards.com/Handlers/Image.ashx?name=!name!&type=card");
|
||||
setValue(QVariant::fromValue(downloadURLs), "urls", "downloads");
|
||||
}
|
||||
|
|
|
@ -22,62 +22,62 @@
|
|||
<context>
|
||||
<name>AppearanceSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="418"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="338"/>
|
||||
<source>Theme settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="419"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="339"/>
|
||||
<source>Current theme:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="421"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="341"/>
|
||||
<source>Card rendering</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="422"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="342"/>
|
||||
<source>Display card names on cards having a picture</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="423"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="343"/>
|
||||
<source>Scale cards on mouse over</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="425"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="345"/>
|
||||
<source>Hand layout</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="426"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="346"/>
|
||||
<source>Display hand horizontally (wastes space)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="427"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="347"/>
|
||||
<source>Enable left justification</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="429"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="349"/>
|
||||
<source>Table grid layout</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="430"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="350"/>
|
||||
<source>Invert vertical coordinate</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="431"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="351"/>
|
||||
<source>Minimum player count for multi-column layout:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="432"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="352"/>
|
||||
<source>Maximum font size for information displayed on cards:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -192,22 +192,22 @@ This is only saved for moderators and cannot be seen by the banned person.</sour
|
|||
<context>
|
||||
<name>BetaReleaseChannel</name>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="203"/>
|
||||
<location filename="../src/releasechannel.cpp" line="200"/>
|
||||
<source>Beta Releases</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="229"/>
|
||||
<location filename="../src/releasechannel.cpp" line="226"/>
|
||||
<source>No reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="238"/>
|
||||
<location filename="../src/releasechannel.cpp" line="235"/>
|
||||
<source>Invalid reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="273"/>
|
||||
<location filename="../src/releasechannel.cpp" line="268"/>
|
||||
<source>No reply received from the file update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -330,17 +330,17 @@ This is only saved for moderators and cannot be seen by the banned person.</sour
|
|||
<context>
|
||||
<name>CardFrame</name>
|
||||
<message>
|
||||
<location filename="../src/cardframe.cpp" line="63"/>
|
||||
<location filename="../src/cardframe.cpp" line="64"/>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardframe.cpp" line="64"/>
|
||||
<location filename="../src/cardframe.cpp" line="65"/>
|
||||
<source>Description</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardframe.cpp" line="65"/>
|
||||
<location filename="../src/cardframe.cpp" line="66"/>
|
||||
<source>Both</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -348,40 +348,20 @@ This is only saved for moderators and cannot be seen by the banned person.</sour
|
|||
<context>
|
||||
<name>CardInfoText</name>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="123"/>
|
||||
<location filename="../src/cardinfotext.cpp" line="53"/>
|
||||
<source>Related cards:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="77"/>
|
||||
<source>Unknown card:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="131"/>
|
||||
<location filename="../src/cardinfotext.cpp" line="37"/>
|
||||
<source>Name:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="132"/>
|
||||
<source>Mana cost:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="133"/>
|
||||
<source>Color(s):</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="134"/>
|
||||
<source>Card type:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="135"/>
|
||||
<source>P / T:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/cardinfotext.cpp" line="136"/>
|
||||
<source>Loyalty:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CardItem</name>
|
||||
|
@ -522,58 +502,120 @@ This is only saved for moderators and cannot be seen by the banned person.</sour
|
|||
<context>
|
||||
<name>DeckEditorSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="511"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="561"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="440"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="615"/>
|
||||
<source>Update Spoilers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="517"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="548"/>
|
||||
<source>Success</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="517"/>
|
||||
<source>Download URLs have been reset.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="548"/>
|
||||
<source>Downloaded card pictures have been reset.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="550"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="550"/>
|
||||
<source>One or more downloaded card pictures could not be cleared.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="557"/>
|
||||
<source>Add URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="557"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="577"/>
|
||||
<source>URL:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="577"/>
|
||||
<source>Edit URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="604"/>
|
||||
<source>Updating...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="580"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="634"/>
|
||||
<source>Choose path</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="606"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="660"/>
|
||||
<source>URL Download Priority</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="661"/>
|
||||
<source>Spoilers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="607"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="662"/>
|
||||
<source>Download Spoilers Automatically</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="608"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="663"/>
|
||||
<source>Spoiler Location:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="609"/>
|
||||
<source>Hey, something's here finally!</source>
|
||||
<location filename="../src/dlg_settings.cpp" line="668"/>
|
||||
<source>Download card pictures on the fly</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="610"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="669"/>
|
||||
<source>How to add a custom URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="670"/>
|
||||
<source>Delete Downloaded Images</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="671"/>
|
||||
<source>Reset Download URLs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="664"/>
|
||||
<source>Last Updated</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="611"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="665"/>
|
||||
<source>Spoilers download automatically on launch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="612"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="666"/>
|
||||
<source>Press the button to manually update without relaunching</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="613"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="667"/>
|
||||
<source>Do not close settings until manual update complete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1498,12 +1540,12 @@ Make sure to enable the 'Token' set in the "Manage sets" dia
|
|||
<context>
|
||||
<name>DlgSettings</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1017"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1079"/>
|
||||
<source>Unknown Error loading card database</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1025"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1087"/>
|
||||
<source>Your card database is invalid.
|
||||
|
||||
Cockatrice may not function correctly with an invalid database
|
||||
|
@ -1514,7 +1556,7 @@ Would you like to change your database location setting?</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1031"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1093"/>
|
||||
<source>Your card database version is too old.
|
||||
|
||||
This can cause problems loading card information or images
|
||||
|
@ -1525,7 +1567,7 @@ Would you like to change your database location setting?</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1037"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1099"/>
|
||||
<source>Your card database did not finish loading
|
||||
|
||||
Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached
|
||||
|
@ -1534,21 +1576,21 @@ Would you like to change your database location setting?</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1043"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1105"/>
|
||||
<source>File Error loading your card database.
|
||||
|
||||
Would you like to change your database location setting?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1047"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1109"/>
|
||||
<source>Your card database was loaded but contains no cards.
|
||||
|
||||
Would you like to change your database location setting?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1051"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1113"/>
|
||||
<source>Unknown card database load status
|
||||
|
||||
Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues
|
||||
|
@ -1557,59 +1599,59 @@ Would you like to change your database location setting?</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1059"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1069"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1079"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1121"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1131"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1141"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1070"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1132"/>
|
||||
<source>The path to your deck directory is invalid. Would you like to go back and set the correct path?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1080"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1142"/>
|
||||
<source>The path to your card pictures directory is invalid. Would you like to go back and set the correct path?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1092"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1154"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1094"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1156"/>
|
||||
<source>General</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1095"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1157"/>
|
||||
<source>Appearance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1096"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1158"/>
|
||||
<source>User Interface</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1097"/>
|
||||
<source>Deck Editor</source>
|
||||
<location filename="../src/dlg_settings.cpp" line="1159"/>
|
||||
<source>Card Sources</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1098"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1160"/>
|
||||
<source>Chat</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1099"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1161"/>
|
||||
<source>Sound</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="1100"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="1162"/>
|
||||
<source>Shortcuts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -2001,127 +2043,76 @@ You may have to build from source yourself.</source>
|
|||
<context>
|
||||
<name>GeneralSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="173"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="183"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="193"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="203"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="213"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="223"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="233"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="267"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="277"/>
|
||||
<source>Choose path</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="260"/>
|
||||
<source>Success</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="260"/>
|
||||
<source>Downloaded card pictures have been reset.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="262"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="262"/>
|
||||
<source>One or more downloaded card pictures could not be cleared.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="292"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="228"/>
|
||||
<source>Personal settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="293"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="229"/>
|
||||
<source>Language:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="294"/>
|
||||
<source>Download card pictures on the fly</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="297"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="232"/>
|
||||
<source>Paths (editing disabled in portable mode)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="299"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="234"/>
|
||||
<source>Paths</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="302"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="237"/>
|
||||
<source>Decks directory:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="303"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="238"/>
|
||||
<source>Replays directory:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="304"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="239"/>
|
||||
<source>Pictures directory:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="305"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="240"/>
|
||||
<source>Card database:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="306"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="241"/>
|
||||
<source>Token database:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="307"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="242"/>
|
||||
<source>Picture cache size:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="308"/>
|
||||
<source>Primary download URL:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="309"/>
|
||||
<source>Fallback download URL:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="311"/>
|
||||
<source>How to set a custom picture url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="312"/>
|
||||
<source>Reset/clear downloaded pictures</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="313"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="243"/>
|
||||
<source>Update channel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="314"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="244"/>
|
||||
<source>Notify if a feature supported by the server is missing in my client</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="315"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="316"/>
|
||||
<source>Reset</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="317"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="245"/>
|
||||
<source>Show tips on startup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3443,94 +3434,157 @@ Cockatrice will now reload the card database.</source>
|
|||
<context>
|
||||
<name>MessagesSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="652"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="710"/>
|
||||
<source>Word1 Word2 Word3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="779"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="750"/>
|
||||
<source>Add New URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="755"/>
|
||||
<source>Edit URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="759"/>
|
||||
<source>Remove URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="841"/>
|
||||
<source>Add message</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="779"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="791"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="841"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="853"/>
|
||||
<source>Message:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="791"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="853"/>
|
||||
<source>Edit message</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="809"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="871"/>
|
||||
<source>Chat settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="810"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="872"/>
|
||||
<source>Custom alert words</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="811"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="873"/>
|
||||
<source>Enable chat mentions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="812"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="874"/>
|
||||
<source>Enable mention completer</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="813"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="875"/>
|
||||
<source>In-game message macros</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="814"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="876"/>
|
||||
<source>Ignore chat room messages sent by unregistered users</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="815"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="877"/>
|
||||
<source>Ignore private messages sent by unregistered users</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="816"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="817"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="878"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="879"/>
|
||||
<source>Invert text color</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="818"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="880"/>
|
||||
<source>Enable desktop notifications for private messages</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="819"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="881"/>
|
||||
<source>Enable desktop notification for mentions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="820"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="882"/>
|
||||
<source>Enable room message history on join</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="821"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="822"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="883"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="884"/>
|
||||
<source>(Color is hexadecimal)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="823"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="885"/>
|
||||
<source>Separate words with a space, alphanumeric characters only</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Mtg</name>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="28"/>
|
||||
<source>Card type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="30"/>
|
||||
<source>Converted mana cost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="32"/>
|
||||
<source>Color(s)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="34"/>
|
||||
<source>Loyalty</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="36"/>
|
||||
<source>Main card type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="38"/>
|
||||
<source>Mana cost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="40"/>
|
||||
<source>P / T</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="42"/>
|
||||
<source>Side</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/game_specific_terms.h" line="44"/>
|
||||
<source>Layout</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PhasesToolbar</name>
|
||||
<message>
|
||||
|
@ -3948,7 +4002,7 @@ Cockatrice will now reload the card database.</source>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="1160"/>
|
||||
<location filename="../src/player.cpp" line="3080"/>
|
||||
<location filename="../src/player.cpp" line="3077"/>
|
||||
<source>C&reate another %1 token</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3958,34 +4012,32 @@ Cockatrice will now reload the card database.</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="1448"/>
|
||||
<location filename="../src/player.cpp" line="1449"/>
|
||||
<location filename="../src/player.cpp" line="2968"/>
|
||||
<location filename="../src/player.cpp" line="2965"/>
|
||||
<source>Token: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2298"/>
|
||||
<location filename="../src/player.cpp" line="2286"/>
|
||||
<source>Place card X cards from top of library</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2299"/>
|
||||
<location filename="../src/player.cpp" line="2287"/>
|
||||
<source>How many cards from the top of the deck should this card be placed:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2940"/>
|
||||
<location filename="../src/player.cpp" line="2928"/>
|
||||
<source>View related cards</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2970"/>
|
||||
<location filename="../src/player.cpp" line="2967"/>
|
||||
<source>Attach to </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2984"/>
|
||||
<location filename="../src/player.cpp" line="2981"/>
|
||||
<source>All tokens</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4036,7 +4088,7 @@ Cockatrice will now reload the card database.</source>
|
|||
<location filename="../src/player.cpp" line="1025"/>
|
||||
<location filename="../src/player.cpp" line="1051"/>
|
||||
<location filename="../src/player.cpp" line="1307"/>
|
||||
<location filename="../src/player.cpp" line="2733"/>
|
||||
<location filename="../src/player.cpp" line="2721"/>
|
||||
<source>Number:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4061,27 +4113,27 @@ Cockatrice will now reload the card database.</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2566"/>
|
||||
<location filename="../src/player.cpp" line="2554"/>
|
||||
<source>Set power/toughness</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2566"/>
|
||||
<location filename="../src/player.cpp" line="2554"/>
|
||||
<source>Please enter the new PT:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2647"/>
|
||||
<location filename="../src/player.cpp" line="2635"/>
|
||||
<source>Set annotation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2647"/>
|
||||
<location filename="../src/player.cpp" line="2635"/>
|
||||
<source>Please enter the new annotation:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/player.cpp" line="2733"/>
|
||||
<location filename="../src/player.cpp" line="2721"/>
|
||||
<source>Set counters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4352,27 +4404,27 @@ Please check your shortcut settings!</source>
|
|||
<context>
|
||||
<name>SoundSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="891"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="953"/>
|
||||
<source>Enable &sounds</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="892"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="954"/>
|
||||
<source>Current sounds theme:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="893"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="955"/>
|
||||
<source>Test system sound engine</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="894"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="956"/>
|
||||
<source>Sound settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="895"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="957"/>
|
||||
<source>Master volume</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4429,27 +4481,27 @@ Please check your shortcut settings!</source>
|
|||
<context>
|
||||
<name>StableReleaseChannel</name>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="86"/>
|
||||
<location filename="../src/releasechannel.cpp" line="85"/>
|
||||
<source>Stable Releases</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="104"/>
|
||||
<location filename="../src/releasechannel.cpp" line="101"/>
|
||||
<source>No reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="111"/>
|
||||
<location filename="../src/releasechannel.cpp" line="109"/>
|
||||
<source>Invalid reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="169"/>
|
||||
<location filename="../src/releasechannel.cpp" line="165"/>
|
||||
<source>No reply received from the tag update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/releasechannel.cpp" line="175"/>
|
||||
<location filename="../src/releasechannel.cpp" line="172"/>
|
||||
<source>Invalid reply received from the tag update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -5788,42 +5840,42 @@ Please refrain from engaging in this activity or further actions may be taken ag
|
|||
<context>
|
||||
<name>UserInterfaceSettingsPage</name>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="489"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="409"/>
|
||||
<source>General interface settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="490"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="410"/>
|
||||
<source>Enable notifications in taskbar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="491"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="411"/>
|
||||
<source>Notify in the taskbar for game events while you are spectating</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="492"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="412"/>
|
||||
<source>&Double-click cards to play them (instead of single-click)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="493"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="413"/>
|
||||
<source>&Play all nonlands onto the stack (not the battlefield) by default</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="494"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="414"/>
|
||||
<source>Annotate card text on tokens</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="495"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="415"/>
|
||||
<source>Animation settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/dlg_settings.cpp" line="496"/>
|
||||
<location filename="../src/dlg_settings.cpp" line="416"/>
|
||||
<source>&Tap/untap animation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -11,9 +11,12 @@ SET(oracle_SOURCES
|
|||
src/main.cpp
|
||||
src/oraclewizard.cpp
|
||||
src/oracleimporter.cpp
|
||||
src/qt-json/json.cpp
|
||||
../cockatrice/src/carddatabase.cpp
|
||||
../cockatrice/src/pictureloader.cpp
|
||||
../cockatrice/src/carddbparser/carddatabaseparser.cpp
|
||||
../cockatrice/src/carddbparser/cockatricexml3.cpp
|
||||
../cockatrice/src/carddbparser/cockatricexml4.cpp
|
||||
../cockatrice/src/settingscache.cpp
|
||||
../cockatrice/src/shortcutssettings.cpp
|
||||
../cockatrice/src/settings/carddatabasesettings.cpp
|
||||
|
@ -24,7 +27,6 @@ SET(oracle_SOURCES
|
|||
../cockatrice/src/settings/layoutssettings.cpp
|
||||
../cockatrice/src/settings/downloadsettings.cpp
|
||||
../cockatrice/src/thememanager.cpp
|
||||
../cockatrice/src/qt-json/json.cpp
|
||||
../cockatrice/src/releasechannel.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "oracleimporter.h"
|
||||
#include "carddbparser/cockatricexml3.h"
|
||||
#include "carddbparser/cockatricexml4.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtWidgets>
|
||||
|
@ -7,6 +7,14 @@
|
|||
|
||||
#include "qt-json/json.h"
|
||||
|
||||
SplitCardPart::SplitCardPart(const int _index,
|
||||
const QString &_text,
|
||||
const QVariantHash &_properties,
|
||||
const CardInfoPerSet _setInfo)
|
||||
: index(_index), text(_text), properties(_properties), setInfo(_setInfo)
|
||||
{
|
||||
}
|
||||
|
||||
OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) : CardDatabase(parent), dataDir(_dataDir)
|
||||
{
|
||||
}
|
||||
|
@ -25,24 +33,23 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
|||
QListIterator<QVariant> it(setsMap.values());
|
||||
QVariantMap map;
|
||||
|
||||
QString edition;
|
||||
QString editionLong;
|
||||
QVariant editionCards;
|
||||
QString shortName;
|
||||
QString longName;
|
||||
QList<QVariant> setCards;
|
||||
QString setType;
|
||||
QDate releaseDate;
|
||||
|
||||
while (it.hasNext()) {
|
||||
map = it.next().toMap();
|
||||
edition = map.value("code").toString().toUpper();
|
||||
editionLong = map.value("name").toString();
|
||||
editionCards = map.value("cards");
|
||||
shortName = map.value("code").toString().toUpper();
|
||||
longName = map.value("name").toString();
|
||||
setCards = map.value("cards").toList();
|
||||
setType = map.value("type").toString();
|
||||
// capitalize set type
|
||||
if (setType.length() > 0)
|
||||
setType[0] = setType[0].toUpper();
|
||||
releaseDate = map.value("releaseDate").toDate();
|
||||
|
||||
newSetList.append(SetToDownload(edition, editionLong, editionCards, setType, releaseDate));
|
||||
newSetList.append(SetToDownload(shortName, longName, setCards, setType, releaseDate));
|
||||
}
|
||||
|
||||
qSort(newSetList);
|
||||
|
@ -53,37 +60,27 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
|||
return true;
|
||||
}
|
||||
|
||||
CardInfoPtr OracleImporter::addCard(const QString &setName,
|
||||
QString cardName,
|
||||
CardInfoPtr OracleImporter::addCard(QString name,
|
||||
QString text,
|
||||
bool isToken,
|
||||
int cardId,
|
||||
QString &cardUuId,
|
||||
QString &setNumber,
|
||||
QString &cardCost,
|
||||
QString &cmc,
|
||||
const QString &cardType,
|
||||
const QString &cardPT,
|
||||
const QString &cardLoyalty,
|
||||
const QString &cardText,
|
||||
const QStringList &colors,
|
||||
const QList<CardRelation *> &relatedCards,
|
||||
const QList<CardRelation *> &reverseRelatedCards,
|
||||
bool upsideDown,
|
||||
QString &rarity)
|
||||
QVariantHash properties,
|
||||
QList<CardRelation *> &relatedCards,
|
||||
CardInfoPerSet setInfo)
|
||||
{
|
||||
QStringList cardTextRows = cardText.split("\n");
|
||||
|
||||
// Workaround for card name weirdness
|
||||
cardName = cardName.replace("Æ", "AE");
|
||||
cardName = cardName.replace("’", "'");
|
||||
name = name.replace("Æ", "AE");
|
||||
name = name.replace("’", "'");
|
||||
if (cards.contains(name)) {
|
||||
CardInfoPtr card = cards.value(name);
|
||||
card->addToSet(setInfo.getPtr(), setInfo);
|
||||
return card;
|
||||
}
|
||||
|
||||
CardInfoPtr card;
|
||||
if (cards.contains(cardName)) {
|
||||
card = cards.value(cardName);
|
||||
} else {
|
||||
// Remove {} around mana costs, except if it's split cost
|
||||
QStringList symbols = cardCost.split("}");
|
||||
QString formattedCardCost = QString();
|
||||
QString manacost = properties.value("manacost").toString();
|
||||
if (!manacost.isEmpty()) {
|
||||
QStringList symbols = manacost.split("}");
|
||||
QString formattedCardCost;
|
||||
for (QString symbol : symbols) {
|
||||
if (symbol.contains(QRegExp("[0-9WUBGRP]/[0-9WUBGRP]"))) {
|
||||
symbol.append("}");
|
||||
|
@ -92,9 +89,26 @@ CardInfoPtr OracleImporter::addCard(const QString &setName,
|
|||
}
|
||||
formattedCardCost.append(symbol);
|
||||
}
|
||||
properties.insert("manacost", formattedCardCost);
|
||||
}
|
||||
|
||||
// fix colors
|
||||
QString allColors = properties.value("colors").toString();
|
||||
if (allColors.size() > 1) {
|
||||
sortAndReduceColors(allColors);
|
||||
properties.insert("colors", allColors);
|
||||
}
|
||||
|
||||
// DETECT CARD POSITIONING INFO
|
||||
|
||||
// cards that enter the field tapped
|
||||
bool cipt = text.contains("Hideaway") || (text.contains(name + " enters the battlefield tapped") &&
|
||||
!text.contains(name + " enters the battlefield tapped unless"));
|
||||
|
||||
// detect mana generator artifacts
|
||||
QStringList cardTextRows = text.split("\n");
|
||||
bool mArtifact = false;
|
||||
QString cardType = properties.value("type").toString();
|
||||
if (cardType.endsWith("Artifact")) {
|
||||
for (int i = 0; i < cardTextRows.size(); ++i) {
|
||||
cardTextRows[i].remove(QRegularExpression(R"(\".*?\")"));
|
||||
|
@ -104,228 +118,222 @@ CardInfoPtr OracleImporter::addCard(const QString &setName,
|
|||
}
|
||||
}
|
||||
|
||||
// detect cards that enter the field tapped
|
||||
bool cipt =
|
||||
cardText.contains("Hideaway") || (cardText.contains(cardName + " enters the battlefield tapped") &&
|
||||
!cardText.contains(cardName + " enters the battlefield tapped unless"));
|
||||
|
||||
// insert the card and its properties
|
||||
card = CardInfo::newInstance(cardName, isToken, formattedCardCost, cmc, cardType, cardPT, cardText, colors,
|
||||
relatedCards, reverseRelatedCards, upsideDown, cardLoyalty, cipt);
|
||||
// table row
|
||||
int tableRow = 1;
|
||||
QString mainCardType = card->getMainCardType();
|
||||
QString mainCardType = properties.value("maintype").toString();
|
||||
if ((mainCardType == "Land") || mArtifact)
|
||||
tableRow = 0;
|
||||
else if ((mainCardType == "Sorcery") || (mainCardType == "Instant"))
|
||||
tableRow = 3;
|
||||
else if (mainCardType == "Creature")
|
||||
tableRow = 2;
|
||||
card->setTableRow(tableRow);
|
||||
|
||||
cards.insert(cardName, card);
|
||||
// card side
|
||||
QString side = properties.value("side").toString() == "b" ? "back" : "front";
|
||||
properties.insert("side", side);
|
||||
|
||||
// upsideDown (flip cards)
|
||||
bool upsideDown = false;
|
||||
QStringList additionalNames = properties.value("names").toStringList();
|
||||
QString layout = properties.value("layout").toString();
|
||||
if (layout == "flip") {
|
||||
if (properties.value("side").toString() != "front") {
|
||||
upsideDown = true;
|
||||
}
|
||||
// reset the side property, since the card has no back image
|
||||
properties.insert("side", "front");
|
||||
}
|
||||
|
||||
card->setMuId(setName, cardId);
|
||||
card->setUuId(setName, cardUuId);
|
||||
card->setSetNumber(setName, setNumber);
|
||||
card->setRarity(setName, rarity);
|
||||
// insert the card and its properties
|
||||
QList<CardRelation *> reverseRelatedCards;
|
||||
CardInfoPerSetMap setsInfo;
|
||||
setsInfo.insert(setInfo.getPtr()->getShortName(), setInfo);
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards, reverseRelatedCards,
|
||||
setsInfo, cipt, tableRow, upsideDown);
|
||||
|
||||
return card;
|
||||
cards.insert(name, newCard);
|
||||
return newCard;
|
||||
}
|
||||
|
||||
int OracleImporter::importTextSpoiler(CardSetPtr set, const QVariant &data)
|
||||
QString OracleImporter::getStringPropertyFromMap(QVariantMap card, QString propertyName)
|
||||
{
|
||||
int cards = 0;
|
||||
return card.contains(propertyName) ? card.value(propertyName).toString() : QString("");
|
||||
}
|
||||
|
||||
QListIterator<QVariant> it(data.toList());
|
||||
QVariantMap map;
|
||||
QString cardName;
|
||||
QString cardCost;
|
||||
QString cmc;
|
||||
QString cardType;
|
||||
QString cardPT;
|
||||
QString cardText;
|
||||
QStringList colors;
|
||||
int OracleImporter::importCardsFromSet(CardSetPtr currentSet, const QList<QVariant> &cardsList)
|
||||
{
|
||||
static const QMap<QString, QString> cardProperties{
|
||||
// mtgjson name => xml name
|
||||
{"manaCost", "manacost"}, {"convertedManaCost", "cmc"}, {"type", "type"},
|
||||
{"loyalty", "loyalty"}, {"layout", "layout"}, {"side", "side"},
|
||||
};
|
||||
|
||||
static const QMap<QString, QString> setInfoProperties{// mtgjson name => xml name
|
||||
{"multiverseId", "muid"},
|
||||
{"scryfallId", "uuid"},
|
||||
{"number", "num"},
|
||||
{"rarity", "rarity"}};
|
||||
|
||||
int numCards = 0;
|
||||
QMap<QString, SplitCardPart> splitCards;
|
||||
QString ptSeparator("/");
|
||||
QVariantMap card;
|
||||
QString layout, name, text, colors, maintype, power, toughness;
|
||||
bool isToken;
|
||||
QStringList additionalNames;
|
||||
QVariantHash properties;
|
||||
CardInfoPerSet setInfo;
|
||||
QList<CardRelation *> relatedCards;
|
||||
QList<CardRelation *> reverseRelatedCards; // dummy
|
||||
int cardId;
|
||||
QString cardUuId;
|
||||
QString setNumber;
|
||||
QString rarity;
|
||||
QString cardLoyalty;
|
||||
bool upsideDown;
|
||||
QMap<int, QVariantMap> splitCards;
|
||||
|
||||
while (it.hasNext()) {
|
||||
map = it.next().toMap();
|
||||
for (const QVariant &cardVar : cardsList) {
|
||||
card = cardVar.toMap();
|
||||
|
||||
/* Currently used layouts are:
|
||||
* augment, double_faced_token, flip, host, leveler, meld, normal, planar,
|
||||
* saga, scheme, split, token, transform, vanguard
|
||||
*/
|
||||
QString layout = map.value("layout").toString();
|
||||
layout = getStringPropertyFromMap(card, "layout");
|
||||
|
||||
// don't import tokens from the json file
|
||||
isToken = false;
|
||||
if (layout == "token")
|
||||
continue;
|
||||
|
||||
// Aftermath card layout seems to have been integrated in "split"
|
||||
if (layout == "split") {
|
||||
// Enqueue split card for later handling
|
||||
cardId = map.contains("multiverseId") ? map.value("multiverseId").toInt() : 0;
|
||||
if (cardId)
|
||||
splitCards.insertMulti(cardId, map);
|
||||
continue;
|
||||
}
|
||||
|
||||
// normal cards handling
|
||||
cardName = map.contains("name") ? map.value("name").toString() : QString("");
|
||||
cardCost = map.contains("manaCost") ? map.value("manaCost").toString() : QString("");
|
||||
cmc = map.contains("convertedManaCost") ? map.value("convertedManaCost").toString() : QString("0");
|
||||
cardType = map.contains("type") ? map.value("type").toString() : QString("");
|
||||
cardPT = map.contains("power") || map.contains("toughness")
|
||||
? map.value("power").toString() + QString('/') + map.value("toughness").toString()
|
||||
: QString("");
|
||||
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
||||
cardId = map.contains("multiverseId") ? map.value("multiverseId").toInt() : 0;
|
||||
cardUuId = map.contains("scryfallId") ? map.value("scryfallId").toString() : QString("");
|
||||
setNumber = map.contains("number") ? map.value("number").toString() : QString("");
|
||||
rarity = map.contains("rarity") ? map.value("rarity").toString() : QString("");
|
||||
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toString() : QString("");
|
||||
colors = map.contains("colors") ? map.value("colors").toStringList() : QStringList();
|
||||
relatedCards = QList<CardRelation *>();
|
||||
if (map.contains("names"))
|
||||
for (const QString &name : map.value("names").toStringList()) {
|
||||
if (name != cardName)
|
||||
relatedCards.append(new CardRelation(name, true));
|
||||
name = getStringPropertyFromMap(card, "name");
|
||||
text = getStringPropertyFromMap(card, "text");
|
||||
|
||||
// card properties
|
||||
properties.clear();
|
||||
QMapIterator<QString, QString> it(cardProperties);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QString mtgjsonProperty = it.key();
|
||||
QString xmlPropertyName = it.value();
|
||||
QString propertyValue = getStringPropertyFromMap(card, mtgjsonProperty);
|
||||
if (!propertyValue.isEmpty())
|
||||
properties.insert(xmlPropertyName, propertyValue);
|
||||
}
|
||||
|
||||
if (0 == QString::compare(map.value("layout").toString(), QString("flip"), Qt::CaseInsensitive)) {
|
||||
QStringList cardNames = map.contains("names") ? map.value("names").toStringList() : QStringList();
|
||||
upsideDown = (cardNames.indexOf(cardName) > 0);
|
||||
// per-set properties
|
||||
setInfo = CardInfoPerSet(currentSet);
|
||||
QMapIterator<QString, QString> it2(setInfoProperties);
|
||||
while (it2.hasNext()) {
|
||||
it2.next();
|
||||
QString mtgjsonProperty = it2.key();
|
||||
QString xmlPropertyName = it2.value();
|
||||
QString propertyValue = getStringPropertyFromMap(card, mtgjsonProperty);
|
||||
if (!propertyValue.isEmpty())
|
||||
setInfo.setProperty(xmlPropertyName, propertyValue);
|
||||
}
|
||||
|
||||
// special handling properties
|
||||
colors = card.value("colors").toStringList().join("");
|
||||
if (!colors.isEmpty())
|
||||
properties.insert("colors", colors);
|
||||
|
||||
maintype = card.value("types").toStringList().first();
|
||||
if (!maintype.isEmpty())
|
||||
properties.insert("maintype", maintype);
|
||||
|
||||
power = getStringPropertyFromMap(card, "power");
|
||||
toughness = getStringPropertyFromMap(card, "toughness");
|
||||
if (!(power.isEmpty() && toughness.isEmpty()))
|
||||
properties.insert("pt", power + ptSeparator + toughness);
|
||||
|
||||
additionalNames = card.value("names").toStringList();
|
||||
// split cards are considered a single card, enqueue for later merging
|
||||
if (layout == "split") {
|
||||
// get the position of this card part
|
||||
int index = additionalNames.indexOf(name);
|
||||
// construct full card name
|
||||
name = additionalNames.join(QString(" // "));
|
||||
SplitCardPart split(index, text, properties, setInfo);
|
||||
splitCards.insertMulti(name, split);
|
||||
} else {
|
||||
upsideDown = false;
|
||||
}
|
||||
|
||||
CardInfoPtr card =
|
||||
addCard(set->getShortName(), cardName, false, cardId, cardUuId, setNumber, cardCost, cmc, cardType, cardPT,
|
||||
cardLoyalty, cardText, colors, relatedCards, reverseRelatedCards, upsideDown, rarity);
|
||||
|
||||
if (!set->contains(card)) {
|
||||
card->addToSet(set);
|
||||
cards++;
|
||||
// relations
|
||||
relatedCards.clear();
|
||||
if (additionalNames.size() > 1) {
|
||||
for (const QString &additionalName : additionalNames) {
|
||||
if (additionalName != name)
|
||||
relatedCards.append(new CardRelation(additionalName, true));
|
||||
}
|
||||
}
|
||||
|
||||
// split cards handling - get all unique card muids
|
||||
QList<int> muids = splitCards.uniqueKeys();
|
||||
for (int muid : muids) {
|
||||
// get all cards for this specific muid
|
||||
QList<QVariantMap> maps = splitCards.values(muid);
|
||||
QStringList names;
|
||||
// now, reorder the cards using the ordered list of names
|
||||
QMap<int, QVariantMap> orderedMaps;
|
||||
for (const QVariantMap &inner_map : maps) {
|
||||
if (names.isEmpty())
|
||||
names = inner_map.contains("names") ? inner_map.value("names").toStringList() : QStringList();
|
||||
QString name = inner_map.value("name").toString();
|
||||
int index = names.indexOf(name);
|
||||
orderedMaps.insertMulti(index, inner_map);
|
||||
}
|
||||
|
||||
// clean variables
|
||||
cardName = "";
|
||||
cardCost = "";
|
||||
cmc = "";
|
||||
cardType = "";
|
||||
cardPT = "";
|
||||
cardText = "";
|
||||
cardUuId = "";
|
||||
setNumber = "";
|
||||
rarity = "";
|
||||
cardLoyalty = "";
|
||||
colors.clear();
|
||||
|
||||
// loop cards and merge their contents
|
||||
QString prefix = QString(" // ");
|
||||
QString prefix2 = QString("\n\n---\n\n");
|
||||
for (const QVariantMap &inner_map : orderedMaps.values()) {
|
||||
if (inner_map.contains("name")) {
|
||||
if (!cardName.isEmpty())
|
||||
cardName += (orderedMaps.count() > 2) ? QString("/") : prefix;
|
||||
cardName += inner_map.value("name").toString();
|
||||
}
|
||||
if (inner_map.contains("manaCost")) {
|
||||
if (!cardCost.isEmpty())
|
||||
cardCost += prefix;
|
||||
cardCost += inner_map.value("manaCost").toString();
|
||||
}
|
||||
if (inner_map.contains("convertedManaCost")) {
|
||||
if (!cmc.isEmpty())
|
||||
cmc += prefix;
|
||||
cmc += inner_map.value("convertedManaCost").toString();
|
||||
}
|
||||
if (inner_map.contains("type")) {
|
||||
if (!cardType.isEmpty())
|
||||
cardType += prefix;
|
||||
cardType += inner_map.value("type").toString();
|
||||
}
|
||||
if (inner_map.contains("power") || inner_map.contains("toughness")) {
|
||||
if (!cardPT.isEmpty())
|
||||
cardPT += prefix;
|
||||
cardPT += inner_map.value("power").toString() + QString('/') + inner_map.value("toughness").toString();
|
||||
}
|
||||
if (inner_map.contains("text")) {
|
||||
if (!cardText.isEmpty())
|
||||
cardText += prefix2;
|
||||
cardText += inner_map.value("text").toString();
|
||||
}
|
||||
if (inner_map.contains("uuid")) {
|
||||
if (cardUuId.isEmpty())
|
||||
cardUuId = inner_map.value("uuid").toString();
|
||||
}
|
||||
if (inner_map.contains("number")) {
|
||||
if (setNumber.isEmpty())
|
||||
setNumber = inner_map.value("number").toString();
|
||||
}
|
||||
if (inner_map.contains("rarity")) {
|
||||
if (rarity.isEmpty())
|
||||
rarity = inner_map.value("rarity").toString();
|
||||
}
|
||||
|
||||
colors << inner_map.value("colors").toStringList();
|
||||
}
|
||||
|
||||
colors.removeDuplicates();
|
||||
if (colors.length() > 1) {
|
||||
sortColors(colors);
|
||||
}
|
||||
|
||||
// Fortunately, there are no split cards that flip, transform or meld.
|
||||
relatedCards = QList<CardRelation *>();
|
||||
reverseRelatedCards = QList<CardRelation *>();
|
||||
upsideDown = false;
|
||||
|
||||
// add the card
|
||||
CardInfoPtr card =
|
||||
addCard(set->getShortName(), cardName, false, muid, cardUuId, setNumber, cardCost, cmc, cardType, cardPT,
|
||||
cardLoyalty, cardText, colors, relatedCards, reverseRelatedCards, upsideDown, rarity);
|
||||
|
||||
if (!set->contains(card)) {
|
||||
card->addToSet(set);
|
||||
cards++;
|
||||
CardInfoPtr newCard = addCard(name, text, isToken, properties, relatedCards, setInfo);
|
||||
numCards++;
|
||||
}
|
||||
}
|
||||
|
||||
return cards;
|
||||
// split cards handling
|
||||
QString splitCardPropSeparator = QString(" // ");
|
||||
QString splitCardTextSeparator = QString("\n\n---\n\n");
|
||||
for (const QString &nameSplit : splitCards.uniqueKeys()) {
|
||||
// get all parts for this specific card
|
||||
QList<SplitCardPart> splitCardParts = splitCards.values(nameSplit);
|
||||
// sort them by index (aka position)
|
||||
qSort(splitCardParts.begin(), splitCardParts.end(),
|
||||
[](const SplitCardPart &a, const SplitCardPart &b) -> bool { return a.getIndex() < b.getIndex(); });
|
||||
|
||||
text = QString("");
|
||||
isToken = false;
|
||||
properties.clear();
|
||||
relatedCards.clear();
|
||||
|
||||
int lastIndex = -1;
|
||||
for (const SplitCardPart &tmp : splitCardParts) {
|
||||
// some sets have 2 different variations of the same split card,
|
||||
// eg. Fire // Ice in WC02. Avoid adding duplicates.
|
||||
if (lastIndex == tmp.getIndex())
|
||||
continue;
|
||||
lastIndex = tmp.getIndex();
|
||||
|
||||
if (!text.isEmpty())
|
||||
text.append(splitCardTextSeparator);
|
||||
text.append(tmp.getText());
|
||||
|
||||
if (properties.isEmpty()) {
|
||||
properties = tmp.getProperties();
|
||||
setInfo = tmp.getSetInfo();
|
||||
} else {
|
||||
const QVariantHash &props = tmp.getProperties();
|
||||
for (const QString &prop : props.keys()) {
|
||||
QString originalPropertyValue = properties.value(prop).toString();
|
||||
QString thisCardPropertyValue = props.value(prop).toString();
|
||||
if (originalPropertyValue != thisCardPropertyValue) {
|
||||
if (prop == "colors") {
|
||||
properties.insert(prop, originalPropertyValue + thisCardPropertyValue);
|
||||
} else {
|
||||
properties.insert(prop,
|
||||
originalPropertyValue + splitCardPropSeparator + thisCardPropertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CardInfoPtr newCard = addCard(name, text, isToken, properties, relatedCards, setInfo);
|
||||
numCards++;
|
||||
}
|
||||
|
||||
return numCards;
|
||||
}
|
||||
|
||||
void OracleImporter::sortColors(QStringList &colors)
|
||||
void OracleImporter::sortAndReduceColors(QString &colors)
|
||||
{
|
||||
const QHash<QString, unsigned int> colorOrder{{"W", 0}, {"U", 1}, {"B", 2}, {"R", 3}, {"G", 4}};
|
||||
std::sort(colors.begin(), colors.end(), [&colorOrder](const QString a, const QString b) {
|
||||
// sort
|
||||
const QHash<QChar, unsigned int> colorOrder{{'W', 0}, {'U', 1}, {'B', 2}, {'R', 3}, {'G', 4}};
|
||||
std::sort(colors.begin(), colors.end(), [&colorOrder](const QChar a, const QChar b) {
|
||||
return colorOrder.value(a, INT_MAX) < colorOrder.value(b, INT_MAX);
|
||||
});
|
||||
// reduce
|
||||
QChar lastChar = '\0';
|
||||
for (int i = 0; i < colors.size(); ++i) {
|
||||
if (colors.at(i) == lastChar)
|
||||
colors.remove(i, 1);
|
||||
else
|
||||
lastChar = colors.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
int OracleImporter::startImport()
|
||||
|
@ -333,25 +341,21 @@ int OracleImporter::startImport()
|
|||
clear();
|
||||
|
||||
int setCards = 0, setIndex = 0;
|
||||
QListIterator<SetToDownload> it(allSets);
|
||||
const SetToDownload *curSet;
|
||||
|
||||
// add an empty set for tokens
|
||||
CardSetPtr tokenSet = CardSet::newInstance(TOKENS_SETNAME, tr("Dummy set containing tokens"), "Tokens");
|
||||
sets.insert(TOKENS_SETNAME, tokenSet);
|
||||
|
||||
while (it.hasNext()) {
|
||||
curSet = &it.next();
|
||||
CardSetPtr set = CardSet::newInstance(curSet->getShortName(), curSet->getLongName(), curSet->getSetType(),
|
||||
curSet->getReleaseDate());
|
||||
if (!sets.contains(set->getShortName()))
|
||||
sets.insert(set->getShortName(), set);
|
||||
for (const SetToDownload &curSetToParse : allSets) {
|
||||
CardSetPtr newSet = CardSet::newInstance(curSetToParse.getShortName(), curSetToParse.getLongName(),
|
||||
curSetToParse.getSetType(), curSetToParse.getReleaseDate());
|
||||
if (!sets.contains(newSet->getShortName()))
|
||||
sets.insert(newSet->getShortName(), newSet);
|
||||
|
||||
int setCardsHere = importTextSpoiler(set, curSet->getCards());
|
||||
int numCardsInSet = importCardsFromSet(newSet, curSetToParse.getCards());
|
||||
|
||||
++setIndex;
|
||||
|
||||
emit setIndexChanged(setCardsHere, setIndex, curSet->getLongName());
|
||||
emit setIndexChanged(numCardsInSet, setIndex, curSetToParse.getLongName());
|
||||
}
|
||||
|
||||
emit setIndexChanged(setCards, setIndex, QString());
|
||||
|
@ -362,6 +366,6 @@ int OracleImporter::startImport()
|
|||
|
||||
bool OracleImporter::saveToFile(const QString &fileName)
|
||||
{
|
||||
CockatriceXml3Parser parser;
|
||||
CockatriceXml4Parser parser;
|
||||
return parser.saveToFile(sets, cards, fileName);
|
||||
}
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
#include <carddatabase.h>
|
||||
#include <utility>
|
||||
|
||||
class SetToDownload
|
||||
{
|
||||
private:
|
||||
QString shortName, longName;
|
||||
QVariant cards;
|
||||
QList<QVariant> cards;
|
||||
QDate releaseDate;
|
||||
QString setType;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public:
|
|||
{
|
||||
return longName;
|
||||
}
|
||||
const QVariant &getCards() const
|
||||
const QList<QVariant> &getCards() const
|
||||
{
|
||||
return cards;
|
||||
}
|
||||
|
@ -35,12 +35,13 @@ public:
|
|||
{
|
||||
return releaseDate;
|
||||
}
|
||||
SetToDownload(const QString &_shortName,
|
||||
const QString &_longName,
|
||||
const QVariant &_cards,
|
||||
const QString &_setType = QString(),
|
||||
SetToDownload(QString _shortName,
|
||||
QString _longName,
|
||||
QList<QVariant> _cards,
|
||||
QString _setType = QString(),
|
||||
const QDate &_releaseDate = QDate())
|
||||
: shortName(_shortName), longName(_longName), cards(_cards), releaseDate(_releaseDate), setType(_setType)
|
||||
: shortName(std::move(_shortName)), longName(std::move(_longName)), cards(std::move(_cards)),
|
||||
releaseDate(_releaseDate), setType(std::move(_setType))
|
||||
{
|
||||
}
|
||||
bool operator<(const SetToDownload &set) const
|
||||
|
@ -49,6 +50,34 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SplitCardPart
|
||||
{
|
||||
public:
|
||||
SplitCardPart(int _index, const QString &_text, const QVariantHash &_properties, CardInfoPerSet setInfo);
|
||||
inline const int &getIndex() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
inline const QString &getText() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
inline const QVariantHash &getProperties() const
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
inline const CardInfoPerSet &getSetInfo() const
|
||||
{
|
||||
return setInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
int index;
|
||||
QString text;
|
||||
QVariantHash properties;
|
||||
CardInfoPerSet setInfo;
|
||||
};
|
||||
|
||||
class OracleImporter : public CardDatabase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -57,33 +86,22 @@ private:
|
|||
QVariantMap setsMap;
|
||||
QString dataDir;
|
||||
|
||||
CardInfoPtr addCard(const QString &setName,
|
||||
QString cardName,
|
||||
CardInfoPtr addCard(QString name,
|
||||
QString text,
|
||||
bool isToken,
|
||||
int cardId,
|
||||
QString &cardUuId,
|
||||
QString &setNumber,
|
||||
QString &cardCost,
|
||||
QString &cmc,
|
||||
const QString &cardType,
|
||||
const QString &cardPT,
|
||||
const QString &cardLoyalty,
|
||||
const QString &cardText,
|
||||
const QStringList &colors,
|
||||
const QList<CardRelation *> &relatedCards,
|
||||
const QList<CardRelation *> &reverseRelatedCards,
|
||||
bool upsideDown,
|
||||
QString &rarity);
|
||||
QVariantHash properties,
|
||||
QList<CardRelation *> &relatedCards,
|
||||
CardInfoPerSet setInfo);
|
||||
signals:
|
||||
void setIndexChanged(int cardsImported, int setIndex, const QString &setName);
|
||||
void dataReadProgress(int bytesRead, int totalBytes);
|
||||
|
||||
public:
|
||||
OracleImporter(const QString &_dataDir, QObject *parent = 0);
|
||||
explicit OracleImporter(const QString &_dataDir, QObject *parent = nullptr);
|
||||
bool readSetsFromByteArray(const QByteArray &data);
|
||||
int startImport();
|
||||
bool saveToFile(const QString &fileName);
|
||||
int importTextSpoiler(CardSetPtr set, const QVariant &data);
|
||||
int importCardsFromSet(CardSetPtr currentSet, const QList<QVariant> &cards);
|
||||
QList<SetToDownload> &getSets()
|
||||
{
|
||||
return allSets;
|
||||
|
@ -94,7 +112,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void sortColors(QStringList &colors);
|
||||
inline QString getStringPropertyFromMap(QVariantMap card, QString propertyName);
|
||||
void sortAndReduceColors(QString &colors);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -253,7 +253,7 @@
|
|||
<context>
|
||||
<name>OracleImporter</name>
|
||||
<message>
|
||||
<location filename="../src/oracleimporter.cpp" line="339"/>
|
||||
<location filename="../src/oracleimporter.cpp" line="359"/>
|
||||
<source>Dummy set containing tokens</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -2,8 +2,9 @@ ADD_DEFINITIONS("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"")
|
|||
add_executable(carddatabase_test
|
||||
carddatabase_test.cpp
|
||||
../../cockatrice/src/carddatabase.cpp
|
||||
../../cockatrice/src/carddbparser/carddatabaseparser.cpp
|
||||
../../cockatrice/src/carddbparser/cockatricexml3.cpp
|
||||
|
||||
../../cockatrice/src/carddbparser/cockatricexml4.cpp
|
||||
)
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(carddatabase_test gtest)
|
||||
|
|
|
@ -64,7 +64,6 @@ TEST(CardDatabaseTest, LoadXml)
|
|||
// ensure the card database is empty at start
|
||||
ASSERT_EQ(0, db->getCardList().size()) << "Cards not empty at start";
|
||||
ASSERT_EQ(0, db->getSetList().size()) << "Sets not empty at start";
|
||||
ASSERT_EQ(0, db->getAllColors().size()) << "Colors not empty at start";
|
||||
ASSERT_EQ(0, db->getAllMainCardTypes().size()) << "Types not empty at start";
|
||||
ASSERT_EQ(NotLoaded, db->getLoadStatus()) << "Incorrect status at start";
|
||||
|
||||
|
@ -72,7 +71,6 @@ TEST(CardDatabaseTest, LoadXml)
|
|||
db->loadCardDatabases();
|
||||
ASSERT_EQ(6, db->getCardList().size()) << "Wrong card count after load";
|
||||
ASSERT_EQ(3, db->getSetList().size()) << "Wrong sets count after load";
|
||||
ASSERT_EQ(4, db->getAllColors().size()) << "Wrong colors count after load";
|
||||
ASSERT_EQ(2, db->getAllMainCardTypes().size()) << "Wrong types count after load";
|
||||
ASSERT_EQ(Ok, db->getLoadStatus()) << "Wrong status after load";
|
||||
|
||||
|
@ -80,7 +78,6 @@ TEST(CardDatabaseTest, LoadXml)
|
|||
db->clear();
|
||||
ASSERT_EQ(0, db->getCardList().size()) << "Cards not empty after clear";
|
||||
ASSERT_EQ(0, db->getSetList().size()) << "Sets not empty after clear";
|
||||
ASSERT_EQ(0, db->getAllColors().size()) << "Colors not empty after clear";
|
||||
ASSERT_EQ(0, db->getAllMainCardTypes().size()) << "Types not empty after clear";
|
||||
ASSERT_EQ(NotLoaded, db->getLoadStatus()) << "Incorrect status after clear";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue