diff --git a/cockatrice/src/abstractcarddragitem.cpp b/cockatrice/src/abstractcarddragitem.cpp index 42287038..ac640046 100644 --- a/cockatrice/src/abstractcarddragitem.cpp +++ b/cockatrice/src/abstractcarddragitem.cpp @@ -2,6 +2,7 @@ #include "carddatabase.h" #include #include +#include AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag) : QGraphicsItem(), item(_item), hotSpot(_hotSpot) @@ -11,10 +12,10 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item, const QPoint setZValue(2000000007 + hotSpot.x() * 1000000 + hotSpot.y() * 1000 + 1000); } else { if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) { - qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); + qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y(); hotSpot = QPointF(); } else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) { - qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); + qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y(); hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT); } setCursor(Qt::ClosedHandCursor); diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index a3b0b6a4..65c39f78 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -61,9 +61,169 @@ void SetList::sortByKey() qSort(begin(), end(), CompareFunctor()); } -PictureLoadingThread::PictureLoadingThread(QObject *parent) - : QThread(parent) +PictureToLoad::PictureToLoad(CardInfo *_card, bool _stripped, bool _hq) + : card(_card), stripped(_stripped), setIndex(0), hq(_hq) { + if (card) { + sortedSets = card->getSets(); + sortedSets.sortByKey(); + } +} + +bool PictureToLoad::nextSet() +{ + if (setIndex == sortedSets.size() - 1) + return false; + ++setIndex; + return true; +} + +PictureLoader::PictureLoader(QObject *parent) + : QObject(parent), downloadRunning(false), loadQueueRunning(false) +{ + connect(this, SIGNAL(startLoadQueue()), this, SLOT(processLoadQueue()), Qt::QueuedConnection); + + networkManager = new QNetworkAccessManager(this); + connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(picDownloadFinished(QNetworkReply *))); +} + +void PictureLoader::processLoadQueue() +{ + if (loadQueueRunning) + return; + + loadQueueRunning = true; + forever { + mutex.lock(); + if (loadQueue.isEmpty()) { + mutex.unlock(); + loadQueueRunning = false; + return; + } + PictureToLoad ptl = loadQueue.takeFirst(); + mutex.unlock(); + QString correctedName = ptl.getCard()->getCorrectedName(); + QString picsPath = _picsPath; + QString setName = ptl.getSetName(); + + QImage image; + if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(setName).arg(correctedName))) + if (!image.load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(setName).arg(correctedName).arg(1))) + if (!image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) { + if (picDownload) { + cardsToDownload.append(ptl); + if (!downloadRunning) + startNextPicDownload(); + } else { + if (ptl.nextSet()) + loadQueue.prepend(ptl); + else + emit imageLoaded(ptl.getCard(), QImage()); + } + continue; + } + + emit imageLoaded(ptl.getCard(), image); + } +} + +void PictureLoader::startNextPicDownload() +{ + if (cardsToDownload.isEmpty()) { + cardBeingDownloaded = 0; + downloadRunning = false; + return; + } + + downloadRunning = true; + + cardBeingDownloaded = cardsToDownload.takeFirst(); + QString picUrl; + if (cardBeingDownloaded.getStripped()) + picUrl = cardBeingDownloaded.getCard()->getPicURLSt(cardBeingDownloaded.getSetName()); + else if (cardBeingDownloaded.getHq()) + picUrl = cardBeingDownloaded.getCard()->getPicURLHq(cardBeingDownloaded.getSetName()); + else + picUrl = cardBeingDownloaded.getCard()->getPicURL(cardBeingDownloaded.getSetName()); + QUrl url(picUrl); + + QNetworkRequest req(url); + qDebug() << "starting picture download:" << req.url(); + networkManager->get(req); +} + +void PictureLoader::picDownloadFinished(QNetworkReply *reply) +{ + QString picsPath = _picsPath; + const QByteArray &picData = reply->readAll(); + QImage testImage; + if (testImage.loadFromData(picData)) { + if (!QDir(QString(picsPath + "/downloadedPics/")).exists()) { + QDir dir(picsPath); + if (!dir.exists()) + return; + dir.mkdir("downloadedPics"); + } + if (!QDir(QString(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName())).exists()) { + QDir dir(QString(picsPath + "/downloadedPics")); + dir.mkdir(cardBeingDownloaded.getSetName()); + } + + QString suffix; + if (!cardBeingDownloaded.getStripped()) + suffix = ".full"; + + QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + ".jpg"); + if (!newPic.open(QIODevice::WriteOnly)) + return; + newPic.write(picData); + newPic.close(); + + emit imageLoaded(cardBeingDownloaded.getCard(), testImage); + } else if (cardBeingDownloaded.getHq()) { + qDebug() << "HQ: received invalid picture. URL:" << reply->request().url(); + cardBeingDownloaded.setHq(false); + cardsToDownload.prepend(cardBeingDownloaded); + } else { + qDebug() << "LQ: received invalid picture. URL:" << reply->request().url(); + if (cardBeingDownloaded.nextSet()) { + cardBeingDownloaded.setHq(true); + mutex.lock(); + loadQueue.prepend(cardBeingDownloaded); + mutex.unlock(); + emit startLoadQueue(); + } else + emit imageLoaded(cardBeingDownloaded.getCard(), QImage()); + } + + reply->deleteLater(); + startNextPicDownload(); +} + +void PictureLoader::loadImage(CardInfo *card, bool stripped) +{ + QMutexLocker locker(&mutex); + + loadQueue.append(PictureToLoad(card, stripped)); + emit startLoadQueue(); +} + +void PictureLoader::setPicsPath(const QString &path) +{ + QMutexLocker locker(&mutex); + _picsPath = path; +} + +void PictureLoader::setPicDownload(bool _picDownload) +{ + QMutexLocker locker(&mutex); + picDownload = _picDownload; +} + +PictureLoadingThread::PictureLoadingThread(const QString &_picsPath, bool _picDownload, QObject *parent) + : QThread(parent), picsPath(_picsPath), picDownload(_picDownload) +{ + initMutex.lock(); } PictureLoadingThread::~PictureLoadingThread() @@ -74,47 +234,15 @@ PictureLoadingThread::~PictureLoadingThread() void PictureLoadingThread::run() { - forever { - mutex.lock(); - if (loadQueue.isEmpty()) { - mutex.unlock(); - return; - } - CardInfo *card = loadQueue.takeFirst(); - QString correctedName = card->getCorrectedName(); - QString picsPath = _picsPath; - SetList sortedSets = card->getSets(); - mutex.unlock(); - - sortedSets.sortByKey(); - - QImage image; - for (int i = 0; i < sortedSets.size(); i++) { - if (image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName))) - break; - if (image.load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName).arg(1))) - break; - if (image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(sortedSets[i]->getShortName()).arg(correctedName))) - break; - } - - emit imageLoaded(card, image); - } -} - -void PictureLoadingThread::loadImage(CardInfo *card) -{ - QMutexLocker locker(&mutex); - loadQueue.append(card); + pictureLoader = new PictureLoader; + connect(pictureLoader, SIGNAL(imageLoaded(CardInfo *, const QImage &)), this, SIGNAL(imageLoaded(CardInfo *, const QImage &))); + pictureLoader->setPicsPath(picsPath); + pictureLoader->setPicDownload(picDownload); - if (!isRunning()) - start(LowPriority); -} - -void PictureLoadingThread::setPicsPath(const QString &path) -{ - QMutexLocker locker(&mutex); - _picsPath = path; + initMutex.unlock(); + exec(); + + delete pictureLoader; } CardInfo::CardInfo(CardDatabase *_db, const QString &_name, const QString &_manacost, const QString &_cardtype, const QString &_powtough, const QString &_text, const QStringList &_colors, bool _cipt, int _tableRow, const SetList &_sets, const QMap &_picURLs, const QMap &_picURLsHq, const QMap &_picURLsSt) @@ -197,8 +325,7 @@ void CardInfo::imageLoaded(const QImage &image) if (!image.isNull()) { *pixmap = QPixmap::fromImage(image); emit pixmapUpdated(); - } else if (settingsCache->getPicDownload()) - db->startPicDownload(this, false); + } } QPixmap *CardInfo::getPixmap(QSize size) @@ -290,21 +417,17 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) } CardDatabase::CardDatabase(QObject *parent) - : QObject(parent), downloadRunning(false), loadSuccess(false), noCard(0) + : QObject(parent), loadSuccess(false), noCard(0) { connect(settingsCache, SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged())); connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase())); connect(settingsCache, SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged())); - networkManager = new QNetworkAccessManager(this); - connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(picDownloadFinished(QNetworkReply *))); - loadCardDatabase(); - loadingThread = new PictureLoadingThread(this); - loadingThread->setPicsPath(settingsCache->getPicsPath()); + loadingThread = new PictureLoadingThread(settingsCache->getPicsPath(), settingsCache->getPicDownload(), this); connect(loadingThread, SIGNAL(imageLoaded(CardInfo *, QImage)), this, SLOT(imageLoaded(CardInfo *, QImage))); - loadingThread->start(); + loadingThread->start(QThread::LowPriority); noCard = new CardInfo(this); noCard->loadPixmap(); // cache pixmap for card back @@ -381,83 +504,6 @@ void CardDatabase::clearPixmapCache() noCard->clearPixmapCache(); } -void CardDatabase::startPicDownload(CardInfo *card, bool stripped) -{ - SetList sortedSets = card->getSets(); - if (sortedSets.isEmpty()) - return; - sortedSets.sortByKey(); - for (int i = 0; i < sortedSets.size(); ++i) - qDebug() << sortedSets[i]->getShortName(); - - cardsToDownload.append(PictureToDownload(card, stripped, sortedSets.first()->getShortName())); - if (!downloadRunning) - startNextPicDownload(); -} - -void CardDatabase::startNextPicDownload() -{ - if (cardsToDownload.isEmpty()) { - cardBeingDownloaded = 0; - downloadRunning = false; - return; - } - - downloadRunning = true; - - cardBeingDownloaded = cardsToDownload.takeFirst(); - QString picUrl; - if (cardBeingDownloaded.getStripped()) - picUrl = cardBeingDownloaded.getCard()->getPicURLSt(cardBeingDownloaded.getSetName()); - else if (cardBeingDownloaded.getHq()) - picUrl = cardBeingDownloaded.getCard()->getPicURLHq(cardBeingDownloaded.getSetName()); - else - picUrl = cardBeingDownloaded.getCard()->getPicURL(cardBeingDownloaded.getSetName()); - QUrl url(picUrl); - - QNetworkRequest req(url); - qDebug() << "starting picture download:" << req.url(); - networkManager->get(req); -} - -void CardDatabase::picDownloadFinished(QNetworkReply *reply) -{ - QString picsPath = settingsCache->getPicsPath(); - const QByteArray &picData = reply->readAll(); - QPixmap testPixmap; - if (testPixmap.loadFromData(picData)) { - if (!QDir(QString(picsPath + "/downloadedPics/")).exists()) { - QDir dir(picsPath); - if (!dir.exists()) - return; - dir.mkdir("downloadedPics"); - } - if (!QDir(QString(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName())).exists()) { - QDir dir(QString(picsPath + "/downloadedPics")); - dir.mkdir(cardBeingDownloaded.getSetName()); - } - - QString suffix; - if (!cardBeingDownloaded.getStripped()) - suffix = ".full"; - - QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + ".jpg"); - if (!newPic.open(QIODevice::WriteOnly)) - return; - newPic.write(picData); - newPic.close(); - - cardBeingDownloaded.getCard()->updatePixmapCache(); - } else { - qDebug() << "Download finished, received invalid picture. URL:" << reply->request().url(); - cardBeingDownloaded.setHq(false); - cardsToDownload.prepend(cardBeingDownloaded); - } - - reply->deleteLater(); - startNextPicDownload(); -} - void CardDatabase::loadSetsFromXml(QXmlStreamReader &xml) { while (!xml.atEnd()) { @@ -582,6 +628,7 @@ bool CardDatabase::saveToFile(const QString &fileName) void CardDatabase::picDownloadChanged() { + loadingThread->getPictureLoader()->setPicDownload(settingsCache->getPicDownload()); if (settingsCache->getPicDownload()) { QHashIterator cardIterator(cardHash); while (cardIterator.hasNext()) @@ -645,7 +692,7 @@ void CardDatabase::cacheCardPixmaps(const QStringList &cardNames) void CardDatabase::loadImage(CardInfo *card) { - loadingThread->loadImage(card); + loadingThread->getPictureLoader()->loadImage(card, false); } void CardDatabase::imageLoaded(CardInfo *card, QImage image) @@ -655,6 +702,6 @@ void CardDatabase::imageLoaded(CardInfo *card, QImage image) void CardDatabase::picsPathChanged() { - loadingThread->setPicsPath(settingsCache->getPicsPath()); + loadingThread->getPictureLoader()->setPicsPath(settingsCache->getPicsPath()); clearPixmapCache(); } \ No newline at end of file diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index 16d165e5..4e1b43f0 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -37,19 +37,63 @@ public: void sortByKey(); }; -class PictureLoadingThread : public QThread { +class PictureToLoad { +private: + CardInfo *card; + bool stripped; + SetList sortedSets; + int setIndex; + bool hq; +public: + PictureToLoad(CardInfo *_card = 0, bool _stripped = false, bool _hq = true); + CardInfo *getCard() const { return card; } + bool getStripped() const { return stripped; } + QString getSetName() const { return sortedSets[setIndex]->getShortName(); } + bool nextSet(); + + bool getHq() const { return hq; } + void setHq(bool _hq) { hq = _hq; } + +}; + +class PictureLoader : public QObject { Q_OBJECT private: QString _picsPath; - QList loadQueue; + QList loadQueue; QMutex mutex; + QNetworkAccessManager *networkManager; + QList cardsToDownload; + PictureToLoad cardBeingDownloaded; + bool picDownload, downloadRunning, loadQueueRunning; + void startNextPicDownload(); +public: + PictureLoader(QObject *parent = 0); + void setPicsPath(const QString &path); + void setPicDownload(bool _picDownload); + void loadImage(CardInfo *card, bool stripped); +private slots: + void picDownloadFinished(QNetworkReply *reply); +public slots: + void processLoadQueue(); +signals: + void startLoadQueue(); + void imageLoaded(CardInfo *card, const QImage &image); +}; + +class PictureLoadingThread : public QThread { + Q_OBJECT +private: + QString picsPath; + bool picDownload; + PictureLoader *pictureLoader; + mutable QMutex initMutex; protected: void run(); public: - PictureLoadingThread(QObject *parent); + PictureLoadingThread(const QString &_picsPath, bool _picDownload, QObject *parent); ~PictureLoadingThread(); - void setPicsPath(const QString &path); - void loadImage(CardInfo *card); + PictureLoader *getPictureLoader() const { QMutexLocker locker(&initMutex); return pictureLoader; } signals: void imageLoaded(CardInfo *card, const QImage &image); }; @@ -119,38 +163,17 @@ signals: void pixmapUpdated(); }; -class PictureToDownload { -private: - CardInfo *card; - bool stripped; - QString setName; - bool hq; -public: - PictureToDownload(CardInfo *_card = 0, bool _stripped = false, const QString &_setName = QString(), bool _hq = true) - : card(_card), stripped(_stripped), setName(_setName), hq(_hq) { } - CardInfo *getCard() const { return card; } - bool getStripped() const { return stripped; } - QString getSetName() const { return setName; } - bool getHq() const { return hq; } - void setHq(bool _hq) { hq = _hq; } -}; - class CardDatabase : public QObject { Q_OBJECT protected: QHash cardHash; QHash setHash; - QNetworkAccessManager *networkManager; - QList cardsToDownload; - PictureToDownload cardBeingDownloaded; - bool downloadRunning; bool loadSuccess; CardInfo *noCard; PictureLoadingThread *loadingThread; private: void loadCardsFromXml(QXmlStreamReader &xml); void loadSetsFromXml(QXmlStreamReader &xml); - void startNextPicDownload(); public: CardDatabase(QObject *parent = 0); ~CardDatabase(); @@ -161,7 +184,6 @@ public: SetList getSetList() const; bool loadFromFile(const QString &fileName); bool saveToFile(const QString &fileName); - void startPicDownload(CardInfo *card, bool stripped); QStringList getAllColors() const; QStringList getAllMainCardTypes() const; bool getLoadSuccess() const { return loadSuccess; } @@ -172,9 +194,8 @@ public slots: bool loadCardDatabase(const QString &path); bool loadCardDatabase(); private slots: - void picDownloadFinished(QNetworkReply *reply); - void picDownloadChanged(); void imageLoaded(CardInfo *card, QImage image); + void picDownloadChanged(); void picsPathChanged(); }; diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 0270bc1b..06245daf 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -204,6 +204,8 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QByteArray &data) QString OracleImporter::getPictureUrl(QString url, int cardId, QString name, const QString &setName) const { + if ((name == "Island") || (name == "Swamp") || (name == "Mountain") || (name == "Plains") || (name == "Forest")) + name.append("1"); return url.replace("!cardid!", QString::number(cardId)).replace("!set!", setName).replace("!name!", name .replace("รถ", "o") // .remove('\'')