Automatic Spoiler Season (#2991)
* oracle now can be run in spoiler or normal mode * tests for travis * only run on relaunch * spoilers in client (not oracle now) and tray icon shows when done * spoiler status will be checked before downloading spoiler file * only download if they care about spoilers * reload db on spoiler download * manual update button, code cleanup, and fix enabling sets when new * cleanup, nullchecks, and fixes to spoiler * reload DB even if not in spoiler season; necessary as we have a check elsewhere to prevent the reload if spoiler check happens * Implement changes from 2991#issuecomment-356169374 * Change implicit nullptrs, alert on file deletion, minor changes * make reload thread safe and minor changes from 2991#issuecomment-356450302 * Fix locking * Disable update now button while process running
This commit is contained in:
parent
51ec593759
commit
d19744236e
23 changed files with 2106 additions and 913 deletions
|
@ -116,6 +116,7 @@ SET(cockatrice_SOURCES
|
||||||
src/logger.cpp
|
src/logger.cpp
|
||||||
src/releasechannel.cpp
|
src/releasechannel.cpp
|
||||||
src/userconnection_information.cpp
|
src/userconnection_information.cpp
|
||||||
|
src/spoilerbackgroundupdater.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,7 @@
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
|
#include <QBasicMutex>
|
||||||
|
|
||||||
class CardDatabase;
|
class CardDatabase;
|
||||||
class CardInfo;
|
class CardInfo;
|
||||||
|
@ -18,159 +19,173 @@ typedef QMap<QString, QString> QStringMap;
|
||||||
// If we don't typedef this, CardInfo::CardInfo will refuse to compile on OS X < 10.9
|
// If we don't typedef this, CardInfo::CardInfo will refuse to compile on OS X < 10.9
|
||||||
typedef QMap<QString, int> MuidMap;
|
typedef QMap<QString, int> MuidMap;
|
||||||
|
|
||||||
class CardSet : public QList<CardInfo *> {
|
class CardSet : public QList<CardInfo *>
|
||||||
private:
|
{
|
||||||
QString shortName, longName;
|
private:
|
||||||
unsigned int sortKey;
|
QString shortName, longName;
|
||||||
QDate releaseDate;
|
unsigned int sortKey;
|
||||||
QString setType;
|
QDate releaseDate;
|
||||||
bool enabled, isknown;
|
QString setType;
|
||||||
public:
|
bool enabled, isknown;
|
||||||
CardSet(const QString &_shortName = QString(), const QString &_longName = QString(), const QString &_setType = QString(), const QDate &_releaseDate = QDate());
|
|
||||||
QString getCorrectedShortName() const;
|
|
||||||
QString getShortName() const { return shortName; }
|
|
||||||
QString getLongName() const { return longName; }
|
|
||||||
QString getSetType() const { return setType; }
|
|
||||||
QDate getReleaseDate() const { return releaseDate; }
|
|
||||||
void setLongName(QString & _longName) { longName = _longName; }
|
|
||||||
void setSetType(QString & _setType) { setType = _setType; }
|
|
||||||
void setReleaseDate(QDate & _releaseDate) { releaseDate = _releaseDate; }
|
|
||||||
|
|
||||||
void loadSetOptions();
|
public:
|
||||||
int getSortKey() const { return sortKey; }
|
explicit CardSet(const QString &_shortName = QString(), const QString &_longName = QString(), const QString &_setType = QString(), const QDate &_releaseDate = QDate());
|
||||||
void setSortKey(unsigned int _sortKey);
|
QString getCorrectedShortName() const;
|
||||||
bool getEnabled() const { return enabled; }
|
QString getShortName() const { return shortName; }
|
||||||
void setEnabled(bool _enabled);
|
QString getLongName() const { return longName; }
|
||||||
bool getIsKnown() const { return isknown; }
|
QString getSetType() const { return setType; }
|
||||||
void setIsKnown(bool _isknown);
|
QDate getReleaseDate() const { return releaseDate; }
|
||||||
//Determine incomplete sets.
|
void setLongName(QString & _longName) { longName = _longName; }
|
||||||
bool getIsKnownIgnored() const { return longName.length() + setType.length() + releaseDate.toString().length() == 0 ; }
|
void setSetType(QString & _setType) { setType = _setType; }
|
||||||
|
void setReleaseDate(QDate & _releaseDate) { releaseDate = _releaseDate; }
|
||||||
|
|
||||||
|
void loadSetOptions();
|
||||||
|
int getSortKey() const { return sortKey; }
|
||||||
|
void setSortKey(unsigned int _sortKey);
|
||||||
|
bool getEnabled() const { return enabled; }
|
||||||
|
void setEnabled(bool _enabled);
|
||||||
|
bool getIsKnown() const { return isknown; }
|
||||||
|
void setIsKnown(bool _isknown);
|
||||||
|
|
||||||
|
//Determine incomplete sets.
|
||||||
|
bool getIsKnownIgnored() const { return longName.length() + setType.length() + releaseDate.toString().length() == 0 ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class SetList : public QList<CardSet *> {
|
class SetList : public QList<CardSet *>
|
||||||
private:
|
{
|
||||||
class KeyCompareFunctor;
|
private:
|
||||||
public:
|
class KeyCompareFunctor;
|
||||||
void sortByKey();
|
|
||||||
void guessSortKeys();
|
public:
|
||||||
void enableAllUnknown();
|
void sortByKey();
|
||||||
void enableAll();
|
void guessSortKeys();
|
||||||
void markAllAsKnown();
|
void enableAllUnknown();
|
||||||
int getEnabledSetsNum();
|
void enableAll();
|
||||||
int getUnknownSetsNum();
|
void markAllAsKnown();
|
||||||
QStringList getUnknownSetsNames();
|
int getEnabledSetsNum();
|
||||||
|
int getUnknownSetsNum();
|
||||||
|
QStringList getUnknownSetsNames();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CardInfo : public QObject {
|
class CardInfo : public QObject
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The name without punctuation or capitalization, for better card tag name
|
* The name without punctuation or capitalization, for better card tag name
|
||||||
* recognition.
|
* recognition.
|
||||||
*/
|
*/
|
||||||
QString simpleName;
|
QString simpleName;
|
||||||
|
|
||||||
bool isToken;
|
bool isToken;
|
||||||
SetList sets;
|
SetList sets;
|
||||||
QString manacost;
|
QString manacost;
|
||||||
QString cmc;
|
QString cmc;
|
||||||
QString cardtype;
|
QString cardtype;
|
||||||
QString powtough;
|
QString powtough;
|
||||||
QString text;
|
QString text;
|
||||||
QStringList colors;
|
QStringList colors;
|
||||||
// the cards i'm related to
|
|
||||||
QList<CardRelation *> relatedCards;
|
|
||||||
// the card i'm reverse-related to
|
|
||||||
QList<CardRelation *> reverseRelatedCards;
|
|
||||||
// the cards thare are reverse-related to me
|
|
||||||
QList<CardRelation *> reverseRelatedCardsToMe;
|
|
||||||
QString setsNames;
|
|
||||||
bool upsideDownArt;
|
|
||||||
int loyalty;
|
|
||||||
QStringMap customPicURLs;
|
|
||||||
MuidMap muIds;
|
|
||||||
QStringMap collectorNumbers;
|
|
||||||
QStringMap rarities;
|
|
||||||
bool cipt;
|
|
||||||
int tableRow;
|
|
||||||
QString pixmapCacheKey;
|
|
||||||
public:
|
|
||||||
CardInfo(const QString &_name = QString(),
|
|
||||||
bool _isToken = false,
|
|
||||||
const QString &_manacost = QString(),
|
|
||||||
const QString &_cmc = QString(),
|
|
||||||
const QString &_cardtype = QString(),
|
|
||||||
const QString &_powtough = QString(),
|
|
||||||
const QString &_text = QString(),
|
|
||||||
const QStringList &_colors = QStringList(),
|
|
||||||
const QList<CardRelation *> &_relatedCards = QList<CardRelation *>(),
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards = QList<CardRelation *>(),
|
|
||||||
bool _upsideDownArt = false,
|
|
||||||
int _loyalty = 0,
|
|
||||||
bool _cipt = false,
|
|
||||||
int _tableRow = 0,
|
|
||||||
const SetList &_sets = SetList(),
|
|
||||||
const QStringMap &_customPicURLs = QStringMap(),
|
|
||||||
MuidMap muids = MuidMap(),
|
|
||||||
QStringMap _collectorNumbers = QStringMap(),
|
|
||||||
QStringMap _rarities = QStringMap()
|
|
||||||
);
|
|
||||||
~CardInfo();
|
|
||||||
inline const QString &getName() const { return name; }
|
|
||||||
inline const QString &getSetsNames() const { return setsNames; }
|
|
||||||
const QString &getSimpleName() const { return simpleName; }
|
|
||||||
bool getIsToken() const { return isToken; }
|
|
||||||
const SetList &getSets() const { return sets; }
|
|
||||||
inline const QString &getManaCost() const { return manacost; }
|
|
||||||
inline const QString &getCmc() const { return cmc; }
|
|
||||||
inline const QString &getCardType() const { return cardtype; }
|
|
||||||
inline const QString &getPowTough() const { return powtough; }
|
|
||||||
const QString &getText() const { return text; }
|
|
||||||
const QString &getPixmapCacheKey() const { return pixmapCacheKey; }
|
|
||||||
const int &getLoyalty() const { return loyalty; }
|
|
||||||
bool getCipt() const { return cipt; }
|
|
||||||
void setManaCost(const QString &_manaCost) { manacost = _manaCost; emit cardInfoChanged(this); }
|
|
||||||
void setCmc(const QString &_cmc) { cmc = _cmc; emit cardInfoChanged(this); }
|
|
||||||
void setCardType(const QString &_cardType) { cardtype = _cardType; emit cardInfoChanged(this); }
|
|
||||||
void setPowTough(const QString &_powTough) { powtough = _powTough; emit cardInfoChanged(this); }
|
|
||||||
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
|
|
||||||
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
|
|
||||||
const QChar getColorChar() const;
|
|
||||||
const QStringList &getColors() const { return colors; }
|
|
||||||
const QList<CardRelation *> &getRelatedCards() const { return relatedCards; }
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards() const { return reverseRelatedCards; }
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards2Me() const { return reverseRelatedCardsToMe; }
|
|
||||||
void resetReverseRelatedCards2Me();
|
|
||||||
void addReverseRelatedCards2Me(CardRelation * cardRelation) { reverseRelatedCardsToMe.append(cardRelation); }
|
|
||||||
bool getUpsideDownArt() const { return upsideDownArt; }
|
|
||||||
QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); }
|
|
||||||
int getMuId(const QString &set) const { return muIds.value(set); }
|
|
||||||
QString getCollectorNumber(const QString &set) const { return collectorNumbers.value(set); }
|
|
||||||
QString getRarity(const QString &set) const { return rarities.value(set); }
|
|
||||||
QStringMap getRarities() const { return rarities; }
|
|
||||||
QString getMainCardType() const;
|
|
||||||
QString getCorrectedName() const;
|
|
||||||
int getTableRow() const { return tableRow; }
|
|
||||||
void setTableRow(int _tableRow) { tableRow = _tableRow; }
|
|
||||||
void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(this); }
|
|
||||||
void setCustomPicURL(const QString &_set, const QString &_customPicURL) { customPicURLs.insert(_set, _customPicURL); }
|
|
||||||
void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); }
|
|
||||||
void setSetNumber(const QString &_set, const QString &_setNumber) { collectorNumbers.insert(_set, _setNumber); }
|
|
||||||
void setRarity(const QString &_set, const QString &_setNumber) { rarities.insert(_set, _setNumber); }
|
|
||||||
void addToSet(CardSet *set);
|
|
||||||
void emitPixmapUpdated() { emit pixmapUpdated(); }
|
|
||||||
void refreshCachedSetNames();
|
|
||||||
|
|
||||||
/**
|
// the cards i'm related to
|
||||||
* Simplify a name to have no punctuation and lowercase all letters, for
|
QList<CardRelation *> relatedCards;
|
||||||
* less strict name-matching.
|
|
||||||
*/
|
// the card i'm reverse-related to
|
||||||
static QString simplifyName(const QString &name);
|
QList<CardRelation *> reverseRelatedCards;
|
||||||
signals:
|
|
||||||
void pixmapUpdated();
|
// the cards thare are reverse-related to me
|
||||||
void cardInfoChanged(CardInfo *card);
|
QList<CardRelation *> reverseRelatedCardsToMe;
|
||||||
|
|
||||||
|
QString setsNames;
|
||||||
|
|
||||||
|
bool upsideDownArt;
|
||||||
|
int loyalty;
|
||||||
|
QStringMap customPicURLs;
|
||||||
|
MuidMap muIds;
|
||||||
|
QStringMap collectorNumbers;
|
||||||
|
QStringMap rarities;
|
||||||
|
bool cipt;
|
||||||
|
int tableRow;
|
||||||
|
QString pixmapCacheKey;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CardInfo(const QString &_name = QString(),
|
||||||
|
bool _isToken = false,
|
||||||
|
const QString &_manacost = QString(),
|
||||||
|
const QString &_cmc = QString(),
|
||||||
|
const QString &_cardtype = QString(),
|
||||||
|
const QString &_powtough = QString(),
|
||||||
|
const QString &_text = QString(),
|
||||||
|
const QStringList &_colors = QStringList(),
|
||||||
|
const QList<CardRelation *> &_relatedCards = QList<CardRelation *>(),
|
||||||
|
const QList<CardRelation *> &_reverseRelatedCards = QList<CardRelation *>(),
|
||||||
|
bool _upsideDownArt = false,
|
||||||
|
int _loyalty = 0,
|
||||||
|
bool _cipt = false,
|
||||||
|
int _tableRow = 0,
|
||||||
|
const SetList &_sets = SetList(),
|
||||||
|
const QStringMap &_customPicURLs = QStringMap(),
|
||||||
|
MuidMap muids = MuidMap(),
|
||||||
|
QStringMap _collectorNumbers = QStringMap(),
|
||||||
|
QStringMap _rarities = QStringMap()
|
||||||
|
);
|
||||||
|
~CardInfo() override;
|
||||||
|
|
||||||
|
inline const QString &getName() const { return name; }
|
||||||
|
inline const QString &getSetsNames() const { return setsNames; }
|
||||||
|
const QString &getSimpleName() const { return simpleName; }
|
||||||
|
bool getIsToken() const { return isToken; }
|
||||||
|
const SetList &getSets() const { return sets; }
|
||||||
|
inline const QString &getManaCost() const { return manacost; }
|
||||||
|
inline const QString &getCmc() const { return cmc; }
|
||||||
|
inline const QString &getCardType() const { return cardtype; }
|
||||||
|
inline const QString &getPowTough() const { return powtough; }
|
||||||
|
const QString &getText() const { return text; }
|
||||||
|
const QString &getPixmapCacheKey() const { return pixmapCacheKey; }
|
||||||
|
const int &getLoyalty() const { return loyalty; }
|
||||||
|
bool getCipt() const { return cipt; }
|
||||||
|
//void setManaCost(const QString &_manaCost) { manacost = _manaCost; emit cardInfoChanged(this); }
|
||||||
|
//void setCmc(const QString &_cmc) { cmc = _cmc; emit cardInfoChanged(this); }
|
||||||
|
void setCardType(const QString &_cardType) { cardtype = _cardType; emit cardInfoChanged(this); }
|
||||||
|
void setPowTough(const QString &_powTough) { powtough = _powTough; emit cardInfoChanged(this); }
|
||||||
|
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
|
||||||
|
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
|
||||||
|
const QChar getColorChar() const;
|
||||||
|
const QStringList &getColors() const { return colors; }
|
||||||
|
const QList<CardRelation *> &getRelatedCards() const { return relatedCards; }
|
||||||
|
const QList<CardRelation *> &getReverseRelatedCards() const { return reverseRelatedCards; }
|
||||||
|
const QList<CardRelation *> &getReverseRelatedCards2Me() const { return reverseRelatedCardsToMe; }
|
||||||
|
void resetReverseRelatedCards2Me();
|
||||||
|
void addReverseRelatedCards2Me(CardRelation * cardRelation) { reverseRelatedCardsToMe.append(cardRelation); }
|
||||||
|
bool getUpsideDownArt() const { return upsideDownArt; }
|
||||||
|
QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); }
|
||||||
|
int getMuId(const QString &set) const { return muIds.value(set); }
|
||||||
|
QString getCollectorNumber(const QString &set) const { return collectorNumbers.value(set); }
|
||||||
|
QString getRarity(const QString &set) const { return rarities.value(set); }
|
||||||
|
QStringMap getRarities() const { return rarities; }
|
||||||
|
QString getMainCardType() const;
|
||||||
|
QString getCorrectedName() const;
|
||||||
|
int getTableRow() const { return tableRow; }
|
||||||
|
void setTableRow(int _tableRow) { tableRow = _tableRow; }
|
||||||
|
//void setLoyalty(int _loyalty) { loyalty = _loyalty; emit cardInfoChanged(this); }
|
||||||
|
//void setCustomPicURL(const QString &_set, const QString &_customPicURL) { customPicURLs.insert(_set, _customPicURL); }
|
||||||
|
void setMuId(const QString &_set, const int &_muId) { muIds.insert(_set, _muId); }
|
||||||
|
void setSetNumber(const QString &_set, const QString &_setNumber) { collectorNumbers.insert(_set, _setNumber); }
|
||||||
|
void setRarity(const QString &_set, const QString &_setNumber) { rarities.insert(_set, _setNumber); }
|
||||||
|
void addToSet(CardSet *set);
|
||||||
|
void emitPixmapUpdated() { emit pixmapUpdated(); }
|
||||||
|
void refreshCachedSetNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify a name to have no punctuation and lowercase all letters, for
|
||||||
|
* less strict name-matching.
|
||||||
|
*/
|
||||||
|
static QString simplifyName(const QString &name);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void pixmapUpdated();
|
||||||
|
void cardInfoChanged(CardInfo *card);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
||||||
|
@ -178,97 +193,106 @@ enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
||||||
typedef QHash<QString, CardInfo *> CardNameMap;
|
typedef QHash<QString, CardInfo *> CardNameMap;
|
||||||
typedef QHash<QString, CardSet *> SetNameMap;
|
typedef QHash<QString, CardSet *> SetNameMap;
|
||||||
|
|
||||||
class CardDatabase : public QObject {
|
class CardDatabase : public QObject
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
/*
|
/*
|
||||||
* The cards, indexed by name.
|
* The cards, indexed by name.
|
||||||
*/
|
*/
|
||||||
CardNameMap cards;
|
CardNameMap cards;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cards, indexed by their simple name.
|
* The cards, indexed by their simple name.
|
||||||
*/
|
*/
|
||||||
CardNameMap simpleNameCards;
|
CardNameMap simpleNameCards;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sets, indexed by short name.
|
* The sets, indexed by short name.
|
||||||
*/
|
*/
|
||||||
SetNameMap sets;
|
SetNameMap sets;
|
||||||
|
|
||||||
LoadStatus loadStatus;
|
LoadStatus loadStatus;
|
||||||
private:
|
private:
|
||||||
static const int versionNeeded;
|
static const int versionNeeded;
|
||||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||||
|
|
||||||
CardInfo *getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
CardInfo *getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
||||||
void checkUnknownSets();
|
void checkUnknownSets();
|
||||||
void refreshCachedReverseRelatedCards();
|
void refreshCachedReverseRelatedCards();
|
||||||
public:
|
|
||||||
static const char* TOKENS_SETNAME;
|
|
||||||
|
|
||||||
CardDatabase(QObject *parent = 0);
|
QBasicMutex *reloadDatabaseMutex = new QBasicMutex(),
|
||||||
~CardDatabase();
|
*clearDatabaseMutex = new QBasicMutex(),
|
||||||
void clear();
|
*loadFromFileMutex = new QBasicMutex(),
|
||||||
void addCard(CardInfo *card);
|
*addCardMutex = new QBasicMutex(),
|
||||||
void removeCard(CardInfo *card);
|
*removeCardMutex = new QBasicMutex();
|
||||||
CardInfo *getCard(const QString &cardName) const;
|
|
||||||
QList <CardInfo *> getCards(const QStringList &cardNames) const;
|
|
||||||
|
|
||||||
/*
|
public:
|
||||||
* Get a card by its simple name. The name will be simplified in this
|
static const char* TOKENS_SETNAME;
|
||||||
* function, so you don't need to simplify it beforehand.
|
|
||||||
*/
|
|
||||||
CardInfo *getCardBySimpleName(const QString &cardName) const;
|
|
||||||
|
|
||||||
CardSet *getSet(const QString &setName);
|
explicit CardDatabase(QObject *parent = nullptr);
|
||||||
QList<CardInfo *> getCardList() const { return cards.values(); }
|
~CardDatabase() override;
|
||||||
SetList getSetList() const;
|
void clear();
|
||||||
LoadStatus loadFromFile(const QString &fileName);
|
void addCard(CardInfo *card);
|
||||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
void removeCard(CardInfo *card);
|
||||||
bool saveCustomTokensToFile();
|
CardInfo *getCard(const QString &cardName) const;
|
||||||
QStringList getAllColors() const;
|
QList <CardInfo *> getCards(const QStringList &cardNames) const;
|
||||||
QStringList getAllMainCardTypes() const;
|
|
||||||
LoadStatus getLoadStatus() const { return loadStatus; }
|
|
||||||
void enableAllUnknownSets();
|
|
||||||
void markAllSetsAsKnown();
|
|
||||||
void notifyEnabledSetsChanged();
|
|
||||||
|
|
||||||
public slots:
|
/*
|
||||||
LoadStatus loadCardDatabases();
|
* Get a card by its simple name. The name will be simplified in this
|
||||||
private slots:
|
* function, so you don't need to simplify it beforehand.
|
||||||
LoadStatus loadCardDatabase(const QString &path);
|
*/
|
||||||
signals:
|
CardInfo *getCardBySimpleName(const QString &cardName) const;
|
||||||
void cardDatabaseLoadingFailed();
|
|
||||||
void cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames);
|
CardSet *getSet(const QString &setName);
|
||||||
void cardDatabaseAllNewSetsEnabled();
|
QList<CardInfo *> getCardList() const { return cards.values(); }
|
||||||
void cardDatabaseEnabledSetsChanged();
|
SetList getSetList() const;
|
||||||
void cardAdded(CardInfo *card);
|
LoadStatus loadFromFile(const QString &fileName);
|
||||||
void cardRemoved(CardInfo *card);
|
bool saveToFile(const QString &fileName, bool tokens = false);
|
||||||
|
bool saveCustomTokensToFile();
|
||||||
|
QStringList getAllColors() const;
|
||||||
|
QStringList getAllMainCardTypes() const;
|
||||||
|
LoadStatus getLoadStatus() const { return loadStatus; }
|
||||||
|
void enableAllUnknownSets();
|
||||||
|
void markAllSetsAsKnown();
|
||||||
|
void notifyEnabledSetsChanged();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
LoadStatus loadCardDatabases();
|
||||||
|
private slots:
|
||||||
|
LoadStatus loadCardDatabase(const QString &path);
|
||||||
|
signals:
|
||||||
|
void cardDatabaseLoadingFailed();
|
||||||
|
void cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames);
|
||||||
|
void cardDatabaseAllNewSetsEnabled();
|
||||||
|
void cardDatabaseEnabledSetsChanged();
|
||||||
|
void cardAdded(CardInfo *card);
|
||||||
|
void cardRemoved(CardInfo *card);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CardRelation : public QObject {
|
class CardRelation : public QObject
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
bool doesAttach;
|
bool doesAttach;
|
||||||
bool isCreateAllExclusion;
|
bool isCreateAllExclusion;
|
||||||
bool isVariableCount;
|
bool isVariableCount;
|
||||||
int defaultCount;
|
int defaultCount;
|
||||||
public:
|
public:
|
||||||
CardRelation(const QString &_name = QString(),
|
explicit CardRelation(const QString &_name = QString(),
|
||||||
bool _doesAttach = false,
|
bool _doesAttach = false,
|
||||||
bool _isCreateAllExclusion = false,
|
bool _isCreateAllExclusion = false,
|
||||||
bool _isVariableCount = false,
|
bool _isVariableCount = false,
|
||||||
int _defaultCount = 1
|
int _defaultCount = 1
|
||||||
);
|
);
|
||||||
inline const QString &getName() const { return name; }
|
|
||||||
bool getDoesAttach() const { return doesAttach; }
|
|
||||||
bool getCanCreateAnother() const { return !doesAttach; }
|
|
||||||
bool getIsCreateAllExclusion() const { return isCreateAllExclusion; }
|
|
||||||
bool getIsVariable() const { return isVariableCount; }
|
|
||||||
int getDefaultCount() const { return defaultCount; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
inline const QString &getName() const { return name; }
|
||||||
|
bool getDoesAttach() const { return doesAttach; }
|
||||||
|
bool getCanCreateAnother() const { return !doesAttach; }
|
||||||
|
bool getIsCreateAllExclusion() const { return isCreateAllExclusion; }
|
||||||
|
bool getIsVariable() const { return isVariableCount; }
|
||||||
|
int getDefaultCount() const { return defaultCount; }
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -16,8 +16,7 @@
|
||||||
|
|
||||||
#define PUBLIC_SERVERS_URL "https://github.com/Cockatrice/Cockatrice/wiki/Public-Servers"
|
#define PUBLIC_SERVERS_URL "https://github.com/Cockatrice/Cockatrice/wiki/Public-Servers"
|
||||||
|
|
||||||
DlgConnect::DlgConnect(QWidget *parent)
|
DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||||
: QDialog(parent)
|
|
||||||
{
|
{
|
||||||
previousHostButton = new QRadioButton(tr("Known Hosts"), this);
|
previousHostButton = new QRadioButton(tr("Known Hosts"), this);
|
||||||
previousHosts = new QComboBox(this);
|
previousHosts = new QComboBox(this);
|
||||||
|
@ -64,7 +63,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
||||||
|
|
||||||
if (savePasswordCheckBox->isChecked())
|
if (savePasswordCheckBox->isChecked())
|
||||||
{
|
{
|
||||||
autoConnectCheckBox->setChecked(settingsCache->servers().getAutoConnect());
|
autoConnectCheckBox->setChecked(static_cast<bool>(settingsCache->servers().getAutoConnect()));
|
||||||
autoConnectCheckBox->setEnabled(true);
|
autoConnectCheckBox->setEnabled(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -87,11 +86,11 @@ DlgConnect::DlgConnect(QWidget *parent)
|
||||||
btnCancel->setFixedWidth(100);
|
btnCancel->setFixedWidth(100);
|
||||||
connect(btnCancel, SIGNAL(released()), this, SLOT(actCancel()));
|
connect(btnCancel, SIGNAL(released()), this, SLOT(actCancel()));
|
||||||
|
|
||||||
QGridLayout *newHostLayout = new QGridLayout;
|
auto *newHostLayout = new QGridLayout;
|
||||||
newHostLayout->addWidget(newHostButton, 0, 1);
|
newHostLayout->addWidget(newHostButton, 0, 1);
|
||||||
newHostLayout->addWidget(publicServersLabel, 0, 2);
|
newHostLayout->addWidget(publicServersLabel, 0, 2);
|
||||||
|
|
||||||
QGridLayout *connectionLayout = new QGridLayout;
|
auto *connectionLayout = new QGridLayout;
|
||||||
connectionLayout->addWidget(previousHostButton, 0, 1);
|
connectionLayout->addWidget(previousHostButton, 0, 1);
|
||||||
connectionLayout->addWidget(previousHosts, 1, 1);
|
connectionLayout->addWidget(previousHosts, 1, 1);
|
||||||
connectionLayout->addLayout(newHostLayout, 2, 1, 1, 2);
|
connectionLayout->addLayout(newHostLayout, 2, 1, 1, 2);
|
||||||
|
@ -103,7 +102,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
||||||
connectionLayout->addWidget(portEdit, 5, 1);
|
connectionLayout->addWidget(portEdit, 5, 1);
|
||||||
connectionLayout->addWidget(autoConnectCheckBox, 6, 1);
|
connectionLayout->addWidget(autoConnectCheckBox, 6, 1);
|
||||||
|
|
||||||
QGridLayout *buttons = new QGridLayout;
|
auto *buttons = new QGridLayout;
|
||||||
buttons->addWidget(btnOk, 0, 0);
|
buttons->addWidget(btnOk, 0, 0);
|
||||||
buttons->addWidget(btnForgotPassword, 0, 1);
|
buttons->addWidget(btnForgotPassword, 0, 1);
|
||||||
buttons->addWidget(btnCancel, 0, 2);
|
buttons->addWidget(btnCancel, 0, 2);
|
||||||
|
@ -111,7 +110,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
||||||
QGroupBox *restrictionsGroupBox = new QGroupBox(tr("Server"));
|
QGroupBox *restrictionsGroupBox = new QGroupBox(tr("Server"));
|
||||||
restrictionsGroupBox->setLayout(connectionLayout);
|
restrictionsGroupBox->setLayout(connectionLayout);
|
||||||
|
|
||||||
QGridLayout *loginLayout = new QGridLayout;
|
auto *loginLayout = new QGridLayout;
|
||||||
loginLayout->addWidget(playernameLabel, 0, 0);
|
loginLayout->addWidget(playernameLabel, 0, 0);
|
||||||
loginLayout->addWidget(playernameEdit, 0, 1);
|
loginLayout->addWidget(playernameEdit, 0, 1);
|
||||||
loginLayout->addWidget(passwordLabel, 1, 0);
|
loginLayout->addWidget(passwordLabel, 1, 0);
|
||||||
|
@ -124,12 +123,12 @@ DlgConnect::DlgConnect(QWidget *parent)
|
||||||
QGroupBox *btnGroupBox = new QGroupBox(tr(""));
|
QGroupBox *btnGroupBox = new QGroupBox(tr(""));
|
||||||
btnGroupBox->setLayout(buttons);
|
btnGroupBox->setLayout(buttons);
|
||||||
|
|
||||||
QGridLayout *grid = new QGridLayout;
|
auto *grid = new QGridLayout;
|
||||||
grid->addWidget(restrictionsGroupBox, 0, 0);
|
grid->addWidget(restrictionsGroupBox, 0, 0);
|
||||||
grid->addWidget(loginGroupBox, 1, 0);
|
grid->addWidget(loginGroupBox, 1, 0);
|
||||||
grid->addWidget(btnGroupBox, 2, 0);
|
grid->addWidget(btnGroupBox, 2, 0);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(grid);
|
mainLayout->addLayout(grid);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
@ -289,9 +288,9 @@ void DlgConnect::actCancel()
|
||||||
bool DeleteHighlightedItemWhenShiftDelPressedEventFilter::eventFilter(QObject *obj, QEvent *event)
|
bool DeleteHighlightedItemWhenShiftDelPressedEventFilter::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
auto *keyEvent = dynamic_cast<QKeyEvent *>(event);
|
||||||
if (keyEvent->key() == Qt::Key_Delete) {
|
if (keyEvent->key() == Qt::Key_Delete) {
|
||||||
QComboBox* combobox = reinterpret_cast<QComboBox *>(obj);
|
auto *combobox = reinterpret_cast<QComboBox *>(obj);
|
||||||
combobox->removeItem(combobox->currentIndex());
|
combobox->removeItem(combobox->currentIndex());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "releasechannel.h"
|
#include "releasechannel.h"
|
||||||
#include "soundengine.h"
|
#include "soundengine.h"
|
||||||
#include "sequenceEdit/shortcutstab.h"
|
#include "sequenceEdit/shortcutstab.h"
|
||||||
|
#include "spoilerbackgroundupdater.h"
|
||||||
|
|
||||||
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
|
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
pixmapCacheEdit.setSingleStep(64);
|
pixmapCacheEdit.setSingleStep(64);
|
||||||
pixmapCacheEdit.setValue(settingsCache->getPixmapCacheSize());
|
pixmapCacheEdit.setValue(settingsCache->getPixmapCacheSize());
|
||||||
pixmapCacheEdit.setSuffix(" MB");
|
pixmapCacheEdit.setSuffix(" MB");
|
||||||
|
|
||||||
defaultUrlEdit = new QLineEdit(settingsCache->getPicUrl());
|
defaultUrlEdit = new QLineEdit(settingsCache->getPicUrl());
|
||||||
fallbackUrlEdit = new QLineEdit(settingsCache->getPicUrlFallback());
|
fallbackUrlEdit = new QLineEdit(settingsCache->getPicUrlFallback());
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
|
|
||||||
setEnabledStatus(settingsCache->getPicDownload());
|
setEnabledStatus(settingsCache->getPicDownload());
|
||||||
|
|
||||||
QGridLayout *personalGrid = new QGridLayout;
|
auto *personalGrid = new QGridLayout;
|
||||||
personalGrid->addWidget(&languageLabel, 0, 0);
|
personalGrid->addWidget(&languageLabel, 0, 0);
|
||||||
personalGrid->addWidget(&languageBox, 0, 1);
|
personalGrid->addWidget(&languageBox, 0, 1);
|
||||||
personalGrid->addWidget(&updateReleaseChannelLabel, 1, 0);
|
personalGrid->addWidget(&updateReleaseChannelLabel, 1, 0);
|
||||||
|
@ -98,7 +99,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
personalGrid->addWidget(&fallbackUrlRestoreButton, 6, 2, 1, 1);
|
personalGrid->addWidget(&fallbackUrlRestoreButton, 6, 2, 1, 1);
|
||||||
personalGrid->addWidget(&urlLinkLabel, 7, 1, 1, 1);
|
personalGrid->addWidget(&urlLinkLabel, 7, 1, 1, 1);
|
||||||
personalGrid->addWidget(&clearDownloadedPicsButton, 8, 0, 1, 3);
|
personalGrid->addWidget(&clearDownloadedPicsButton, 8, 0, 1, 3);
|
||||||
|
|
||||||
urlLinkLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
urlLinkLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
||||||
urlLinkLabel.setOpenExternalLinks(true);
|
urlLinkLabel.setOpenExternalLinks(true);
|
||||||
|
|
||||||
|
@ -114,23 +115,23 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
replaysPathEdit->setReadOnly(true);
|
replaysPathEdit->setReadOnly(true);
|
||||||
QPushButton *replaysPathButton = new QPushButton("...");
|
QPushButton *replaysPathButton = new QPushButton("...");
|
||||||
connect(replaysPathButton, SIGNAL(clicked()), this, SLOT(replaysPathButtonClicked()));
|
connect(replaysPathButton, SIGNAL(clicked()), this, SLOT(replaysPathButtonClicked()));
|
||||||
|
|
||||||
picsPathEdit = new QLineEdit(settingsCache->getPicsPath());
|
picsPathEdit = new QLineEdit(settingsCache->getPicsPath());
|
||||||
picsPathEdit->setReadOnly(true);
|
picsPathEdit->setReadOnly(true);
|
||||||
QPushButton *picsPathButton = new QPushButton("...");
|
QPushButton *picsPathButton = new QPushButton("...");
|
||||||
connect(picsPathButton, SIGNAL(clicked()), this, SLOT(picsPathButtonClicked()));
|
connect(picsPathButton, SIGNAL(clicked()), this, SLOT(picsPathButtonClicked()));
|
||||||
|
|
||||||
cardDatabasePathEdit = new QLineEdit(settingsCache->getCardDatabasePath());
|
cardDatabasePathEdit = new QLineEdit(settingsCache->getCardDatabasePath());
|
||||||
cardDatabasePathEdit->setReadOnly(true);
|
cardDatabasePathEdit->setReadOnly(true);
|
||||||
QPushButton *cardDatabasePathButton = new QPushButton("...");
|
QPushButton *cardDatabasePathButton = new QPushButton("...");
|
||||||
connect(cardDatabasePathButton, SIGNAL(clicked()), this, SLOT(cardDatabasePathButtonClicked()));
|
connect(cardDatabasePathButton, SIGNAL(clicked()), this, SLOT(cardDatabasePathButtonClicked()));
|
||||||
|
|
||||||
tokenDatabasePathEdit = new QLineEdit(settingsCache->getTokenDatabasePath());
|
tokenDatabasePathEdit = new QLineEdit(settingsCache->getTokenDatabasePath());
|
||||||
tokenDatabasePathEdit->setReadOnly(true);
|
tokenDatabasePathEdit->setReadOnly(true);
|
||||||
QPushButton *tokenDatabasePathButton = new QPushButton("...");
|
QPushButton *tokenDatabasePathButton = new QPushButton("...");
|
||||||
connect(tokenDatabasePathButton, SIGNAL(clicked()), this, SLOT(tokenDatabasePathButtonClicked()));
|
connect(tokenDatabasePathButton, SIGNAL(clicked()), this, SLOT(tokenDatabasePathButtonClicked()));
|
||||||
|
|
||||||
if(settingsCache->getIsPortableBuild())
|
if (settingsCache->getIsPortableBuild())
|
||||||
{
|
{
|
||||||
deckPathEdit->setEnabled(false);
|
deckPathEdit->setEnabled(false);
|
||||||
replaysPathEdit->setEnabled(false);
|
replaysPathEdit->setEnabled(false);
|
||||||
|
@ -145,7 +146,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
tokenDatabasePathButton->setVisible(false);
|
tokenDatabasePathButton->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QGridLayout *pathsGrid = new QGridLayout;
|
auto *pathsGrid = new QGridLayout;
|
||||||
pathsGrid->addWidget(&deckPathLabel, 0, 0);
|
pathsGrid->addWidget(&deckPathLabel, 0, 0);
|
||||||
pathsGrid->addWidget(deckPathEdit, 0, 1);
|
pathsGrid->addWidget(deckPathEdit, 0, 1);
|
||||||
pathsGrid->addWidget(deckPathButton, 0, 2);
|
pathsGrid->addWidget(deckPathButton, 0, 2);
|
||||||
|
@ -164,10 +165,10 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||||
pathsGroupBox = new QGroupBox;
|
pathsGroupBox = new QGroupBox;
|
||||||
pathsGroupBox->setLayout(pathsGrid);
|
pathsGroupBox->setLayout(pathsGrid);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(personalGroupBox);
|
mainLayout->addWidget(personalGroupBox);
|
||||||
mainLayout->addWidget(pathsGroupBox);
|
mainLayout->addWidget(pathsGroupBox);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +187,7 @@ QString GeneralSettingsPage::languageName(const QString &qmFile)
|
||||||
|
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
||||||
|
|
||||||
return translator.translate("i18n", DEFAULT_LANG_NAME);
|
return translator.translate("i18n", DEFAULT_LANG_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ void GeneralSettingsPage::deckPathButtonClicked()
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
deckPathEdit->setText(path);
|
deckPathEdit->setText(path);
|
||||||
settingsCache->setDeckPath(path);
|
settingsCache->setDeckPath(path);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +220,7 @@ void GeneralSettingsPage::replaysPathButtonClicked()
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
replaysPathEdit->setText(path);
|
replaysPathEdit->setText(path);
|
||||||
settingsCache->setReplaysPath(path);
|
settingsCache->setReplaysPath(path);
|
||||||
}
|
}
|
||||||
|
@ -229,7 +230,7 @@ void GeneralSettingsPage::picsPathButtonClicked()
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
picsPathEdit->setText(path);
|
picsPathEdit->setText(path);
|
||||||
settingsCache->setPicsPath(path);
|
settingsCache->setPicsPath(path);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +264,7 @@ void GeneralSettingsPage::cardDatabasePathButtonClicked()
|
||||||
QString path = QFileDialog::getOpenFileName(this, tr("Choose path"));
|
QString path = QFileDialog::getOpenFileName(this, tr("Choose path"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cardDatabasePathEdit->setText(path);
|
cardDatabasePathEdit->setText(path);
|
||||||
settingsCache->setCardDatabasePath(path);
|
settingsCache->setCardDatabasePath(path);
|
||||||
}
|
}
|
||||||
|
@ -273,7 +274,7 @@ void GeneralSettingsPage::tokenDatabasePathButtonClicked()
|
||||||
QString path = QFileDialog::getOpenFileName(this, tr("Choose path"));
|
QString path = QFileDialog::getOpenFileName(this, tr("Choose path"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tokenDatabasePathEdit->setText(path);
|
tokenDatabasePathEdit->setText(path);
|
||||||
settingsCache->setTokenDatabasePath(path);
|
settingsCache->setTokenDatabasePath(path);
|
||||||
}
|
}
|
||||||
|
@ -332,8 +333,8 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int)));
|
connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int)));
|
||||||
|
|
||||||
QGridLayout *themeGrid = new QGridLayout;
|
auto *themeGrid = new QGridLayout;
|
||||||
themeGrid->addWidget(&themeLabel, 0, 0);
|
themeGrid->addWidget(&themeLabel, 0, 0);
|
||||||
themeGrid->addWidget(&themeBox, 0, 1);
|
themeGrid->addWidget(&themeBox, 0, 1);
|
||||||
|
|
||||||
|
@ -345,30 +346,30 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||||
|
|
||||||
cardScalingCheckBox.setChecked(settingsCache->getScaleCards());
|
cardScalingCheckBox.setChecked(settingsCache->getScaleCards());
|
||||||
connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setCardScaling(int)));
|
connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setCardScaling(int)));
|
||||||
|
|
||||||
QGridLayout *cardsGrid = new QGridLayout;
|
auto *cardsGrid = new QGridLayout;
|
||||||
cardsGrid->addWidget(&displayCardNamesCheckBox, 0, 0, 1, 2);
|
cardsGrid->addWidget(&displayCardNamesCheckBox, 0, 0, 1, 2);
|
||||||
cardsGrid->addWidget(&cardScalingCheckBox, 1, 0, 1, 2);
|
cardsGrid->addWidget(&cardScalingCheckBox, 1, 0, 1, 2);
|
||||||
|
|
||||||
cardsGroupBox = new QGroupBox;
|
cardsGroupBox = new QGroupBox;
|
||||||
cardsGroupBox->setLayout(cardsGrid);
|
cardsGroupBox->setLayout(cardsGrid);
|
||||||
|
|
||||||
horizontalHandCheckBox.setChecked(settingsCache->getHorizontalHand());
|
horizontalHandCheckBox.setChecked(settingsCache->getHorizontalHand());
|
||||||
connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setHorizontalHand(int)));
|
connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setHorizontalHand(int)));
|
||||||
|
|
||||||
leftJustifiedHandCheckBox.setChecked(settingsCache->getLeftJustified());
|
leftJustifiedHandCheckBox.setChecked(settingsCache->getLeftJustified());
|
||||||
connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setLeftJustified(int)));
|
connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setLeftJustified(int)));
|
||||||
|
|
||||||
QGridLayout *handGrid = new QGridLayout;
|
auto *handGrid = new QGridLayout;
|
||||||
handGrid->addWidget(&horizontalHandCheckBox, 0, 0, 1, 2);
|
handGrid->addWidget(&horizontalHandCheckBox, 0, 0, 1, 2);
|
||||||
handGrid->addWidget(&leftJustifiedHandCheckBox, 1, 0, 1, 2);
|
handGrid->addWidget(&leftJustifiedHandCheckBox, 1, 0, 1, 2);
|
||||||
|
|
||||||
handGroupBox = new QGroupBox;
|
handGroupBox = new QGroupBox;
|
||||||
handGroupBox->setLayout(handGrid);
|
handGroupBox->setLayout(handGrid);
|
||||||
|
|
||||||
invertVerticalCoordinateCheckBox.setChecked(settingsCache->getInvertVerticalCoordinate());
|
invertVerticalCoordinateCheckBox.setChecked(settingsCache->getInvertVerticalCoordinate());
|
||||||
connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setInvertVerticalCoordinate(int)));
|
connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setInvertVerticalCoordinate(int)));
|
||||||
|
|
||||||
minPlayersForMultiColumnLayoutEdit.setMinimum(2);
|
minPlayersForMultiColumnLayoutEdit.setMinimum(2);
|
||||||
minPlayersForMultiColumnLayoutEdit.setValue(settingsCache->getMinPlayersForMultiColumnLayout());
|
minPlayersForMultiColumnLayoutEdit.setValue(settingsCache->getMinPlayersForMultiColumnLayout());
|
||||||
connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMinPlayersForMultiColumnLayout(int)));
|
connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMinPlayersForMultiColumnLayout(int)));
|
||||||
|
@ -380,22 +381,22 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||||
maxFontSizeForCardsEdit.setMinimum(9);
|
maxFontSizeForCardsEdit.setMinimum(9);
|
||||||
maxFontSizeForCardsEdit.setMaximum(100);
|
maxFontSizeForCardsEdit.setMaximum(100);
|
||||||
|
|
||||||
QGridLayout *tableGrid = new QGridLayout;
|
auto *tableGrid = new QGridLayout;
|
||||||
tableGrid->addWidget(&invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
|
tableGrid->addWidget(&invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
|
||||||
tableGrid->addWidget(&minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1);
|
tableGrid->addWidget(&minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1);
|
||||||
tableGrid->addWidget(&minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1);
|
tableGrid->addWidget(&minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1);
|
||||||
tableGrid->addWidget(&maxFontSizeForCardsLabel, 2, 0, 1, 1);
|
tableGrid->addWidget(&maxFontSizeForCardsLabel, 2, 0, 1, 1);
|
||||||
tableGrid->addWidget(&maxFontSizeForCardsEdit, 2, 1, 1, 1);
|
tableGrid->addWidget(&maxFontSizeForCardsEdit, 2, 1, 1, 1);
|
||||||
|
|
||||||
tableGroupBox = new QGroupBox;
|
tableGroupBox = new QGroupBox;
|
||||||
tableGroupBox->setLayout(tableGrid);
|
tableGroupBox->setLayout(tableGrid);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(themeGroupBox);
|
mainLayout->addWidget(themeGroupBox);
|
||||||
mainLayout->addWidget(cardsGroupBox);
|
mainLayout->addWidget(cardsGroupBox);
|
||||||
mainLayout->addWidget(handGroupBox);
|
mainLayout->addWidget(handGroupBox);
|
||||||
mainLayout->addWidget(tableGroupBox);
|
mainLayout->addWidget(tableGroupBox);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,15 +411,15 @@ void AppearanceSettingsPage::retranslateUi()
|
||||||
{
|
{
|
||||||
themeGroupBox->setTitle(tr("Theme settings"));
|
themeGroupBox->setTitle(tr("Theme settings"));
|
||||||
themeLabel.setText(tr("Current theme:"));
|
themeLabel.setText(tr("Current theme:"));
|
||||||
|
|
||||||
cardsGroupBox->setTitle(tr("Card rendering"));
|
cardsGroupBox->setTitle(tr("Card rendering"));
|
||||||
displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture"));
|
displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture"));
|
||||||
cardScalingCheckBox.setText(tr("Scale cards on mouse over"));
|
cardScalingCheckBox.setText(tr("Scale cards on mouse over"));
|
||||||
|
|
||||||
handGroupBox->setTitle(tr("Hand layout"));
|
handGroupBox->setTitle(tr("Hand layout"));
|
||||||
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
|
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
|
||||||
leftJustifiedHandCheckBox.setText(tr("Enable left justification"));
|
leftJustifiedHandCheckBox.setText(tr("Enable left justification"));
|
||||||
|
|
||||||
tableGroupBox->setTitle(tr("Table grid layout"));
|
tableGroupBox->setTitle(tr("Table grid layout"));
|
||||||
invertVerticalCoordinateCheckBox.setText(tr("Invert vertical coordinate"));
|
invertVerticalCoordinateCheckBox.setText(tr("Invert vertical coordinate"));
|
||||||
minPlayersForMultiColumnLayoutLabel.setText(tr("Minimum player count for multi-column layout:"));
|
minPlayersForMultiColumnLayoutLabel.setText(tr("Minimum player count for multi-column layout:"));
|
||||||
|
@ -437,36 +438,36 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
||||||
|
|
||||||
doubleClickToPlayCheckBox.setChecked(settingsCache->getDoubleClickToPlay());
|
doubleClickToPlayCheckBox.setChecked(settingsCache->getDoubleClickToPlay());
|
||||||
connect(&doubleClickToPlayCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setDoubleClickToPlay(int)));
|
connect(&doubleClickToPlayCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setDoubleClickToPlay(int)));
|
||||||
|
|
||||||
playToStackCheckBox.setChecked(settingsCache->getPlayToStack());
|
playToStackCheckBox.setChecked(settingsCache->getPlayToStack());
|
||||||
connect(&playToStackCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPlayToStack(int)));
|
connect(&playToStackCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPlayToStack(int)));
|
||||||
|
|
||||||
annotateTokensCheckBox.setChecked(settingsCache->getAnnotateTokens());
|
annotateTokensCheckBox.setChecked(settingsCache->getAnnotateTokens());
|
||||||
connect(&annotateTokensCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setAnnotateTokens(int)));
|
connect(&annotateTokensCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setAnnotateTokens(int)));
|
||||||
|
|
||||||
QGridLayout *generalGrid = new QGridLayout;
|
auto *generalGrid = new QGridLayout;
|
||||||
generalGrid->addWidget(¬ificationsEnabledCheckBox, 0, 0);
|
generalGrid->addWidget(¬ificationsEnabledCheckBox, 0, 0);
|
||||||
generalGrid->addWidget(&specNotificationsEnabledCheckBox, 1, 0);
|
generalGrid->addWidget(&specNotificationsEnabledCheckBox, 1, 0);
|
||||||
generalGrid->addWidget(&doubleClickToPlayCheckBox, 2, 0);
|
generalGrid->addWidget(&doubleClickToPlayCheckBox, 2, 0);
|
||||||
generalGrid->addWidget(&playToStackCheckBox, 3, 0);
|
generalGrid->addWidget(&playToStackCheckBox, 3, 0);
|
||||||
generalGrid->addWidget(&annotateTokensCheckBox, 4, 0);
|
generalGrid->addWidget(&annotateTokensCheckBox, 4, 0);
|
||||||
|
|
||||||
generalGroupBox = new QGroupBox;
|
generalGroupBox = new QGroupBox;
|
||||||
generalGroupBox->setLayout(generalGrid);
|
generalGroupBox->setLayout(generalGrid);
|
||||||
|
|
||||||
tapAnimationCheckBox.setChecked(settingsCache->getTapAnimation());
|
tapAnimationCheckBox.setChecked(settingsCache->getTapAnimation());
|
||||||
connect(&tapAnimationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setTapAnimation(int)));
|
connect(&tapAnimationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setTapAnimation(int)));
|
||||||
|
|
||||||
QGridLayout *animationGrid = new QGridLayout;
|
auto *animationGrid = new QGridLayout;
|
||||||
animationGrid->addWidget(&tapAnimationCheckBox, 0, 0);
|
animationGrid->addWidget(&tapAnimationCheckBox, 0, 0);
|
||||||
|
|
||||||
animationGroupBox = new QGroupBox;
|
animationGroupBox = new QGroupBox;
|
||||||
animationGroupBox->setLayout(animationGrid);
|
animationGroupBox->setLayout(animationGrid);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(generalGroupBox);
|
mainLayout->addWidget(generalGroupBox);
|
||||||
mainLayout->addWidget(animationGroupBox);
|
mainLayout->addWidget(animationGroupBox);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,25 +487,123 @@ void UserInterfaceSettingsPage::retranslateUi()
|
||||||
tapAnimationCheckBox.setText(tr("&Tap/untap animation"));
|
tapAnimationCheckBox.setText(tr("&Tap/untap animation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeckEditorSettingsPage::DeckEditorSettingsPage()
|
DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||||
{
|
{
|
||||||
QGridLayout *generalGrid = new QGridLayout;
|
auto *lpGeneralGrid = new QGridLayout;
|
||||||
|
auto *lpSpoilerGrid = new QGridLayout;
|
||||||
generalGrid->addWidget(new QLabel(tr("Nothing is here... yet")), 0, 0);
|
|
||||||
|
mcDownloadSpoilersCheckBox.setChecked(settingsCache->getDownloadSpoilersStatus());
|
||||||
generalGroupBox = new QGroupBox;
|
|
||||||
generalGroupBox->setLayout(generalGrid);
|
mpSpoilerSavePathLineEdit = new QLineEdit(settingsCache->getSpoilerCardDatabasePath());
|
||||||
|
mpSpoilerSavePathLineEdit->setReadOnly(true);
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
mpSpoilerPathButton = new QPushButton("...");
|
||||||
mainLayout->addWidget(generalGroupBox);
|
connect(mpSpoilerPathButton, SIGNAL(clicked()), this, SLOT(spoilerPathButtonClicked()));
|
||||||
|
|
||||||
setLayout(mainLayout);
|
updateNowButton = new QPushButton(tr("Update Spoilers"));
|
||||||
|
connect(updateNowButton, SIGNAL(clicked()), this, SLOT(updateSpoilers()));
|
||||||
|
|
||||||
|
// Update the GUI depending on if the box is ticked or not
|
||||||
|
setSpoilersEnabled(mcDownloadSpoilersCheckBox.isChecked());
|
||||||
|
|
||||||
|
// Create the layout
|
||||||
|
lpGeneralGrid->addWidget(&mcGeneralMessageLabel, 0, 0);
|
||||||
|
|
||||||
|
lpSpoilerGrid->addWidget(&mcDownloadSpoilersCheckBox, 0, 0);
|
||||||
|
lpSpoilerGrid->addWidget(updateNowButton, 0, 2);
|
||||||
|
lpSpoilerGrid->addWidget(&mcSpoilerSaveLabel, 1, 0);
|
||||||
|
lpSpoilerGrid->addWidget(mpSpoilerSavePathLineEdit, 1, 1);
|
||||||
|
lpSpoilerGrid->addWidget(mpSpoilerPathButton, 1, 2);
|
||||||
|
lpSpoilerGrid->addWidget(&infoOnSpoilersLabel, 2, 0, 1, 3, Qt::AlignTop);
|
||||||
|
|
||||||
|
// On a change to the check box, hide/unhide the other fields
|
||||||
|
connect(&mcDownloadSpoilersCheckBox, SIGNAL(toggled(bool)), settingsCache, SLOT(setDownloadSpoilerStatus(bool)));
|
||||||
|
connect(&mcDownloadSpoilersCheckBox, SIGNAL(toggled(bool)), this, SLOT(setSpoilersEnabled(bool)));
|
||||||
|
|
||||||
|
mpGeneralGroupBox = new QGroupBox;
|
||||||
|
mpGeneralGroupBox->setLayout(lpGeneralGrid);
|
||||||
|
|
||||||
|
mpSpoilerGroupBox = new QGroupBox;
|
||||||
|
mpSpoilerGroupBox->setLayout(lpSpoilerGrid);
|
||||||
|
|
||||||
|
auto *lpMainLayout = new QVBoxLayout;
|
||||||
|
lpMainLayout->addWidget(mpGeneralGroupBox);
|
||||||
|
lpMainLayout->addWidget(mpSpoilerGroupBox);
|
||||||
|
|
||||||
|
setLayout(lpMainLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorSettingsPage::updateSpoilers()
|
||||||
|
{
|
||||||
|
// Disable the button so the user can only press it once at a time
|
||||||
|
updateNowButton->setDisabled(true);
|
||||||
|
updateNowButton->setText(tr("Updating Spoilers"));
|
||||||
|
|
||||||
|
// Create a new SBU that will act as if the client was just reloaded
|
||||||
|
auto *sbu = new SpoilerBackgroundUpdater();
|
||||||
|
connect(sbu, SIGNAL(spoilerCheckerDone()), this, SLOT(unlockSettings()));
|
||||||
|
connect(sbu, SIGNAL(spoilersUpdatedSuccessfully()), this, SLOT(unlockSettings()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorSettingsPage::unlockSettings()
|
||||||
|
{
|
||||||
|
updateNowButton->setDisabled(false);
|
||||||
|
updateNowButton->setText(tr("Update Spoilers"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeckEditorSettingsPage::getLastUpdateTime()
|
||||||
|
{
|
||||||
|
QString fileName = settingsCache->getSpoilerCardDatabasePath();
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDir fileDir(fi.path());
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return fi.lastModified().toString("MMM d, hh:mm");
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorSettingsPage::spoilerPathButtonClicked()
|
||||||
|
{
|
||||||
|
QString lsPath = QFileDialog::getExistingDirectory(this, tr("Choose path"));
|
||||||
|
if (lsPath.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpSpoilerSavePathLineEdit->setText(lsPath + "/spoiler.xml");
|
||||||
|
settingsCache->setSpoilerDatabasePath(lsPath + "/spoiler.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorSettingsPage::setSpoilersEnabled(bool anInput)
|
||||||
|
{
|
||||||
|
msDownloadSpoilersLabel.setEnabled(anInput);
|
||||||
|
mcSpoilerSaveLabel.setEnabled(anInput);
|
||||||
|
mpSpoilerSavePathLineEdit->setEnabled(anInput);
|
||||||
|
mpSpoilerPathButton->setEnabled(anInput);
|
||||||
|
updateNowButton->setEnabled(anInput);
|
||||||
|
infoOnSpoilersLabel.setEnabled(anInput);
|
||||||
|
|
||||||
|
if (! anInput)
|
||||||
|
{
|
||||||
|
SpoilerBackgroundUpdater::deleteSpoilerFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckEditorSettingsPage::retranslateUi()
|
void DeckEditorSettingsPage::retranslateUi()
|
||||||
{
|
{
|
||||||
generalGroupBox->setTitle(tr("General"));
|
mpSpoilerGroupBox->setTitle(tr("Spoilers"));
|
||||||
|
mcDownloadSpoilersCheckBox.setText(tr("Download Spoilers Automatically"));
|
||||||
|
mcSpoilerSaveLabel.setText(tr("Spoiler Location:"));
|
||||||
|
mcGeneralMessageLabel.setText(tr("Hey, something's here finally!"));
|
||||||
|
infoOnSpoilersLabel.setText(
|
||||||
|
tr("Last Updated") + ": " + getLastUpdateTime() + "\n\n" +
|
||||||
|
tr("Spoilers download automatically on launch") + "\n" +
|
||||||
|
tr("Press the button to manually update without relaunching") + "\n\n" +
|
||||||
|
tr("Do not close settings until manual update complete")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesSettingsPage::MessagesSettingsPage()
|
MessagesSettingsPage::MessagesSettingsPage()
|
||||||
|
@ -514,12 +613,12 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||||
|
|
||||||
chatMentionCompleterCheckbox.setChecked(settingsCache->getChatMentionCompleter());
|
chatMentionCompleterCheckbox.setChecked(settingsCache->getChatMentionCompleter());
|
||||||
connect(&chatMentionCompleterCheckbox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setChatMentionCompleter(int)));
|
connect(&chatMentionCompleterCheckbox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setChatMentionCompleter(int)));
|
||||||
|
|
||||||
ignoreUnregUsersMainChat.setChecked(settingsCache->getIgnoreUnregisteredUsers());
|
ignoreUnregUsersMainChat.setChecked(settingsCache->getIgnoreUnregisteredUsers());
|
||||||
ignoreUnregUserMessages.setChecked(settingsCache->getIgnoreUnregisteredUserMessages());
|
ignoreUnregUserMessages.setChecked(settingsCache->getIgnoreUnregisteredUserMessages());
|
||||||
connect(&ignoreUnregUsersMainChat, SIGNAL(stateChanged(int)), settingsCache, SLOT(setIgnoreUnregisteredUsers(int)));
|
connect(&ignoreUnregUsersMainChat, SIGNAL(stateChanged(int)), settingsCache, SLOT(setIgnoreUnregisteredUsers(int)));
|
||||||
connect(&ignoreUnregUserMessages, SIGNAL(stateChanged(int)), settingsCache, SLOT(setIgnoreUnregisteredUserMessages(int)));
|
connect(&ignoreUnregUserMessages, SIGNAL(stateChanged(int)), settingsCache, SLOT(setIgnoreUnregisteredUserMessages(int)));
|
||||||
|
|
||||||
invertMentionForeground.setChecked(settingsCache->getChatMentionForeground());
|
invertMentionForeground.setChecked(settingsCache->getChatMentionForeground());
|
||||||
connect(&invertMentionForeground, SIGNAL(stateChanged(int)), this, SLOT(updateTextColor(int)));
|
connect(&invertMentionForeground, SIGNAL(stateChanged(int)), this, SLOT(updateTextColor(int)));
|
||||||
|
|
||||||
|
@ -545,7 +644,7 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||||
customAlertString->setText(settingsCache->getHighlightWords());
|
customAlertString->setText(settingsCache->getHighlightWords());
|
||||||
connect(customAlertString, SIGNAL(textChanged(QString)), settingsCache, SLOT(setHighlightWords(QString)));
|
connect(customAlertString, SIGNAL(textChanged(QString)), settingsCache, SLOT(setHighlightWords(QString)));
|
||||||
|
|
||||||
QGridLayout *chatGrid = new QGridLayout;
|
auto *chatGrid = new QGridLayout;
|
||||||
chatGrid->addWidget(&chatMentionCheckBox, 0, 0);
|
chatGrid->addWidget(&chatMentionCheckBox, 0, 0);
|
||||||
chatGrid->addWidget(&invertMentionForeground, 0, 1);
|
chatGrid->addWidget(&invertMentionForeground, 0, 1);
|
||||||
chatGrid->addWidget(mentionColor, 0, 2);
|
chatGrid->addWidget(mentionColor, 0, 2);
|
||||||
|
@ -558,13 +657,13 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||||
chatGrid->addWidget(&roomHistory, 6, 0);
|
chatGrid->addWidget(&roomHistory, 6, 0);
|
||||||
chatGroupBox = new QGroupBox;
|
chatGroupBox = new QGroupBox;
|
||||||
chatGroupBox->setLayout(chatGrid);
|
chatGroupBox->setLayout(chatGrid);
|
||||||
|
|
||||||
highlightColor = new QLineEdit();
|
highlightColor = new QLineEdit();
|
||||||
highlightColor->setText(settingsCache->getChatHighlightColor());
|
highlightColor->setText(settingsCache->getChatHighlightColor());
|
||||||
updateHighlightPreview();
|
updateHighlightPreview();
|
||||||
connect(highlightColor, SIGNAL(textChanged(QString)), this, SLOT(updateHighlightColor(QString)));
|
connect(highlightColor, SIGNAL(textChanged(QString)), this, SLOT(updateHighlightColor(QString)));
|
||||||
|
|
||||||
QGridLayout *highlightNotice = new QGridLayout;
|
auto *highlightNotice = new QGridLayout;
|
||||||
highlightNotice->addWidget(highlightColor, 0, 2);
|
highlightNotice->addWidget(highlightColor, 0, 2);
|
||||||
highlightNotice->addWidget(&invertHighlightForeground, 0, 1);
|
highlightNotice->addWidget(&invertHighlightForeground, 0, 1);
|
||||||
highlightNotice->addWidget(&hexHighlightLabel, 1, 2);
|
highlightNotice->addWidget(&hexHighlightLabel, 1, 2);
|
||||||
|
@ -578,7 +677,7 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||||
int count = settingsCache->messages().getCount();
|
int count = settingsCache->messages().getCount();
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
messageList->addItem(settingsCache->messages().getMessageAt(i));
|
messageList->addItem(settingsCache->messages().getMessageAt(i));
|
||||||
|
|
||||||
aAdd = new QAction(this);
|
aAdd = new QAction(this);
|
||||||
aAdd->setIcon(QPixmap("theme:icons/increment"));
|
aAdd->setIcon(QPixmap("theme:icons/increment"));
|
||||||
connect(aAdd, SIGNAL(triggered()), this, SLOT(actAdd()));
|
connect(aAdd, SIGNAL(triggered()), this, SLOT(actAdd()));
|
||||||
|
@ -586,30 +685,31 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||||
aRemove->setIcon(QPixmap("theme:icons/decrement"));
|
aRemove->setIcon(QPixmap("theme:icons/decrement"));
|
||||||
connect(aRemove, SIGNAL(triggered()), this, SLOT(actRemove()));
|
connect(aRemove, SIGNAL(triggered()), this, SLOT(actRemove()));
|
||||||
|
|
||||||
QToolBar *messageToolBar = new QToolBar;
|
auto *messageToolBar = new QToolBar;
|
||||||
messageToolBar->setOrientation(Qt::Vertical);
|
messageToolBar->setOrientation(Qt::Vertical);
|
||||||
messageToolBar->addAction(aAdd);
|
messageToolBar->addAction(aAdd);
|
||||||
messageToolBar->addAction(aRemove);
|
messageToolBar->addAction(aRemove);
|
||||||
|
|
||||||
QHBoxLayout *messageListLayout = new QHBoxLayout;
|
auto *messageListLayout = new QHBoxLayout;
|
||||||
messageListLayout->addWidget(messageToolBar);
|
messageListLayout->addWidget(messageToolBar);
|
||||||
messageListLayout->addWidget(messageList);
|
messageListLayout->addWidget(messageList);
|
||||||
|
|
||||||
messageShortcuts = new QGroupBox;
|
messageShortcuts = new QGroupBox;
|
||||||
messageShortcuts->setLayout(messageListLayout);
|
messageShortcuts->setLayout(messageListLayout);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
|
|
||||||
mainLayout->addWidget(messageShortcuts);
|
mainLayout->addWidget(messageShortcuts);
|
||||||
mainLayout->addWidget(chatGroupBox);
|
mainLayout->addWidget(chatGroupBox);
|
||||||
mainLayout->addWidget(highlightGroupBox);
|
mainLayout->addWidget(highlightGroupBox);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateColor(const QString &value) {
|
void MessagesSettingsPage::updateColor(const QString &value)
|
||||||
|
{
|
||||||
QColor colorToSet;
|
QColor colorToSet;
|
||||||
colorToSet.setNamedColor("#" + value);
|
colorToSet.setNamedColor("#" + value);
|
||||||
if (colorToSet.isValid()) {
|
if (colorToSet.isValid()) {
|
||||||
|
@ -618,7 +718,8 @@ void MessagesSettingsPage::updateColor(const QString &value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateHighlightColor(const QString &value) {
|
void MessagesSettingsPage::updateHighlightColor(const QString &value)
|
||||||
|
{
|
||||||
QColor colorToSet;
|
QColor colorToSet;
|
||||||
colorToSet.setNamedColor("#" + value);
|
colorToSet.setNamedColor("#" + value);
|
||||||
if (colorToSet.isValid()) {
|
if (colorToSet.isValid()) {
|
||||||
|
@ -627,22 +728,26 @@ void MessagesSettingsPage::updateHighlightColor(const QString &value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateTextColor(int value) {
|
void MessagesSettingsPage::updateTextColor(int value)
|
||||||
|
{
|
||||||
settingsCache->setChatMentionForeground(value);
|
settingsCache->setChatMentionForeground(value);
|
||||||
updateMentionPreview();
|
updateMentionPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateTextHighlightColor(int value) {
|
void MessagesSettingsPage::updateTextHighlightColor(int value)
|
||||||
|
{
|
||||||
settingsCache->setChatHighlightForeground(value);
|
settingsCache->setChatHighlightForeground(value);
|
||||||
updateHighlightPreview();
|
updateHighlightPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateMentionPreview() {
|
void MessagesSettingsPage::updateMentionPreview()
|
||||||
mentionColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatMentionColor() +
|
{
|
||||||
|
mentionColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatMentionColor() +
|
||||||
";color: " + (settingsCache->getChatMentionForeground() ? "white" : "black") + ";}");
|
";color: " + (settingsCache->getChatMentionForeground() ? "white" : "black") + ";}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesSettingsPage::updateHighlightPreview() {
|
void MessagesSettingsPage::updateHighlightPreview()
|
||||||
|
{
|
||||||
highlightColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatHighlightColor() +
|
highlightColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatHighlightColor() +
|
||||||
";color: " + (settingsCache->getChatHighlightForeground() ? "white" : "black") + ";}");
|
";color: " + (settingsCache->getChatHighlightForeground() ? "white" : "black") + ";}");
|
||||||
}
|
}
|
||||||
|
@ -725,7 +830,7 @@ SoundSettingsPage::SoundSettingsPage()
|
||||||
connect(masterVolumeSlider, SIGNAL(valueChanged(int)), masterVolumeSpinBox, SLOT(setValue(int)));
|
connect(masterVolumeSlider, SIGNAL(valueChanged(int)), masterVolumeSpinBox, SLOT(setValue(int)));
|
||||||
connect(masterVolumeSpinBox, SIGNAL(valueChanged(int)), masterVolumeSlider, SLOT(setValue(int)));
|
connect(masterVolumeSpinBox, SIGNAL(valueChanged(int)), masterVolumeSlider, SLOT(setValue(int)));
|
||||||
|
|
||||||
QGridLayout *soundGrid = new QGridLayout;
|
auto *soundGrid = new QGridLayout;
|
||||||
soundGrid->addWidget(&soundEnabledCheckBox, 0, 0, 1, 3);
|
soundGrid->addWidget(&soundEnabledCheckBox, 0, 0, 1, 3);
|
||||||
soundGrid->addWidget(&masterVolumeLabel, 1, 0);
|
soundGrid->addWidget(&masterVolumeLabel, 1, 0);
|
||||||
soundGrid->addWidget(masterVolumeSlider, 1, 1);
|
soundGrid->addWidget(masterVolumeSlider, 1, 1);
|
||||||
|
@ -737,7 +842,7 @@ SoundSettingsPage::SoundSettingsPage()
|
||||||
soundGroupBox = new QGroupBox;
|
soundGroupBox = new QGroupBox;
|
||||||
soundGroupBox->setLayout(soundGrid);
|
soundGroupBox->setLayout(soundGrid);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(soundGroupBox);
|
mainLayout->addWidget(soundGroupBox);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
@ -750,27 +855,28 @@ void SoundSettingsPage::themeBoxChanged(int index)
|
||||||
settingsCache->setSoundThemeName(themeDirs.at(index));
|
settingsCache->setSoundThemeName(themeDirs.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSettingsPage::masterVolumeChanged(int value) {
|
void SoundSettingsPage::masterVolumeChanged(int value)
|
||||||
|
{
|
||||||
masterVolumeSlider->setToolTip(QString::number(value));
|
masterVolumeSlider->setToolTip(QString::number(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSettingsPage::retranslateUi() {
|
void SoundSettingsPage::retranslateUi()
|
||||||
|
{
|
||||||
soundEnabledCheckBox.setText(tr("Enable &sounds"));
|
soundEnabledCheckBox.setText(tr("Enable &sounds"));
|
||||||
themeLabel.setText(tr("Current sounds theme:"));
|
themeLabel.setText(tr("Current sounds theme:"));
|
||||||
soundTestButton.setText(tr("Test system sound engine"));
|
soundTestButton.setText(tr("Test system sound engine"));
|
||||||
soundGroupBox->setTitle(tr("Sound settings"));
|
soundGroupBox->setTitle(tr("Sound settings"));
|
||||||
masterVolumeLabel.setText(tr("Master volume"));
|
masterVolumeLabel.setText(tr("Master volume"));
|
||||||
}
|
}
|
||||||
|
|
||||||
DlgSettings::DlgSettings(QWidget *parent)
|
DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
||||||
: QDialog(parent)
|
|
||||||
{
|
{
|
||||||
QRect rec = QApplication::desktop()->availableGeometry();
|
QRect rec = QApplication::desktop()->availableGeometry();
|
||||||
this->setMinimumSize(rec.width() / 2, rec.height() - 100);
|
this->setMinimumSize(rec.width() / 2, rec.height() - 100);
|
||||||
this->setBaseSize(rec.width(), rec.height());
|
this->setBaseSize(rec.width(), rec.height());
|
||||||
|
|
||||||
connect(settingsCache, SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
connect(settingsCache, SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
||||||
|
|
||||||
contentsWidget = new QListWidget;
|
contentsWidget = new QListWidget;
|
||||||
contentsWidget->setViewMode(QListView::IconMode);
|
contentsWidget->setViewMode(QListView::IconMode);
|
||||||
contentsWidget->setIconSize(QSize(58, 50));
|
contentsWidget->setIconSize(QSize(58, 50));
|
||||||
|
@ -778,7 +884,7 @@ DlgSettings::DlgSettings(QWidget *parent)
|
||||||
contentsWidget->setMinimumHeight(85);
|
contentsWidget->setMinimumHeight(85);
|
||||||
contentsWidget->setMaximumHeight(85);
|
contentsWidget->setMaximumHeight(85);
|
||||||
contentsWidget->setSpacing(5);
|
contentsWidget->setSpacing(5);
|
||||||
|
|
||||||
pagesWidget = new QStackedWidget;
|
pagesWidget = new QStackedWidget;
|
||||||
pagesWidget->addWidget(new GeneralSettingsPage);
|
pagesWidget->addWidget(new GeneralSettingsPage);
|
||||||
pagesWidget->addWidget(new AppearanceSettingsPage);
|
pagesWidget->addWidget(new AppearanceSettingsPage);
|
||||||
|
@ -787,25 +893,25 @@ DlgSettings::DlgSettings(QWidget *parent)
|
||||||
pagesWidget->addWidget(new MessagesSettingsPage);
|
pagesWidget->addWidget(new MessagesSettingsPage);
|
||||||
pagesWidget->addWidget(new SoundSettingsPage);
|
pagesWidget->addWidget(new SoundSettingsPage);
|
||||||
pagesWidget->addWidget(new ShortcutsTab);
|
pagesWidget->addWidget(new ShortcutsTab);
|
||||||
|
|
||||||
createIcons();
|
createIcons();
|
||||||
contentsWidget->setCurrentRow(0);
|
contentsWidget->setCurrentRow(0);
|
||||||
|
|
||||||
QVBoxLayout *vboxLayout = new QVBoxLayout;
|
auto *vboxLayout = new QVBoxLayout;
|
||||||
vboxLayout->addWidget(contentsWidget);
|
vboxLayout->addWidget(contentsWidget);
|
||||||
vboxLayout->addWidget(pagesWidget);
|
vboxLayout->addWidget(pagesWidget);
|
||||||
|
|
||||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(vboxLayout);
|
mainLayout->addLayout(vboxLayout);
|
||||||
mainLayout->addSpacing(12);
|
mainLayout->addSpacing(12);
|
||||||
mainLayout->addWidget(buttonBox);
|
mainLayout->addWidget(buttonBox);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,22 +921,22 @@ void DlgSettings::createIcons()
|
||||||
generalButton->setTextAlignment(Qt::AlignHCenter);
|
generalButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
generalButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
generalButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
generalButton->setIcon(QPixmap("theme:config/general"));
|
generalButton->setIcon(QPixmap("theme:config/general"));
|
||||||
|
|
||||||
appearanceButton = new QListWidgetItem(contentsWidget);
|
appearanceButton = new QListWidgetItem(contentsWidget);
|
||||||
appearanceButton->setTextAlignment(Qt::AlignHCenter);
|
appearanceButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
appearanceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
appearanceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
appearanceButton->setIcon(QPixmap("theme:config/appearance"));
|
appearanceButton->setIcon(QPixmap("theme:config/appearance"));
|
||||||
|
|
||||||
userInterfaceButton = new QListWidgetItem(contentsWidget);
|
userInterfaceButton = new QListWidgetItem(contentsWidget);
|
||||||
userInterfaceButton->setTextAlignment(Qt::AlignHCenter);
|
userInterfaceButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
userInterfaceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
userInterfaceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
userInterfaceButton->setIcon(QPixmap("theme:config/interface"));
|
userInterfaceButton->setIcon(QPixmap("theme:config/interface"));
|
||||||
|
|
||||||
deckEditorButton = new QListWidgetItem(contentsWidget);
|
deckEditorButton = new QListWidgetItem(contentsWidget);
|
||||||
deckEditorButton->setTextAlignment(Qt::AlignHCenter);
|
deckEditorButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
deckEditorButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
deckEditorButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
deckEditorButton->setIcon(QPixmap("theme:config/deckeditor"));
|
deckEditorButton->setIcon(QPixmap("theme:config/deckeditor"));
|
||||||
|
|
||||||
messagesButton = new QListWidgetItem(contentsWidget);
|
messagesButton = new QListWidgetItem(contentsWidget);
|
||||||
messagesButton->setTextAlignment(Qt::AlignHCenter);
|
messagesButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
messagesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
messagesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
@ -840,7 +946,7 @@ void DlgSettings::createIcons()
|
||||||
soundButton->setTextAlignment(Qt::AlignHCenter);
|
soundButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
soundButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
soundButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
soundButton->setIcon(QPixmap("theme:config/sound"));
|
soundButton->setIcon(QPixmap("theme:config/sound"));
|
||||||
|
|
||||||
shortcutsButton = new QListWidgetItem(contentsWidget);
|
shortcutsButton = new QListWidgetItem(contentsWidget);
|
||||||
shortcutsButton->setTextAlignment(Qt::AlignHCenter);
|
shortcutsButton->setTextAlignment(Qt::AlignHCenter);
|
||||||
shortcutsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
shortcutsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
@ -853,11 +959,12 @@ void DlgSettings::changePage(QListWidgetItem *current, QListWidgetItem *previous
|
||||||
{
|
{
|
||||||
if (!current)
|
if (!current)
|
||||||
current = previous;
|
current = previous;
|
||||||
|
|
||||||
pagesWidget->setCurrentIndex(contentsWidget->row(current));
|
pagesWidget->setCurrentIndex(contentsWidget->row(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DlgSettings::setTab(int index) {
|
void DlgSettings::setTab(int index)
|
||||||
|
{
|
||||||
if (index <= contentsWidget->count()-1 && index >= 0) {
|
if (index <= contentsWidget->count()-1 && index >= 0) {
|
||||||
changePage(contentsWidget->item(index), contentsWidget->currentItem());
|
changePage(contentsWidget->item(index), contentsWidget->currentItem());
|
||||||
contentsWidget->setCurrentRow(index);
|
contentsWidget->setCurrentRow(index);
|
||||||
|
@ -883,72 +990,86 @@ void DlgSettings::closeEvent(QCloseEvent *event)
|
||||||
QString loadErrorMessage = tr("Unknown Error loading card database");
|
QString loadErrorMessage = tr("Unknown Error loading card database");
|
||||||
LoadStatus loadStatus = db->getLoadStatus();
|
LoadStatus loadStatus = db->getLoadStatus();
|
||||||
qDebug() << "Card Database load status: " << loadStatus;
|
qDebug() << "Card Database load status: " << loadStatus;
|
||||||
switch(loadStatus) {
|
switch(loadStatus)
|
||||||
case Ok:
|
{
|
||||||
showLoadError = false;
|
case Ok:
|
||||||
break;
|
showLoadError = false;
|
||||||
case Invalid:
|
break;
|
||||||
loadErrorMessage =
|
case Invalid:
|
||||||
tr("Your card database is invalid.\n\n"
|
loadErrorMessage =
|
||||||
"Cockatrice may not function correctly with an invalid database\n\n"
|
tr("Your card database is invalid.\n\n"
|
||||||
"You may need to rerun oracle to update your card database.\n\n"
|
"Cockatrice may not function correctly with an invalid database\n\n"
|
||||||
"Would you like to change your database location setting?");
|
"You may need to rerun oracle to update your card database.\n\n"
|
||||||
break;
|
"Would you like to change your database location setting?");
|
||||||
case VersionTooOld:
|
break;
|
||||||
loadErrorMessage =
|
case VersionTooOld:
|
||||||
tr("Your card database version is too old.\n\n"
|
loadErrorMessage =
|
||||||
"This can cause problems loading card information or images\n\n"
|
tr("Your card database version is too old.\n\n"
|
||||||
"Usually this can be fixed by rerunning oracle to to update your card database.\n\n"
|
"This can cause problems loading card information or images\n\n"
|
||||||
"Would you like to change your database location setting?");
|
"Usually this can be fixed by rerunning oracle to to update your card database.\n\n"
|
||||||
break;
|
"Would you like to change your database location setting?");
|
||||||
case NotLoaded:
|
break;
|
||||||
loadErrorMessage =
|
case NotLoaded:
|
||||||
tr("Your card database did not finish loading\n\n"
|
loadErrorMessage =
|
||||||
"Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached\n\n"
|
tr("Your card database did not finish loading\n\n"
|
||||||
"Would you like to change your database location setting?");
|
"Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached\n\n"
|
||||||
break;
|
"Would you like to change your database location setting?");
|
||||||
case FileError:
|
break;
|
||||||
loadErrorMessage =
|
case FileError:
|
||||||
tr("File Error loading your card database.\n\n"
|
loadErrorMessage =
|
||||||
"Would you like to change your database location setting?");
|
tr("File Error loading your card database.\n\n"
|
||||||
break;
|
"Would you like to change your database location setting?");
|
||||||
case NoCards:
|
break;
|
||||||
loadErrorMessage =
|
case NoCards:
|
||||||
tr("Your card database was loaded but contains no cards.\n\n"
|
loadErrorMessage =
|
||||||
"Would you like to change your database location setting?");
|
tr("Your card database was loaded but contains no cards.\n\n"
|
||||||
break;
|
"Would you like to change your database location setting?");
|
||||||
default:
|
break;
|
||||||
loadErrorMessage =
|
default:
|
||||||
tr("Unknown card database load status\n\n"
|
loadErrorMessage =
|
||||||
"Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues\n\n"
|
tr("Unknown card database load status\n\n"
|
||||||
"Would you like to change your database location setting?");
|
"Please file a ticket at http://github.com/Cockatrice/Cockatrice/issues\n\n"
|
||||||
|
"Would you like to change your database location setting?");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showLoadError)
|
if (showLoadError)
|
||||||
if (QMessageBox::critical(this, tr("Error"), loadErrorMessage, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
{
|
||||||
|
if (QMessageBox::critical(this, tr("Error"), loadErrorMessage, QMessageBox::Yes | QMessageBox::No) ==
|
||||||
|
QMessageBox::Yes)
|
||||||
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!QDir(settingsCache->getDeckPath()).exists() || settingsCache->getDeckPath().isEmpty())
|
if (!QDir(settingsCache->getDeckPath()).exists() || settingsCache->getDeckPath().isEmpty())
|
||||||
|
{
|
||||||
// TODO: Prompt to create it
|
// TODO: Prompt to create it
|
||||||
if (QMessageBox::critical(this, tr("Error"), tr("The path to your deck directory is invalid. Would you like to go back and set the correct path?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
if (QMessageBox::critical(this, tr("Error"), tr("The path to your deck directory is invalid. Would you like to go back and set the correct path?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
|
||||||
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!QDir(settingsCache->getPicsPath()).exists() || settingsCache->getPicsPath().isEmpty())
|
if (!QDir(settingsCache->getPicsPath()).exists() || settingsCache->getPicsPath().isEmpty())
|
||||||
|
{
|
||||||
// TODO: Prompt to create it
|
// TODO: Prompt to create it
|
||||||
if (QMessageBox::critical(this, tr("Error"), tr("The path to your card pictures directory is invalid. Would you like to go back and set the correct path?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
if (QMessageBox::critical(this, tr("Error"), tr("The path to your card pictures directory is invalid. Would you like to go back and set the correct path?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
|
||||||
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DlgSettings::retranslateUi()
|
void DlgSettings::retranslateUi()
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Settings"));
|
setWindowTitle(tr("Settings"));
|
||||||
|
|
||||||
generalButton->setText(tr("General"));
|
generalButton->setText(tr("General"));
|
||||||
appearanceButton->setText(tr("Appearance"));
|
appearanceButton->setText(tr("Appearance"));
|
||||||
userInterfaceButton->setText(tr("User Interface"));
|
userInterfaceButton->setText(tr("User Interface"));
|
||||||
|
@ -956,10 +1077,9 @@ void DlgSettings::retranslateUi()
|
||||||
messagesButton->setText(tr("Chat"));
|
messagesButton->setText(tr("Chat"));
|
||||||
soundButton->setText(tr("Sound"));
|
soundButton->setText(tr("Sound"));
|
||||||
shortcutsButton->setText(tr("Shortcuts"));
|
shortcutsButton->setText(tr("Shortcuts"));
|
||||||
|
|
||||||
for (int i = 0; i < pagesWidget->count(); i++)
|
for (int i = 0; i < pagesWidget->count(); i++)
|
||||||
dynamic_cast<AbstractSettingsPage *>(pagesWidget->widget(i))->retranslateUi();
|
dynamic_cast<AbstractSettingsPage *>(pagesWidget->widget(i))->retranslateUi();
|
||||||
|
|
||||||
contentsWidget->reset();
|
contentsWidget->reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,192 +26,227 @@ class QSpinBox;
|
||||||
class QSlider;
|
class QSlider;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
|
|
||||||
class AbstractSettingsPage : public QWidget {
|
class AbstractSettingsPage : public QWidget
|
||||||
public:
|
{
|
||||||
virtual void retranslateUi() = 0;
|
public:
|
||||||
|
virtual void retranslateUi() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GeneralSettingsPage : public AbstractSettingsPage {
|
class GeneralSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
GeneralSettingsPage();
|
GeneralSettingsPage();
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private slots:
|
|
||||||
void deckPathButtonClicked();
|
private slots:
|
||||||
void replaysPathButtonClicked();
|
void deckPathButtonClicked();
|
||||||
void picsPathButtonClicked();
|
void replaysPathButtonClicked();
|
||||||
void clearDownloadedPicsButtonClicked();
|
void picsPathButtonClicked();
|
||||||
void cardDatabasePathButtonClicked();
|
void clearDownloadedPicsButtonClicked();
|
||||||
void tokenDatabasePathButtonClicked();
|
void cardDatabasePathButtonClicked();
|
||||||
void languageBoxChanged(int index);
|
void tokenDatabasePathButtonClicked();
|
||||||
void setEnabledStatus(bool);
|
void languageBoxChanged(int index);
|
||||||
void defaultUrlRestoreButtonClicked();
|
void setEnabledStatus(bool);
|
||||||
void fallbackUrlRestoreButtonClicked();
|
void defaultUrlRestoreButtonClicked();
|
||||||
private:
|
void fallbackUrlRestoreButtonClicked();
|
||||||
QStringList findQmFiles();
|
|
||||||
QString languageName(const QString &qmFile);
|
private:
|
||||||
QLineEdit *deckPathEdit;
|
QStringList findQmFiles();
|
||||||
QLineEdit *replaysPathEdit;
|
QString languageName(const QString &qmFile);
|
||||||
QLineEdit *picsPathEdit;
|
QLineEdit *deckPathEdit;
|
||||||
QLineEdit *cardDatabasePathEdit;
|
QLineEdit *replaysPathEdit;
|
||||||
QLineEdit *tokenDatabasePathEdit;
|
QLineEdit *picsPathEdit;
|
||||||
QLineEdit *defaultUrlEdit;
|
QLineEdit *cardDatabasePathEdit;
|
||||||
QLineEdit *fallbackUrlEdit;
|
QLineEdit *tokenDatabasePathEdit;
|
||||||
QSpinBox pixmapCacheEdit;
|
QLineEdit *defaultUrlEdit;
|
||||||
QGroupBox *personalGroupBox;
|
QLineEdit *fallbackUrlEdit;
|
||||||
QGroupBox *pathsGroupBox;
|
QSpinBox pixmapCacheEdit;
|
||||||
QComboBox languageBox;
|
QGroupBox *personalGroupBox;
|
||||||
QCheckBox picDownloadCheckBox;
|
QGroupBox *pathsGroupBox;
|
||||||
QCheckBox updateNotificationCheckBox;
|
QComboBox languageBox;
|
||||||
QComboBox updateReleaseChannelBox;
|
QCheckBox picDownloadCheckBox;
|
||||||
QLabel languageLabel;
|
QCheckBox updateNotificationCheckBox;
|
||||||
QLabel pixmapCacheLabel;
|
QComboBox updateReleaseChannelBox;
|
||||||
QLabel deckPathLabel;
|
QLabel languageLabel;
|
||||||
QLabel replaysPathLabel;
|
QLabel pixmapCacheLabel;
|
||||||
QLabel picsPathLabel;
|
QLabel deckPathLabel;
|
||||||
QLabel cardDatabasePathLabel;
|
QLabel replaysPathLabel;
|
||||||
QLabel tokenDatabasePathLabel;
|
QLabel picsPathLabel;
|
||||||
QLabel defaultUrlLabel;
|
QLabel cardDatabasePathLabel;
|
||||||
QLabel fallbackUrlLabel;
|
QLabel tokenDatabasePathLabel;
|
||||||
QLabel urlLinkLabel;
|
QLabel defaultUrlLabel;
|
||||||
QLabel updateReleaseChannelLabel;
|
QLabel fallbackUrlLabel;
|
||||||
QPushButton clearDownloadedPicsButton;
|
QLabel urlLinkLabel;
|
||||||
QPushButton defaultUrlRestoreButton;
|
QLabel updateReleaseChannelLabel;
|
||||||
QPushButton fallbackUrlRestoreButton;
|
QPushButton clearDownloadedPicsButton;
|
||||||
|
QPushButton defaultUrlRestoreButton;
|
||||||
|
QPushButton fallbackUrlRestoreButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppearanceSettingsPage : public AbstractSettingsPage {
|
class AppearanceSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void themeBoxChanged(int index);
|
void themeBoxChanged(int index);
|
||||||
private:
|
|
||||||
QLabel themeLabel;
|
private:
|
||||||
QComboBox themeBox;
|
QLabel themeLabel;
|
||||||
QLabel minPlayersForMultiColumnLayoutLabel;
|
QComboBox themeBox;
|
||||||
QLabel maxFontSizeForCardsLabel;
|
QLabel minPlayersForMultiColumnLayoutLabel;
|
||||||
QCheckBox displayCardNamesCheckBox;
|
QLabel maxFontSizeForCardsLabel;
|
||||||
QCheckBox cardScalingCheckBox;
|
QCheckBox displayCardNamesCheckBox;
|
||||||
QCheckBox horizontalHandCheckBox;
|
QCheckBox cardScalingCheckBox;
|
||||||
QCheckBox leftJustifiedHandCheckBox;
|
QCheckBox horizontalHandCheckBox;
|
||||||
QCheckBox invertVerticalCoordinateCheckBox;
|
QCheckBox leftJustifiedHandCheckBox;
|
||||||
QGroupBox *themeGroupBox;
|
QCheckBox invertVerticalCoordinateCheckBox;
|
||||||
QGroupBox *cardsGroupBox;
|
QGroupBox *themeGroupBox;
|
||||||
QGroupBox *handGroupBox;
|
QGroupBox *cardsGroupBox;
|
||||||
QGroupBox *tableGroupBox;
|
QGroupBox *handGroupBox;
|
||||||
QSpinBox minPlayersForMultiColumnLayoutEdit;
|
QGroupBox *tableGroupBox;
|
||||||
QSpinBox maxFontSizeForCardsEdit;
|
QSpinBox minPlayersForMultiColumnLayoutEdit;
|
||||||
public:
|
QSpinBox maxFontSizeForCardsEdit;
|
||||||
AppearanceSettingsPage();
|
|
||||||
void retranslateUi();
|
public:
|
||||||
|
AppearanceSettingsPage();
|
||||||
|
void retranslateUi() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UserInterfaceSettingsPage : public AbstractSettingsPage {
|
class UserInterfaceSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void setSpecNotificationEnabled(int);
|
void setSpecNotificationEnabled(int);
|
||||||
private:
|
|
||||||
QCheckBox notificationsEnabledCheckBox;
|
private:
|
||||||
QCheckBox specNotificationsEnabledCheckBox;
|
QCheckBox notificationsEnabledCheckBox;
|
||||||
QCheckBox doubleClickToPlayCheckBox;
|
QCheckBox specNotificationsEnabledCheckBox;
|
||||||
QCheckBox playToStackCheckBox;
|
QCheckBox doubleClickToPlayCheckBox;
|
||||||
QCheckBox annotateTokensCheckBox;
|
QCheckBox playToStackCheckBox;
|
||||||
QCheckBox tapAnimationCheckBox;
|
QCheckBox annotateTokensCheckBox;
|
||||||
QGroupBox *generalGroupBox;
|
QCheckBox tapAnimationCheckBox;
|
||||||
QGroupBox *animationGroupBox;
|
QGroupBox *generalGroupBox;
|
||||||
|
QGroupBox *animationGroupBox;
|
||||||
public:
|
|
||||||
UserInterfaceSettingsPage();
|
public:
|
||||||
void retranslateUi();
|
UserInterfaceSettingsPage();
|
||||||
|
void retranslateUi() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeckEditorSettingsPage : public AbstractSettingsPage {
|
class DeckEditorSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DeckEditorSettingsPage();
|
DeckEditorSettingsPage();
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private slots:
|
QString getLastUpdateTime();
|
||||||
signals:
|
|
||||||
private:
|
private slots:
|
||||||
QGroupBox *generalGroupBox;
|
void setSpoilersEnabled(bool);
|
||||||
|
void spoilerPathButtonClicked();
|
||||||
|
void updateSpoilers();
|
||||||
|
void unlockSettings();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QCheckBox mcDownloadSpoilersCheckBox;
|
||||||
|
QLabel msDownloadSpoilersLabel;
|
||||||
|
QGroupBox *mpGeneralGroupBox;
|
||||||
|
QGroupBox *mpSpoilerGroupBox;
|
||||||
|
QLineEdit *mpSpoilerSavePathLineEdit;
|
||||||
|
QLabel mcSpoilerSaveLabel;
|
||||||
|
QLabel mcGeneralMessageLabel;
|
||||||
|
QLabel infoOnSpoilersLabel;
|
||||||
|
QPushButton *mpSpoilerPathButton;
|
||||||
|
QPushButton *updateNowButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessagesSettingsPage : public AbstractSettingsPage {
|
class MessagesSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MessagesSettingsPage();
|
MessagesSettingsPage();
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private slots:
|
|
||||||
void actAdd();
|
|
||||||
void actRemove();
|
|
||||||
void updateColor(const QString &value);
|
|
||||||
void updateHighlightColor(const QString &value);
|
|
||||||
void updateTextColor(int value);
|
|
||||||
void updateTextHighlightColor(int value);
|
|
||||||
private:
|
|
||||||
QListWidget *messageList;
|
|
||||||
QAction *aAdd;
|
|
||||||
QAction *aRemove;
|
|
||||||
QCheckBox chatMentionCheckBox;
|
|
||||||
QCheckBox chatMentionCompleterCheckbox;
|
|
||||||
QCheckBox invertMentionForeground;
|
|
||||||
QCheckBox invertHighlightForeground;
|
|
||||||
QCheckBox ignoreUnregUsersMainChat;
|
|
||||||
QCheckBox ignoreUnregUserMessages;
|
|
||||||
QCheckBox messagePopups;
|
|
||||||
QCheckBox mentionPopups;
|
|
||||||
QCheckBox roomHistory;
|
|
||||||
QGroupBox *chatGroupBox;
|
|
||||||
QGroupBox *highlightGroupBox;
|
|
||||||
QGroupBox *messageShortcuts;
|
|
||||||
QLineEdit *mentionColor;
|
|
||||||
QLineEdit *highlightColor;
|
|
||||||
QLineEdit *customAlertString;
|
|
||||||
QLabel hexLabel;
|
|
||||||
QLabel hexHighlightLabel;
|
|
||||||
QLabel customAlertStringLabel;
|
|
||||||
|
|
||||||
void storeSettings();
|
private slots:
|
||||||
void updateMentionPreview();
|
void actAdd();
|
||||||
void updateHighlightPreview();
|
void actRemove();
|
||||||
|
void updateColor(const QString &value);
|
||||||
|
void updateHighlightColor(const QString &value);
|
||||||
|
void updateTextColor(int value);
|
||||||
|
void updateTextHighlightColor(int value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QListWidget *messageList;
|
||||||
|
QAction *aAdd;
|
||||||
|
QAction *aRemove;
|
||||||
|
QCheckBox chatMentionCheckBox;
|
||||||
|
QCheckBox chatMentionCompleterCheckbox;
|
||||||
|
QCheckBox invertMentionForeground;
|
||||||
|
QCheckBox invertHighlightForeground;
|
||||||
|
QCheckBox ignoreUnregUsersMainChat;
|
||||||
|
QCheckBox ignoreUnregUserMessages;
|
||||||
|
QCheckBox messagePopups;
|
||||||
|
QCheckBox mentionPopups;
|
||||||
|
QCheckBox roomHistory;
|
||||||
|
QGroupBox *chatGroupBox;
|
||||||
|
QGroupBox *highlightGroupBox;
|
||||||
|
QGroupBox *messageShortcuts;
|
||||||
|
QLineEdit *mentionColor;
|
||||||
|
QLineEdit *highlightColor;
|
||||||
|
QLineEdit *customAlertString;
|
||||||
|
QLabel hexLabel;
|
||||||
|
QLabel hexHighlightLabel;
|
||||||
|
QLabel customAlertStringLabel;
|
||||||
|
|
||||||
|
void storeSettings();
|
||||||
|
void updateMentionPreview();
|
||||||
|
void updateHighlightPreview();
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoundSettingsPage : public AbstractSettingsPage {
|
class SoundSettingsPage : public AbstractSettingsPage
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SoundSettingsPage();
|
SoundSettingsPage();
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private:
|
|
||||||
QLabel themeLabel;
|
private:
|
||||||
QComboBox themeBox;
|
QLabel themeLabel;
|
||||||
QGroupBox *soundGroupBox;
|
QComboBox themeBox;
|
||||||
QPushButton soundTestButton;
|
QGroupBox *soundGroupBox;
|
||||||
QCheckBox soundEnabledCheckBox;
|
QPushButton soundTestButton;
|
||||||
QLabel masterVolumeLabel;
|
QCheckBox soundEnabledCheckBox;
|
||||||
QSlider *masterVolumeSlider;
|
QLabel masterVolumeLabel;
|
||||||
QSpinBox *masterVolumeSpinBox;
|
QSlider *masterVolumeSlider;
|
||||||
private slots:
|
QSpinBox *masterVolumeSpinBox;
|
||||||
void masterVolumeChanged(int value);
|
|
||||||
void themeBoxChanged(int index);
|
private slots:
|
||||||
|
void masterVolumeChanged(int value);
|
||||||
|
void themeBoxChanged(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DlgSettings : public QDialog {
|
class DlgSettings : public QDialog
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DlgSettings(QWidget *parent = 0);
|
explicit DlgSettings(QWidget *parent = nullptr);
|
||||||
void setTab(int index);
|
void setTab(int index);
|
||||||
private slots:
|
|
||||||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
private slots:
|
||||||
void updateLanguage();
|
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||||
private:
|
void updateLanguage();
|
||||||
QListWidget *contentsWidget;
|
|
||||||
QStackedWidget *pagesWidget;
|
private:
|
||||||
QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *messagesButton, *soundButton;
|
QListWidget *contentsWidget;
|
||||||
QListWidgetItem *shortcutsButton;
|
QStackedWidget *pagesWidget;
|
||||||
void createIcons();
|
QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *messagesButton, *soundButton;
|
||||||
void retranslateUi();
|
QListWidgetItem *shortcutsButton;
|
||||||
protected:
|
void createIcons();
|
||||||
void changeEvent(QEvent *event);
|
void retranslateUi();
|
||||||
void closeEvent(QCloseEvent *event);
|
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent *event) override;
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -42,6 +42,7 @@
|
||||||
#include "soundengine.h"
|
#include "soundengine.h"
|
||||||
#include "featureset.h"
|
#include "featureset.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "spoilerbackgroundupdater.h"
|
||||||
|
|
||||||
CardDatabase *db;
|
CardDatabase *db;
|
||||||
QTranslator *translator, *qtTranslator;
|
QTranslator *translator, *qtTranslator;
|
||||||
|
@ -129,6 +130,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
settingsCache->setClientID(generateClientID());
|
settingsCache->setClientID(generateClientID());
|
||||||
|
|
||||||
|
// If spoiler mode is enabled, we will download the spoilers
|
||||||
|
// then reload the DB. otherwise just reload the DB
|
||||||
|
SpoilerBackgroundUpdater spoilerBackgroundUpdater;
|
||||||
|
|
||||||
ui.show();
|
ui.show();
|
||||||
qDebug("main(): ui.show() finished");
|
qDebug("main(): ui.show() finished");
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ class QSystemTrayIcon;
|
||||||
class SoundEngine;
|
class SoundEngine;
|
||||||
|
|
||||||
extern CardDatabase *db;
|
extern CardDatabase *db;
|
||||||
|
|
||||||
extern QSystemTrayIcon *trayIcon;
|
extern QSystemTrayIcon *trayIcon;
|
||||||
extern QTranslator *translator;
|
extern QTranslator *translator;
|
||||||
extern const QString translationPrefix;
|
extern const QString translationPrefix;
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
#include "carddatabasesettings.h"
|
#include "carddatabasesettings.h"
|
||||||
|
|
||||||
CardDatabaseSettings::CardDatabaseSettings(QString settingPath, QObject *parent)
|
CardDatabaseSettings::CardDatabaseSettings(QString settingPath, QObject *parent) : SettingsManager(settingPath+"cardDatabase.ini", parent)
|
||||||
: SettingsManager(settingPath+"cardDatabase.ini", parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabaseSettings::setSortKey(QString shortName, unsigned int sortKey)
|
void CardDatabaseSettings::setSortKey(QString shortName, unsigned int sortKey)
|
||||||
{
|
{
|
||||||
setValue(sortKey,"sortkey", "sets", shortName);
|
setValue(sortKey, "sortkey", "sets", std::move(shortName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabaseSettings::setEnabled(QString shortName, bool enabled)
|
void CardDatabaseSettings::setEnabled(QString shortName, bool enabled)
|
||||||
{
|
{
|
||||||
setValue(enabled, "enabled", "sets", shortName);
|
setValue(enabled, "enabled", "sets", std::move(shortName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabaseSettings::setIsKnown(QString shortName, bool isknown)
|
void CardDatabaseSettings::setIsKnown(QString shortName, bool isknown)
|
||||||
{
|
{
|
||||||
setValue(isknown, "isknown", "sets", shortName);
|
setValue(isknown, "isknown", "sets", std::move(shortName));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CardDatabaseSettings::getSortKey(QString shortName)
|
unsigned int CardDatabaseSettings::getSortKey(QString shortName)
|
||||||
{
|
{
|
||||||
return getValue("sortkey", "sets", shortName).toUInt();
|
return getValue("sortkey", "sets", std::move(shortName)).toUInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CardDatabaseSettings::isEnabled(QString shortName)
|
bool CardDatabaseSettings::isEnabled(QString shortName)
|
||||||
{
|
{
|
||||||
return getValue("enabled", "sets", shortName).toBool();
|
return getValue("enabled", "sets", std::move(shortName)).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CardDatabaseSettings::isKnown(QString shortName)
|
bool CardDatabaseSettings::isKnown(QString shortName)
|
||||||
{
|
{
|
||||||
return getValue("isknown", "sets", shortName).toBool();
|
return getValue("isknown", "sets", std::move(shortName)).toBool();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,58 @@
|
||||||
#include "settingsmanager.h"
|
#include "settingsmanager.h"
|
||||||
|
|
||||||
SettingsManager::SettingsManager(QString settingPath, QObject *parent)
|
SettingsManager::SettingsManager(QString settingPath, QObject *parent) : QObject(parent), settings(settingPath, QSettings::IniFormat)
|
||||||
: QObject(parent),
|
|
||||||
settings(settingPath, QSettings::IniFormat)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsManager::setValue(QVariant value, QString name, QString group, QString subGroup)
|
void SettingsManager::setValue(QVariant value, QString name, QString group, QString subGroup)
|
||||||
{
|
{
|
||||||
if(!group.isEmpty())
|
if (!group.isEmpty())
|
||||||
|
{
|
||||||
settings.beginGroup(group);
|
settings.beginGroup(group);
|
||||||
|
}
|
||||||
|
|
||||||
if(!subGroup.isEmpty())
|
if (!subGroup.isEmpty())
|
||||||
|
{
|
||||||
settings.beginGroup(subGroup);
|
settings.beginGroup(subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
settings.setValue(name, value);
|
settings.setValue(name, value);
|
||||||
|
|
||||||
if(!subGroup.isEmpty())
|
if (!subGroup.isEmpty())
|
||||||
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
if(!group.isEmpty())
|
if (!group.isEmpty())
|
||||||
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SettingsManager::getValue(QString name, QString group, QString subGroup)
|
QVariant SettingsManager::getValue(QString name, QString group, QString subGroup)
|
||||||
{
|
{
|
||||||
if(!group.isEmpty())
|
if (!group.isEmpty())
|
||||||
|
{
|
||||||
settings.beginGroup(group);
|
settings.beginGroup(group);
|
||||||
|
}
|
||||||
|
|
||||||
if(!subGroup.isEmpty())
|
if (!subGroup.isEmpty())
|
||||||
|
{
|
||||||
settings.beginGroup(subGroup);
|
settings.beginGroup(subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
QVariant value = settings.value(name);
|
QVariant value = settings.value(name);
|
||||||
|
|
||||||
if(!subGroup.isEmpty())
|
if (!subGroup.isEmpty())
|
||||||
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
if(!group.isEmpty())
|
if (!group.isEmpty())
|
||||||
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,6 +171,8 @@ SettingsCache::SettingsCache()
|
||||||
releaseChannels << new StableReleaseChannel();
|
releaseChannels << new StableReleaseChannel();
|
||||||
releaseChannels << new DevReleaseChannel();
|
releaseChannels << new DevReleaseChannel();
|
||||||
|
|
||||||
|
mbDownloadSpoilers = settings->value("personal/downloadspoilers", false).toBool();
|
||||||
|
|
||||||
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
|
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
|
||||||
updateReleaseChannel = settings->value("personal/updatereleasechannel", 0).toInt();
|
updateReleaseChannel = settings->value("personal/updatereleasechannel", 0).toInt();
|
||||||
|
|
||||||
|
@ -187,6 +189,7 @@ SettingsCache::SettingsCache()
|
||||||
|
|
||||||
cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
|
cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
|
||||||
tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
|
tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
|
||||||
|
spoilerDatabasePath = getSafeConfigFilePath("paths/spoilerdatabase", dataPath + "/spoiler.xml");
|
||||||
|
|
||||||
themeName = settings->value("theme/name").toString();
|
themeName = settings->value("theme/name").toString();
|
||||||
|
|
||||||
|
@ -348,6 +351,13 @@ void SettingsCache::setCardDatabasePath(const QString &_cardDatabasePath)
|
||||||
emit cardDatabasePathChanged();
|
emit cardDatabasePathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsCache::setSpoilerDatabasePath(const QString &_spoilerDatabasePath)
|
||||||
|
{
|
||||||
|
spoilerDatabasePath = _spoilerDatabasePath;
|
||||||
|
settings->setValue("paths/spoilerdatabase", spoilerDatabasePath);
|
||||||
|
emit cardDatabasePathChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsCache::setTokenDatabasePath(const QString &_tokenDatabasePath)
|
void SettingsCache::setTokenDatabasePath(const QString &_tokenDatabasePath)
|
||||||
{
|
{
|
||||||
tokenDatabasePath = _tokenDatabasePath;
|
tokenDatabasePath = _tokenDatabasePath;
|
||||||
|
@ -644,10 +654,17 @@ void SettingsCache::setRememberGameSettings(const bool _rememberGameSettings)
|
||||||
|
|
||||||
void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
|
void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
|
||||||
{
|
{
|
||||||
notifyAboutUpdates = _notifyaboutupdate;
|
notifyAboutUpdates = static_cast<bool>(_notifyaboutupdate);
|
||||||
settings->setValue("personal/updatenotification", notifyAboutUpdates);
|
settings->setValue("personal/updatenotification", notifyAboutUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsCache::setDownloadSpoilerStatus(bool _spoilerStatus)
|
||||||
|
{
|
||||||
|
mbDownloadSpoilers = _spoilerStatus;
|
||||||
|
settings->setValue("personal/downloadspoilers", mbDownloadSpoilers);
|
||||||
|
emit downloadSpoilerStatusChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsCache::setUpdateReleaseChannel(int _updateReleaseChannel)
|
void SettingsCache::setUpdateReleaseChannel(int _updateReleaseChannel)
|
||||||
{
|
{
|
||||||
updateReleaseChannel = _updateReleaseChannel;
|
updateReleaseChannel = _updateReleaseChannel;
|
||||||
|
|
|
@ -48,6 +48,8 @@ signals:
|
||||||
void pixmapCacheSizeChanged(int newSizeInMBs);
|
void pixmapCacheSizeChanged(int newSizeInMBs);
|
||||||
void masterVolumeChanged(int value);
|
void masterVolumeChanged(int value);
|
||||||
void chatMentionCompleterChanged();
|
void chatMentionCompleterChanged();
|
||||||
|
void downloadSpoilerTimeIndexChanged();
|
||||||
|
void downloadSpoilerStatusChanged();
|
||||||
private:
|
private:
|
||||||
QSettings *settings;
|
QSettings *settings;
|
||||||
ShortcutsSettings *shortcutsSettings;
|
ShortcutsSettings *shortcutsSettings;
|
||||||
|
@ -60,8 +62,9 @@ private:
|
||||||
QByteArray mainWindowGeometry;
|
QByteArray mainWindowGeometry;
|
||||||
QByteArray tokenDialogGeometry;
|
QByteArray tokenDialogGeometry;
|
||||||
QString lang;
|
QString lang;
|
||||||
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, tokenDatabasePath, themeName;
|
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, spoilerDatabasePath, tokenDatabasePath, themeName;
|
||||||
bool notifyAboutUpdates;
|
bool notifyAboutUpdates;
|
||||||
|
bool mbDownloadSpoilers;
|
||||||
int updateReleaseChannel;
|
int updateReleaseChannel;
|
||||||
int maxFontSize;
|
int maxFontSize;
|
||||||
bool picDownload;
|
bool picDownload;
|
||||||
|
@ -130,6 +133,7 @@ public:
|
||||||
QString getCustomPicsPath() const { return customPicsPath; }
|
QString getCustomPicsPath() const { return customPicsPath; }
|
||||||
QString getCustomCardDatabasePath() const { return customCardDatabasePath; }
|
QString getCustomCardDatabasePath() const { return customCardDatabasePath; }
|
||||||
QString getCardDatabasePath() const { return cardDatabasePath; }
|
QString getCardDatabasePath() const { return cardDatabasePath; }
|
||||||
|
QString getSpoilerCardDatabasePath() const { return spoilerDatabasePath; }
|
||||||
QString getTokenDatabasePath() const { return tokenDatabasePath; }
|
QString getTokenDatabasePath() const { return tokenDatabasePath; }
|
||||||
QString getThemeName() const { return themeName; }
|
QString getThemeName() const { return themeName; }
|
||||||
QString getChatMentionColor() const { return chatMentionColor; }
|
QString getChatMentionColor() const { return chatMentionColor; }
|
||||||
|
@ -200,7 +204,10 @@ public:
|
||||||
GameFiltersSettings& gameFilters() const { return *gameFiltersSettings; }
|
GameFiltersSettings& gameFilters() const { return *gameFiltersSettings; }
|
||||||
LayoutsSettings& layouts() const { return *layoutsSettings; }
|
LayoutsSettings& layouts() const { return *layoutsSettings; }
|
||||||
bool getIsPortableBuild() const { return isPortableBuild; }
|
bool getIsPortableBuild() const { return isPortableBuild; }
|
||||||
|
bool getDownloadSpoilersStatus() const { return mbDownloadSpoilers; }
|
||||||
public slots:
|
public slots:
|
||||||
|
void setDownloadSpoilerStatus(bool _spoilerStatus);
|
||||||
|
|
||||||
void setMainWindowGeometry(const QByteArray &_mainWindowGeometry);
|
void setMainWindowGeometry(const QByteArray &_mainWindowGeometry);
|
||||||
void setTokenDialogGeometry(const QByteArray &_tokenDialog);
|
void setTokenDialogGeometry(const QByteArray &_tokenDialog);
|
||||||
void setLang(const QString &_lang);
|
void setLang(const QString &_lang);
|
||||||
|
@ -208,6 +215,7 @@ public slots:
|
||||||
void setReplaysPath(const QString &_replaysPath);
|
void setReplaysPath(const QString &_replaysPath);
|
||||||
void setPicsPath(const QString &_picsPath);
|
void setPicsPath(const QString &_picsPath);
|
||||||
void setCardDatabasePath(const QString &_cardDatabasePath);
|
void setCardDatabasePath(const QString &_cardDatabasePath);
|
||||||
|
void setSpoilerDatabasePath(const QString &_spoilerDatabasePath);
|
||||||
void setTokenDatabasePath(const QString &_tokenDatabasePath);
|
void setTokenDatabasePath(const QString &_tokenDatabasePath);
|
||||||
void setThemeName(const QString &_themeName);
|
void setThemeName(const QString &_themeName);
|
||||||
void setChatMentionColor(const QString &_chatMentionColor);
|
void setChatMentionColor(const QString &_chatMentionColor);
|
||||||
|
|
251
cockatrice/src/spoilerbackgroundupdater.cpp
Normal file
251
cockatrice/src/spoilerbackgroundupdater.cpp
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
|
#include "spoilerbackgroundupdater.h"
|
||||||
|
#include "settingscache.h"
|
||||||
|
#include "carddatabase.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "window_main.h"
|
||||||
|
|
||||||
|
#define SPOILERS_STATUS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/SpoilerSeasonEnabled"
|
||||||
|
#define SPOILERS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/spoiler.xml"
|
||||||
|
|
||||||
|
SpoilerBackgroundUpdater::SpoilerBackgroundUpdater(QObject *apParent) : QObject(apParent), cardUpdateProcess(nullptr)
|
||||||
|
{
|
||||||
|
isSpoilerDownloadEnabled = settingsCache->getDownloadSpoilersStatus();
|
||||||
|
if (isSpoilerDownloadEnabled)
|
||||||
|
{
|
||||||
|
// Start the process of checking if we're in spoiler season
|
||||||
|
// File exists means we're in spoiler season
|
||||||
|
// We will load the database before attempting to download spoilers, incase they fail
|
||||||
|
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||||
|
startSpoilerDownloadProcess(SPOILERS_STATUS_URL, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpoilerBackgroundUpdater::startSpoilerDownloadProcess(QString url, bool saveResults)
|
||||||
|
{
|
||||||
|
auto spoilerURL = QUrl(url);
|
||||||
|
downloadFromURL(spoilerURL, saveResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpoilerBackgroundUpdater::downloadFromURL(QUrl url, bool saveResults)
|
||||||
|
{
|
||||||
|
auto *nam = new QNetworkAccessManager(this);
|
||||||
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
|
if (saveResults)
|
||||||
|
{
|
||||||
|
// This will write out to the file (used for spoiler.xml)
|
||||||
|
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSpoilersFile()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This will check the status (used to see if we're in spoiler season or not)
|
||||||
|
connect(reply, SIGNAL(finished()), this, SLOT(actCheckIfSpoilerSeasonEnabled()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpoilerBackgroundUpdater::actDownloadFinishedSpoilersFile()
|
||||||
|
{
|
||||||
|
// Check for server reply
|
||||||
|
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||||
|
QNetworkReply::NetworkError errorCode = reply->error();
|
||||||
|
|
||||||
|
if (errorCode == QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
spoilerData = reply->readAll();
|
||||||
|
|
||||||
|
// Save the spoiler.xml file to the disk
|
||||||
|
saveDownloadedFile(spoilerData);
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
emit spoilerCheckerDone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Error downloading spoilers file" << errorCode;
|
||||||
|
emit spoilerCheckerDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpoilerBackgroundUpdater::deleteSpoilerFile()
|
||||||
|
{
|
||||||
|
QString fileName = settingsCache->getSpoilerCardDatabasePath();
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDir fileDir(fi.path());
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
// Delete the spoiler.xml file
|
||||||
|
if (file.exists() && file.remove())
|
||||||
|
{
|
||||||
|
qDebug() << "Deleting spoiler.xml";
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Error: Spoiler.xml not found or not deleted";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
|
||||||
|
{
|
||||||
|
auto *response = dynamic_cast<QNetworkReply *>(sender());
|
||||||
|
QNetworkReply::NetworkError errorCode = response->error();
|
||||||
|
|
||||||
|
if (errorCode == QNetworkReply::ContentNotFoundError)
|
||||||
|
{
|
||||||
|
// Spoiler season is offline at this point, so the spoiler.xml file can be safely deleted
|
||||||
|
// The user should run Oracle to get the latest card information
|
||||||
|
if (deleteSpoilerFile() && trayIcon)
|
||||||
|
{
|
||||||
|
trayIcon->showMessage(tr("Spoilers season has ended"), tr("Deleting spoiler.xml. Please run Oracle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Spoiler Season Offline";
|
||||||
|
emit spoilerCheckerDone();
|
||||||
|
}
|
||||||
|
else if (errorCode == QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
qDebug() << "Spoiler Service Online";
|
||||||
|
startSpoilerDownloadProcess(SPOILERS_URL, true);
|
||||||
|
}
|
||||||
|
else if (errorCode == QNetworkReply::HostNotFoundError)
|
||||||
|
{
|
||||||
|
if (trayIcon)
|
||||||
|
{
|
||||||
|
trayIcon->showMessage(tr("Spoilers download failed"), tr("No internet connection"));
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Spoiler download failed due to no internet connection";
|
||||||
|
emit spoilerCheckerDone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (trayIcon)
|
||||||
|
{
|
||||||
|
trayIcon->showMessage(tr("Spoilers download failed"), tr("Error") + " " + errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Spoiler download failed with reason" << errorCode;
|
||||||
|
emit spoilerCheckerDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
||||||
|
{
|
||||||
|
QString fileName = settingsCache->getSpoilerCardDatabasePath();
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDir fileDir(fi.path());
|
||||||
|
|
||||||
|
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the data matches. If it does, then spoilers are up to date.
|
||||||
|
if (getHash(fileName) == getHash(data))
|
||||||
|
{
|
||||||
|
if (trayIcon)
|
||||||
|
{
|
||||||
|
trayIcon->showMessage(tr("Spoilers already up to date"), tr("No new spoilers added"));
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Spoilers Up to Date";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
qDebug() << "Spoiler Service Error: File open (w) failed for" << fileName;
|
||||||
|
file.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.write(data) == -1)
|
||||||
|
{
|
||||||
|
qDebug() << "Spoiler Service Error: File write (w) failed for" << fileName;
|
||||||
|
file.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
|
||||||
|
// Data written, so reload the card database
|
||||||
|
qDebug() << "Spoiler Service Data Written";
|
||||||
|
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||||
|
|
||||||
|
// If the user has notifications enabled, let them know
|
||||||
|
// when the database was last updated
|
||||||
|
if (trayIcon)
|
||||||
|
{
|
||||||
|
QList<QByteArray> lines = data.split('\n');
|
||||||
|
|
||||||
|
foreach (QByteArray line, lines)
|
||||||
|
{
|
||||||
|
if (line.indexOf("created:") > -1)
|
||||||
|
{
|
||||||
|
QString timeStamp = QString(line).replace("created:", "").trimmed();
|
||||||
|
timeStamp.chop(6); // Remove " (UTC)"
|
||||||
|
|
||||||
|
auto utcTime = QDateTime::fromString(timeStamp, QString("ddd, MMM dd yyyy, hh:mm:ss"));
|
||||||
|
utcTime.setTimeSpec(Qt::UTC);
|
||||||
|
|
||||||
|
QString localTime = utcTime.toLocalTime().toString("MMM d, hh:mm");
|
||||||
|
|
||||||
|
trayIcon->showMessage(tr("Spoilers have been updated!"), tr("Last change:") + " " + localTime);
|
||||||
|
emit spoilersUpdatedSuccessfully();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SpoilerBackgroundUpdater::getHash(const QString fileName)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
if (file.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
// Only read the first 512 bytes (enough to get the "created" tag)
|
||||||
|
const QByteArray bytes = file.read(512);
|
||||||
|
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||||
|
hash.addData(bytes);
|
||||||
|
|
||||||
|
qDebug() << "File Hash =" << hash.result();
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return hash.result();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "getHash ReadOnly failed!";
|
||||||
|
file.close();
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SpoilerBackgroundUpdater::getHash(QByteArray data)
|
||||||
|
{
|
||||||
|
// Only read the first 512 bytes (enough to get the "created" tag)
|
||||||
|
const QByteArray bytes = data.left(512);
|
||||||
|
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||||
|
hash.addData(bytes);
|
||||||
|
|
||||||
|
qDebug() << "Data Hash =" << hash.result();
|
||||||
|
|
||||||
|
return hash.result();
|
||||||
|
}
|
35
cockatrice/src/spoilerbackgroundupdater.h
Normal file
35
cockatrice/src/spoilerbackgroundupdater.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef COCKATRICE_SPOILER_DOWNLOADER_H
|
||||||
|
#define COCKATRICE_SPOILER_DOWNLOADER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
class SpoilerBackgroundUpdater : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SpoilerBackgroundUpdater(QObject *apParent = nullptr);
|
||||||
|
inline QString getCardUpdaterBinaryName() { return "oracle"; };
|
||||||
|
QByteArray getHash(const QString fileName);
|
||||||
|
QByteArray getHash(QByteArray data);
|
||||||
|
static bool deleteSpoilerFile();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actDownloadFinishedSpoilersFile();
|
||||||
|
void actCheckIfSpoilerSeasonEnabled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isSpoilerDownloadEnabled;
|
||||||
|
QProcess *cardUpdateProcess;
|
||||||
|
QByteArray spoilerData;
|
||||||
|
void startSpoilerDownloadProcess(QString url, bool saveResults);
|
||||||
|
void downloadFromURL(QUrl url, bool saveResults);
|
||||||
|
bool saveDownloadedFile(QByteArray data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void spoilersUpdatedSuccessfully();
|
||||||
|
void spoilerCheckerDone();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //COCKATRICE_SPOILER_DOWNLOADER_H
|
|
@ -76,11 +76,11 @@ const QStringList MainWindow::fileNameFilters = QStringList()
|
||||||
|
|
||||||
void MainWindow::updateTabMenu(const QList<QMenu *> &newMenuList)
|
void MainWindow::updateTabMenu(const QList<QMenu *> &newMenuList)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tabMenus.size(); ++i)
|
for (auto &tabMenu : tabMenus)
|
||||||
menuBar()->removeAction(tabMenus[i]->menuAction());
|
menuBar()->removeAction(tabMenu->menuAction());
|
||||||
tabMenus = newMenuList;
|
tabMenus = newMenuList;
|
||||||
for (int i = 0; i < tabMenus.size(); ++i)
|
for (auto &tabMenu : tabMenus)
|
||||||
menuBar()->insertMenu(helpMenu->menuAction(), tabMenus[i]);
|
menuBar()->insertMenu(helpMenu->menuAction(), tabMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processConnectionClosedEvent(const Event_ConnectionClosed &event)
|
void MainWindow::processConnectionClosedEvent(const Event_ConnectionClosed &event)
|
||||||
|
@ -166,10 +166,10 @@ void MainWindow::activateAccepted()
|
||||||
|
|
||||||
void MainWindow::actConnect()
|
void MainWindow::actConnect()
|
||||||
{
|
{
|
||||||
DlgConnect *dlg = new DlgConnect(this);
|
auto *dlg = new DlgConnect(this);
|
||||||
connect(dlg, SIGNAL(sigStartForgotPasswordRequest()), this, SLOT(actForgotPasswordRequest()));
|
connect(dlg, SIGNAL(sigStartForgotPasswordRequest()), this, SLOT(actForgotPasswordRequest()));
|
||||||
if (dlg->exec())
|
if (dlg->exec())
|
||||||
client->connectToServer(dlg->getHost(), dlg->getPort(), dlg->getPlayerName(), dlg->getPassword());
|
client->connectToServer(dlg->getHost(), static_cast<unsigned int>(dlg->getPort()), dlg->getPlayerName(), dlg->getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::actRegister()
|
void MainWindow::actRegister()
|
||||||
|
@ -179,7 +179,7 @@ void MainWindow::actRegister()
|
||||||
{
|
{
|
||||||
client->registerToServer(
|
client->registerToServer(
|
||||||
dlg.getHost(),
|
dlg.getHost(),
|
||||||
dlg.getPort(),
|
static_cast<unsigned int>(dlg.getPort()),
|
||||||
dlg.getPlayerName(),
|
dlg.getPlayerName(),
|
||||||
dlg.getPassword(),
|
dlg.getPassword(),
|
||||||
dlg.getEmail(),
|
dlg.getEmail(),
|
||||||
|
@ -220,7 +220,7 @@ void MainWindow::actSinglePlayer()
|
||||||
tabSupervisor->startLocal(localClients);
|
tabSupervisor->startLocal(localClients);
|
||||||
|
|
||||||
Command_CreateGame createCommand;
|
Command_CreateGame createCommand;
|
||||||
createCommand.set_max_players(numberPlayers);
|
createCommand.set_max_players(static_cast<google::protobuf::uint32>(numberPlayers));
|
||||||
mainClient->sendCommand(mainClient->prepareRoomCommand(createCommand, 0));
|
mainClient->sendCommand(mainClient->prepareRoomCommand(createCommand, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ void MainWindow::actWatchReplay()
|
||||||
QByteArray buf = file.readAll();
|
QByteArray buf = file.readAll();
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
GameReplay *replay = new GameReplay;
|
auto *replay = new GameReplay;
|
||||||
replay->ParseFromArray(buf.data(), buf.size());
|
replay->ParseFromArray(buf.data(), buf.size());
|
||||||
|
|
||||||
tabSupervisor->openReplay(replay);
|
tabSupervisor->openReplay(replay);
|
||||||
|
@ -248,7 +248,7 @@ void MainWindow::actWatchReplay()
|
||||||
void MainWindow::localGameEnded()
|
void MainWindow::localGameEnded()
|
||||||
{
|
{
|
||||||
delete localServer;
|
delete localServer;
|
||||||
localServer = 0;
|
localServer = nullptr;
|
||||||
|
|
||||||
aConnect->setEnabled(true);
|
aConnect->setEnabled(true);
|
||||||
aRegister->setEnabled(true);
|
aRegister->setEnabled(true);
|
||||||
|
@ -257,7 +257,7 @@ void MainWindow::localGameEnded()
|
||||||
|
|
||||||
void MainWindow::actDeckEditor()
|
void MainWindow::actDeckEditor()
|
||||||
{
|
{
|
||||||
tabSupervisor->addDeckEditorTab(0);
|
tabSupervisor->addDeckEditorTab(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::actFullScreen(bool checked)
|
void MainWindow::actFullScreen(bool checked)
|
||||||
|
@ -655,7 +655,7 @@ void MainWindow::createMenus()
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent), localServer(0), bHasActivated(false), cardUpdateProcess(0), logviewDialog(0)
|
: QMainWindow(parent), localServer(nullptr), bHasActivated(false), cardUpdateProcess(nullptr), logviewDialog(nullptr)
|
||||||
{
|
{
|
||||||
connect(settingsCache, SIGNAL(pixmapCacheSizeChanged(int)), this, SLOT(pixmapCacheSizeChanged(int)));
|
connect(settingsCache, SIGNAL(pixmapCacheSizeChanged(int)), this, SLOT(pixmapCacheSizeChanged(int)));
|
||||||
pixmapCacheSizeChanged(settingsCache->getPixmapCacheSize());
|
pixmapCacheSizeChanged(settingsCache->getPixmapCacheSize());
|
||||||
|
@ -691,7 +691,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(tabSupervisor, SIGNAL(setMenu(QList<QMenu *>)), this, SLOT(updateTabMenu(QList<QMenu *>)));
|
connect(tabSupervisor, SIGNAL(setMenu(QList<QMenu *>)), this, SLOT(updateTabMenu(QList<QMenu *>)));
|
||||||
connect(tabSupervisor, SIGNAL(localGameEnded()), this, SLOT(localGameEnded()));
|
connect(tabSupervisor, SIGNAL(localGameEnded()), this, SLOT(localGameEnded()));
|
||||||
connect(tabSupervisor, SIGNAL(showWindowIfHidden()), this, SLOT(showWindowIfHidden()));
|
connect(tabSupervisor, SIGNAL(showWindowIfHidden()), this, SLOT(showWindowIfHidden()));
|
||||||
tabSupervisor->addDeckEditorTab(0);
|
tabSupervisor->addDeckEditorTab(nullptr);
|
||||||
|
|
||||||
setCentralWidget(tabSupervisor);
|
setCentralWidget(tabSupervisor);
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
|
|
||||||
resize(900, 700);
|
resize(900, 700);
|
||||||
restoreGeometry(settingsCache->getMainWindowGeometry());
|
restoreGeometry(settingsCache->getMainWindowGeometry());
|
||||||
aFullScreen->setChecked(windowState() & Qt::WindowFullScreen);
|
aFullScreen->setChecked(static_cast<bool>(windowState() & Qt::WindowFullScreen));
|
||||||
|
|
||||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
createTrayActions();
|
createTrayActions();
|
||||||
|
@ -712,7 +712,12 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(db, SIGNAL(cardDatabaseLoadingFailed()), this, SLOT(cardDatabaseLoadingFailed()));
|
connect(db, SIGNAL(cardDatabaseLoadingFailed()), this, SLOT(cardDatabaseLoadingFailed()));
|
||||||
connect(db, SIGNAL(cardDatabaseNewSetsFound(int, QStringList)), this, SLOT(cardDatabaseNewSetsFound(int, QStringList)));
|
connect(db, SIGNAL(cardDatabaseNewSetsFound(int, QStringList)), this, SLOT(cardDatabaseNewSetsFound(int, QStringList)));
|
||||||
connect(db, SIGNAL(cardDatabaseAllNewSetsEnabled()), this, SLOT(cardDatabaseAllNewSetsEnabled()));
|
connect(db, SIGNAL(cardDatabaseAllNewSetsEnabled()), this, SLOT(cardDatabaseAllNewSetsEnabled()));
|
||||||
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
|
||||||
|
if (! settingsCache->getDownloadSpoilersStatus())
|
||||||
|
{
|
||||||
|
qDebug() << "Spoilers Disabled";
|
||||||
|
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
@ -727,7 +732,7 @@ MainWindow::~MainWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createTrayIcon() {
|
void MainWindow::createTrayIcon() {
|
||||||
QMenu *trayIconMenu = new QMenu(this);
|
auto *trayIconMenu = new QMenu(this);
|
||||||
trayIconMenu->addAction(closeAction);
|
trayIconMenu->addAction(closeAction);
|
||||||
|
|
||||||
trayIcon = new QSystemTrayIcon(this);
|
trayIcon = new QSystemTrayIcon(this);
|
||||||
|
@ -754,7 +759,7 @@ void MainWindow::promptForgotPasswordChallenge()
|
||||||
{
|
{
|
||||||
DlgForgotPasswordChallenge dlg(this);
|
DlgForgotPasswordChallenge dlg(this);
|
||||||
if (dlg.exec())
|
if (dlg.exec())
|
||||||
client->submitForgotPasswordChallengeToServer(dlg.getHost(),dlg.getPort(),dlg.getPlayerName(),dlg.getEmail());
|
client->submitForgotPasswordChallengeToServer(dlg.getHost(), static_cast<unsigned int>(dlg.getPort()), dlg.getPlayerName(), dlg.getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -794,7 +799,7 @@ void MainWindow::changeEvent(QEvent *event)
|
||||||
if(settingsCache->servers().getAutoConnect()) {
|
if(settingsCache->servers().getAutoConnect()) {
|
||||||
qDebug() << "Attempting auto-connect...";
|
qDebug() << "Attempting auto-connect...";
|
||||||
DlgConnect dlg(this);
|
DlgConnect dlg(this);
|
||||||
client->connectToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName(), dlg.getPassword());
|
client->connectToServer(dlg.getHost(), static_cast<unsigned int>(dlg.getPort()), dlg.getPlayerName(), dlg.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -856,11 +861,17 @@ void MainWindow::cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknow
|
||||||
|
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
if (msgBox.clickedButton() == yesButton) {
|
if (msgBox.clickedButton() == yesButton)
|
||||||
|
{
|
||||||
db->enableAllUnknownSets();
|
db->enableAllUnknownSets();
|
||||||
} else if (msgBox.clickedButton() == noButton) {
|
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||||
|
}
|
||||||
|
else if (msgBox.clickedButton() == noButton)
|
||||||
|
{
|
||||||
db->markAllSetsAsKnown();
|
db->markAllSetsAsKnown();
|
||||||
} else if (msgBox.clickedButton() == settingsButton) {
|
}
|
||||||
|
else if (msgBox.clickedButton() == settingsButton)
|
||||||
|
{
|
||||||
db->markAllSetsAsKnown();
|
db->markAllSetsAsKnown();
|
||||||
actEditSets();
|
actEditSets();
|
||||||
}
|
}
|
||||||
|
@ -873,10 +884,9 @@ void MainWindow::cardDatabaseAllNewSetsEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CARD UPDATER */
|
/* CARD UPDATER */
|
||||||
|
|
||||||
void MainWindow::actCheckCardUpdates()
|
void MainWindow::actCheckCardUpdates()
|
||||||
{
|
{
|
||||||
if(cardUpdateProcess)
|
if (cardUpdateProcess)
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Information"), tr("A card database update is already running."));
|
QMessageBox::information(this, tr("Information"), tr("A card database update is already running."));
|
||||||
return;
|
return;
|
||||||
|
@ -946,7 +956,7 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cardUpdateProcess->deleteLater();
|
cardUpdateProcess->deleteLater();
|
||||||
cardUpdateProcess = 0;
|
cardUpdateProcess = nullptr;
|
||||||
|
|
||||||
QMessageBox::warning(this, tr("Error"), tr("The card database updater exited with an error: %1").arg(error));
|
QMessageBox::warning(this, tr("Error"), tr("The card database updater exited with an error: %1").arg(error));
|
||||||
}
|
}
|
||||||
|
@ -954,10 +964,9 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err)
|
||||||
void MainWindow::cardUpdateFinished(int, QProcess::ExitStatus)
|
void MainWindow::cardUpdateFinished(int, QProcess::ExitStatus)
|
||||||
{
|
{
|
||||||
cardUpdateProcess->deleteLater();
|
cardUpdateProcess->deleteLater();
|
||||||
cardUpdateProcess = 0;
|
cardUpdateProcess = nullptr;
|
||||||
|
|
||||||
QMessageBox::information(this, tr("Information"), tr("Update completed successfully.\nCockatrice will now reload the card database."));
|
QMessageBox::information(this, tr("Information"), tr("Update completed successfully.\nCockatrice will now reload the card database."));
|
||||||
|
|
||||||
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,7 +998,7 @@ void MainWindow::actOpenCustomFolder()
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
QStringList scriptArgs;
|
QStringList scriptArgs;
|
||||||
scriptArgs << QLatin1String("-e");
|
scriptArgs << QLatin1String("-e");
|
||||||
scriptArgs << QString::fromLatin1("tell application \"Finder\" to open POSIX file \"%1\"").arg(dir);
|
scriptArgs << QString::fromLatin1(R"(tell application "Finder" to open POSIX file "%1")").arg(dir);
|
||||||
scriptArgs << QLatin1String("-e");
|
scriptArgs << QLatin1String("-e");
|
||||||
scriptArgs << QLatin1String("tell application \"Finder\" to activate");
|
scriptArgs << QLatin1String("tell application \"Finder\" to activate");
|
||||||
|
|
||||||
|
@ -1008,7 +1017,7 @@ void MainWindow::actOpenCustomsetsFolder()
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
QStringList scriptArgs;
|
QStringList scriptArgs;
|
||||||
scriptArgs << QLatin1String("-e");
|
scriptArgs << QLatin1String("-e");
|
||||||
scriptArgs << QString::fromLatin1("tell application \"Finder\" to open POSIX file \"%1\"").arg(dir);
|
scriptArgs << QString::fromLatin1(R"(tell application "Finder" to open POSIX file "%1")").arg(dir);
|
||||||
scriptArgs << QLatin1String("-e");
|
scriptArgs << QLatin1String("-e");
|
||||||
scriptArgs << QLatin1String("tell application \"Finder\" to activate");
|
scriptArgs << QLatin1String("tell application \"Finder\" to activate");
|
||||||
|
|
||||||
|
@ -1025,16 +1034,20 @@ void MainWindow::actAddCustomSet()
|
||||||
QFileDialog dialog(this, tr("Load sets/cards"), QDir::homePath());
|
QFileDialog dialog(this, tr("Load sets/cards"), QDir::homePath());
|
||||||
dialog.setNameFilters(MainWindow::fileNameFilters);
|
dialog.setNameFilters(MainWindow::fileNameFilters);
|
||||||
if (!dialog.exec())
|
if (!dialog.exec())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString fullFilePath = dialog.selectedFiles().at(0);
|
QString fullFilePath = dialog.selectedFiles().at(0);
|
||||||
|
|
||||||
if (!QFile::exists(fullFilePath)) {
|
if (!QFile::exists(fullFilePath))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, tr("Load sets/cards"), tr("Selected file cannot be found."));
|
QMessageBox::warning(this, tr("Load sets/cards"), tr("Selected file cannot be found."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QFileInfo(fullFilePath).suffix() != "xml") { // fileName = *.xml
|
if (QFileInfo(fullFilePath).suffix() != "xml") // fileName = *.xml
|
||||||
|
{
|
||||||
QMessageBox::warning(this, tr("Load sets/cards"), tr("You can only import XML databases at this time."));
|
QMessageBox::warning(this, tr("Load sets/cards"), tr("You can only import XML databases at this time."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1055,7 @@ void MainWindow::actAddCustomSet()
|
||||||
QDir dir = settingsCache->getCustomCardDatabasePath();
|
QDir dir = settingsCache->getCustomCardDatabasePath();
|
||||||
int nextPrefix = getNextCustomSetPrefix(dir);
|
int nextPrefix = getNextCustomSetPrefix(dir);
|
||||||
|
|
||||||
bool res = false;
|
bool res;
|
||||||
|
|
||||||
QString fileName = QFileInfo(fullFilePath).fileName();
|
QString fileName = QFileInfo(fullFilePath).fileName();
|
||||||
if (fileName.compare("spoiler.xml", Qt::CaseInsensitive) == 0)
|
if (fileName.compare("spoiler.xml", Qt::CaseInsensitive) == 0)
|
||||||
|
@ -1078,7 +1091,8 @@ void MainWindow::actAddCustomSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::getNextCustomSetPrefix(QDir dataDir) {
|
int MainWindow::getNextCustomSetPrefix(QDir dataDir)
|
||||||
|
{
|
||||||
QStringList files = dataDir.entryList();
|
QStringList files = dataDir.entryList();
|
||||||
int maxIndex = 0;
|
int maxIndex = 0;
|
||||||
|
|
||||||
|
@ -1094,7 +1108,7 @@ int MainWindow::getNextCustomSetPrefix(QDir dataDir) {
|
||||||
|
|
||||||
void MainWindow::actEditSets()
|
void MainWindow::actEditSets()
|
||||||
{
|
{
|
||||||
WndSets *w = new WndSets;
|
auto *w = new WndSets;
|
||||||
w->setWindowModality(Qt::WindowModal);
|
w->setWindowModality(Qt::WindowModal);
|
||||||
w->show();
|
w->show();
|
||||||
}
|
}
|
||||||
|
@ -1110,7 +1124,7 @@ void MainWindow::actForgotPasswordRequest()
|
||||||
{
|
{
|
||||||
DlgForgotPasswordRequest dlg(this);
|
DlgForgotPasswordRequest dlg(this);
|
||||||
if (dlg.exec())
|
if (dlg.exec())
|
||||||
client->requestForgotPasswordToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName());
|
client->requestForgotPasswordToServer(dlg.getHost(), static_cast<unsigned int>(dlg.getPort()), dlg.getPlayerName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::forgotPasswordSuccess()
|
void MainWindow::forgotPasswordSuccess()
|
||||||
|
@ -1134,5 +1148,8 @@ void MainWindow::promptForgotPasswordReset()
|
||||||
QMessageBox::information(this, tr("Forgot Password"), tr("Activation request received, please check your email for an activation token."));
|
QMessageBox::information(this, tr("Forgot Password"), tr("Activation request received, please check your email for an activation token."));
|
||||||
DlgForgotPasswordReset dlg(this);
|
DlgForgotPasswordReset dlg(this);
|
||||||
if (dlg.exec())
|
if (dlg.exec())
|
||||||
client->submitForgotPasswordResetToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName(), dlg.getToken(), dlg.getPassword());
|
{
|
||||||
|
client->submitForgotPasswordResetToServer(dlg.getHost(), static_cast<unsigned int>(dlg.getPort()),
|
||||||
|
dlg.getPlayerName(), dlg.getToken(), dlg.getPassword());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ class DlgViewLog;
|
||||||
|
|
||||||
class MainWindow : public QMainWindow {
|
class MainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
public slots:
|
||||||
|
void actCheckCardUpdates();
|
||||||
private slots:
|
private slots:
|
||||||
void updateTabMenu(const QList<QMenu *> &newMenuList);
|
void updateTabMenu(const QList<QMenu *> &newMenuList);
|
||||||
void statusChanged(ClientStatus _status);
|
void statusChanged(ClientStatus _status);
|
||||||
|
@ -78,7 +80,6 @@ private slots:
|
||||||
void promptForgotPasswordChallenge();
|
void promptForgotPasswordChallenge();
|
||||||
void showWindowIfHidden();
|
void showWindowIfHidden();
|
||||||
|
|
||||||
void actCheckCardUpdates();
|
|
||||||
void cardUpdateError(QProcess::ProcessError err);
|
void cardUpdateError(QProcess::ProcessError err);
|
||||||
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
void refreshShortcuts();
|
void refreshShortcuts();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "oraclewizard.h"
|
#include "oraclewizard.h"
|
||||||
|
@ -15,6 +16,7 @@ ThemeManager *themeManager;
|
||||||
|
|
||||||
const QString translationPrefix = "oracle";
|
const QString translationPrefix = "oracle";
|
||||||
QString translationPath;
|
QString translationPath;
|
||||||
|
bool isSpoilersOnly;
|
||||||
|
|
||||||
void installNewTranslator()
|
void installNewTranslator()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +37,13 @@ int main(int argc, char *argv[])
|
||||||
// this can't be changed, as it influences the default savepath for cards.xml
|
// this can't be changed, as it influences the default savepath for cards.xml
|
||||||
QCoreApplication::setApplicationName("Cockatrice");
|
QCoreApplication::setApplicationName("Cockatrice");
|
||||||
|
|
||||||
|
// If the program is opened with the -s flag, it will only do spoilers. Otherwise it will do MTGJSON/Tokens
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QCommandLineOption showProgressOption("s", QCoreApplication::translate("main", "Only run in spoiler mode"));
|
||||||
|
parser.addOption(showProgressOption);
|
||||||
|
parser.process(app);
|
||||||
|
isSpoilersOnly = parser.isSet(showProgressOption);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
translationPath = qApp->applicationDirPath() + "/../Resources/translations";
|
translationPath = qApp->applicationDirPath() + "/../Resources/translations";
|
||||||
#elif defined(Q_OS_WIN)
|
#elif defined(Q_OS_WIN)
|
||||||
|
|
|
@ -6,6 +6,7 @@ class QTranslator;
|
||||||
extern QTranslator *translator;
|
extern QTranslator *translator;
|
||||||
extern const QString translationPrefix;
|
extern const QString translationPrefix;
|
||||||
extern QString translationPath;
|
extern QString translationPath;
|
||||||
|
extern bool isSpoilersOnly;
|
||||||
|
|
||||||
void installNewTranslator();
|
void installNewTranslator();
|
||||||
|
|
||||||
|
|
|
@ -37,21 +37,28 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TOKENS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Token/master/tokens.xml"
|
#define TOKENS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Token/master/tokens.xml"
|
||||||
|
#define SPOILERS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/spoiler.xml"
|
||||||
|
|
||||||
|
OracleWizard::OracleWizard(QWidget *parent) : QWizard(parent)
|
||||||
OracleWizard::OracleWizard(QWidget *parent)
|
|
||||||
: QWizard(parent)
|
|
||||||
{
|
{
|
||||||
settings = new QSettings(settingsCache->getSettingsPath()+"global.ini",QSettings::IniFormat, this);
|
settings = new QSettings(settingsCache->getSettingsPath()+"global.ini",QSettings::IniFormat, this);
|
||||||
connect(settingsCache, SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
connect(settingsCache, SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
||||||
|
|
||||||
importer = new OracleImporter(settingsCache->getDataPath(), this);
|
importer = new OracleImporter(settingsCache->getDataPath(), this);
|
||||||
|
|
||||||
addPage(new IntroPage);
|
if (! isSpoilersOnly)
|
||||||
addPage(new LoadSetsPage);
|
{
|
||||||
addPage(new SaveSetsPage);
|
addPage(new IntroPage);
|
||||||
addPage(new LoadTokensPage);
|
addPage(new LoadSetsPage);
|
||||||
addPage(new SaveTokensPage);
|
addPage(new SaveSetsPage);
|
||||||
|
addPage(new LoadTokensPage);
|
||||||
|
addPage(new SaveTokensPage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addPage(new LoadSpoilersPage);
|
||||||
|
addPage(new SaveSpoilersPage);
|
||||||
|
}
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +72,10 @@ void OracleWizard::updateLanguage()
|
||||||
void OracleWizard::changeEvent(QEvent *event)
|
void OracleWizard::changeEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::LanguageChange)
|
if (event->type() == QEvent::LanguageChange)
|
||||||
|
{
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
QDialog::changeEvent(event);
|
QDialog::changeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +85,9 @@ void OracleWizard::retranslateUi()
|
||||||
QWizard::setButtonText(QWizard::FinishButton, tr("Save"));
|
QWizard::setButtonText(QWizard::FinishButton, tr("Save"));
|
||||||
|
|
||||||
for (int i = 0; i < pageIds().count(); i++)
|
for (int i = 0; i < pageIds().count(); i++)
|
||||||
|
{
|
||||||
dynamic_cast<OracleWizardPage *>(page(i))->retranslateUi();
|
dynamic_cast<OracleWizardPage *>(page(i))->retranslateUi();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OracleWizard::accept()
|
void OracleWizard::accept()
|
||||||
|
@ -98,22 +110,23 @@ void OracleWizard::disableButtons()
|
||||||
bool OracleWizard::saveTokensToFile(const QString & fileName)
|
bool OracleWizard::saveTokensToFile(const QString & fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if(!file.open(QIODevice::WriteOnly))
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
{
|
{
|
||||||
qDebug() << "File open (w) failed for" << fileName;
|
qDebug() << "File open (w) failed for" << fileName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(file.write(tokensData) == -1)
|
|
||||||
|
if (file.write(tokensData) == -1)
|
||||||
{
|
{
|
||||||
qDebug() << "File write (w) failed for" << fileName;
|
qDebug() << "File write (w) failed for" << fileName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntroPage::IntroPage(QWidget *parent)
|
IntroPage::IntroPage(QWidget *parent) : OracleWizardPage(parent)
|
||||||
: OracleWizardPage(parent)
|
|
||||||
{
|
{
|
||||||
label = new QLabel(this);
|
label = new QLabel(this);
|
||||||
label->setWordWrap(true);
|
label->setWordWrap(true);
|
||||||
|
@ -122,16 +135,21 @@ IntroPage::IntroPage(QWidget *parent)
|
||||||
versionLabel = new QLabel(this);
|
versionLabel = new QLabel(this);
|
||||||
languageBox = new QComboBox(this);
|
languageBox = new QComboBox(this);
|
||||||
QString setLanguage = settingsCache->getLang();
|
QString setLanguage = settingsCache->getLang();
|
||||||
|
|
||||||
QStringList qmFiles = findQmFiles();
|
QStringList qmFiles = findQmFiles();
|
||||||
for (int i = 0; i < qmFiles.size(); i++) {
|
for (int i = 0; i < qmFiles.size(); i++)
|
||||||
|
{
|
||||||
QString langName = languageName(qmFiles[i]);
|
QString langName = languageName(qmFiles[i]);
|
||||||
languageBox->addItem(langName, qmFiles[i]);
|
languageBox->addItem(langName, qmFiles[i]);
|
||||||
if ((qmFiles[i] == setLanguage) || (setLanguage.isEmpty() && langName == QCoreApplication::translate("i18n", DEFAULT_LANG_NAME)))
|
if ((qmFiles[i] == setLanguage) || (setLanguage.isEmpty() && langName == QCoreApplication::translate("i18n", DEFAULT_LANG_NAME)))
|
||||||
|
{
|
||||||
languageBox->setCurrentIndex(i);
|
languageBox->setCurrentIndex(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int)));
|
connect(languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int)));
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout(this);
|
auto *layout = new QGridLayout(this);
|
||||||
layout->addWidget(label, 0, 0, 1, 2);
|
layout->addWidget(label, 0, 0, 1, 2);
|
||||||
layout->addWidget(languageLabel, 1, 0);
|
layout->addWidget(languageLabel, 1, 0);
|
||||||
layout->addWidget(languageBox, 1, 1);
|
layout->addWidget(languageBox, 1, 1);
|
||||||
|
@ -150,8 +168,10 @@ QStringList IntroPage::findQmFiles()
|
||||||
|
|
||||||
QString IntroPage::languageName(const QString &qmFile)
|
QString IntroPage::languageName(const QString &qmFile)
|
||||||
{
|
{
|
||||||
if(qmFile == DEFAULT_LANG_CODE)
|
if (qmFile == DEFAULT_LANG_CODE)
|
||||||
|
{
|
||||||
return DEFAULT_LANG_NAME;
|
return DEFAULT_LANG_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
||||||
|
@ -173,8 +193,7 @@ void IntroPage::retranslateUi()
|
||||||
versionLabel->setText(tr("Version:") + QString(" %1").arg(VERSION_STRING));
|
versionLabel->setText(tr("Version:") + QString(" %1").arg(VERSION_STRING));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadSetsPage::LoadSetsPage(QWidget *parent)
|
LoadSetsPage::LoadSetsPage(QWidget *parent) : OracleWizardPage(parent), nam(nullptr)
|
||||||
: OracleWizardPage(parent), nam(0)
|
|
||||||
{
|
{
|
||||||
urlRadioButton = new QRadioButton(this);
|
urlRadioButton = new QRadioButton(this);
|
||||||
fileRadioButton = new QRadioButton(this);
|
fileRadioButton = new QRadioButton(this);
|
||||||
|
@ -193,7 +212,7 @@ LoadSetsPage::LoadSetsPage(QWidget *parent)
|
||||||
fileButton = new QPushButton(this);
|
fileButton = new QPushButton(this);
|
||||||
connect(fileButton, SIGNAL(clicked()), this, SLOT(actLoadSetsFile()));
|
connect(fileButton, SIGNAL(clicked()), this, SLOT(actLoadSetsFile()));
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout(this);
|
auto *layout = new QGridLayout(this);
|
||||||
layout->addWidget(urlRadioButton, 0, 0);
|
layout->addWidget(urlRadioButton, 0, 0);
|
||||||
layout->addWidget(urlLineEdit, 0, 1);
|
layout->addWidget(urlLineEdit, 0, 1);
|
||||||
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
||||||
|
@ -245,11 +264,15 @@ void LoadSetsPage::actLoadSetsFile()
|
||||||
dialog.setNameFilter(tr("Sets JSON file (*.json)"));
|
dialog.setNameFilter(tr("Sets JSON file (*.json)"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!fileLineEdit->text().isEmpty() && QFile::exists(fileLineEdit->text()))
|
if (!fileLineEdit->text().isEmpty() && QFile::exists(fileLineEdit->text()))
|
||||||
|
{
|
||||||
dialog.selectFile(fileLineEdit->text());
|
dialog.selectFile(fileLineEdit->text());
|
||||||
|
}
|
||||||
|
|
||||||
if (!dialog.exec())
|
if (!dialog.exec())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fileLineEdit->setText(dialog.selectedFiles().at(0));
|
fileLineEdit->setText(dialog.selectedFiles().at(0));
|
||||||
}
|
}
|
||||||
|
@ -257,14 +280,16 @@ void LoadSetsPage::actLoadSetsFile()
|
||||||
bool LoadSetsPage::validatePage()
|
bool LoadSetsPage::validatePage()
|
||||||
{
|
{
|
||||||
// once the import is finished, we call next(); skip validation
|
// once the import is finished, we call next(); skip validation
|
||||||
if(wizard()->importer->getSets().count() > 0)
|
if (wizard()->importer->getSets().count() > 0)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// else, try to import sets
|
// else, try to import sets
|
||||||
if(urlRadioButton->isChecked())
|
if (urlRadioButton->isChecked())
|
||||||
{
|
{
|
||||||
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
||||||
if(!url.isValid())
|
if (!url.isValid())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
|
QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
|
||||||
return false;
|
return false;
|
||||||
|
@ -282,16 +307,19 @@ bool LoadSetsPage::validatePage()
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
|
|
||||||
downloadSetsFile(url);
|
downloadSetsFile(url);
|
||||||
} else if(fileRadioButton->isChecked()) {
|
}
|
||||||
|
else if (fileRadioButton->isChecked())
|
||||||
|
{
|
||||||
QFile setsFile(fileLineEdit->text());
|
QFile setsFile(fileLineEdit->text());
|
||||||
if(!setsFile.exists())
|
if (!setsFile.exists())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Please choose a file."));
|
QMessageBox::critical(this, tr("Error"), tr("Please choose a file."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!setsFile.open(QIODevice::ReadOnly)) {
|
if (!setsFile.open(QIODevice::ReadOnly))
|
||||||
QMessageBox::critical(0, tr("Error"), tr("Cannot open file '%1'.").arg(fileLineEdit->text()));
|
{
|
||||||
|
QMessageBox::critical(nullptr, tr("Error"), tr("Cannot open file '%1'.").arg(fileLineEdit->text()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,13 +329,16 @@ bool LoadSetsPage::validatePage()
|
||||||
readSetsFromByteArray(setsFile.readAll());
|
readSetsFromByteArray(setsFile.readAll());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadSetsPage::downloadSetsFile(QUrl url)
|
void LoadSetsPage::downloadSetsFile(QUrl url)
|
||||||
{
|
{
|
||||||
if(!nam)
|
if (!nam)
|
||||||
|
{
|
||||||
nam = new QNetworkAccessManager(this);
|
nam = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSetsFile()));
|
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSetsFile()));
|
||||||
|
@ -316,10 +347,10 @@ void LoadSetsPage::downloadSetsFile(QUrl url)
|
||||||
|
|
||||||
void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
||||||
{
|
{
|
||||||
if(total > 0)
|
if (total > 0)
|
||||||
{
|
{
|
||||||
progressBar->setMaximum(total);
|
progressBar->setMaximum(static_cast<int>(total));
|
||||||
progressBar->setValue(received);
|
progressBar->setValue(static_cast<int>(received));
|
||||||
}
|
}
|
||||||
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
||||||
}
|
}
|
||||||
|
@ -327,9 +358,10 @@ void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
||||||
void LoadSetsPage::actDownloadFinishedSetsFile()
|
void LoadSetsPage::actDownloadFinishedSetsFile()
|
||||||
{
|
{
|
||||||
// check for a reply
|
// check for a reply
|
||||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||||
QNetworkReply::NetworkError errorCode = reply->error();
|
QNetworkReply::NetworkError errorCode = reply->error();
|
||||||
if (errorCode != QNetworkReply::NoError) {
|
if (errorCode != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
||||||
|
|
||||||
wizard()->enableButtons();
|
wizard()->enableButtons();
|
||||||
|
@ -340,7 +372,8 @@ void LoadSetsPage::actDownloadFinishedSetsFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
if (statusCode == 301 || statusCode == 302) {
|
if (statusCode == 301 || statusCode == 302)
|
||||||
|
{
|
||||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||||
qDebug() << "following redirect url:" << redirectUrl.toString();
|
qDebug() << "following redirect url:" << redirectUrl.toString();
|
||||||
downloadSetsFile(redirectUrl);
|
downloadSetsFile(redirectUrl);
|
||||||
|
@ -352,10 +385,14 @@ void LoadSetsPage::actDownloadFinishedSetsFile()
|
||||||
progressBar->hide();
|
progressBar->hide();
|
||||||
|
|
||||||
// save allsets.json url, but only if the user customized it and download was successfull
|
// save allsets.json url, but only if the user customized it and download was successfull
|
||||||
if(urlLineEdit->text() != QString(ALLSETS_URL))
|
if (urlLineEdit->text() != QString(ALLSETS_URL))
|
||||||
|
{
|
||||||
wizard()->settings->setValue("allsetsurl", urlLineEdit->text());
|
wizard()->settings->setValue("allsetsurl", urlLineEdit->text());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
wizard()->settings->remove("allsetsurl");
|
wizard()->settings->remove("allsetsurl");
|
||||||
|
}
|
||||||
|
|
||||||
readSetsFromByteArray(reply->readAll());
|
readSetsFromByteArray(reply->readAll());
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
@ -376,19 +413,20 @@ void LoadSetsPage::readSetsFromByteArray(QByteArray data)
|
||||||
{
|
{
|
||||||
#ifdef HAS_ZLIB
|
#ifdef HAS_ZLIB
|
||||||
// zipped file
|
// zipped file
|
||||||
QBuffer *inBuffer = new QBuffer(&data);
|
auto *inBuffer = new QBuffer(&data);
|
||||||
QBuffer *outBuffer = new QBuffer(this);
|
auto *outBuffer = new QBuffer(this);
|
||||||
QString fileName;
|
QString fileName;
|
||||||
UnZip::ErrorCode ec;
|
UnZip::ErrorCode ec;
|
||||||
UnZip uz;
|
UnZip uz;
|
||||||
|
|
||||||
ec = uz.openArchive(inBuffer);
|
ec = uz.openArchive(inBuffer);
|
||||||
if (ec != UnZip::Ok) {
|
if (ec != UnZip::Ok)
|
||||||
|
{
|
||||||
zipDownloadFailed(tr("Failed to open Zip archive: %1.").arg(uz.formatError(ec)));
|
zipDownloadFailed(tr("Failed to open Zip archive: %1.").arg(uz.formatError(ec)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uz.fileList().size() != 1)
|
if (uz.fileList().size() != 1)
|
||||||
{
|
{
|
||||||
zipDownloadFailed(tr("Zip extraction failed: the Zip archive doesn't contain exactly one file."));
|
zipDownloadFailed(tr("Zip extraction failed: the Zip archive doesn't contain exactly one file."));
|
||||||
return;
|
return;
|
||||||
|
@ -397,7 +435,8 @@ void LoadSetsPage::readSetsFromByteArray(QByteArray data)
|
||||||
|
|
||||||
outBuffer->open(QBuffer::ReadWrite);
|
outBuffer->open(QBuffer::ReadWrite);
|
||||||
ec = uz.extractFile(fileName, outBuffer);
|
ec = uz.extractFile(fileName, outBuffer);
|
||||||
if (ec != UnZip::Ok) {
|
if (ec != UnZip::Ok)
|
||||||
|
{
|
||||||
zipDownloadFailed(tr("Zip extraction failed: %1.").arg(uz.formatError(ec)));
|
zipDownloadFailed(tr("Zip extraction failed: %1.").arg(uz.formatError(ec)));
|
||||||
uz.closeArchive();
|
uz.closeArchive();
|
||||||
return;
|
return;
|
||||||
|
@ -429,7 +468,8 @@ void LoadSetsPage::zipDownloadFailed(const QString &message)
|
||||||
progressBar->hide();
|
progressBar->hide();
|
||||||
|
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
reply = QMessageBox::question(this, tr("Error"), message + "<br/>" + tr("Do you want to try to download a fresh copy of the uncompressed file instead?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
|
reply = static_cast<QMessageBox::StandardButton>(QMessageBox::question(this, tr("Error"), message + "<br/>" + tr("Do you want to try to download a fresh copy of the uncompressed file instead?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes));
|
||||||
|
|
||||||
if (reply == QMessageBox::Yes)
|
if (reply == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
urlRadioButton->setChecked(true);
|
urlRadioButton->setChecked(true);
|
||||||
|
@ -446,16 +486,17 @@ void LoadSetsPage::importFinished()
|
||||||
progressLabel->hide();
|
progressLabel->hide();
|
||||||
progressBar->hide();
|
progressBar->hide();
|
||||||
|
|
||||||
if(watcher.future().result())
|
if (watcher.future().result())
|
||||||
{
|
{
|
||||||
wizard()->next();
|
wizard()->next();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file was retrieved successfully, but it does not contain any sets data."));
|
QMessageBox::critical(this, tr("Error"), tr("The file was retrieved successfully, but it does not contain any sets data."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveSetsPage::SaveSetsPage(QWidget *parent)
|
SaveSetsPage::SaveSetsPage(QWidget *parent) : OracleWizardPage(parent)
|
||||||
: OracleWizardPage(parent)
|
|
||||||
{
|
{
|
||||||
defaultPathCheckBox = new QCheckBox(this);
|
defaultPathCheckBox = new QCheckBox(this);
|
||||||
defaultPathCheckBox->setChecked(true);
|
defaultPathCheckBox->setChecked(true);
|
||||||
|
@ -463,7 +504,7 @@ SaveSetsPage::SaveSetsPage(QWidget *parent)
|
||||||
messageLog = new QTextEdit(this);
|
messageLog = new QTextEdit(this);
|
||||||
messageLog->setReadOnly(true);
|
messageLog->setReadOnly(true);
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout(this);
|
auto *layout = new QGridLayout(this);
|
||||||
layout->addWidget(defaultPathCheckBox, 0, 0);
|
layout->addWidget(defaultPathCheckBox, 0, 0);
|
||||||
layout->addWidget(messageLog, 1, 0);
|
layout->addWidget(messageLog, 1, 0);
|
||||||
|
|
||||||
|
@ -472,7 +513,7 @@ SaveSetsPage::SaveSetsPage(QWidget *parent)
|
||||||
|
|
||||||
void SaveSetsPage::cleanupPage()
|
void SaveSetsPage::cleanupPage()
|
||||||
{
|
{
|
||||||
disconnect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), 0, 0);
|
disconnect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSetsPage::initializePage()
|
void SaveSetsPage::initializePage()
|
||||||
|
@ -482,7 +523,9 @@ void SaveSetsPage::initializePage()
|
||||||
connect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
|
connect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
|
||||||
|
|
||||||
if (!wizard()->importer->startImport())
|
if (!wizard()->importer->startImport())
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSetsPage::retranslateUi()
|
void SaveSetsPage::retranslateUi()
|
||||||
|
@ -496,11 +539,15 @@ void SaveSetsPage::retranslateUi()
|
||||||
|
|
||||||
void SaveSetsPage::updateTotalProgress(int cardsImported, int /* setIndex */, const QString &setName)
|
void SaveSetsPage::updateTotalProgress(int cardsImported, int /* setIndex */, const QString &setName)
|
||||||
{
|
{
|
||||||
if (setName.isEmpty()) {
|
if (setName.isEmpty())
|
||||||
|
{
|
||||||
messageLog->append("<b>" + tr("Import finished: %1 cards.").arg(wizard()->importer->getCardList().size()) + "</b>");
|
messageLog->append("<b>" + tr("Import finished: %1 cards.").arg(wizard()->importer->getCardList().size()) + "</b>");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
messageLog->append(tr("%1: %2 cards imported").arg(setName).arg(cardsImported));
|
messageLog->append(tr("%1: %2 cards imported").arg(setName).arg(cardsImported));
|
||||||
}
|
}
|
||||||
|
|
||||||
messageLog->verticalScrollBar()->setValue(messageLog->verticalScrollBar()->maximum());
|
messageLog->verticalScrollBar()->setValue(messageLog->verticalScrollBar()->maximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,39 +558,51 @@ bool SaveSetsPage::validatePage()
|
||||||
QString windowName = tr("Save card database");
|
QString windowName = tr("Save card database");
|
||||||
QString fileType = tr("XML; card database (*.xml)");
|
QString fileType = tr("XML; card database (*.xml)");
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
QString fileName;
|
QString fileName;
|
||||||
if (defaultPathCheckBox->isChecked())
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
fileName = defaultPath;
|
fileName = defaultPath;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
|
fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
|
||||||
|
}
|
||||||
|
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
QDir fileDir(fi.path());
|
QDir fileDir(fi.path());
|
||||||
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath())) {
|
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wizard()->importer->saveToFile(fileName))
|
if (wizard()->importer->saveToFile(fileName))
|
||||||
{
|
{
|
||||||
ok = true;
|
ok = true;
|
||||||
QMessageBox::information(this,
|
QMessageBox::information(this,
|
||||||
tr("Success"),
|
tr("Success"),
|
||||||
tr("The card database has been saved successfully to\n%1").arg(fileName));
|
tr("The card database has been saved successfully to\n%1").arg(fileName));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));;
|
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));;
|
||||||
if (defaultPathCheckBox->isChecked())
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
defaultPathCheckBox->setChecked(false);
|
defaultPathCheckBox->setChecked(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadTokensPage::LoadTokensPage(QWidget *parent)
|
LoadSpoilersPage::LoadSpoilersPage(QWidget *parent) : OracleWizardPage(parent), nam(nullptr)
|
||||||
: OracleWizardPage(parent), nam(0)
|
|
||||||
{
|
{
|
||||||
urlLabel = new QLabel(this);
|
urlLabel = new QLabel(this);
|
||||||
urlLineEdit = new QLineEdit(this);
|
urlLineEdit = new QLineEdit(this);
|
||||||
|
@ -554,7 +613,152 @@ LoadTokensPage::LoadTokensPage(QWidget *parent)
|
||||||
urlButton = new QPushButton(this);
|
urlButton = new QPushButton(this);
|
||||||
connect(urlButton, SIGNAL(clicked()), this, SLOT(actRestoreDefaultUrl()));
|
connect(urlButton, SIGNAL(clicked()), this, SLOT(actRestoreDefaultUrl()));
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout(this);
|
auto *layout = new QGridLayout(this);
|
||||||
|
layout->addWidget(urlLabel, 0, 0);
|
||||||
|
layout->addWidget(urlLineEdit, 0, 1);
|
||||||
|
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
||||||
|
layout->addWidget(progressLabel, 2, 0);
|
||||||
|
layout->addWidget(progressBar, 2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::actRestoreDefaultUrl()
|
||||||
|
{
|
||||||
|
urlLineEdit->setText(SPOILERS_URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::initializePage()
|
||||||
|
{
|
||||||
|
urlLineEdit->setText(wizard()->settings->value("spoilersurl", SPOILERS_URL).toString());
|
||||||
|
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::actDownloadProgressSpoilersFile(qint64 received, qint64 total)
|
||||||
|
{
|
||||||
|
if (total > 0)
|
||||||
|
{
|
||||||
|
progressBar->setMaximum(static_cast<int>(total));
|
||||||
|
progressBar->setValue(static_cast<int>(received));
|
||||||
|
}
|
||||||
|
|
||||||
|
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::actDownloadFinishedSpoilersFile()
|
||||||
|
{
|
||||||
|
// Check for server reply
|
||||||
|
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||||
|
QNetworkReply::NetworkError errorCode = reply->error();
|
||||||
|
|
||||||
|
if (errorCode != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
||||||
|
|
||||||
|
wizard()->enableButtons();
|
||||||
|
setEnabled(true);
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
if (statusCode == 301 || statusCode == 302)
|
||||||
|
{
|
||||||
|
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||||
|
qDebug() << "following redirect url:" << redirectUrl.toString();
|
||||||
|
downloadSpoilersFile(redirectUrl);
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
|
||||||
|
// save spoiler.xml url, but only if the user customized it and download was successful
|
||||||
|
if (urlLineEdit->text() != QString(SPOILERS_URL))
|
||||||
|
{
|
||||||
|
wizard()->settings->setValue("spoilersurl", urlLineEdit->text());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wizard()->settings->remove("spoilersurl");
|
||||||
|
}
|
||||||
|
|
||||||
|
wizard()->setTokensData(reply->readAll());
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
wizard()->enableButtons();
|
||||||
|
setEnabled(true);
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
|
||||||
|
wizard()->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::downloadSpoilersFile(QUrl url)
|
||||||
|
{
|
||||||
|
if (!nam)
|
||||||
|
{
|
||||||
|
nam = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
|
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSpoilersFile()));
|
||||||
|
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(actDownloadProgressSpoilersFile(qint64, qint64)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadSpoilersPage::validatePage()
|
||||||
|
{
|
||||||
|
// once the import is finished, we call next(); skip validation
|
||||||
|
if (wizard()->hasTokensData())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
||||||
|
if (!url.isValid())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressLabel->setText(tr("Downloading (0MB)"));
|
||||||
|
// show an infinite progressbar
|
||||||
|
progressBar->setMaximum(0);
|
||||||
|
progressBar->setMinimum(0);
|
||||||
|
progressBar->setValue(0);
|
||||||
|
progressLabel->show();
|
||||||
|
progressBar->show();
|
||||||
|
|
||||||
|
wizard()->disableButtons();
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
|
downloadSpoilersFile(url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSpoilersPage::retranslateUi()
|
||||||
|
{
|
||||||
|
setTitle(tr("Spoilers source selection"));
|
||||||
|
setSubTitle(tr("Please specify a spoiler source."));
|
||||||
|
|
||||||
|
urlLabel->setText(tr("Download URL:"));
|
||||||
|
urlButton->setText(tr("Restore default URL"));
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadTokensPage::LoadTokensPage(QWidget *parent) : OracleWizardPage(parent), nam(nullptr)
|
||||||
|
{
|
||||||
|
urlLabel = new QLabel(this);
|
||||||
|
urlLineEdit = new QLineEdit(this);
|
||||||
|
|
||||||
|
progressLabel = new QLabel(this);
|
||||||
|
progressBar = new QProgressBar(this);
|
||||||
|
|
||||||
|
urlButton = new QPushButton(this);
|
||||||
|
connect(urlButton, SIGNAL(clicked()), this, SLOT(actRestoreDefaultUrl()));
|
||||||
|
|
||||||
|
auto *layout = new QGridLayout(this);
|
||||||
layout->addWidget(urlLabel, 0, 0);
|
layout->addWidget(urlLabel, 0, 0);
|
||||||
layout->addWidget(urlLineEdit, 0, 1);
|
layout->addWidget(urlLineEdit, 0, 1);
|
||||||
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
||||||
|
@ -589,11 +793,13 @@ void LoadTokensPage::actRestoreDefaultUrl()
|
||||||
bool LoadTokensPage::validatePage()
|
bool LoadTokensPage::validatePage()
|
||||||
{
|
{
|
||||||
// once the import is finished, we call next(); skip validation
|
// once the import is finished, we call next(); skip validation
|
||||||
if(wizard()->hasTokensData())
|
if (wizard()->hasTokensData())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
||||||
if(!url.isValid())
|
if (!url.isValid())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
|
QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
|
||||||
return false;
|
return false;
|
||||||
|
@ -616,8 +822,10 @@ bool LoadTokensPage::validatePage()
|
||||||
|
|
||||||
void LoadTokensPage::downloadTokensFile(QUrl url)
|
void LoadTokensPage::downloadTokensFile(QUrl url)
|
||||||
{
|
{
|
||||||
if(!nam)
|
if (!nam)
|
||||||
|
{
|
||||||
nam = new QNetworkAccessManager(this);
|
nam = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedTokensFile()));
|
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedTokensFile()));
|
||||||
|
@ -626,10 +834,10 @@ void LoadTokensPage::downloadTokensFile(QUrl url)
|
||||||
|
|
||||||
void LoadTokensPage::actDownloadProgressTokensFile(qint64 received, qint64 total)
|
void LoadTokensPage::actDownloadProgressTokensFile(qint64 received, qint64 total)
|
||||||
{
|
{
|
||||||
if(total > 0)
|
if (total > 0)
|
||||||
{
|
{
|
||||||
progressBar->setMaximum(total);
|
progressBar->setMaximum(static_cast<int>(total));
|
||||||
progressBar->setValue(received);
|
progressBar->setValue(static_cast<int>(received));
|
||||||
}
|
}
|
||||||
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
||||||
}
|
}
|
||||||
|
@ -637,9 +845,10 @@ void LoadTokensPage::actDownloadProgressTokensFile(qint64 received, qint64 total
|
||||||
void LoadTokensPage::actDownloadFinishedTokensFile()
|
void LoadTokensPage::actDownloadFinishedTokensFile()
|
||||||
{
|
{
|
||||||
// check for a reply
|
// check for a reply
|
||||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||||
QNetworkReply::NetworkError errorCode = reply->error();
|
QNetworkReply::NetworkError errorCode = reply->error();
|
||||||
if (errorCode != QNetworkReply::NoError) {
|
if (errorCode != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
||||||
|
|
||||||
wizard()->enableButtons();
|
wizard()->enableButtons();
|
||||||
|
@ -650,7 +859,8 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
if (statusCode == 301 || statusCode == 302) {
|
if (statusCode == 301 || statusCode == 302)
|
||||||
|
{
|
||||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||||
qDebug() << "following redirect url:" << redirectUrl.toString();
|
qDebug() << "following redirect url:" << redirectUrl.toString();
|
||||||
downloadTokensFile(redirectUrl);
|
downloadTokensFile(redirectUrl);
|
||||||
|
@ -662,10 +872,14 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
||||||
progressBar->hide();
|
progressBar->hide();
|
||||||
|
|
||||||
// save tokens.xml url, but only if the user customized it and download was successfull
|
// save tokens.xml url, but only if the user customized it and download was successfull
|
||||||
if(urlLineEdit->text() != QString(TOKENS_URL))
|
if (urlLineEdit->text() != QString(TOKENS_URL))
|
||||||
|
{
|
||||||
wizard()->settings->setValue("tokensurl", urlLineEdit->text());
|
wizard()->settings->setValue("tokensurl", urlLineEdit->text());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
wizard()->settings->remove("tokensurl");
|
wizard()->settings->remove("tokensurl");
|
||||||
|
}
|
||||||
|
|
||||||
wizard()->setTokensData(reply->readAll());
|
wizard()->setTokensData(reply->readAll());
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
@ -678,13 +892,81 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
||||||
wizard()->next();
|
wizard()->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveTokensPage::SaveTokensPage(QWidget *parent)
|
SaveSpoilersPage::SaveSpoilersPage(QWidget *parent) : OracleWizardPage(parent)
|
||||||
: OracleWizardPage(parent)
|
|
||||||
{
|
{
|
||||||
defaultPathCheckBox = new QCheckBox(this);
|
defaultPathCheckBox = new QCheckBox(this);
|
||||||
defaultPathCheckBox->setChecked(true);
|
defaultPathCheckBox->setChecked(true);
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout(this);
|
auto *layout = new QGridLayout(this);
|
||||||
|
layout->addWidget(defaultPathCheckBox, 0, 0);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveSpoilersPage::retranslateUi()
|
||||||
|
{
|
||||||
|
setTitle(tr("Spoilers imported"));
|
||||||
|
setSubTitle(tr("The spoilers file has been imported. "
|
||||||
|
"Press \"Save\" to save the imported spoilers to the Cockatrice card database."));
|
||||||
|
|
||||||
|
defaultPathCheckBox->setText(tr("Save to the default path (recommended)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveSpoilersPage::validatePage()
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
QString defaultPath = settingsCache->getSpoilerCardDatabasePath();
|
||||||
|
QString windowName = tr("Save spoiler database");
|
||||||
|
QString fileType = tr("XML; card database (*.xml)");
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
QString fileName;
|
||||||
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
|
fileName = defaultPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDir fileDir(fi.path());
|
||||||
|
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wizard()->saveTokensToFile(fileName))
|
||||||
|
{
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));;
|
||||||
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
|
defaultPathCheckBox->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!ok);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveTokensPage::SaveTokensPage(QWidget *parent) : OracleWizardPage(parent)
|
||||||
|
{
|
||||||
|
defaultPathCheckBox = new QCheckBox(this);
|
||||||
|
defaultPathCheckBox->setChecked(true);
|
||||||
|
|
||||||
|
auto *layout = new QGridLayout(this);
|
||||||
layout->addWidget(defaultPathCheckBox, 0, 0);
|
layout->addWidget(defaultPathCheckBox, 0, 0);
|
||||||
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
@ -706,33 +988,47 @@ bool SaveTokensPage::validatePage()
|
||||||
QString windowName = tr("Save token database");
|
QString windowName = tr("Save token database");
|
||||||
QString fileType = tr("XML; token database (*.xml)");
|
QString fileType = tr("XML; token database (*.xml)");
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
QString fileName;
|
QString fileName;
|
||||||
if (defaultPathCheckBox->isChecked())
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
fileName = defaultPath;
|
fileName = defaultPath;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
|
fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
|
||||||
|
}
|
||||||
|
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
QDir fileDir(fi.path());
|
QDir fileDir(fi.path());
|
||||||
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath())) {
|
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wizard()->saveTokensToFile(fileName))
|
if (wizard()->saveTokensToFile(fileName))
|
||||||
{
|
{
|
||||||
ok = true;
|
ok = true;
|
||||||
QMessageBox::information(this,
|
QMessageBox::information(this,
|
||||||
tr("Success"),
|
tr("Success"),
|
||||||
tr("The token database has been saved successfully to\n%1").arg(fileName));
|
tr("The token database has been saved successfully to\n%1").arg(fileName));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));;
|
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));;
|
||||||
if (defaultPathCheckBox->isChecked())
|
if (defaultPathCheckBox->isChecked())
|
||||||
|
{
|
||||||
defaultPathCheckBox->setChecked(false);
|
defaultPathCheckBox->setChecked(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QWizard>
|
#include <QWizard>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QGroupBox;
|
class QGroupBox;
|
||||||
|
@ -20,139 +21,195 @@ class QSettings;
|
||||||
|
|
||||||
class OracleWizard : public QWizard
|
class OracleWizard : public QWizard
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OracleWizard(QWidget *parent = 0);
|
explicit OracleWizard(QWidget *parent = nullptr);
|
||||||
void accept();
|
void accept() override;
|
||||||
void enableButtons();
|
void enableButtons();
|
||||||
void disableButtons();
|
void disableButtons();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void setTokensData(QByteArray _tokensData) { tokensData = _tokensData; }
|
void setTokensData(QByteArray _tokensData) { tokensData = std::move(_tokensData); }
|
||||||
bool hasTokensData() { return !tokensData.isEmpty(); }
|
bool hasTokensData() { return !tokensData.isEmpty(); }
|
||||||
bool saveTokensToFile(const QString & fileName);
|
bool saveTokensToFile(const QString & fileName);
|
||||||
public:
|
|
||||||
OracleImporter *importer;
|
|
||||||
QSettings * settings;
|
|
||||||
private slots:
|
|
||||||
void updateLanguage();
|
|
||||||
private:
|
|
||||||
QStringList findQmFiles();
|
|
||||||
QString languageName(const QString &qmFile);
|
|
||||||
QByteArray tokensData;
|
|
||||||
protected:
|
|
||||||
void changeEvent(QEvent *event);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
OracleImporter *importer;
|
||||||
|
QSettings *settings;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateLanguage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray tokensData;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent *event) override;
|
||||||
|
};
|
||||||
|
|
||||||
class OracleWizardPage : public QWizardPage
|
class OracleWizardPage : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OracleWizardPage(QWidget *parent = 0): QWizardPage(parent) {};
|
explicit OracleWizardPage(QWidget *parent = nullptr): QWizardPage(parent) {};
|
||||||
virtual void retranslateUi() = 0;
|
virtual void retranslateUi() = 0;
|
||||||
protected:
|
|
||||||
inline OracleWizard *wizard() { return (OracleWizard*) QWizardPage::wizard(); };
|
protected:
|
||||||
|
inline OracleWizard *wizard() { return (OracleWizard*) QWizardPage::wizard(); };
|
||||||
};
|
};
|
||||||
|
|
||||||
class IntroPage : public OracleWizardPage
|
class IntroPage : public OracleWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
IntroPage(QWidget *parent = 0);
|
explicit IntroPage(QWidget *parent = nullptr);
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private:
|
|
||||||
QStringList findQmFiles();
|
private:
|
||||||
QString languageName(const QString &qmFile);
|
QStringList findQmFiles();
|
||||||
private:
|
QString languageName(const QString &qmFile);
|
||||||
QLabel *label, *languageLabel, *versionLabel;
|
|
||||||
QComboBox *languageBox;
|
private:
|
||||||
private slots:
|
QLabel *label, *languageLabel, *versionLabel;
|
||||||
void languageBoxChanged(int index);
|
QComboBox *languageBox;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void languageBoxChanged(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
class LoadSetsPage : public OracleWizardPage
|
class LoadSetsPage : public OracleWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
LoadSetsPage(QWidget *parent = 0);
|
explicit LoadSetsPage(QWidget *parent = nullptr);
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
protected:
|
|
||||||
void initializePage();
|
|
||||||
bool validatePage();
|
|
||||||
void readSetsFromByteArray(QByteArray data);
|
|
||||||
void downloadSetsFile(QUrl url);
|
|
||||||
private:
|
|
||||||
QRadioButton *urlRadioButton;
|
|
||||||
QRadioButton *fileRadioButton;
|
|
||||||
QLineEdit *urlLineEdit;
|
|
||||||
QLineEdit *fileLineEdit;
|
|
||||||
QPushButton *urlButton;
|
|
||||||
QPushButton *fileButton;
|
|
||||||
QLabel *progressLabel;
|
|
||||||
QProgressBar * progressBar;
|
|
||||||
|
|
||||||
QNetworkAccessManager *nam;
|
protected:
|
||||||
QFutureWatcher<bool> watcher;
|
void initializePage() override;
|
||||||
QFuture<bool> future;
|
bool validatePage() override;
|
||||||
private slots:
|
void readSetsFromByteArray(QByteArray data);
|
||||||
void actLoadSetsFile();
|
void downloadSetsFile(QUrl url);
|
||||||
void actRestoreDefaultUrl();
|
|
||||||
void actDownloadProgressSetsFile(qint64 received, qint64 total);
|
private:
|
||||||
void actDownloadFinishedSetsFile();
|
QRadioButton *urlRadioButton;
|
||||||
void importFinished();
|
QRadioButton *fileRadioButton;
|
||||||
void zipDownloadFailed(const QString &message);
|
QLineEdit *urlLineEdit;
|
||||||
|
QLineEdit *fileLineEdit;
|
||||||
|
QPushButton *urlButton;
|
||||||
|
QPushButton *fileButton;
|
||||||
|
QLabel *progressLabel;
|
||||||
|
QProgressBar *progressBar;
|
||||||
|
|
||||||
|
QNetworkAccessManager *nam;
|
||||||
|
QFutureWatcher<bool> watcher;
|
||||||
|
QFuture<bool> future;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actLoadSetsFile();
|
||||||
|
void actRestoreDefaultUrl();
|
||||||
|
void actDownloadProgressSetsFile(qint64 received, qint64 total);
|
||||||
|
void actDownloadFinishedSetsFile();
|
||||||
|
void importFinished();
|
||||||
|
void zipDownloadFailed(const QString &message);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SaveSetsPage : public OracleWizardPage
|
class SaveSetsPage : public OracleWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SaveSetsPage(QWidget *parent = 0);
|
explicit SaveSetsPage(QWidget *parent = nullptr);
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private:
|
|
||||||
QTextEdit *messageLog;
|
private:
|
||||||
QCheckBox * defaultPathCheckBox;
|
QTextEdit *messageLog;
|
||||||
protected:
|
QCheckBox *defaultPathCheckBox;
|
||||||
void initializePage();
|
|
||||||
void cleanupPage();
|
protected:
|
||||||
bool validatePage();
|
void initializePage() override;
|
||||||
private slots:
|
void cleanupPage() override;
|
||||||
void updateTotalProgress(int cardsImported, int setIndex, const QString &setName);
|
bool validatePage() override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateTotalProgress(int cardsImported, int setIndex, const QString &setName);
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoadSpoilersPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LoadSpoilersPage(QWidget *parent = nullptr);
|
||||||
|
void retranslateUi() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel *urlLabel;
|
||||||
|
QLineEdit *urlLineEdit;
|
||||||
|
QPushButton *urlButton;
|
||||||
|
QLabel *progressLabel;
|
||||||
|
QProgressBar *progressBar;
|
||||||
|
QNetworkAccessManager *nam;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actRestoreDefaultUrl();
|
||||||
|
void actDownloadProgressSpoilersFile(qint64 received, qint64 total);
|
||||||
|
void actDownloadFinishedSpoilersFile();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initializePage() override;
|
||||||
|
bool validatePage() override;
|
||||||
|
void downloadSpoilersFile(QUrl url);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SaveSpoilersPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SaveSpoilersPage(QWidget *parent = nullptr);
|
||||||
|
void retranslateUi() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QCheckBox *defaultPathCheckBox;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool validatePage() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LoadTokensPage : public OracleWizardPage
|
class LoadTokensPage : public OracleWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
LoadTokensPage(QWidget *parent = 0);
|
explicit LoadTokensPage(QWidget *parent = nullptr);
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
protected:
|
|
||||||
void initializePage();
|
|
||||||
bool validatePage();
|
|
||||||
void downloadTokensFile(QUrl url);
|
|
||||||
private:
|
|
||||||
QLabel *urlLabel;
|
|
||||||
QLineEdit *urlLineEdit;
|
|
||||||
QPushButton *urlButton;
|
|
||||||
QLabel *progressLabel;
|
|
||||||
QProgressBar * progressBar;
|
|
||||||
|
|
||||||
QNetworkAccessManager *nam;
|
protected:
|
||||||
private slots:
|
void initializePage() override;
|
||||||
void actRestoreDefaultUrl();
|
bool validatePage() override;
|
||||||
void actDownloadProgressTokensFile(qint64 received, qint64 total);
|
void downloadTokensFile(QUrl url);
|
||||||
void actDownloadFinishedTokensFile();
|
|
||||||
|
private:
|
||||||
|
QLabel *urlLabel;
|
||||||
|
QLineEdit *urlLineEdit;
|
||||||
|
QPushButton *urlButton;
|
||||||
|
QLabel *progressLabel;
|
||||||
|
QProgressBar *progressBar;
|
||||||
|
QNetworkAccessManager *nam;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actRestoreDefaultUrl();
|
||||||
|
void actDownloadProgressTokensFile(qint64 received, qint64 total);
|
||||||
|
void actDownloadFinishedTokensFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
class SaveTokensPage : public OracleWizardPage
|
class SaveTokensPage : public OracleWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SaveTokensPage(QWidget *parent = 0);
|
explicit SaveTokensPage(QWidget *parent = nullptr);
|
||||||
void retranslateUi();
|
void retranslateUi() override;
|
||||||
private:
|
|
||||||
QCheckBox * defaultPathCheckBox;
|
private:
|
||||||
protected:
|
QCheckBox *defaultPathCheckBox;
|
||||||
bool validatePage();
|
|
||||||
|
protected:
|
||||||
|
bool validatePage() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -14,6 +14,7 @@ SettingsCache::~SettingsCache() { delete cardDatabaseSettings; };
|
||||||
QString SettingsCache::getCustomCardDatabasePath() const { return QString("%1/customsets/").arg(CARDDB_DATADIR); }
|
QString SettingsCache::getCustomCardDatabasePath() const { return QString("%1/customsets/").arg(CARDDB_DATADIR); }
|
||||||
QString SettingsCache::getCardDatabasePath() const { return QString("%1/cards.xml").arg(CARDDB_DATADIR); }
|
QString SettingsCache::getCardDatabasePath() const { return QString("%1/cards.xml").arg(CARDDB_DATADIR); }
|
||||||
QString SettingsCache::getTokenDatabasePath() const { return QString("%1/tokens.xml").arg(CARDDB_DATADIR); }
|
QString SettingsCache::getTokenDatabasePath() const { return QString("%1/tokens.xml").arg(CARDDB_DATADIR); }
|
||||||
|
QString SettingsCache::getSpoilerCardDatabasePath() const { return QString("%1/spoiler.xml").arg(CARDDB_DATADIR); }
|
||||||
CardDatabaseSettings& SettingsCache::cardDatabase() const { return *cardDatabaseSettings; }
|
CardDatabaseSettings& SettingsCache::cardDatabase() const { return *cardDatabaseSettings; }
|
||||||
|
|
||||||
SettingsCache *settingsCache;
|
SettingsCache *settingsCache;
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
QString getCustomCardDatabasePath() const;
|
QString getCustomCardDatabasePath() const;
|
||||||
QString getCardDatabasePath() const;
|
QString getCardDatabasePath() const;
|
||||||
QString getTokenDatabasePath() const;
|
QString getTokenDatabasePath() const;
|
||||||
|
QString getSpoilerCardDatabasePath() const;
|
||||||
CardDatabaseSettings& cardDatabase() const;
|
CardDatabaseSettings& cardDatabase() const;
|
||||||
signals:
|
signals:
|
||||||
void cardDatabasePathChanged();
|
void cardDatabasePathChanged();
|
||||||
|
|
17
tests/carddatabase/data/spoilers.xml
Normal file
17
tests/carddatabase/data/spoilers.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<cockatrice_carddatabase version="3">
|
||||||
|
<cards>
|
||||||
|
<card>
|
||||||
|
<name>Fluffy</name>
|
||||||
|
<set muId="311">CAT</set>
|
||||||
|
<color>G</color>
|
||||||
|
<manacost></manacost>
|
||||||
|
<cmc></cmc>
|
||||||
|
<type>Token</type>
|
||||||
|
<pt>0/1</pt>
|
||||||
|
<tablerow>0</tablerow>
|
||||||
|
<text></text>
|
||||||
|
<token>1</token>
|
||||||
|
</card>
|
||||||
|
</cards>
|
||||||
|
</cockatrice_carddatabase>
|
Loading…
Reference in a new issue