Commit 1e3fb6c6 authored by Fabio Bas's avatar Fabio Bas
Browse files

Rework "paths" settings loading and card database loading

 * main.cpp: removed path checking and db loading
 * card database: merge card loading methods into a single one
 * settings cache: take care of returning safe paths for decks,
replays, etc..
 * main window: if db loading fails (eg. first run), propose to run
oracle

NSIS: propose to run cockatrice instead of oracle

Rework card database loading

 * Move carddatabase-related method out of deckeditor tab
 * Load cards in another thread and render them progressively
 * Optimize database reload after enabled sets change

Fix deck editor column width

 * removed the noCard hack.
 * getCard() no more creates cards instead of just returning existing
ones
 * Fix the “edit tokens” dialog.
 * PictureLoader: avoid trying to download twice the same card
 * PictureLoader: correct return of card background
 * AbstractCardItem: avoid recalculating card color at every paint

Use a different file to save custom tokens

Misc required improvements

 * Use nullptr;
 * Refactor CardInfoWidget to use CardInfoPicture and CardInfoText
instead of duplicating code;
 * Added CardInfo::getColorChar()
 * Fixed some potential crashes
 * removed dead code related to CardInfoWidget
 * Don't require a restart after adding a new custom sets file
 * Bump CMake requirements to 3.1
parent 0b8f52e0
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
# This file sets all the variables shared between the projects # This file sets all the variables shared between the projects
# like the installation path, compilation flags etc.. # like the installation path, compilation flags etc..
cmake_minimum_required(VERSION 2.6) # Cmake 3.1 is required to enable C++11 support correctly
cmake_minimum_required(VERSION 3.1)
if(POLICY CMP0020) if(POLICY CMP0020)
cmake_policy(SET CMP0020 OLD) cmake_policy(SET CMP0020 OLD)
...@@ -171,7 +172,7 @@ IF(WIN32) ...@@ -171,7 +172,7 @@ IF(WIN32)
ENDIF() ENDIF()
# Package builder # Package builder
set(CPACK_PACKAGE_CONTACT "Daenyth+github@gmail.com") set(CPACK_PACKAGE_CONTACT "Gavin Bisesi <Daenyth+github@gmail.com>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME})
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team") set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
......
...@@ -16,9 +16,8 @@ InstallDir "$PROGRAMFILES\Cockatrice" ...@@ -16,9 +16,8 @@ InstallDir "$PROGRAMFILES\Cockatrice"
!define MUI_HEADERIMAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp" !define MUI_HEADERIMAGE_BITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp"
!define MUI_HEADERIMAGE_UNBITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp" !define MUI_HEADERIMAGE_UNBITMAP "${NSIS_SOURCE_PATH}\cmake\headerimage.bmp"
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue."
!define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" !define MUI_FINISHPAGE_RUN "$INSTDIR/cockatrice.exe"
!define MUI_FINISHPAGE_RUN_TEXT "Run 'Oracle' now to update your card database" !define MUI_FINISHPAGE_RUN_TEXT "Run 'Cockatrice' now"
!define MUI_FINISHPAGE_RUN_PARAMETERS "-dlsets"
!insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "${NSIS_SOURCE_PATH}\COPYING" !insertmacro MUI_PAGE_LICENSE "${NSIS_SOURCE_PATH}\COPYING"
...@@ -68,22 +67,20 @@ Section "Start menu item" SecStartMenu ...@@ -68,22 +67,20 @@ Section "Start menu item" SecStartMenu
createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe"
createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe"
createShortCut "$SMPROGRAMS\Cockatrice\Servatrice.lnk" "$INSTDIR\servatrice.exe" createShortCut "$SMPROGRAMS\Cockatrice\Servatrice.lnk" "$INSTDIR\servatrice.exe"
createShortCut "$SMPROGRAMS\Cockatrice\Usermanual.lnk" "$INSTDIR\Usermanual.pdf"
SectionEnd SectionEnd
Section "un.Application" UnSecApplication Section "un.Application" UnSecApplication
SetShellVarContext all SetShellVarContext all
RMDir /r "$INSTDIR\zonebg"
RMDir /r "$INSTDIR\plugins" RMDir /r "$INSTDIR\plugins"
RMDir /r "$INSTDIR\sounds" RMDir /r "$INSTDIR\sounds"
RMDir /r "$INSTDIR\themes"
RMDir /r "$INSTDIR\translations" RMDir /r "$INSTDIR\translations"
Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\uninstall.exe"
Delete "$INSTDIR\cockatrice.exe" Delete "$INSTDIR\cockatrice.exe"
Delete "$INSTDIR\oracle.exe" Delete "$INSTDIR\oracle.exe"
Delete "$INSTDIR\servatrice.exe" Delete "$INSTDIR\servatrice.exe"
Delete "$INSTDIR\Usermanual.pdf"
Delete "$INSTDIR\libprotobuf.lib"
Delete "$INSTDIR\Qt*.dll" Delete "$INSTDIR\Qt*.dll"
Delete "$INSTDIR\libmysql.dll"
Delete "$INSTDIR\icu*.dll" Delete "$INSTDIR\icu*.dll"
Delete "$INSTDIR\libeay32.dll" Delete "$INSTDIR\libeay32.dll"
Delete "$INSTDIR\ssleay32.dll" Delete "$INSTDIR\ssleay32.dll"
...@@ -91,7 +88,7 @@ Section "un.Application" UnSecApplication ...@@ -91,7 +88,7 @@ Section "un.Application" UnSecApplication
Delete "$INSTDIR\qdebug.txt" Delete "$INSTDIR\qdebug.txt"
Delete "$INSTDIR\servatrice.sql" Delete "$INSTDIR\servatrice.sql"
Delete "$INSTDIR\servatrice.ini.example" Delete "$INSTDIR\servatrice.ini.example"
Delete "$INSTDIR\zlib1.dll" Delete "$INSTDIR\zlib*.dll"
RMDir "$INSTDIR" RMDir "$INSTDIR"
RMDir "$SMPROGRAMS\Cockatrice" RMDir "$SMPROGRAMS\Cockatrice"
......
...@@ -7,7 +7,6 @@ PROJECT(cockatrice) ...@@ -7,7 +7,6 @@ PROJECT(cockatrice)
SET(cockatrice_SOURCES SET(cockatrice_SOURCES
src/abstractcounter.cpp src/abstractcounter.cpp
src/counter_general.cpp src/counter_general.cpp
src/dlg_add_set_result.cpp
src/dlg_creategame.cpp src/dlg_creategame.cpp
src/dlg_filter_games.cpp src/dlg_filter_games.cpp
src/dlg_connect.cpp src/dlg_connect.cpp
...@@ -175,6 +174,13 @@ if(Qt5Widgets_FOUND) ...@@ -175,6 +174,13 @@ if(Qt5Widgets_FOUND)
include_directories(${Qt5Widgets_INCLUDE_DIRS}) include_directories(${Qt5Widgets_INCLUDE_DIRS})
list(APPEND COCKATRICE_LIBS Widgets) list(APPEND COCKATRICE_LIBS Widgets)
# QtConcurrent
find_package(Qt5Concurrent)
if(Qt5Concurrent_FOUND)
include_directories(${Qt5Concurrent_INCLUDE_DIRS})
list(APPEND ORACLE_LIBS Concurrent)
endif()
# QtNetwork # QtNetwork
find_package(Qt5Network) find_package(Qt5Network)
if(Qt5Network_FOUND) if(Qt5Network_FOUND)
......
...@@ -7,22 +7,19 @@ ...@@ -7,22 +7,19 @@
#include "round.h" #include "round.h"
#endif /* _WIN32 */ #endif /* _WIN32 */
#include "carddatabase.h" #include "carddatabase.h"
#include "cardinfowidget.h"
#include "abstractcarditem.h" #include "abstractcarditem.h"
#include "pictureloader.h" #include "pictureloader.h"
#include "settingscache.h" #include "settingscache.h"
#include "main.h" #include "main.h"
#include "gamescene.h" #include "gamescene.h"
#include <QDebug>
AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent) AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent)
: ArrowTarget(_owner, parent), infoWidget(0), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0), isHovered(false), realZValue(0) : ArrowTarget(_owner, parent), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0), bgColor(Qt::transparent), isHovered(false), realZValue(0)
{ {
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
setFlag(ItemIsSelectable); setFlag(ItemIsSelectable);
setCacheMode(DeviceCoordinateCache); setCacheMode(DeviceCoordinateCache);
connect(db, SIGNAL(cardListChanged()), this, SLOT(cardInfoUpdated()));
connect(settingsCache, SIGNAL(displayCardNamesChanged()), this, SLOT(callUpdate())); connect(settingsCache, SIGNAL(displayCardNamesChanged()), this, SLOT(callUpdate()));
cardInfoUpdated(); cardInfoUpdated();
} }
...@@ -46,7 +43,11 @@ void AbstractCardItem::pixmapUpdated() ...@@ -46,7 +43,11 @@ void AbstractCardItem::pixmapUpdated()
void AbstractCardItem::cardInfoUpdated() void AbstractCardItem::cardInfoUpdated()
{ {
info = db->getCard(name); info = db->getCard(name);
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(pixmapUpdated())); if(info)
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(pixmapUpdated()));
cacheBgColor();
update();
} }
void AbstractCardItem::setRealZValue(qreal _zValue) void AbstractCardItem::setRealZValue(qreal _zValue)
...@@ -89,45 +90,35 @@ void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &transla ...@@ -89,45 +90,35 @@ void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &transla
void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle) void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle)
{ {
qreal scaleFactor = translatedSize.width() / boundingRect().width(); qreal scaleFactor = translatedSize.width() / boundingRect().width();
CardInfo *imageSource = facedown ? db->getCard() : info;
QPixmap translatedPixmap; QPixmap translatedPixmap;
// don't even spend time trying to load the picture if our size is too small bool paintImage = true;
if(translatedSize.width() > 10)
PictureLoader::getPixmap(translatedPixmap, imageSource, translatedSize.toSize());
painter->save(); if(facedown)
QColor bgColor = Qt::transparent; {
if (translatedPixmap.isNull()) { // never reveal card color, always paint the card back
QString colorStr; PictureLoader::getPixmap(translatedPixmap, nullptr, translatedSize.toSize());
if (!color.isEmpty())
colorStr = color;
else if (info->getColors().size() > 1)
colorStr = "m";
else if (!info->getColors().isEmpty())
colorStr = info->getColors().first().toLower();
if (colorStr == "b")
bgColor = QColor(0, 0, 0);
else if (colorStr == "u")
bgColor = QColor(0, 140, 180);
else if (colorStr == "w")
bgColor = QColor(255, 250, 140);
else if (colorStr == "r")
bgColor = QColor(230, 0, 0);
else if (colorStr == "g")
bgColor = QColor(0, 160, 0);
else if (colorStr == "m")
bgColor = QColor(250, 190, 30);
else
bgColor = QColor(230, 230, 230);
} else { } else {
// don't even spend time trying to load the picture if our size is too small
if(info && translatedSize.width() > 10)
{
PictureLoader::getPixmap(translatedPixmap, info, translatedSize.toSize());
if(translatedPixmap.isNull())
paintImage = false;
} else {
paintImage = false;
}
}
painter->save();
if (paintImage) {
painter->save(); painter->save();
transformPainter(painter, translatedSize, angle); transformPainter(painter, translatedSize, angle);
painter->drawPixmap(QPointF(1, 1), translatedPixmap); painter->drawPixmap(QPointF(1, 1), translatedPixmap);
painter->restore(); painter->restore();
} else {
painter->setBrush(bgColor);
} }
painter->setBrush(bgColor);
QPen pen(Qt::black); QPen pen(Qt::black);
pen.setJoinStyle(Qt::MiterJoin); pen.setJoinStyle(Qt::MiterJoin);
...@@ -192,11 +183,11 @@ void AbstractCardItem::setName(const QString &_name) ...@@ -192,11 +183,11 @@ void AbstractCardItem::setName(const QString &_name)
return; return;
emit deleteCardInfoPopup(name); emit deleteCardInfoPopup(name);
disconnect(info, 0, this, 0); if(info)
disconnect(info, nullptr, this, nullptr);
name = _name; name = _name;
info = db->getCard(name);
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(pixmapUpdated())); cardInfoUpdated();
update();
} }
void AbstractCardItem::setHovered(bool _hovered) void AbstractCardItem::setHovered(bool _hovered)
...@@ -216,9 +207,47 @@ void AbstractCardItem::setHovered(bool _hovered) ...@@ -216,9 +207,47 @@ void AbstractCardItem::setHovered(bool _hovered)
void AbstractCardItem::setColor(const QString &_color) void AbstractCardItem::setColor(const QString &_color)
{ {
color = _color; color = _color;
cacheBgColor();
update(); update();
} }
void AbstractCardItem::cacheBgColor()
{
QChar colorChar;
if (color.isEmpty())
{
if(info)
colorChar = info->getColorChar();
} else {
colorChar = color.at(0);
}
switch(colorChar.toLower().toLatin1())
{
case 'b':
bgColor = QColor(0, 0, 0);
break;
case 'u':
bgColor = QColor(0, 140, 180);
break;
case 'w':
bgColor = QColor(255, 250, 140);
break;
case 'r':
bgColor = QColor(230, 0, 0);
break;
case 'g':
bgColor = QColor(0, 160, 0);
break;
case 'm':
bgColor = QColor(250, 190, 30);
break;
default:
bgColor = QColor(230, 230, 230);
break;
}
}
void AbstractCardItem::setTapped(bool _tapped, bool canAnimate) void AbstractCardItem::setTapped(bool _tapped, bool canAnimate)
{ {
if (tapped == _tapped) if (tapped == _tapped)
......
...@@ -4,9 +4,7 @@ ...@@ -4,9 +4,7 @@
#include "arrowtarget.h" #include "arrowtarget.h"
class CardInfo; class CardInfo;
class CardInfoWidget;
class Player; class Player;
class QTimer;
const int CARD_WIDTH = 72; const int CARD_WIDTH = 72;
const int CARD_HEIGHT = 102; const int CARD_HEIGHT = 102;
...@@ -15,13 +13,13 @@ class AbstractCardItem : public ArrowTarget { ...@@ -15,13 +13,13 @@ class AbstractCardItem : public ArrowTarget {
Q_OBJECT Q_OBJECT
protected: protected:
CardInfo *info; CardInfo *info;
CardInfoWidget *infoWidget;
int id; int id;
QString name; QString name;
bool tapped; bool tapped;
bool facedown; bool facedown;
int tapAngle; int tapAngle;
QString color; QString color;
QColor bgColor;
private: private:
bool isHovered; bool isHovered;
qreal realZValue; qreal realZValue;
...@@ -65,6 +63,7 @@ protected: ...@@ -65,6 +63,7 @@ protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
void cacheBgColor();
}; };
#endif #endif
...@@ -287,6 +287,22 @@ QString CardInfo::simplifyName(const QString &name) { ...@@ -287,6 +287,22 @@ QString CardInfo::simplifyName(const QString &name) {
return simpleName; return simpleName;
} }
const QChar CardInfo::getColorChar() const
{
switch(colors.size())
{
case 0:
return QChar();
break;
case 1:
return colors.first().isEmpty() ? QChar() : colors.first().at(0);
break;
default:
return QChar('m');
break;
}
}
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
{ {
xml.writeStartElement("card"); xml.writeStartElement("card");
...@@ -341,39 +357,35 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) ...@@ -341,39 +357,35 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
} }
CardDatabase::CardDatabase(QObject *parent) CardDatabase::CardDatabase(QObject *parent)
: QObject(parent), noCard(0), loadStatus(NotLoaded) : QObject(parent), loadStatus(NotLoaded)
{ {
connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase())); connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabases()));
connect(settingsCache, SIGNAL(tokenDatabasePathChanged()), this, SLOT(loadTokenDatabase()));
noCard = new CardInfo();
} }
CardDatabase::~CardDatabase() CardDatabase::~CardDatabase()
{ {
clear(); clear();
delete noCard;
} }
void CardDatabase::clear() void CardDatabase::clear()
{ {
QHashIterator<QString, CardSet *> setIt(sets);
while (setIt.hasNext()) {
setIt.next();
delete setIt.value();
}
sets.clear();
QHashIterator<QString, CardInfo *> i(cards); QHashIterator<QString, CardInfo *> i(cards);
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
delete i.value(); removeCard(i.value());
i.value()->deleteLater();
} }
cards.clear();
// The pointers themselves were already deleted, so we don't delete them // The pointers themselves were already deleted, so we don't delete them again.
// again. cards.clear();
simpleNameCards.clear(); simpleNameCards.clear();
QHashIterator<QString, CardSet *> setIt(sets);
while (setIt.hasNext()) {
setIt.next();
delete setIt.value();
}
sets.clear();
} }
void CardDatabase::addCard(CardInfo *card) void CardDatabase::addCard(CardInfo *card)
...@@ -390,22 +402,23 @@ void CardDatabase::removeCard(CardInfo *card) ...@@ -390,22 +402,23 @@ void CardDatabase::removeCard(CardInfo *card)
emit cardRemoved(card); emit cardRemoved(card);
} }
CardInfo *CardDatabase::getCard(const QString &cardName, bool createIfNotFound) { CardInfo *CardDatabase::getCard(const QString &cardName) const
return getCardFromMap(cards, cardName, createIfNotFound); {
return getCardFromMap(cards, cardName);
} }
QList<CardInfo *> CardDatabase::getCards(const QStringList &cardNames) QList<CardInfo *> CardDatabase::getCards(const QStringList &cardNames) const
{ {
QList<CardInfo *> cardInfos; QList<CardInfo *> cardInfos;
foreach(QString cardName, cardNames) foreach(QString cardName, cardNames)
cardInfos.append(getCardFromMap(cards, cardName, false)); cardInfos.append(getCardFromMap(cards, cardName));
return cardInfos; return cardInfos;
} }
CardInfo *CardDatabase::getCardBySimpleName(const QString &cardName, bool createIfNotFound) { CardInfo *CardDatabase::getCardBySimpleName(const QString &cardName) const
QString simpleName = CardInfo::simplifyName(cardName); {
return getCardFromMap(simpleNameCards, simpleName, createIfNotFound); return getCardFromMap(simpleNameCards, CardInfo::simplifyName(cardName));
} }
CardSet *CardDatabase::getSet(const QString &setName) CardSet *CardDatabase::getSet(const QString &setName)
...@@ -459,7 +472,7 @@ void CardDatabase::loadSetsFromXml(QXmlStreamReader &xml) ...@@ -459,7 +472,7 @@ void CardDatabase::loadSetsFromXml(QXmlStreamReader &xml)
} }
} }
void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens) void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
{ {
while (!xml.atEnd()) { while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement) if (xml.readNext() == QXmlStreamReader::EndElement)
...@@ -518,28 +531,20 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens) ...@@ -518,28 +531,20 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens)
isToken = xml.readElementText().toInt(); isToken = xml.readElementText().toInt();
} }
if (isToken == tokens) { addCard(new CardInfo(name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, reverseRelatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs, muids));
addCard(new CardInfo(name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, reverseRelatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs, muids));
}
} }
} }
} }
CardInfo *CardDatabase::getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound) { CardInfo *CardDatabase::getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const
{
if (cardMap.contains(cardName)) if (cardMap.contains(cardName))
return cardMap.value(cardName); return cardMap.value(cardName);
if (createIfNotFound) {
CardInfo *newCard = new CardInfo(cardName, true);
newCard->addToSet(getSet(CardDatabase::TOKENS_SETNAME));
cardMap.insert(cardName, newCard);
return newCard;
}
return noCard; return nullptr;
} }
LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens) LoadStatus CardDatabase::loadFromFile(const QString &fileName)
{ {
QFile file(fileName); QFile file(fileName);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
...@@ -562,11 +567,10 @@ LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens) ...@@ -562,11 +567,10 @@ LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens)
if (xml.name() == "sets") if (xml.name() == "sets")
loadSetsFromXml(xml); loadSetsFromXml(xml);
else if (xml.name() == "cards") else if (xml.name() == "cards")
loadCardsFromXml(xml, tokens); loadCardsFromXml(xml);
} }
} }
} }
qDebug() << cards.size() << "cards in" << sets.size() << "sets loaded";
if (cards.isEmpty()) return NoCards; if (cards.isEmpty()) return NoCards;
...@@ -609,57 +613,59 @@ bool CardDatabase::saveToFile(const QString &fileName, bool tokens) ...@@ -609,57 +613,59 @@ bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
return true; return true;
} }
void CardDatabase::emitCardListChanged() LoadStatus CardDatabase::loadCardDatabase(const QString &path)
{
emit cardListChanged();
}
LoadStatus CardDatabase::loadCardDatabase(const QString &path, bool tokens)
{ {
LoadStatus tempLoadStatus = NotLoaded; LoadStatus tempLoadStatus = NotLoaded;
if (!path.isEmpty()) if (!path.isEmpty())
tempLoadStatus = loadFromFile(path, tokens); tempLoadStatus = loadFromFile(path);
if (tempLoadStatus == Ok) {
SetList allSets;
QHashIterator<QString, CardSet *> setsIterator(sets);
while (setsIterator.hasNext())
allSets.append(setsIterator.next().value());
allSets.sortByKey();
if(!tokens)
checkUnknownSets();
emit cardListChanged();
}
if (!tokens)
loadStatus = tempLoadStatus;
qDebug() << "loadCardDatabase(): Path =" << path << "Tokens =" << tokens << "Status =" << loadStatus; qDebug() << "[CardDatabase] loadCardDatabase(): Path =" << path << "Status =" << tempLoadStatus << "Cards =" << cards.size() << "Sets=" << sets.size();
return tempLoadStatus; return tempLoadStatus;
} }
LoadStatus CardDatabase::loadCardDatabase() LoadStatus CardDatabase::loadCardDatabases()
{ {
return loadCardDatabase(settingsCache->getCardDatabasePath(), false); qDebug() << "CardDatabase::loadCardDatabases start";
} // clean old db
clear();
// load main card database
loadStatus = loadCardDatabase(settingsCache->getCardDatabasePath());
// laod tokens database
loadCardDatabase(settingsCache->getTokenDatabasePath());
// load custom card databases
QDir dir(settingsCache->getCustomCardDatabasePath());
foreach(QString fileName, dir.entryList(QStringList("*.xml"), QDir::Files | QDir::Readable, QDir::Name | QDir::IgnoreCase))
{
loadCardDatabase(dir.absoluteFilePath(fileName));
}
LoadStatus CardDatabase::loadTokenDatabase() // AFTER all the cards have been loaded
{
return loadCardDatabase(settingsCache->getTokenDatabasePath(), true);
}
void CardDatabase::loadCustomCardDatabases(const QString &path) // reorder sets (TODO: refactor, this smells)
{ SetList allSets;
QDir dir(path); QHashIterator<QString, CardSet *> setsIterator(sets);
if(!dir.exists()) while (setsIterator.hasNext())
return; allSets.append(setsIterator.next().value());
allSets.sortByKey();
foreach(QString fileName, dir.entryList(QStringList("*.xml"), QDir::Files | QDir::Readable, QDir::Name | QDir::IgnoreCase)) // resolve the reverse-related tags
refreshCachedReverseRelatedCards();
if(loadStatus == Ok)
{ {
loadCardDatabase(dir.absoluteFilePath(fileName), false); // check for unknown sets
checkUnknownSets();
// update deck editors, etc
qDebug() << "CardDatabase::loadCardDatabases success";
} else {
// bring up thr settings dialog
qDebug() << "CardDatabase::loadCardDatabases failed";
emit cardDatabaseLoadingFailed();
} }
// return the loadstatus of the main card database.
return loadStatus;
} }
void CardDatabase::refreshCachedReverseRelatedCards() void CardDatabase::refreshCachedReverseRelatedCards()
...@@ -716,48 +722,70 @@ void CardDatabase::checkUnknownSets() ...@@ -716,48 +722,70 @@ void CardDatabase::checkUnknownSets()
{ {
SetList sets = getSetList(); SetList sets = getSetList();
// no set is enabled. Probably this is the first time running trice if(sets.getEnabledSetsNum())
if(!sets.getEnabledSetsNum())
{ {
// if some sets are first found on thus run, ask the user
int numUnknownSets = sets.getUnknownSetsNum();
if(numUnknownSets > 0)
emit cardDatabaseNewSetsFound(numUnknownSets);
} else {
// No set enabled. Probably this is the first time running trice
sets.guessSortKeys(); sets.guessSortKeys();
sets.sortByKey(); sets.sortByKey();
sets.enableAll(); sets.enableAll();
notifyEnabledSetsChanged();
detectedFirstRun = true; emit cardDatabaseAllNewSetsEnabled();
return;
} }
}
detectedFirstRun = false; void CardDatabase::enableAllUnknownSets()
{
int numUnknownSets = sets.getUnknownSetsNum(); SetList sets = getSetList();
// no unkown sets. sets.enableAllUnknown();
if(!numUnknownSets) }
return;
QMessageBox msgbox(QMessageBox::Question, tr("New sets found"), tr("%1 new set(s) have been found in the card database. Do you want to enable them?").arg(numUnknownSets), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); void CardDatabase::markAllSetsAsKnown()
{
SetList sets = getSetList();
sets.markAllAsKnown();
}
switch(msgbox.exec()) void CardDatabase::notifyEnabledSetsChanged()
{ {
case QMessageBox::No: // refresh the list of cached set names
sets.markAllAsKnown(); foreach(CardInfo * card, cards)
break; card->refreshCachedSetNames();
case QMessageBox::Yes:
sets.enableAllUnknown();
break;
default:
break;
}
return; // inform the carddatabasemodels that they need to re-check their list of cards
emit cardDatabaseEnabledSetsChanged();
} }
bool CardDatabase::hasDetectedFirstRun() bool CardDatabase::saveCustomTokensToFile()
{ {
if(detectedFirstRun) CardSet * customTokensSet = getSet(CardDatabase::TOKENS_SETNAME);
{ QString fileName = settingsCache->getCustomCardDatabasePath() + "/" + CardDatabase::TOKENS_SETNAME + ".xml";
detectedFirstRun=false; QFile file(fileName);
return true; if (!file.open(QIODevice::WriteOnly))
return false;
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true);
xml.writeStartDocument();
xml.writeStartElement("cockatrice_carddatabase");
xml.writeAttribute("version", QString::number(versionNeeded));
xml.writeStartElement("cards");
QHashIterator<QString, CardInfo *> cardIterator(cards);
while (cardIterator.hasNext()) {
CardInfo *card = cardIterator.next().value();
if(card->getSets().contains(customTokensSet))
xml << card;
} }
xml.writeEndElement(); // cards
return false; xml.writeEndElement(); // cockatrice_carddatabase
} xml.writeEndDocument();
return true;
}
\ No newline at end of file
...@@ -90,8 +90,6 @@ private: ...@@ -90,8 +90,6 @@ private:
bool cipt; bool cipt;
int tableRow; int tableRow;
QString pixmapCacheKey; QString pixmapCacheKey;
void refreshCachedSetNames();
public: public:
CardInfo(const QString &_name = QString(), CardInfo(const QString &_name = QString(),
bool _isToken = false, bool _isToken = false,
...@@ -131,6 +129,7 @@ public: ...@@ -131,6 +129,7 @@ public:
void setPowTough(const QString &_powTough) { powtough = _powTough; emit cardInfoChanged(this); } void setPowTough(const QString &_powTough) { powtough = _powTough; emit cardInfoChanged(this); }
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); } void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); } void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
const QChar getColorChar() const;
const QStringList &getColors() const { return colors; } const QStringList &getColors() const { return colors; }
const QStringList &getRelatedCards() const { return relatedCards; } const QStringList &getRelatedCards() const { return relatedCards; }
const QStringList &getReverseRelatedCards() const { return reverseRelatedCards; } const QStringList &getReverseRelatedCards() const { return reverseRelatedCards; }
...@@ -149,6 +148,7 @@ public: ...@@ -149,6 +148,7 @@ public:
void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); } void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); }
void addToSet(CardSet *set); void addToSet(CardSet *set);
void emitPixmapUpdated() { emit pixmapUpdated(); } void emitPixmapUpdated() { emit pixmapUpdated(); }
void refreshCachedSetNames();
/** /**
* Simplify a name to have no punctuation and lowercase all letters, for * Simplify a name to have no punctuation and lowercase all letters, for
...@@ -183,20 +183,15 @@ protected: ...@@ -183,20 +183,15 @@ protected:
*/ */
SetNameMap sets; SetNameMap sets;
/*
* A dummy card returned by getCard() ad a fallback
*/
CardInfo *noCard;
LoadStatus loadStatus; LoadStatus loadStatus;
bool detectedFirstRun;
private: private:
static const int versionNeeded; static const int versionNeeded;
void loadCardsFromXml(QXmlStreamReader &xml, bool tokens); void loadCardsFromXml(QXmlStreamReader &xml);
void loadSetsFromXml(QXmlStreamReader &xml); void loadSetsFromXml(QXmlStreamReader &xml);
CardInfo *getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound); CardInfo *getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
void checkUnknownSets(); void checkUnknownSets();
void refreshCachedReverseRelatedCards();
public: public:
static const char* TOKENS_SETNAME; static const char* TOKENS_SETNAME;
...@@ -205,38 +200,37 @@ public: ...@@ -205,38 +200,37 @@ public:
void clear(); void clear();
void addCard(CardInfo *card); void addCard(CardInfo *card);
void removeCard(CardInfo *card); void removeCard(CardInfo *card);
/* CardInfo *getCard(const QString &cardName) const;
* Get card object by name. Ensured to return a valid CardInfo * object; check noCard QList <CardInfo *> getCards(const QStringList &cardNames) const;
*/
CardInfo *getCard(const QString &cardName = QString(), bool createIfNotFound = false);
QList <CardInfo *> getCards(const QStringList &cardNames);
/* /*
* Get a card by its simple name. The name will be simplified in this * Get a card by its simple name. The name will be simplified in this
* function, so you don't need to simplify it beforehand. * function, so you don't need to simplify it beforehand.
*/ */
CardInfo *getCardBySimpleName(const QString &cardName = QString(), bool createIfNotFound = false); CardInfo *getCardBySimpleName(const QString &cardName) const;
CardSet *getSet(const QString &setName); CardSet *getSet(const QString &setName);
QList<CardInfo *> getCardList() const { return cards.values(); } QList<CardInfo *> getCardList() const { return cards.values(); }
SetList getSetList() const; SetList getSetList() const;
LoadStatus loadFromFile(const QString &fileName, bool tokens = false); LoadStatus loadFromFile(const QString &fileName);
bool saveToFile(const QString &fileName, bool tokens = false); bool saveToFile(const QString &fileName, bool tokens = false);
bool saveCustomTokensToFile();
QStringList getAllColors() const; QStringList getAllColors() const;
QStringList getAllMainCardTypes() const; QStringList getAllMainCardTypes() const;
LoadStatus getLoadStatus() const { return loadStatus; } LoadStatus getLoadStatus() const { return loadStatus; }
bool getLoadSuccess() const { return loadStatus == Ok; } void enableAllUnknownSets();
bool hasDetectedFirstRun(); void markAllSetsAsKnown();
void refreshCachedReverseRelatedCards(); void notifyEnabledSetsChanged();
public slots: public slots:
LoadStatus loadCardDatabase(); LoadStatus loadCardDatabases();
LoadStatus loadTokenDatabase();
void loadCustomCardDatabases(const QString &path);
void emitCardListChanged();
private slots: private slots:
LoadStatus loadCardDatabase(const QString &path, bool tokens = false); LoadStatus loadCardDatabase(const QString &path);
signals: signals:
void cardListChanged(); void cardDatabaseLoadingFailed();
void cardDatabaseNewSetsFound(int numUnknownSets);
void cardDatabaseAllNewSetsEnabled();
void cardDatabaseEnabledSetsChanged();
void cardAdded(CardInfo *card); void cardAdded(CardInfo *card);
void cardRemoved(CardInfo *card); void cardRemoved(CardInfo *card);
}; };
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent) CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent)
: QAbstractListModel(parent), db(_db) : QAbstractListModel(parent), db(_db)
{ {
connect(db, SIGNAL(cardListChanged()), this, SLOT(updateCardList()));
connect(db, SIGNAL(cardAdded(CardInfo *)), this, SLOT(cardAdded(CardInfo *))); connect(db, SIGNAL(cardAdded(CardInfo *)), this, SLOT(cardAdded(CardInfo *)));
connect(db, SIGNAL(cardRemoved(CardInfo *)), this, SLOT(cardRemoved(CardInfo *))); connect(db, SIGNAL(cardRemoved(CardInfo *)), this, SLOT(cardRemoved(CardInfo *)));
updateCardList(); connect(db, SIGNAL(cardDatabaseEnabledSetsChanged()), this, SLOT(cardDatabaseEnabledSetsChanged()));
cardDatabaseEnabledSetsChanged();
} }
CardDatabaseModel::~CardDatabaseModel() CardDatabaseModel::~CardDatabaseModel()
...@@ -63,52 +64,53 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation, ...@@ -63,52 +64,53 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation,
} }
} }
void CardDatabaseModel::updateCardList() void CardDatabaseModel::cardInfoChanged(CardInfo *card)
{ {
beginResetModel(); const int row = cardList.indexOf(card);
if (row == -1)
for (int i = 0; i < cardList.size(); ++i) return;
disconnect(cardList[i], 0, this, 0);
cardList.clear(); emit dataChanged(index(row, 0), index(row, CARDDBMODEL_COLUMNS - 1));
}
foreach(CardInfo * card, db->getCardList()) bool CardDatabaseModel::checkCardHasAtLeastOneEnabledSet(CardInfo *card)
{
foreach(CardSet * set, card->getSets())
{ {
bool hasSet = false; if(set->getEnabled())
foreach(CardSet * set, card->getSets()) return true;
{
if(set->getEnabled())
{
hasSet = true;
break;
}
}
if(hasSet)
{
cardList.append(card);
connect(card, SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *)));
}
} }
endResetModel(); return false;
} }
void CardDatabaseModel::cardInfoChanged(CardInfo *card) void CardDatabaseModel::cardDatabaseEnabledSetsChanged()
{ {
const int row = cardList.indexOf(card); // remove all the cards no more present in at least one enabled set
if (row == -1) foreach(CardInfo * card, cardList)
return; {
if(!checkCardHasAtLeastOneEnabledSet(card))
emit dataChanged(index(row, 0), index(row, CARDDBMODEL_COLUMNS - 1)); cardRemoved(card);
}
// re-check all the card currently not shown, maybe their part of a newly-enabled set
foreach(CardInfo * card, db->getCardList())
{
if(!cardList.contains(card))
cardAdded(card);
}
} }
void CardDatabaseModel::cardAdded(CardInfo *card) void CardDatabaseModel::cardAdded(CardInfo *card)
{ {
beginInsertRows(QModelIndex(), cardList.size(), cardList.size()); if(checkCardHasAtLeastOneEnabledSet(card))
cardList.append(card); {
connect(card, SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *))); // add the card if it's present in at least one enabled set
endInsertRows(); beginInsertRows(QModelIndex(), cardList.size(), cardList.size());
cardList.append(card);
connect(card, SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *)));
endInsertRows();
}
} }
void CardDatabaseModel::cardRemoved(CardInfo *card) void CardDatabaseModel::cardRemoved(CardInfo *card)
...@@ -118,6 +120,7 @@ void CardDatabaseModel::cardRemoved(CardInfo *card) ...@@ -118,6 +120,7 @@ void CardDatabaseModel::cardRemoved(CardInfo *card)
return; return;
beginRemoveRows(QModelIndex(), row, row); beginRemoveRows(QModelIndex(), row, row);
disconnect(card, 0, this, 0);
cardList.removeAt(row); cardList.removeAt(row);
endRemoveRows(); endRemoveRows();
} }
...@@ -220,3 +223,16 @@ void CardDatabaseDisplayModel::filterTreeChanged() ...@@ -220,3 +223,16 @@ void CardDatabaseDisplayModel::filterTreeChanged()
{ {
invalidate(); invalidate();
} }
TokenDisplayModel::TokenDisplayModel(QObject *parent)
: CardDatabaseDisplayModel(parent)
{
}
bool TokenDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const
{
CardInfo const *info = static_cast<CardDatabaseModel *>(sourceModel())->getCard(sourceRow);
return info->getIsToken();
}
...@@ -25,11 +25,13 @@ public: ...@@ -25,11 +25,13 @@ public:
private: private:
QList<CardInfo *> cardList; QList<CardInfo *> cardList;
CardDatabase *db; CardDatabase *db;
inline bool checkCardHasAtLeastOneEnabledSet(CardInfo *card);
private slots: private slots:
void updateCardList();
void cardAdded(CardInfo *card); void cardAdded(CardInfo *card);
void cardRemoved(CardInfo *card); void cardRemoved(CardInfo *card);
void cardInfoChanged(CardInfo *card); void cardInfoChanged(CardInfo *card);
void cardDatabaseEnabledSetsChanged();
}; };
class CardDatabaseDisplayModel : public QSortFilterProxyModel { class CardDatabaseDisplayModel : public QSortFilterProxyModel {
...@@ -66,4 +68,12 @@ private slots: ...@@ -66,4 +68,12 @@ private slots:
void filterTreeChanged(); void filterTreeChanged();
}; };
class TokenDisplayModel : public CardDatabaseDisplayModel {
Q_OBJECT
public:
TokenDisplayModel(QObject *parent = 0);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
#endif #endif
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <QVBoxLayout> #include <QVBoxLayout>
CardFrame::CardFrame(const QString &cardName, QWidget *parent) CardFrame::CardFrame(const QString &cardName, QWidget *parent)
: QTabWidget(parent), info(0), cardTextOnly(false) : QTabWidget(parent), info(nullptr), cardTextOnly(false)
{ {
setContentsMargins(3, 3, 3, 3); setContentsMargins(3, 3, 3, 3);
pic = new CardInfoPicture(); pic = new CardInfoPicture();
...@@ -91,9 +91,11 @@ void CardFrame::setViewMode(int mode) ...@@ -91,9 +91,11 @@ void CardFrame::setViewMode(int mode)
void CardFrame::setCard(CardInfo *card) void CardFrame::setCard(CardInfo *card)
{ {
if (info) if (info)
disconnect(info, 0, this, 0); disconnect(info, nullptr, this, nullptr);
info = card; info = card;
connect(info, SIGNAL(destroyed()), this, SLOT(clear())); if(info)
connect(info, SIGNAL(destroyed()), this, SLOT(clear()));
text->setCard(info); text->setCard(info);
pic->setCard(info); pic->setCard(info);
} }
...@@ -110,5 +112,5 @@ void CardFrame::setCard(AbstractCardItem *card) ...@@ -110,5 +112,5 @@ void CardFrame::setCard(AbstractCardItem *card)
void CardFrame::clear() void CardFrame::clear()
{ {
setCard(db->getCard()); setCard((CardInfo*) nullptr);
} }
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
CardInfoPicture::CardInfoPicture(QWidget *parent) CardInfoPicture::CardInfoPicture(QWidget *parent)
: QWidget(parent), : QWidget(parent),
info(0), info(nullptr),
pixmapDirty(true) pixmapDirty(true)
{ {
setMinimumHeight(100); setMinimumHeight(100);
...@@ -20,9 +20,10 @@ CardInfoPicture::CardInfoPicture(QWidget *parent) ...@@ -20,9 +20,10 @@ CardInfoPicture::CardInfoPicture(QWidget *parent)
void CardInfoPicture::setCard(CardInfo *card) void CardInfoPicture::setCard(CardInfo *card)
{ {
if (info) if (info)
disconnect(info, 0, this, 0); disconnect(info, nullptr, this, nullptr);
info = card; info = card;
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(updatePixmap())); if(info)
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(updatePixmap()));
updatePixmap(); updatePixmap();
} }
...@@ -40,14 +41,7 @@ void CardInfoPicture::updatePixmap() ...@@ -40,14 +41,7 @@ void CardInfoPicture::updatePixmap()
void CardInfoPicture::loadPixmap() void CardInfoPicture::loadPixmap()
{ {
if(info) PictureLoader::getPixmap(resizedPixmap, info, size());
PictureLoader::getPixmap(resizedPixmap, info, size());
else
resizedPixmap = QPixmap();
if (resizedPixmap.isNull())
PictureLoader::getPixmap(resizedPixmap, db->getCard(), size());
} }
void CardInfoPicture::paintEvent(QPaintEvent *) void CardInfoPicture::paintEvent(QPaintEvent *)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "main.h" #include "main.h"
CardInfoText::CardInfoText(QWidget *parent) CardInfoText::CardInfoText(QWidget *parent)
: QFrame(parent), info(0) : QFrame(parent), info(nullptr)
{ {
nameLabel1 = new QLabel; nameLabel1 = new QLabel;
nameLabel2 = new QLabel; nameLabel2 = new QLabel;
...@@ -53,13 +53,24 @@ CardInfoText::CardInfoText(QWidget *parent) ...@@ -53,13 +53,24 @@ CardInfoText::CardInfoText(QWidget *parent)
void CardInfoText::setCard(CardInfo *card) void CardInfoText::setCard(CardInfo *card)
{ {
nameLabel2->setText(card->getName()); if(card)
manacostLabel2->setText(card->getManaCost()); {
colorLabel2->setText(card->getColors().join("")); nameLabel2->setText(card->getName());
cardtypeLabel2->setText(card->getCardType()); manacostLabel2->setText(card->getManaCost());
powtoughLabel2->setText(card->getPowTough()); colorLabel2->setText(card->getColors().join(""));
loyaltyLabel2->setText(card->getLoyalty() > 0 ? QString::number(card->getLoyalty()) : QString()); cardtypeLabel2->setText(card->getCardType());
textLabel->setText(card->getText()); powtoughLabel2->setText(card->getPowTough());
loyaltyLabel2->setText(card->getLoyalty() > 0 ? QString::number(card->getLoyalty()) : QString());
textLabel->setText(card->getText());
} else {
nameLabel2->setText("");
manacostLabel2->setText("");
colorLabel2->setText("");
cardtypeLabel2->setText("");
powtoughLabel2->setText("");
loyaltyLabel2->setText("");
textLabel->setText("");
}
} }
void CardInfoText::retranslateUi() void CardInfoText::retranslateUi()
......
#include <QGridLayout> #include <QVBoxLayout>
#include <QLabel>
#include <QTextEdit>
#include <QPushButton>
#include <QStyle>
#include <QMouseEvent>
#include <QDesktopWidget> #include <QDesktopWidget>
#include "cardinfowidget.h" #include "cardinfowidget.h"
#include "carditem.h" #include "carditem.h"
#include "carddatabase.h" #include "carddatabase.h"
#include "pictureloader.h" #include "cardinfopicture.h"
#include "cardinfotext.h"
#include "main.h" #include "main.h"
#include "settingscache.h"
CardInfoWidget::CardInfoWidget(ResizeMode _mode, const QString &cardName, QWidget *parent, Qt::WindowFlags flags) CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::WindowFlags flags)
: QFrame(parent, flags) : QFrame(parent, flags)
, pixmapWidth(0)
, aspectRatio((qreal) CARD_HEIGHT / (qreal) CARD_WIDTH) , aspectRatio((qreal) CARD_HEIGHT / (qreal) CARD_WIDTH)
, minimized(settingsCache->getCardInfoMinimized()) // Initialize the cardinfo view status from cache. , info(nullptr)
, mode(_mode)
, info(0)
{ {
if (mode == ModeGameTab) { setContentsMargins(3, 3, 3, 3);
// Create indexed list of status views for card. pic = new CardInfoPicture();
const QStringList cardInfoStatus = QStringList() << tr("Show card only") << tr("Show text only") << tr("Show full info"); pic->setObjectName("pic");
text = new CardInfoText();
// Create droplist for cardinfo view selection, and set right current index. text->setObjectName("text");
dropList = new QComboBox();
dropList->addItems(cardInfoStatus); QVBoxLayout * layout = new QVBoxLayout();
dropList->setCurrentIndex(minimized); layout->setObjectName("layout");
connect(dropList, SIGNAL(currentIndexChanged(int)), this, SLOT(minimizeClicked(int))); layout->setContentsMargins(0, 0, 0, 0);
} layout->setSpacing(0);
layout->addWidget(pic, 0, Qt::AlignCenter);
layout->addWidget(text, 0, Qt::AlignCenter);
setLayout(layout);
cardPicture = new QLabel;
cardPicture->setAlignment(Qt::AlignCenter);
nameLabel1 = new QLabel;
nameLabel2 = new QLabel;
nameLabel2->setWordWrap(true);
manacostLabel1 = new QLabel;
manacostLabel2 = new QLabel;
manacostLabel2->setWordWrap(true);
colorLabel1 = new QLabel;
colorLabel2 = new QLabel;
colorLabel2->setWordWrap(true);
cardtypeLabel1 = new QLabel;
cardtypeLabel2 = new QLabel;
cardtypeLabel2->setWordWrap(true);
powtoughLabel1 = new QLabel;
powtoughLabel2 = new QLabel;
loyaltyLabel1 = new QLabel;
loyaltyLabel2 = new QLabel;
textLabel = new QTextEdit();
textLabel->setReadOnly(true);
QGridLayout *grid = new QGridLayout(this);
int row = 0;
if (mode == ModeGameTab)
grid->addWidget(dropList, row++, 1, 1, 1, Qt::AlignRight);
grid->addWidget(cardPicture, row++, 0, 1, 2);
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->setColumnStretch(1, 1);
retranslateUi();
setFrameStyle(QFrame::Panel | QFrame::Raised); setFrameStyle(QFrame::Panel | QFrame::Raised);
if (mode == ModeGameTab) { QDesktopWidget desktopWidget;
textLabel->setMinimumHeight(100); int pixmapHeight = desktopWidget.screenGeometry().height() / 3;
setFixedWidth(sizeHint().width()); int pixmapWidth = pixmapHeight / aspectRatio;
} else if (mode == ModePopUp) { pic->setFixedWidth(pixmapWidth);
QDesktopWidget desktopWidget; pic->setFixedHeight(pixmapHeight);
pixmapWidth = desktopWidget.screenGeometry().height() / 3 / aspectRatio; setFixedWidth(pixmapWidth + 150);
setFixedWidth(pixmapWidth + 150);
} else
setFixedWidth(250);
setCard(getCard(cardName));
setMinimized(settingsCache->getCardInfoMinimized());
}
void CardInfoWidget::minimizeClicked(int newMinimized)
{
// Set new status, and store it in the settings cache.
setMinimized(newMinimized);
settingsCache->setCardInfoMinimized(newMinimized);
}
bool CardInfoWidget::shouldShowPowTough()
{
return !info->getPowTough().isEmpty();
}
bool CardInfoWidget::shouldShowLoyalty()
{
return (info->getLoyalty() > 0);
}
void CardInfoWidget::setMinimized(int _minimized)
{
minimized = _minimized;
// Toggle oracle fields according to selected view.
bool showAll = ((minimized == 1) || (minimized == 2));
bool showPowTough = info ? (showAll && shouldShowPowTough()) : true;
bool showLoyalty = info ? (showAll && shouldShowLoyalty()) : true;
if (mode == ModeGameTab) {
nameLabel1->setVisible(showAll);
nameLabel2->setVisible(showAll);
manacostLabel1->setVisible(showAll);
manacostLabel2->setVisible(showAll);
colorLabel1->setVisible(showAll);
colorLabel2->setVisible(showAll);
cardtypeLabel1->setVisible(showAll);
cardtypeLabel2->setVisible(showAll);
powtoughLabel1->setVisible(showPowTough);
powtoughLabel2->setVisible(showPowTough);
loyaltyLabel1->setVisible(showLoyalty);
loyaltyLabel2->setVisible(showLoyalty);
textLabel->setVisible(showAll);
}
cardPicture->hide();
cardHeightOffset = minimumSizeHint().height() + 10;
// Set the picture to be shown only at "card only" (0) and "full info" (2) setCard(cardName);
if (mode == ModeGameTab) {
cardPicture->setVisible((minimized == 0) || (minimized == 2));
if (minimized == 0)
setMaximumHeight(cardHeightOffset + width() * aspectRatio);
else
setMaximumHeight(1000000);
} else
cardPicture->show();
resize(width(), sizeHint().height());
} }
void CardInfoWidget::setCard(CardInfo *card) void CardInfoWidget::setCard(CardInfo *card)
{ {
if (info) if (info)
disconnect(info, 0, this, 0); disconnect(info, nullptr, this, nullptr);
info = card; info = card;
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(updatePixmap())); if(info)
connect(info, SIGNAL(destroyed()), this, SLOT(clear())); connect(info, SIGNAL(destroyed()), this, SLOT(clear()));
updatePixmap();
nameLabel2->setText(card->getName());
manacostLabel2->setText(card->getManaCost());
colorLabel2->setText(card->getColors().join(""));
cardtypeLabel2->setText(card->getCardType());
powtoughLabel2->setText(card->getPowTough());
loyaltyLabel2->setText(card->getLoyalty() > 0 ? QString::number(card->getLoyalty()) : QString());
textLabel->setText(card->getText());
powtoughLabel1->setVisible(shouldShowPowTough()); text->setCard(info);
powtoughLabel2->setVisible(shouldShowPowTough()); pic->setCard(info);
loyaltyLabel1->setVisible(shouldShowLoyalty());
loyaltyLabel2->setVisible(shouldShowLoyalty());
} }
void CardInfoWidget::setCard(const QString &cardName) void CardInfoWidget::setCard(const QString &cardName)
{ {
setCard(getCard(cardName)); setCard(db->getCard(cardName));
} }
void CardInfoWidget::setCard(AbstractCardItem *card) void CardInfoWidget::setCard(AbstractCardItem *card)
...@@ -183,51 +61,5 @@ void CardInfoWidget::setCard(AbstractCardItem *card) ...@@ -183,51 +61,5 @@ void CardInfoWidget::setCard(AbstractCardItem *card)
void CardInfoWidget::clear() void CardInfoWidget::clear()
{ {
setCard(getCard()); setCard((CardInfo *) nullptr);
}
CardInfo *CardInfoWidget::getCard(const QString &cardName) {
return db->getCardBySimpleName(cardName);
}
void CardInfoWidget::updatePixmap()
{
if (pixmapWidth == 0)
return;
QPixmap resizedPixmap;
PictureLoader::getPixmap(resizedPixmap, info, QSize(pixmapWidth, pixmapWidth * aspectRatio));
if (resizedPixmap.isNull())
PictureLoader::getPixmap(resizedPixmap, getCard(), QSize(pixmapWidth, pixmapWidth * aspectRatio));
cardPicture->setPixmap(resizedPixmap);
}
void CardInfoWidget::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:"));
}
void CardInfoWidget::resizeEvent(QResizeEvent * /*event*/)
{
if (mode == ModePopUp)
return;
if ((minimized == 1) && (mode == ModeGameTab)) {
pixmapWidth = 0;
return;
}
qreal newPixmapWidth = qMax((qreal) 100.0, qMin((qreal) cardPicture->width(), (qreal) ((height() - cardHeightOffset) / aspectRatio)));
if (newPixmapWidth != pixmapWidth) {
pixmapWidth = newPixmapWidth;
updatePixmap();
}
}
QString CardInfoWidget::getCardName() const
{
return nameLabel2->text();
} }
...@@ -5,53 +5,21 @@ ...@@ -5,53 +5,21 @@
#include <QStringList> #include <QStringList>
#include <QComboBox> #include <QComboBox>
class QLabel;
class QTextEdit;
class QPushButton;
class AbstractCardItem;
class CardInfo; class CardInfo;
class QResizeEvent; class CardInfoPicture;
class QMouseEvent; class CardInfoText;
class AbstractCardItem;
class CardInfoWidget : public QFrame { class CardInfoWidget : public QFrame {
Q_OBJECT Q_OBJECT
public:
enum ResizeMode { ModeDeckEditor, ModeGameTab, ModePopUp };
private: private:
int pixmapWidth;
qreal cardHeightOffset;
qreal aspectRatio; qreal aspectRatio;
// XXX: Why isn't this an eunm?
int minimized; // 0 - card, 1 - oracle only, 2 - full
ResizeMode mode;
QComboBox *dropList;
QLabel *cardPicture;
QLabel *nameLabel1, *nameLabel2;
QLabel *manacostLabel1, *manacostLabel2;
QLabel *colorLabel1, *colorLabel2;
QLabel *cardtypeLabel1, *cardtypeLabel2;
QLabel *powtoughLabel1, *powtoughLabel2;
QLabel *loyaltyLabel1, *loyaltyLabel2;
QTextEdit *textLabel;
bool shouldShowPowTough();
bool shouldShowLoyalty();
CardInfo *info; CardInfo *info;
void setMinimized(int _minimized); CardInfoPicture *pic;
CardInfoText *text;
/*
* Wrapper around db->getCardBySimpleName.
*/
CardInfo *getCard(const QString &cardName = QString());
public: public:
CardInfoWidget(ResizeMode _mode, const QString &cardName = QString(), QWidget *parent = 0, Qt::WindowFlags f = 0); CardInfoWidget(const QString &cardName, QWidget *parent = 0, Qt::WindowFlags f = 0);
void retranslateUi();
QString getCardName() const;
public slots: public slots:
void setCard(CardInfo *card); void setCard(CardInfo *card);
...@@ -60,11 +28,6 @@ public slots: ...@@ -60,11 +28,6 @@ public slots:
private slots: private slots:
void clear(); void clear();
void updatePixmap();
void minimizeClicked(int newMinimized);
protected:
void resizeEvent(QResizeEvent *event);
}; };
#endif #endif
...@@ -107,13 +107,18 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, ...@@ -107,13 +107,18 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->save(); painter->save();
transformPainter(painter, translatedSize, tapAngle); transformPainter(painter, translatedSize, tapAngle);
QStringList ptDbSplit = db->getCard(name)->getPowTough().split("/"); if(info)
QStringList ptSplit = pt.split("/"); {
QStringList ptSplit = pt.split("/");
QStringList ptDbSplit = info->getPowTough().split("/");
if (getFaceDown() || ptDbSplit.at(0) != ptSplit.at(0) || ptDbSplit.at(1) != ptSplit.at(1)) if (getFaceDown() || ptDbSplit.at(0) != ptSplit.at(0) || ptDbSplit.at(1) != ptSplit.at(1))
painter->setPen(QColor(255, 150, 0)); painter->setPen(QColor(255, 150, 0));
else else
painter->setPen(Qt::white);
} else {
painter->setPen(Qt::white); painter->setPen(Qt::white);
}
painter->setBackground(Qt::black); painter->setBackground(Qt::black);
painter->setBackgroundMode(Qt::OpaqueMode); painter->setBackgroundMode(Qt::OpaqueMode);
...@@ -329,7 +334,7 @@ void CardItem::playCard(bool faceDown) ...@@ -329,7 +334,7 @@ void CardItem::playCard(bool faceDown)
if (tz) if (tz)
tz->toggleTapped(); tz->toggleTapped();
else else
zone->getPlayer()->playCard(this, faceDown, info->getCipt()); zone->getPlayer()->playCard(this, faceDown, info ? info->getCipt() : false);
} }
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
......
...@@ -44,11 +44,7 @@ void DeckListModel::rebuildTree() ...@@ -44,11 +44,7 @@ void DeckListModel::rebuildTree()
continue; continue;
CardInfo *info = db->getCard(currentCard->getName()); CardInfo *info = db->getCard(currentCard->getName());
QString cardType; QString cardType = info ? info->getMainCardType() : "unknown";
if (!info)
cardType = "unknown";
else
cardType = info->getMainCardType();
InnerDecklistNode *cardTypeNode = dynamic_cast<InnerDecklistNode *>(node->findChild(cardType)); InnerDecklistNode *cardTypeNode = dynamic_cast<InnerDecklistNode *>(node->findChild(cardType));
if (!cardTypeNode) if (!cardTypeNode)
cardTypeNode = new InnerDecklistNode(cardType, node); cardTypeNode = new InnerDecklistNode(cardType, node);
...@@ -280,6 +276,9 @@ QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneN ...@@ -280,6 +276,9 @@ QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneN
InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root); InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root);
CardInfo *info = db->getCard(cardName); CardInfo *info = db->getCard(cardName);
if(!info)
return QModelIndex();
QString cardType = info->getMainCardType(); QString cardType = info->getMainCardType();
InnerDecklistNode *cardTypeNode = createNodeIfNeeded(cardType, zoneNode); InnerDecklistNode *cardTypeNode = createNodeIfNeeded(cardType, zoneNode);
......
...@@ -89,7 +89,8 @@ struct CopyIfNotAToken { ...@@ -89,7 +89,8 @@ struct CopyIfNotAToken {
const InnerDecklistNode *node, const InnerDecklistNode *node,
const DecklistCardNode *card const DecklistCardNode *card
) const { ) const {
if (!cardDatabase.getCard(card->getName())->getIsToken()) { CardInfo * dbCard = cardDatabase.getCard(card->getName());
if (dbCard && !dbCard->getIsToken()) {
DecklistCardNode *addedCard = destination.addCard( DecklistCardNode *addedCard = destination.addCard(
card->getName(), card->getName(),
node->getName() node->getName()
......
#include "dlg_add_set_result.h"
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
DlgAddSetResult::DlgAddSetResult(QWidget *parent, bool success, QString msg) : QDialog(parent) {
status = new QLabel(this);
message = new QLabel(this);
if (success) {
setWindowTitle(tr("Success"));
status->setText(QString("Sets/cards added to Cockatrice."));
message->setText(QString("You must restart Cockatrice to use the new sets/cards."));
}
else {
setWindowTitle(tr("Failed"));
status->setText(QString("Sets/cards failed to import."));
message->setText(msg);
}
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
ok = new QPushButton(tr("Ok"), this);
buttonBox->addButton(ok, QDialogButtonBox::AcceptRole);
connect(ok, SIGNAL(clicked()), this, SLOT(closeDialog()));
QVBoxLayout *parentLayout = new QVBoxLayout(this);
parentLayout->addWidget(status);
parentLayout->addWidget(message);
parentLayout->addWidget(buttonBox);
setLayout(parentLayout);
}
void DlgAddSetResult::closeDialog()
{
accept();
}
\ No newline at end of file
#ifndef DLG_ADD_SET_RESULT_H
#define DLG_ADD_SET_RESULT_H
#include <QDialog>
#include <QLabel>
#include <QString>
class DlgAddSetResult : public QDialog {
Q_OBJECT
public:
DlgAddSetResult(QWidget *parent, bool success, QString msg);
private slots:
void closeDialog();
private:
QLabel *status, *message;
QPushButton *ok;
};
#endif
\ No newline at end of file
...@@ -27,13 +27,13 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa ...@@ -27,13 +27,13 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
colorLabel = new QLabel(tr("C&olor:")); colorLabel = new QLabel(tr("C&olor:"));
colorEdit = new QComboBox; colorEdit = new QComboBox;
colorEdit->addItem(tr("white"), "w"); colorEdit->addItem(tr("white"), QChar('w'));
colorEdit->addItem(tr("blue"), "u"); colorEdit->addItem(tr("blue"), QChar('u'));
colorEdit->addItem(tr("black"), "b"); colorEdit->addItem(tr("black"), QChar('b'));
colorEdit->addItem(tr("red"), "r"); colorEdit->addItem(tr("red"), QChar('r'));
colorEdit->addItem(tr("green"), "g"); colorEdit->addItem(tr("green"), QChar('g'));
colorEdit->addItem(tr("multicolor"), "m"); colorEdit->addItem(tr("multicolor"), QChar('m'));
colorEdit->addItem(tr("colorless"), QString()); colorEdit->addItem(tr("colorless"), QChar());
colorLabel->setBuddy(colorEdit); colorLabel->setBuddy(colorEdit);
ptLabel = new QLabel(tr("&P/T:")); ptLabel = new QLabel(tr("&P/T:"));
...@@ -132,14 +132,22 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa ...@@ -132,14 +132,22 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
void DlgCreateToken::tokenSelectionChanged(const QModelIndex &current, const QModelIndex & /*previous*/) void DlgCreateToken::tokenSelectionChanged(const QModelIndex &current, const QModelIndex & /*previous*/)
{ {
const QModelIndex realIndex = cardDatabaseDisplayModel->mapToSource(current); const QModelIndex realIndex = cardDatabaseDisplayModel->mapToSource(current);
const CardInfo *cardInfo = current.row() >= 0 ? cardDatabaseModel->getCard(realIndex.row()) : db->getCard(); const CardInfo *cardInfo = current.row() >= 0 ? cardDatabaseModel->getCard(realIndex.row()) : 0;
nameEdit->setText(cardInfo->getName()); if(cardInfo)
const QString cardColor = cardInfo->getColors().isEmpty() ? QString() : (cardInfo->getColors().size() > 1 ? QString("m") : cardInfo->getColors().first()); {
colorEdit->setCurrentIndex(colorEdit->findData(cardColor, Qt::UserRole, Qt::MatchFixedString)); nameEdit->setText(cardInfo->getName());
ptEdit->setText(cardInfo->getPowTough()); const QChar cardColor = cardInfo->getColorChar();
if(settingsCache->getAnnotateTokens()) colorEdit->setCurrentIndex(colorEdit->findData(cardColor, Qt::UserRole, Qt::MatchFixedString));
annotationEdit->setText(cardInfo->getText()); ptEdit->setText(cardInfo->getPowTough());
if(settingsCache->getAnnotateTokens())
annotationEdit->setText(cardInfo->getText());
} else {
nameEdit->setText("");
colorEdit->setCurrentIndex(colorEdit->findData(QString(), Qt::UserRole, Qt::MatchFixedString));
ptEdit->setText("");
annotationEdit->setText("");
}
} }
void DlgCreateToken::actChooseTokenFromAll(bool checked) void DlgCreateToken::actChooseTokenFromAll(bool checked)
...@@ -166,7 +174,7 @@ QString DlgCreateToken::getName() const ...@@ -166,7 +174,7 @@ QString DlgCreateToken::getName() const
QString DlgCreateToken::getColor() const QString DlgCreateToken::getColor() const
{ {
return colorEdit->itemData(colorEdit->currentIndex()).toString(); return QString(colorEdit->itemData(colorEdit->currentIndex()).toChar());
} }
QString DlgCreateToken::getPT() const QString DlgCreateToken::getPT() const
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment