diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 748d8197..2045f95e 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -80,11 +80,13 @@ bool PictureToLoad::nextSet() return true; } -PictureLoader::PictureLoader(const QString &__picsPath, bool _picDownload, QObject *parent) - : QObject(parent), _picsPath(__picsPath), picDownload(_picDownload), downloadRunning(false), loadQueueRunning(false) +PictureLoader::PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent) + : QObject(parent), + _picsPath(__picsPath), picDownload(_picDownload), picDownloadHq(_picDownloadHq), + 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 *))); } @@ -99,7 +101,7 @@ void PictureLoader::processLoadQueue() { if (loadQueueRunning) return; - + loadQueueRunning = true; forever { mutex.lock(); @@ -113,7 +115,7 @@ void PictureLoader::processLoadQueue() 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))) @@ -135,6 +137,20 @@ void PictureLoader::processLoadQueue() } } +QString PictureLoader::getPicUrl(CardInfo *card) +{ + if (!picDownload) return 0; + + QString picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl(); + picUrl.replace("!name!", QUrl::toPercentEncoding(card->getCorrectedName())); + CardSet *set = card->getPreferredSet(); + picUrl.replace("!setcode!", QUrl::toPercentEncoding(set->getShortName())); + picUrl.replace("!setname!", QUrl::toPercentEncoding(set->getLongName())); + picUrl.replace("!cardid!", QUrl::toPercentEncoding(QString::number(card->getPreferredMuId()))); + + return picUrl; +} + void PictureLoader::startNextPicDownload() { if (cardsToDownload.isEmpty()) { @@ -142,23 +158,16 @@ void PictureLoader::startNextPicDownload() 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()); - if (picUrl.isEmpty()) { - picUrl = cardBeingDownloaded.getCard()->getPicURL(cardBeingDownloaded.getSetName()); - cardBeingDownloaded.setHq(false); - } - } else - picUrl = cardBeingDownloaded.getCard()->getPicURL(cardBeingDownloaded.getSetName()); + + // TODO: Do something useful when picUrl is 0 or empty, etc + QString picUrl = getPicUrl(cardBeingDownloaded.getCard()); + QUrl url(picUrl); - + QNetworkRequest req(url); qDebug() << "starting picture download:" << req.url(); networkManager->get(req); @@ -232,6 +241,12 @@ void PictureLoader::setPicDownload(bool _picDownload) picDownload = _picDownload; } +void PictureLoader::setPicDownloadHq(bool _picDownloadHq) +{ + QMutexLocker locker(&mutex); + picDownloadHq = _picDownloadHq; +} + CardInfo::CardInfo(CardDatabase *_db, const QString &_name, bool _isToken, @@ -244,22 +259,18 @@ CardInfo::CardInfo(CardDatabase *_db, bool _cipt, int _tableRow, const SetList &_sets, - const QMap &_picURLs, - const QMap &_picURLsHq, - const QMap &_picURLsSt) + QMap _muIds) : db(_db), name(_name), isToken(_isToken), sets(_sets), + muIds(_muIds), manacost(_manacost), cardtype(_cardtype), powtough(_powtough), text(_text), colors(_colors), loyalty(_loyalty), - picURLs(_picURLs), - picURLsHq(_picURLsHq), - picURLsSt(_picURLsSt), cipt(_cipt), tableRow(_tableRow), pixmap(NULL) @@ -315,19 +326,12 @@ void CardInfo::addToSet(CardSet *set) sets << set; } -QString CardInfo::getPicURL() const -{ - SetList sortedSets = sets; - sortedSets.sortByKey(); - return picURLs.value(sortedSets.first()->getShortName()); -} - QPixmap *CardInfo::loadPixmap() { if (pixmap) return pixmap; pixmap = new QPixmap(); - + if (getName().isEmpty()) { pixmap->load(settingsCache->getCardBackPicturePath()); return pixmap; @@ -400,6 +404,18 @@ void CardInfo::updatePixmapCache() emit pixmapUpdated(); } +CardSet* CardInfo::getPreferredSet() +{ + SetList sortedSets = sets; + sortedSets.sortByKey(); + return sortedSets.first(); +} + +int CardInfo::getPreferredMuId() +{ + return muIds[getPreferredSet()->getShortName()]; +} + QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) { xml.writeStartElement("card"); @@ -414,18 +430,6 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) tmpSet=sets[i]->getShortName(); xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet))); - tmpString = info->getPicURL(tmpSet); - if(!tmpString.isEmpty()) - xml.writeAttribute("picURL", tmpString); - - tmpString = info->getPicURLHq(tmpSet); - if(!tmpString.isEmpty()) - xml.writeAttribute("picURLHq", tmpString); - - tmpString = info->getPicURLSt(tmpSet); - if(!tmpString.isEmpty()) - xml.writeAttribute("picURLSt", tmpString); - xml.writeCharacters(tmpSet); xml.writeEndElement(); } @@ -457,12 +461,13 @@ CardDatabase::CardDatabase(QObject *parent) connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase())); connect(settingsCache, SIGNAL(tokenDatabasePathChanged()), this, SLOT(loadTokenDatabase())); connect(settingsCache, SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged())); - + connect(settingsCache, SIGNAL(picDownloadHqChanged()), this, SLOT(picDownloadHqChanged())); + loadCardDatabase(); loadTokenDatabase(); - + pictureLoaderThread = new QThread; - pictureLoader = new PictureLoader(settingsCache->getPicsPath(), settingsCache->getPicDownload()); + pictureLoader = new PictureLoader(settingsCache->getPicsPath(), settingsCache->getPicDownload(), settingsCache->getPicDownloadHq()); pictureLoader->moveToThread(pictureLoaderThread); connect(pictureLoader, SIGNAL(imageLoaded(CardInfo *, const QImage &)), this, SLOT(imageLoaded(CardInfo *, const QImage &))); pictureLoaderThread->start(QThread::LowPriority); @@ -587,7 +592,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml) if (xml.name() == "card") { QString name, manacost, type, pt, text; QStringList colors; - QMap picURLs, picURLsHq, picURLsSt; + QMap muids; SetList sets; int tableRow = 0; int loyalty = 0; @@ -607,14 +612,12 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml) else if (xml.name() == "text") text = xml.readElementText(); else if (xml.name() == "set") { - QString picURL = xml.attributes().value("picURL").toString(); - QString picURLHq = xml.attributes().value("picURLHq").toString(); - QString picURLSt = xml.attributes().value("picURLSt").toString(); + QXmlStreamAttributes attrs = xml.attributes(); QString setName = xml.readElementText(); sets.append(getSet(setName)); - picURLs.insert(setName, picURL); - picURLsHq.insert(setName, picURLHq); - picURLsSt.insert(setName, picURLSt); + if (attrs.hasAttribute("muId")) { + muids[setName] = attrs.value("muId").toString().toInt(); + } } else if (xml.name() == "color") colors << xml.readElementText(); else if (xml.name() == "tablerow") @@ -626,7 +629,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml) else if (xml.name() == "token") isToken = xml.readElementText().toInt(); } - cardHash.insert(name, new CardInfo(this, name, isToken, manacost, type, pt, text, colors, loyalty, cipt, tableRow, sets, picURLs, picURLsHq, picURLsSt)); + cardHash.insert(name, new CardInfo(this, name, isToken, manacost, type, pt, text, colors, loyalty, cipt, tableRow, sets, muids)); } } } @@ -732,6 +735,16 @@ void CardDatabase::picDownloadChanged() } } +void CardDatabase::picDownloadHqChanged() +{ + pictureLoader->setPicDownloadHq(settingsCache->getPicDownloadHq()); + if (settingsCache->getPicDownloadHq()) { + QHashIterator cardIterator(cardHash); + while (cardIterator.hasNext()) + cardIterator.next().value()->clearPixmapCacheMiss(); + } +} + bool CardDatabase::loadCardDatabase(const QString &path, bool tokens) { bool tempLoadSuccess = false; diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index 987848d3..39d2faec 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -68,13 +68,15 @@ private: QNetworkAccessManager *networkManager; QList cardsToDownload; PictureToLoad cardBeingDownloaded; - bool picDownload, downloadRunning, loadQueueRunning; + bool picDownload, picDownloadHq, downloadRunning, loadQueueRunning; void startNextPicDownload(); + QString getPicUrl(CardInfo* card); public: - PictureLoader(const QString &__picsPath, bool _picDownload, QObject *parent = 0); + PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent = 0); ~PictureLoader(); void setPicsPath(const QString &path); void setPicDownload(bool _picDownload); + void setPicDownloadHq(bool _picDownloadHq); void loadImage(CardInfo *card, bool stripped); private slots: void picDownloadFinished(QNetworkReply *reply); @@ -99,7 +101,6 @@ private: QString text; QStringList colors; int loyalty; - QMap picURLs, picURLsHq, picURLsSt; QMap muIds; bool cipt; int tableRow; @@ -118,9 +119,7 @@ public: bool _cipt = false, int _tableRow = 0, const SetList &_sets = SetList(), - const QStringMap &_picURLs = QStringMap(), - const QStringMap &_picURLsHq = QStringMap(), - const QStringMap &_picURLsSt = QStringMap()); + QMap muids = QMap()); ~CardInfo(); const QString &getName() const { return name; } bool getIsToken() const { return isToken; } @@ -137,20 +136,12 @@ public: void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); } void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); } const QStringList &getColors() const { return colors; } - QString getPicURL(const QString &set) const { return picURLs.value(set); } - QString getPicURLHq(const QString &set) const { return picURLsHq.value(set); } - QString getPicURLSt(const QString &set) const { return picURLsSt.value(set); } int getMuId(const QString &set) const { return muIds.value(set); } - QString getPicURL() const; - const QMap &getPicURLs() const { return picURLs; } QString getMainCardType() const; QString getCorrectedName() const; int getTableRow() const { return tableRow; } void setTableRow(int _tableRow) { tableRow = _tableRow; } void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(this); } - void setPicURL(const QString &_set, const QString &_picURL) { picURLs.insert(_set, _picURL); } - void setPicURLHq(const QString &_set, const QString &_picURL) { picURLsHq.insert(_set, _picURL); } - void setPicURLSt(const QString &_set, const QString &_picURL) { picURLsSt.insert(_set, _picURL); } void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); } void addToSet(CardSet *set); QPixmap *loadPixmap(); @@ -158,6 +149,8 @@ public: void clearPixmapCache(); void clearPixmapCacheMiss(); void imageLoaded(const QImage &image); + CardSet *getPreferredSet(); + int getPreferredMuId(); public slots: void updatePixmapCache(); signals: @@ -172,7 +165,7 @@ protected: QHash setHash; bool loadSuccess; CardInfo *noCard; - + QThread *pictureLoaderThread; PictureLoader *pictureLoader; private: @@ -202,6 +195,7 @@ public slots: private slots: void imageLoaded(CardInfo *card, QImage image); void picDownloadChanged(); + void picDownloadHqChanged(); void picsPathChanged(); void loadCardDatabase(); diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index 32d4f1fb..f7293964 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -27,7 +27,7 @@ GeneralSettingsPage::GeneralSettingsPage() { languageLabel = new QLabel; languageBox = new QComboBox; - + QString setLanguage = settingsCache->getLang(); QStringList qmFiles = findQmFiles(); for (int i = 0; i < qmFiles.size(); i++) { @@ -36,27 +36,32 @@ GeneralSettingsPage::GeneralSettingsPage() if ((qmFiles[i] == setLanguage) || (setLanguage.isEmpty() && langName == tr("English"))) languageBox->setCurrentIndex(i); } - + picDownloadCheckBox = new QCheckBox; picDownloadCheckBox->setChecked(settingsCache->getPicDownload()); - + + picDownloadHqCheckBox = new QCheckBox; + picDownloadHqCheckBox->setChecked(settingsCache->getPicDownloadHq()); + connect(languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int))); connect(picDownloadCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPicDownload(int))); - + connect(picDownloadHqCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPicDownloadHq(int))); + QGridLayout *personalGrid = new QGridLayout; personalGrid->addWidget(languageLabel, 0, 0); personalGrid->addWidget(languageBox, 0, 1); personalGrid->addWidget(picDownloadCheckBox, 1, 0, 1, 2); - + personalGrid->addWidget(picDownloadHqCheckBox, 2, 0, 1, 2); + personalGroupBox = new QGroupBox; personalGroupBox->setLayout(personalGrid); - + deckPathLabel = new QLabel; deckPathEdit = new QLineEdit(settingsCache->getDeckPath()); deckPathEdit->setReadOnly(true); QPushButton *deckPathButton = new QPushButton("..."); connect(deckPathButton, SIGNAL(clicked()), this, SLOT(deckPathButtonClicked())); - + replaysPathLabel = new QLabel; replaysPathEdit = new QLineEdit(settingsCache->getReplaysPath()); replaysPathEdit->setReadOnly(true); @@ -183,6 +188,7 @@ void GeneralSettingsPage::retranslateUi() personalGroupBox->setTitle(tr("Personal settings")); languageLabel->setText(tr("Language:")); picDownloadCheckBox->setText(tr("Download card pictures on the fly")); + picDownloadHqCheckBox->setText(tr("Download high-quality card pictures")); pathsGroupBox->setTitle(tr("Paths")); deckPathLabel->setText(tr("Decks directory:")); replaysPathLabel->setText(tr("Replays directory:")); diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index 5f87887c..8462f612 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -40,6 +40,7 @@ private: QGroupBox *personalGroupBox, *pathsGroupBox; QComboBox *languageBox; QCheckBox *picDownloadCheckBox; + QCheckBox *picDownloadHqCheckBox; QLabel *languageLabel, *deckPathLabel, *replaysPathLabel, *picsPathLabel, *cardDatabasePathLabel, *tokenDatabasePathLabel; }; diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index 3bcc4111..ac5c130f 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -20,6 +20,7 @@ SettingsCache::SettingsCache() cardBackPicturePath = settings->value("paths/cardbackpicture").toString(); picDownload = settings->value("personal/picturedownload", true).toBool(); + picDownloadHq = settings->value("personal/picturedownloadhq", false).toBool(); picUrl = settings->value("personal/picUrl", PIC_URL_DEFAULT).toString(); picUrlHq = settings->value("personal/picUrlHq", PIC_URL_HQ_DEFAULT).toString(); @@ -128,6 +129,13 @@ void SettingsCache::setPicDownload(int _picDownload) emit picDownloadChanged(); } +void SettingsCache::setPicDownloadHq(int _picDownloadHq) +{ + picDownloadHq = _picDownloadHq; + settings->setValue("personal/picturedownloadhq", picDownloadHq); + emit picDownloadHqChanged(); +} + void SettingsCache::setPicUrl(const QString &_picUrl) { picUrl = _picUrl; diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index ba3dbb00..5156772d 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -3,7 +3,7 @@ #include -#define PIC_URL_DEFAULT "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card" +#define PIC_URL_DEFAULT "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card" #define PIC_URL_HQ_DEFAULT "http://mtgimage.com/multiverseid/!cardid!.jpg" class QSettings; @@ -21,6 +21,7 @@ signals: void playerBgPathChanged(); void cardBackPicturePathChanged(); void picDownloadChanged(); + void picDownloadHqChanged(); void displayCardNamesChanged(); void horizontalHandChanged(); void invertVerticalCoordinateChanged(); @@ -36,6 +37,7 @@ private: QString deckPath, replaysPath, picsPath, cardDatabasePath, tokenDatabasePath; QString handBgPath, stackBgPath, tableBgPath, playerBgPath, cardBackPicturePath; bool picDownload; + bool picDownloadHq; bool notificationsEnabled; bool doubleClickToPlay; bool playToStack; @@ -68,6 +70,7 @@ public: QString getPlayerBgPath() const { return playerBgPath; } QString getCardBackPicturePath() const { return cardBackPicturePath; } bool getPicDownload() const { return picDownload; } + bool getPicDownloadHq() const { return picDownloadHq; } bool getNotificationsEnabled() const { return notificationsEnabled; } bool getDoubleClickToPlay() const { return doubleClickToPlay; } bool getPlayToStack() const { return playToStack; } @@ -100,6 +103,7 @@ public slots: void setPlayerBgPath(const QString &_playerBgPath); void setCardBackPicturePath(const QString &_cardBackPicturePath); void setPicDownload(int _picDownload); + void setPicDownloadHq(int _picDownloadHq); void setNotificationsEnabled(int _notificationsEnabled); void setDoubleClickToPlay(int _doubleClickToPlay); void setPlayToStack(int _playToStack);