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/releasechannel.cpp
|
||||
src/userconnection_information.cpp
|
||||
src/spoilerbackgroundupdater.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,7 @@
|
|||
#include <QDataStream>
|
||||
#include <QList>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QBasicMutex>
|
||||
|
||||
class CardDatabase;
|
||||
class CardInfo;
|
||||
|
@ -18,15 +19,17 @@ typedef QMap<QString, QString> QStringMap;
|
|||
// If we don't typedef this, CardInfo::CardInfo will refuse to compile on OS X < 10.9
|
||||
typedef QMap<QString, int> MuidMap;
|
||||
|
||||
class CardSet : public QList<CardInfo *> {
|
||||
class CardSet : public QList<CardInfo *>
|
||||
{
|
||||
private:
|
||||
QString shortName, longName;
|
||||
unsigned int sortKey;
|
||||
QDate releaseDate;
|
||||
QString setType;
|
||||
bool enabled, isknown;
|
||||
|
||||
public:
|
||||
CardSet(const QString &_shortName = QString(), const QString &_longName = QString(), const QString &_setType = QString(), const QDate &_releaseDate = QDate());
|
||||
explicit 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; }
|
||||
|
@ -43,13 +46,16 @@ public:
|
|||
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;
|
||||
|
||||
public:
|
||||
void sortByKey();
|
||||
void guessSortKeys();
|
||||
|
@ -61,7 +67,8 @@ public:
|
|||
QStringList getUnknownSetsNames();
|
||||
};
|
||||
|
||||
class CardInfo : public QObject {
|
||||
class CardInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString name;
|
||||
|
@ -80,13 +87,18 @@ private:
|
|||
QString powtough;
|
||||
QString text;
|
||||
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;
|
||||
|
@ -96,8 +108,9 @@ private:
|
|||
bool cipt;
|
||||
int tableRow;
|
||||
QString pixmapCacheKey;
|
||||
|
||||
public:
|
||||
CardInfo(const QString &_name = QString(),
|
||||
explicit CardInfo(const QString &_name = QString(),
|
||||
bool _isToken = false,
|
||||
const QString &_manacost = QString(),
|
||||
const QString &_cmc = QString(),
|
||||
|
@ -117,7 +130,8 @@ public:
|
|||
QStringMap _collectorNumbers = QStringMap(),
|
||||
QStringMap _rarities = QStringMap()
|
||||
);
|
||||
~CardInfo();
|
||||
~CardInfo() override;
|
||||
|
||||
inline const QString &getName() const { return name; }
|
||||
inline const QString &getSetsNames() const { return setsNames; }
|
||||
const QString &getSimpleName() const { return simpleName; }
|
||||
|
@ -131,8 +145,8 @@ public:
|
|||
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 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); }
|
||||
|
@ -154,8 +168,8 @@ public:
|
|||
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 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); }
|
||||
|
@ -168,6 +182,7 @@ public:
|
|||
* less strict name-matching.
|
||||
*/
|
||||
static QString simplifyName(const QString &name);
|
||||
|
||||
signals:
|
||||
void pixmapUpdated();
|
||||
void cardInfoChanged(CardInfo *card);
|
||||
|
@ -178,7 +193,8 @@ enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
|||
typedef QHash<QString, CardInfo *> CardNameMap;
|
||||
typedef QHash<QString, CardSet *> SetNameMap;
|
||||
|
||||
class CardDatabase : public QObject {
|
||||
class CardDatabase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
/*
|
||||
|
@ -205,11 +221,18 @@ private:
|
|||
CardInfo *getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
||||
void checkUnknownSets();
|
||||
void refreshCachedReverseRelatedCards();
|
||||
|
||||
QBasicMutex *reloadDatabaseMutex = new QBasicMutex(),
|
||||
*clearDatabaseMutex = new QBasicMutex(),
|
||||
*loadFromFileMutex = new QBasicMutex(),
|
||||
*addCardMutex = new QBasicMutex(),
|
||||
*removeCardMutex = new QBasicMutex();
|
||||
|
||||
public:
|
||||
static const char* TOKENS_SETNAME;
|
||||
|
||||
CardDatabase(QObject *parent = 0);
|
||||
~CardDatabase();
|
||||
explicit CardDatabase(QObject *parent = nullptr);
|
||||
~CardDatabase() override;
|
||||
void clear();
|
||||
void addCard(CardInfo *card);
|
||||
void removeCard(CardInfo *card);
|
||||
|
@ -248,7 +271,8 @@ signals:
|
|||
void cardRemoved(CardInfo *card);
|
||||
};
|
||||
|
||||
class CardRelation : public QObject {
|
||||
class CardRelation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString name;
|
||||
|
@ -257,12 +281,13 @@ private:
|
|||
bool isVariableCount;
|
||||
int defaultCount;
|
||||
public:
|
||||
CardRelation(const QString &_name = QString(),
|
||||
explicit CardRelation(const QString &_name = QString(),
|
||||
bool _doesAttach = false,
|
||||
bool _isCreateAllExclusion = false,
|
||||
bool _isVariableCount = false,
|
||||
int _defaultCount = 1
|
||||
);
|
||||
|
||||
inline const QString &getName() const { return name; }
|
||||
bool getDoesAttach() const { return doesAttach; }
|
||||
bool getCanCreateAnother() const { return !doesAttach; }
|
||||
|
@ -270,5 +295,4 @@ public:
|
|||
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"
|
||||
|
||||
DlgConnect::DlgConnect(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
previousHostButton = new QRadioButton(tr("Known Hosts"), this);
|
||||
previousHosts = new QComboBox(this);
|
||||
|
@ -64,7 +63,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
|
||||
if (savePasswordCheckBox->isChecked())
|
||||
{
|
||||
autoConnectCheckBox->setChecked(settingsCache->servers().getAutoConnect());
|
||||
autoConnectCheckBox->setChecked(static_cast<bool>(settingsCache->servers().getAutoConnect()));
|
||||
autoConnectCheckBox->setEnabled(true);
|
||||
}
|
||||
else
|
||||
|
@ -87,11 +86,11 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
btnCancel->setFixedWidth(100);
|
||||
connect(btnCancel, SIGNAL(released()), this, SLOT(actCancel()));
|
||||
|
||||
QGridLayout *newHostLayout = new QGridLayout;
|
||||
auto *newHostLayout = new QGridLayout;
|
||||
newHostLayout->addWidget(newHostButton, 0, 1);
|
||||
newHostLayout->addWidget(publicServersLabel, 0, 2);
|
||||
|
||||
QGridLayout *connectionLayout = new QGridLayout;
|
||||
auto *connectionLayout = new QGridLayout;
|
||||
connectionLayout->addWidget(previousHostButton, 0, 1);
|
||||
connectionLayout->addWidget(previousHosts, 1, 1);
|
||||
connectionLayout->addLayout(newHostLayout, 2, 1, 1, 2);
|
||||
|
@ -103,7 +102,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
connectionLayout->addWidget(portEdit, 5, 1);
|
||||
connectionLayout->addWidget(autoConnectCheckBox, 6, 1);
|
||||
|
||||
QGridLayout *buttons = new QGridLayout;
|
||||
auto *buttons = new QGridLayout;
|
||||
buttons->addWidget(btnOk, 0, 0);
|
||||
buttons->addWidget(btnForgotPassword, 0, 1);
|
||||
buttons->addWidget(btnCancel, 0, 2);
|
||||
|
@ -111,7 +110,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
QGroupBox *restrictionsGroupBox = new QGroupBox(tr("Server"));
|
||||
restrictionsGroupBox->setLayout(connectionLayout);
|
||||
|
||||
QGridLayout *loginLayout = new QGridLayout;
|
||||
auto *loginLayout = new QGridLayout;
|
||||
loginLayout->addWidget(playernameLabel, 0, 0);
|
||||
loginLayout->addWidget(playernameEdit, 0, 1);
|
||||
loginLayout->addWidget(passwordLabel, 1, 0);
|
||||
|
@ -124,12 +123,12 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
QGroupBox *btnGroupBox = new QGroupBox(tr(""));
|
||||
btnGroupBox->setLayout(buttons);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
auto *grid = new QGridLayout;
|
||||
grid->addWidget(restrictionsGroupBox, 0, 0);
|
||||
grid->addWidget(loginGroupBox, 1, 0);
|
||||
grid->addWidget(btnGroupBox, 2, 0);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
setLayout(mainLayout);
|
||||
|
||||
|
@ -289,9 +288,9 @@ void DlgConnect::actCancel()
|
|||
bool DeleteHighlightedItemWhenShiftDelPressedEventFilter::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
auto *keyEvent = dynamic_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key_Delete) {
|
||||
QComboBox* combobox = reinterpret_cast<QComboBox *>(obj);
|
||||
auto *combobox = reinterpret_cast<QComboBox *>(obj);
|
||||
combobox->removeItem(combobox->currentIndex());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "releasechannel.h"
|
||||
#include "soundengine.h"
|
||||
#include "sequenceEdit/shortcutstab.h"
|
||||
#include "spoilerbackgroundupdater.h"
|
||||
|
||||
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
|
||||
|
||||
|
@ -81,7 +82,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
|
||||
setEnabledStatus(settingsCache->getPicDownload());
|
||||
|
||||
QGridLayout *personalGrid = new QGridLayout;
|
||||
auto *personalGrid = new QGridLayout;
|
||||
personalGrid->addWidget(&languageLabel, 0, 0);
|
||||
personalGrid->addWidget(&languageBox, 0, 1);
|
||||
personalGrid->addWidget(&updateReleaseChannelLabel, 1, 0);
|
||||
|
@ -145,7 +146,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
tokenDatabasePathButton->setVisible(false);
|
||||
}
|
||||
|
||||
QGridLayout *pathsGrid = new QGridLayout;
|
||||
auto *pathsGrid = new QGridLayout;
|
||||
pathsGrid->addWidget(&deckPathLabel, 0, 0);
|
||||
pathsGrid->addWidget(deckPathEdit, 0, 1);
|
||||
pathsGrid->addWidget(deckPathButton, 0, 2);
|
||||
|
@ -164,7 +165,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
pathsGroupBox = new QGroupBox;
|
||||
pathsGroupBox->setLayout(pathsGrid);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(personalGroupBox);
|
||||
mainLayout->addWidget(pathsGroupBox);
|
||||
|
||||
|
@ -333,7 +334,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
|
||||
connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int)));
|
||||
|
||||
QGridLayout *themeGrid = new QGridLayout;
|
||||
auto *themeGrid = new QGridLayout;
|
||||
themeGrid->addWidget(&themeLabel, 0, 0);
|
||||
themeGrid->addWidget(&themeBox, 0, 1);
|
||||
|
||||
|
@ -346,7 +347,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
cardScalingCheckBox.setChecked(settingsCache->getScaleCards());
|
||||
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(&cardScalingCheckBox, 1, 0, 1, 2);
|
||||
|
||||
|
@ -359,7 +360,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
leftJustifiedHandCheckBox.setChecked(settingsCache->getLeftJustified());
|
||||
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(&leftJustifiedHandCheckBox, 1, 0, 1, 2);
|
||||
|
||||
|
@ -380,7 +381,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
maxFontSizeForCardsEdit.setMinimum(9);
|
||||
maxFontSizeForCardsEdit.setMaximum(100);
|
||||
|
||||
QGridLayout *tableGrid = new QGridLayout;
|
||||
auto *tableGrid = new QGridLayout;
|
||||
tableGrid->addWidget(&invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
|
||||
tableGrid->addWidget(&minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1);
|
||||
tableGrid->addWidget(&minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1);
|
||||
|
@ -390,7 +391,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
tableGroupBox = new QGroupBox;
|
||||
tableGroupBox->setLayout(tableGrid);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(themeGroupBox);
|
||||
mainLayout->addWidget(cardsGroupBox);
|
||||
mainLayout->addWidget(handGroupBox);
|
||||
|
@ -444,7 +445,7 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
|||
annotateTokensCheckBox.setChecked(settingsCache->getAnnotateTokens());
|
||||
connect(&annotateTokensCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setAnnotateTokens(int)));
|
||||
|
||||
QGridLayout *generalGrid = new QGridLayout;
|
||||
auto *generalGrid = new QGridLayout;
|
||||
generalGrid->addWidget(¬ificationsEnabledCheckBox, 0, 0);
|
||||
generalGrid->addWidget(&specNotificationsEnabledCheckBox, 1, 0);
|
||||
generalGrid->addWidget(&doubleClickToPlayCheckBox, 2, 0);
|
||||
|
@ -457,13 +458,13 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
|||
tapAnimationCheckBox.setChecked(settingsCache->getTapAnimation());
|
||||
connect(&tapAnimationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setTapAnimation(int)));
|
||||
|
||||
QGridLayout *animationGrid = new QGridLayout;
|
||||
auto *animationGrid = new QGridLayout;
|
||||
animationGrid->addWidget(&tapAnimationCheckBox, 0, 0);
|
||||
|
||||
animationGroupBox = new QGroupBox;
|
||||
animationGroupBox->setLayout(animationGrid);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(generalGroupBox);
|
||||
mainLayout->addWidget(animationGroupBox);
|
||||
|
||||
|
@ -486,25 +487,123 @@ void UserInterfaceSettingsPage::retranslateUi()
|
|||
tapAnimationCheckBox.setText(tr("&Tap/untap animation"));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
mpSpoilerPathButton = new QPushButton("...");
|
||||
connect(mpSpoilerPathButton, SIGNAL(clicked()), this, SLOT(spoilerPathButtonClicked()));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(generalGroupBox);
|
||||
updateNowButton = new QPushButton(tr("Update Spoilers"));
|
||||
connect(updateNowButton, SIGNAL(clicked()), this, SLOT(updateSpoilers()));
|
||||
|
||||
setLayout(mainLayout);
|
||||
// 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()
|
||||
{
|
||||
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()
|
||||
|
@ -545,7 +644,7 @@ MessagesSettingsPage::MessagesSettingsPage()
|
|||
customAlertString->setText(settingsCache->getHighlightWords());
|
||||
connect(customAlertString, SIGNAL(textChanged(QString)), settingsCache, SLOT(setHighlightWords(QString)));
|
||||
|
||||
QGridLayout *chatGrid = new QGridLayout;
|
||||
auto *chatGrid = new QGridLayout;
|
||||
chatGrid->addWidget(&chatMentionCheckBox, 0, 0);
|
||||
chatGrid->addWidget(&invertMentionForeground, 0, 1);
|
||||
chatGrid->addWidget(mentionColor, 0, 2);
|
||||
|
@ -564,7 +663,7 @@ MessagesSettingsPage::MessagesSettingsPage()
|
|||
updateHighlightPreview();
|
||||
connect(highlightColor, SIGNAL(textChanged(QString)), this, SLOT(updateHighlightColor(QString)));
|
||||
|
||||
QGridLayout *highlightNotice = new QGridLayout;
|
||||
auto *highlightNotice = new QGridLayout;
|
||||
highlightNotice->addWidget(highlightColor, 0, 2);
|
||||
highlightNotice->addWidget(&invertHighlightForeground, 0, 1);
|
||||
highlightNotice->addWidget(&hexHighlightLabel, 1, 2);
|
||||
|
@ -586,19 +685,19 @@ MessagesSettingsPage::MessagesSettingsPage()
|
|||
aRemove->setIcon(QPixmap("theme:icons/decrement"));
|
||||
connect(aRemove, SIGNAL(triggered()), this, SLOT(actRemove()));
|
||||
|
||||
QToolBar *messageToolBar = new QToolBar;
|
||||
auto *messageToolBar = new QToolBar;
|
||||
messageToolBar->setOrientation(Qt::Vertical);
|
||||
messageToolBar->addAction(aAdd);
|
||||
messageToolBar->addAction(aRemove);
|
||||
|
||||
QHBoxLayout *messageListLayout = new QHBoxLayout;
|
||||
auto *messageListLayout = new QHBoxLayout;
|
||||
messageListLayout->addWidget(messageToolBar);
|
||||
messageListLayout->addWidget(messageList);
|
||||
|
||||
messageShortcuts = new QGroupBox;
|
||||
messageShortcuts->setLayout(messageListLayout);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
|
||||
mainLayout->addWidget(messageShortcuts);
|
||||
mainLayout->addWidget(chatGroupBox);
|
||||
|
@ -609,7 +708,8 @@ MessagesSettingsPage::MessagesSettingsPage()
|
|||
retranslateUi();
|
||||
}
|
||||
|
||||
void MessagesSettingsPage::updateColor(const QString &value) {
|
||||
void MessagesSettingsPage::updateColor(const QString &value)
|
||||
{
|
||||
QColor colorToSet;
|
||||
colorToSet.setNamedColor("#" + value);
|
||||
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;
|
||||
colorToSet.setNamedColor("#" + value);
|
||||
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);
|
||||
updateMentionPreview();
|
||||
}
|
||||
|
||||
void MessagesSettingsPage::updateTextHighlightColor(int value) {
|
||||
void MessagesSettingsPage::updateTextHighlightColor(int value)
|
||||
{
|
||||
settingsCache->setChatHighlightForeground(value);
|
||||
updateHighlightPreview();
|
||||
}
|
||||
|
||||
void MessagesSettingsPage::updateMentionPreview() {
|
||||
void MessagesSettingsPage::updateMentionPreview()
|
||||
{
|
||||
mentionColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatMentionColor() +
|
||||
";color: " + (settingsCache->getChatMentionForeground() ? "white" : "black") + ";}");
|
||||
}
|
||||
|
||||
void MessagesSettingsPage::updateHighlightPreview() {
|
||||
void MessagesSettingsPage::updateHighlightPreview()
|
||||
{
|
||||
highlightColor->setStyleSheet("QLineEdit{background:#" + settingsCache->getChatHighlightColor() +
|
||||
";color: " + (settingsCache->getChatHighlightForeground() ? "white" : "black") + ";}");
|
||||
}
|
||||
|
@ -725,7 +830,7 @@ SoundSettingsPage::SoundSettingsPage()
|
|||
connect(masterVolumeSlider, SIGNAL(valueChanged(int)), masterVolumeSpinBox, 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(&masterVolumeLabel, 1, 0);
|
||||
soundGrid->addWidget(masterVolumeSlider, 1, 1);
|
||||
|
@ -737,7 +842,7 @@ SoundSettingsPage::SoundSettingsPage()
|
|||
soundGroupBox = new QGroupBox;
|
||||
soundGroupBox->setLayout(soundGrid);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(soundGroupBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
@ -750,11 +855,13 @@ void SoundSettingsPage::themeBoxChanged(int index)
|
|||
settingsCache->setSoundThemeName(themeDirs.at(index));
|
||||
}
|
||||
|
||||
void SoundSettingsPage::masterVolumeChanged(int value) {
|
||||
void SoundSettingsPage::masterVolumeChanged(int value)
|
||||
{
|
||||
masterVolumeSlider->setToolTip(QString::number(value));
|
||||
}
|
||||
|
||||
void SoundSettingsPage::retranslateUi() {
|
||||
void SoundSettingsPage::retranslateUi()
|
||||
{
|
||||
soundEnabledCheckBox.setText(tr("Enable &sounds"));
|
||||
themeLabel.setText(tr("Current sounds theme:"));
|
||||
soundTestButton.setText(tr("Test system sound engine"));
|
||||
|
@ -762,8 +869,7 @@ void SoundSettingsPage::retranslateUi() {
|
|||
masterVolumeLabel.setText(tr("Master volume"));
|
||||
}
|
||||
|
||||
DlgSettings::DlgSettings(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QRect rec = QApplication::desktop()->availableGeometry();
|
||||
this->setMinimumSize(rec.width() / 2, rec.height() - 100);
|
||||
|
@ -791,14 +897,14 @@ DlgSettings::DlgSettings(QWidget *parent)
|
|||
createIcons();
|
||||
contentsWidget->setCurrentRow(0);
|
||||
|
||||
QVBoxLayout *vboxLayout = new QVBoxLayout;
|
||||
auto *vboxLayout = new QVBoxLayout;
|
||||
vboxLayout->addWidget(contentsWidget);
|
||||
vboxLayout->addWidget(pagesWidget);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||
auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(vboxLayout);
|
||||
mainLayout->addSpacing(12);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
@ -857,7 +963,8 @@ void DlgSettings::changePage(QListWidgetItem *current, QListWidgetItem *previous
|
|||
pagesWidget->setCurrentIndex(contentsWidget->row(current));
|
||||
}
|
||||
|
||||
void DlgSettings::setTab(int index) {
|
||||
void DlgSettings::setTab(int index)
|
||||
{
|
||||
if (index <= contentsWidget->count()-1 && index >= 0) {
|
||||
changePage(contentsWidget->item(index), contentsWidget->currentItem());
|
||||
contentsWidget->setCurrentRow(index);
|
||||
|
@ -883,7 +990,8 @@ void DlgSettings::closeEvent(QCloseEvent *event)
|
|||
QString loadErrorMessage = tr("Unknown Error loading card database");
|
||||
LoadStatus loadStatus = db->getLoadStatus();
|
||||
qDebug() << "Card Database load status: " << loadStatus;
|
||||
switch(loadStatus) {
|
||||
switch(loadStatus)
|
||||
{
|
||||
case Ok:
|
||||
showLoadError = false;
|
||||
break;
|
||||
|
@ -925,23 +1033,36 @@ void DlgSettings::closeEvent(QCloseEvent *event)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
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();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!QDir(settingsCache->getDeckPath()).exists() || settingsCache->getDeckPath().isEmpty())
|
||||
{
|
||||
// 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();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!QDir(settingsCache->getPicsPath()).exists() || settingsCache->getPicsPath().isEmpty())
|
||||
{
|
||||
// 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();
|
||||
return;
|
||||
}
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
@ -962,4 +1083,3 @@ void DlgSettings::retranslateUi()
|
|||
|
||||
contentsWidget->reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,16 +26,19 @@ class QSpinBox;
|
|||
class QSlider;
|
||||
class QSpinBox;
|
||||
|
||||
class AbstractSettingsPage : public QWidget {
|
||||
class AbstractSettingsPage : public QWidget
|
||||
{
|
||||
public:
|
||||
virtual void retranslateUi() = 0;
|
||||
};
|
||||
|
||||
class GeneralSettingsPage : public AbstractSettingsPage {
|
||||
class GeneralSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GeneralSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
|
||||
private slots:
|
||||
void deckPathButtonClicked();
|
||||
void replaysPathButtonClicked();
|
||||
|
@ -47,6 +50,7 @@ private slots:
|
|||
void setEnabledStatus(bool);
|
||||
void defaultUrlRestoreButtonClicked();
|
||||
void fallbackUrlRestoreButtonClicked();
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &qmFile);
|
||||
|
@ -80,10 +84,12 @@ private:
|
|||
QPushButton fallbackUrlRestoreButton;
|
||||
};
|
||||
|
||||
class AppearanceSettingsPage : public AbstractSettingsPage {
|
||||
class AppearanceSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void themeBoxChanged(int index);
|
||||
|
||||
private:
|
||||
QLabel themeLabel;
|
||||
QComboBox themeBox;
|
||||
|
@ -100,15 +106,18 @@ private:
|
|||
QGroupBox *tableGroupBox;
|
||||
QSpinBox minPlayersForMultiColumnLayoutEdit;
|
||||
QSpinBox maxFontSizeForCardsEdit;
|
||||
|
||||
public:
|
||||
AppearanceSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
};
|
||||
|
||||
class UserInterfaceSettingsPage : public AbstractSettingsPage {
|
||||
class UserInterfaceSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void setSpecNotificationEnabled(int);
|
||||
|
||||
private:
|
||||
QCheckBox notificationsEnabledCheckBox;
|
||||
QCheckBox specNotificationsEnabledCheckBox;
|
||||
|
@ -121,25 +130,43 @@ private:
|
|||
|
||||
public:
|
||||
UserInterfaceSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
};
|
||||
|
||||
class DeckEditorSettingsPage : public AbstractSettingsPage {
|
||||
class DeckEditorSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeckEditorSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
QString getLastUpdateTime();
|
||||
|
||||
private slots:
|
||||
signals:
|
||||
void setSpoilersEnabled(bool);
|
||||
void spoilerPathButtonClicked();
|
||||
void updateSpoilers();
|
||||
void unlockSettings();
|
||||
|
||||
private:
|
||||
QGroupBox *generalGroupBox;
|
||||
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
|
||||
public:
|
||||
MessagesSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
|
||||
private slots:
|
||||
void actAdd();
|
||||
void actRemove();
|
||||
|
@ -147,6 +174,7 @@ private slots:
|
|||
void updateHighlightColor(const QString &value);
|
||||
void updateTextColor(int value);
|
||||
void updateTextHighlightColor(int value);
|
||||
|
||||
private:
|
||||
QListWidget *messageList;
|
||||
QAction *aAdd;
|
||||
|
@ -175,11 +203,13 @@ private:
|
|||
void updateHighlightPreview();
|
||||
};
|
||||
|
||||
class SoundSettingsPage : public AbstractSettingsPage {
|
||||
class SoundSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SoundSettingsPage();
|
||||
void retranslateUi();
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QLabel themeLabel;
|
||||
QComboBox themeBox;
|
||||
|
@ -189,19 +219,23 @@ private:
|
|||
QLabel masterVolumeLabel;
|
||||
QSlider *masterVolumeSlider;
|
||||
QSpinBox *masterVolumeSpinBox;
|
||||
|
||||
private slots:
|
||||
void masterVolumeChanged(int value);
|
||||
void themeBoxChanged(int index);
|
||||
};
|
||||
|
||||
class DlgSettings : public QDialog {
|
||||
class DlgSettings : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgSettings(QWidget *parent = 0);
|
||||
explicit DlgSettings(QWidget *parent = nullptr);
|
||||
void setTab(int index);
|
||||
|
||||
private slots:
|
||||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void updateLanguage();
|
||||
|
||||
private:
|
||||
QListWidget *contentsWidget;
|
||||
QStackedWidget *pagesWidget;
|
||||
|
@ -209,9 +243,10 @@ private:
|
|||
QListWidgetItem *shortcutsButton;
|
||||
void createIcons();
|
||||
void retranslateUi();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void changeEvent(QEvent *event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -42,6 +42,7 @@
|
|||
#include "soundengine.h"
|
||||
#include "featureset.h"
|
||||
#include "logger.h"
|
||||
#include "spoilerbackgroundupdater.h"
|
||||
|
||||
CardDatabase *db;
|
||||
QTranslator *translator, *qtTranslator;
|
||||
|
@ -129,6 +130,10 @@ int main(int argc, char *argv[])
|
|||
|
||||
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();
|
||||
qDebug("main(): ui.show() finished");
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ class QSystemTrayIcon;
|
|||
class SoundEngine;
|
||||
|
||||
extern CardDatabase *db;
|
||||
|
||||
extern QSystemTrayIcon *trayIcon;
|
||||
extern QTranslator *translator;
|
||||
extern const QString translationPrefix;
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
#include "carddatabasesettings.h"
|
||||
|
||||
CardDatabaseSettings::CardDatabaseSettings(QString settingPath, QObject *parent)
|
||||
: SettingsManager(settingPath+"cardDatabase.ini", parent)
|
||||
CardDatabaseSettings::CardDatabaseSettings(QString settingPath, QObject *parent) : SettingsManager(settingPath+"cardDatabase.ini", parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
setValue(enabled, "enabled", "sets", shortName);
|
||||
setValue(enabled, "enabled", "sets", std::move(shortName));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return getValue("sortkey", "sets", shortName).toUInt();
|
||||
return getValue("sortkey", "sets", std::move(shortName)).toUInt();
|
||||
}
|
||||
|
||||
bool CardDatabaseSettings::isEnabled(QString shortName)
|
||||
{
|
||||
return getValue("enabled", "sets", shortName).toBool();
|
||||
return getValue("enabled", "sets", std::move(shortName)).toBool();
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
SettingsManager::SettingsManager(QString settingPath, QObject *parent)
|
||||
: QObject(parent),
|
||||
settings(settingPath, QSettings::IniFormat)
|
||||
SettingsManager::SettingsManager(QString settingPath, QObject *parent) : QObject(parent), settings(settingPath, QSettings::IniFormat)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SettingsManager::setValue(QVariant value, QString name, QString group, QString subGroup)
|
||||
{
|
||||
if (!group.isEmpty())
|
||||
{
|
||||
settings.beginGroup(group);
|
||||
}
|
||||
|
||||
if (!subGroup.isEmpty())
|
||||
{
|
||||
settings.beginGroup(subGroup);
|
||||
}
|
||||
|
||||
settings.setValue(name, value);
|
||||
|
||||
if (!subGroup.isEmpty())
|
||||
{
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
if (!group.isEmpty())
|
||||
{
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant SettingsManager::getValue(QString name, QString group, QString subGroup)
|
||||
{
|
||||
if (!group.isEmpty())
|
||||
{
|
||||
settings.beginGroup(group);
|
||||
}
|
||||
|
||||
if (!subGroup.isEmpty())
|
||||
{
|
||||
settings.beginGroup(subGroup);
|
||||
}
|
||||
|
||||
QVariant value = settings.value(name);
|
||||
|
||||
if (!subGroup.isEmpty())
|
||||
{
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
if (!group.isEmpty())
|
||||
{
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -171,6 +171,8 @@ SettingsCache::SettingsCache()
|
|||
releaseChannels << new StableReleaseChannel();
|
||||
releaseChannels << new DevReleaseChannel();
|
||||
|
||||
mbDownloadSpoilers = settings->value("personal/downloadspoilers", false).toBool();
|
||||
|
||||
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
|
||||
updateReleaseChannel = settings->value("personal/updatereleasechannel", 0).toInt();
|
||||
|
||||
|
@ -187,6 +189,7 @@ SettingsCache::SettingsCache()
|
|||
|
||||
cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
|
||||
tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
|
||||
spoilerDatabasePath = getSafeConfigFilePath("paths/spoilerdatabase", dataPath + "/spoiler.xml");
|
||||
|
||||
themeName = settings->value("theme/name").toString();
|
||||
|
||||
|
@ -348,6 +351,13 @@ void SettingsCache::setCardDatabasePath(const QString &_cardDatabasePath)
|
|||
emit cardDatabasePathChanged();
|
||||
}
|
||||
|
||||
void SettingsCache::setSpoilerDatabasePath(const QString &_spoilerDatabasePath)
|
||||
{
|
||||
spoilerDatabasePath = _spoilerDatabasePath;
|
||||
settings->setValue("paths/spoilerdatabase", spoilerDatabasePath);
|
||||
emit cardDatabasePathChanged();
|
||||
}
|
||||
|
||||
void SettingsCache::setTokenDatabasePath(const QString &_tokenDatabasePath)
|
||||
{
|
||||
tokenDatabasePath = _tokenDatabasePath;
|
||||
|
@ -644,10 +654,17 @@ void SettingsCache::setRememberGameSettings(const bool _rememberGameSettings)
|
|||
|
||||
void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
|
||||
{
|
||||
notifyAboutUpdates = _notifyaboutupdate;
|
||||
notifyAboutUpdates = static_cast<bool>(_notifyaboutupdate);
|
||||
settings->setValue("personal/updatenotification", notifyAboutUpdates);
|
||||
}
|
||||
|
||||
void SettingsCache::setDownloadSpoilerStatus(bool _spoilerStatus)
|
||||
{
|
||||
mbDownloadSpoilers = _spoilerStatus;
|
||||
settings->setValue("personal/downloadspoilers", mbDownloadSpoilers);
|
||||
emit downloadSpoilerStatusChanged();
|
||||
}
|
||||
|
||||
void SettingsCache::setUpdateReleaseChannel(int _updateReleaseChannel)
|
||||
{
|
||||
updateReleaseChannel = _updateReleaseChannel;
|
||||
|
|
|
@ -48,6 +48,8 @@ signals:
|
|||
void pixmapCacheSizeChanged(int newSizeInMBs);
|
||||
void masterVolumeChanged(int value);
|
||||
void chatMentionCompleterChanged();
|
||||
void downloadSpoilerTimeIndexChanged();
|
||||
void downloadSpoilerStatusChanged();
|
||||
private:
|
||||
QSettings *settings;
|
||||
ShortcutsSettings *shortcutsSettings;
|
||||
|
@ -60,8 +62,9 @@ private:
|
|||
QByteArray mainWindowGeometry;
|
||||
QByteArray tokenDialogGeometry;
|
||||
QString lang;
|
||||
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, tokenDatabasePath, themeName;
|
||||
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, spoilerDatabasePath, tokenDatabasePath, themeName;
|
||||
bool notifyAboutUpdates;
|
||||
bool mbDownloadSpoilers;
|
||||
int updateReleaseChannel;
|
||||
int maxFontSize;
|
||||
bool picDownload;
|
||||
|
@ -130,6 +133,7 @@ public:
|
|||
QString getCustomPicsPath() const { return customPicsPath; }
|
||||
QString getCustomCardDatabasePath() const { return customCardDatabasePath; }
|
||||
QString getCardDatabasePath() const { return cardDatabasePath; }
|
||||
QString getSpoilerCardDatabasePath() const { return spoilerDatabasePath; }
|
||||
QString getTokenDatabasePath() const { return tokenDatabasePath; }
|
||||
QString getThemeName() const { return themeName; }
|
||||
QString getChatMentionColor() const { return chatMentionColor; }
|
||||
|
@ -200,7 +204,10 @@ public:
|
|||
GameFiltersSettings& gameFilters() const { return *gameFiltersSettings; }
|
||||
LayoutsSettings& layouts() const { return *layoutsSettings; }
|
||||
bool getIsPortableBuild() const { return isPortableBuild; }
|
||||
bool getDownloadSpoilersStatus() const { return mbDownloadSpoilers; }
|
||||
public slots:
|
||||
void setDownloadSpoilerStatus(bool _spoilerStatus);
|
||||
|
||||
void setMainWindowGeometry(const QByteArray &_mainWindowGeometry);
|
||||
void setTokenDialogGeometry(const QByteArray &_tokenDialog);
|
||||
void setLang(const QString &_lang);
|
||||
|
@ -208,6 +215,7 @@ public slots:
|
|||
void setReplaysPath(const QString &_replaysPath);
|
||||
void setPicsPath(const QString &_picsPath);
|
||||
void setCardDatabasePath(const QString &_cardDatabasePath);
|
||||
void setSpoilerDatabasePath(const QString &_spoilerDatabasePath);
|
||||
void setTokenDatabasePath(const QString &_tokenDatabasePath);
|
||||
void setThemeName(const QString &_themeName);
|
||||
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)
|
||||
{
|
||||
for (int i = 0; i < tabMenus.size(); ++i)
|
||||
menuBar()->removeAction(tabMenus[i]->menuAction());
|
||||
for (auto &tabMenu : tabMenus)
|
||||
menuBar()->removeAction(tabMenu->menuAction());
|
||||
tabMenus = newMenuList;
|
||||
for (int i = 0; i < tabMenus.size(); ++i)
|
||||
menuBar()->insertMenu(helpMenu->menuAction(), tabMenus[i]);
|
||||
for (auto &tabMenu : tabMenus)
|
||||
menuBar()->insertMenu(helpMenu->menuAction(), tabMenu);
|
||||
}
|
||||
|
||||
void MainWindow::processConnectionClosedEvent(const Event_ConnectionClosed &event)
|
||||
|
@ -166,10 +166,10 @@ void MainWindow::activateAccepted()
|
|||
|
||||
void MainWindow::actConnect()
|
||||
{
|
||||
DlgConnect *dlg = new DlgConnect(this);
|
||||
auto *dlg = new DlgConnect(this);
|
||||
connect(dlg, SIGNAL(sigStartForgotPasswordRequest()), this, SLOT(actForgotPasswordRequest()));
|
||||
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()
|
||||
|
@ -179,7 +179,7 @@ void MainWindow::actRegister()
|
|||
{
|
||||
client->registerToServer(
|
||||
dlg.getHost(),
|
||||
dlg.getPort(),
|
||||
static_cast<unsigned int>(dlg.getPort()),
|
||||
dlg.getPlayerName(),
|
||||
dlg.getPassword(),
|
||||
dlg.getEmail(),
|
||||
|
@ -220,7 +220,7 @@ void MainWindow::actSinglePlayer()
|
|||
tabSupervisor->startLocal(localClients);
|
||||
|
||||
Command_CreateGame createCommand;
|
||||
createCommand.set_max_players(numberPlayers);
|
||||
createCommand.set_max_players(static_cast<google::protobuf::uint32>(numberPlayers));
|
||||
mainClient->sendCommand(mainClient->prepareRoomCommand(createCommand, 0));
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ void MainWindow::actWatchReplay()
|
|||
QByteArray buf = file.readAll();
|
||||
file.close();
|
||||
|
||||
GameReplay *replay = new GameReplay;
|
||||
auto *replay = new GameReplay;
|
||||
replay->ParseFromArray(buf.data(), buf.size());
|
||||
|
||||
tabSupervisor->openReplay(replay);
|
||||
|
@ -248,7 +248,7 @@ void MainWindow::actWatchReplay()
|
|||
void MainWindow::localGameEnded()
|
||||
{
|
||||
delete localServer;
|
||||
localServer = 0;
|
||||
localServer = nullptr;
|
||||
|
||||
aConnect->setEnabled(true);
|
||||
aRegister->setEnabled(true);
|
||||
|
@ -257,7 +257,7 @@ void MainWindow::localGameEnded()
|
|||
|
||||
void MainWindow::actDeckEditor()
|
||||
{
|
||||
tabSupervisor->addDeckEditorTab(0);
|
||||
tabSupervisor->addDeckEditorTab(nullptr);
|
||||
}
|
||||
|
||||
void MainWindow::actFullScreen(bool checked)
|
||||
|
@ -655,7 +655,7 @@ void MainWindow::createMenus()
|
|||
}
|
||||
|
||||
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)));
|
||||
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(localGameEnded()), this, SLOT(localGameEnded()));
|
||||
connect(tabSupervisor, SIGNAL(showWindowIfHidden()), this, SLOT(showWindowIfHidden()));
|
||||
tabSupervisor->addDeckEditorTab(0);
|
||||
tabSupervisor->addDeckEditorTab(nullptr);
|
||||
|
||||
setCentralWidget(tabSupervisor);
|
||||
|
||||
|
@ -699,7 +699,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
|
||||
resize(900, 700);
|
||||
restoreGeometry(settingsCache->getMainWindowGeometry());
|
||||
aFullScreen->setChecked(windowState() & Qt::WindowFullScreen);
|
||||
aFullScreen->setChecked(static_cast<bool>(windowState() & Qt::WindowFullScreen));
|
||||
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
createTrayActions();
|
||||
|
@ -712,8 +712,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(db, SIGNAL(cardDatabaseLoadingFailed()), this, SLOT(cardDatabaseLoadingFailed()));
|
||||
connect(db, SIGNAL(cardDatabaseNewSetsFound(int, QStringList)), this, SLOT(cardDatabaseNewSetsFound(int, QStringList)));
|
||||
connect(db, SIGNAL(cardDatabaseAllNewSetsEnabled()), this, SLOT(cardDatabaseAllNewSetsEnabled()));
|
||||
|
||||
if (! settingsCache->getDownloadSpoilersStatus())
|
||||
{
|
||||
qDebug() << "Spoilers Disabled";
|
||||
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
|
@ -727,7 +732,7 @@ MainWindow::~MainWindow()
|
|||
}
|
||||
|
||||
void MainWindow::createTrayIcon() {
|
||||
QMenu *trayIconMenu = new QMenu(this);
|
||||
auto *trayIconMenu = new QMenu(this);
|
||||
trayIconMenu->addAction(closeAction);
|
||||
|
||||
trayIcon = new QSystemTrayIcon(this);
|
||||
|
@ -754,7 +759,7 @@ void MainWindow::promptForgotPasswordChallenge()
|
|||
{
|
||||
DlgForgotPasswordChallenge dlg(this);
|
||||
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()) {
|
||||
qDebug() << "Attempting auto-connect...";
|
||||
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();
|
||||
|
||||
if (msgBox.clickedButton() == yesButton) {
|
||||
if (msgBox.clickedButton() == yesButton)
|
||||
{
|
||||
db->enableAllUnknownSets();
|
||||
} else if (msgBox.clickedButton() == noButton) {
|
||||
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||
}
|
||||
else if (msgBox.clickedButton() == noButton)
|
||||
{
|
||||
db->markAllSetsAsKnown();
|
||||
} else if (msgBox.clickedButton() == settingsButton) {
|
||||
}
|
||||
else if (msgBox.clickedButton() == settingsButton)
|
||||
{
|
||||
db->markAllSetsAsKnown();
|
||||
actEditSets();
|
||||
}
|
||||
|
@ -873,7 +884,6 @@ void MainWindow::cardDatabaseAllNewSetsEnabled()
|
|||
}
|
||||
|
||||
/* CARD UPDATER */
|
||||
|
||||
void MainWindow::actCheckCardUpdates()
|
||||
{
|
||||
if (cardUpdateProcess)
|
||||
|
@ -946,7 +956,7 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err)
|
|||
}
|
||||
|
||||
cardUpdateProcess->deleteLater();
|
||||
cardUpdateProcess = 0;
|
||||
cardUpdateProcess = nullptr;
|
||||
|
||||
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)
|
||||
{
|
||||
cardUpdateProcess->deleteLater();
|
||||
cardUpdateProcess = 0;
|
||||
cardUpdateProcess = nullptr;
|
||||
|
||||
QMessageBox::information(this, tr("Information"), tr("Update completed successfully.\nCockatrice will now reload the card database."));
|
||||
|
||||
QtConcurrent::run(db, &CardDatabase::loadCardDatabases);
|
||||
}
|
||||
|
||||
|
@ -989,7 +998,7 @@ void MainWindow::actOpenCustomFolder()
|
|||
#if defined(Q_OS_MAC)
|
||||
QStringList scriptArgs;
|
||||
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("tell application \"Finder\" to activate");
|
||||
|
||||
|
@ -1008,7 +1017,7 @@ void MainWindow::actOpenCustomsetsFolder()
|
|||
#if defined(Q_OS_MAC)
|
||||
QStringList scriptArgs;
|
||||
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("tell application \"Finder\" to activate");
|
||||
|
||||
|
@ -1025,16 +1034,20 @@ void MainWindow::actAddCustomSet()
|
|||
QFileDialog dialog(this, tr("Load sets/cards"), QDir::homePath());
|
||||
dialog.setNameFilters(MainWindow::fileNameFilters);
|
||||
if (!dialog.exec())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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."));
|
||||
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."));
|
||||
return;
|
||||
}
|
||||
|
@ -1042,7 +1055,7 @@ void MainWindow::actAddCustomSet()
|
|||
QDir dir = settingsCache->getCustomCardDatabasePath();
|
||||
int nextPrefix = getNextCustomSetPrefix(dir);
|
||||
|
||||
bool res = false;
|
||||
bool res;
|
||||
|
||||
QString fileName = QFileInfo(fullFilePath).fileName();
|
||||
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();
|
||||
int maxIndex = 0;
|
||||
|
||||
|
@ -1094,7 +1108,7 @@ int MainWindow::getNextCustomSetPrefix(QDir dataDir) {
|
|||
|
||||
void MainWindow::actEditSets()
|
||||
{
|
||||
WndSets *w = new WndSets;
|
||||
auto *w = new WndSets;
|
||||
w->setWindowModality(Qt::WindowModal);
|
||||
w->show();
|
||||
}
|
||||
|
@ -1110,7 +1124,7 @@ void MainWindow::actForgotPasswordRequest()
|
|||
{
|
||||
DlgForgotPasswordRequest dlg(this);
|
||||
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()
|
||||
|
@ -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."));
|
||||
DlgForgotPasswordReset dlg(this);
|
||||
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 {
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void actCheckCardUpdates();
|
||||
private slots:
|
||||
void updateTabMenu(const QList<QMenu *> &newMenuList);
|
||||
void statusChanged(ClientStatus _status);
|
||||
|
@ -78,7 +80,6 @@ private slots:
|
|||
void promptForgotPasswordChallenge();
|
||||
void showWindowIfHidden();
|
||||
|
||||
void actCheckCardUpdates();
|
||||
void cardUpdateError(QProcess::ProcessError err);
|
||||
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void refreshShortcuts();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <QIcon>
|
||||
#include <QTranslator>
|
||||
#include <QLibraryInfo>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
#include "main.h"
|
||||
#include "oraclewizard.h"
|
||||
|
@ -15,6 +16,7 @@ ThemeManager *themeManager;
|
|||
|
||||
const QString translationPrefix = "oracle";
|
||||
QString translationPath;
|
||||
bool isSpoilersOnly;
|
||||
|
||||
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
|
||||
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
|
||||
translationPath = qApp->applicationDirPath() + "/../Resources/translations";
|
||||
#elif defined(Q_OS_WIN)
|
||||
|
|
|
@ -6,6 +6,7 @@ class QTranslator;
|
|||
extern QTranslator *translator;
|
||||
extern const QString translationPrefix;
|
||||
extern QString translationPath;
|
||||
extern bool isSpoilersOnly;
|
||||
|
||||
void installNewTranslator();
|
||||
|
||||
|
|
|
@ -37,21 +37,28 @@
|
|||
#endif
|
||||
|
||||
#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);
|
||||
connect(settingsCache, SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
||||
|
||||
importer = new OracleImporter(settingsCache->getDataPath(), this);
|
||||
|
||||
if (! isSpoilersOnly)
|
||||
{
|
||||
addPage(new IntroPage);
|
||||
addPage(new LoadSetsPage);
|
||||
addPage(new SaveSetsPage);
|
||||
addPage(new LoadTokensPage);
|
||||
addPage(new SaveTokensPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
addPage(new LoadSpoilersPage);
|
||||
addPage(new SaveSpoilersPage);
|
||||
}
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
@ -65,7 +72,10 @@ void OracleWizard::updateLanguage()
|
|||
void OracleWizard::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
|
@ -75,8 +85,10 @@ void OracleWizard::retranslateUi()
|
|||
QWizard::setButtonText(QWizard::FinishButton, tr("Save"));
|
||||
|
||||
for (int i = 0; i < pageIds().count(); i++)
|
||||
{
|
||||
dynamic_cast<OracleWizardPage *>(page(i))->retranslateUi();
|
||||
}
|
||||
}
|
||||
|
||||
void OracleWizard::accept()
|
||||
{
|
||||
|
@ -103,17 +115,18 @@ bool OracleWizard::saveTokensToFile(const QString & fileName)
|
|||
qDebug() << "File open (w) failed for" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.write(tokensData) == -1)
|
||||
{
|
||||
qDebug() << "File write (w) failed for" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
IntroPage::IntroPage(QWidget *parent)
|
||||
: OracleWizardPage(parent)
|
||||
IntroPage::IntroPage(QWidget *parent) : OracleWizardPage(parent)
|
||||
{
|
||||
label = new QLabel(this);
|
||||
label->setWordWrap(true);
|
||||
|
@ -122,16 +135,21 @@ IntroPage::IntroPage(QWidget *parent)
|
|||
versionLabel = new QLabel(this);
|
||||
languageBox = new QComboBox(this);
|
||||
QString setLanguage = settingsCache->getLang();
|
||||
|
||||
QStringList qmFiles = findQmFiles();
|
||||
for (int i = 0; i < qmFiles.size(); i++) {
|
||||
for (int i = 0; i < qmFiles.size(); i++)
|
||||
{
|
||||
QString langName = languageName(qmFiles[i]);
|
||||
languageBox->addItem(langName, qmFiles[i]);
|
||||
if ((qmFiles[i] == setLanguage) || (setLanguage.isEmpty() && langName == QCoreApplication::translate("i18n", DEFAULT_LANG_NAME)))
|
||||
{
|
||||
languageBox->setCurrentIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
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(languageLabel, 1, 0);
|
||||
layout->addWidget(languageBox, 1, 1);
|
||||
|
@ -151,7 +169,9 @@ QStringList IntroPage::findQmFiles()
|
|||
QString IntroPage::languageName(const QString &qmFile)
|
||||
{
|
||||
if (qmFile == DEFAULT_LANG_CODE)
|
||||
{
|
||||
return DEFAULT_LANG_NAME;
|
||||
}
|
||||
|
||||
QTranslator translator;
|
||||
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
||||
|
@ -173,8 +193,7 @@ void IntroPage::retranslateUi()
|
|||
versionLabel->setText(tr("Version:") + QString(" %1").arg(VERSION_STRING));
|
||||
}
|
||||
|
||||
LoadSetsPage::LoadSetsPage(QWidget *parent)
|
||||
: OracleWizardPage(parent), nam(0)
|
||||
LoadSetsPage::LoadSetsPage(QWidget *parent) : OracleWizardPage(parent), nam(nullptr)
|
||||
{
|
||||
urlRadioButton = new QRadioButton(this);
|
||||
fileRadioButton = new QRadioButton(this);
|
||||
|
@ -193,7 +212,7 @@ LoadSetsPage::LoadSetsPage(QWidget *parent)
|
|||
fileButton = new QPushButton(this);
|
||||
connect(fileButton, SIGNAL(clicked()), this, SLOT(actLoadSetsFile()));
|
||||
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
auto *layout = new QGridLayout(this);
|
||||
layout->addWidget(urlRadioButton, 0, 0);
|
||||
layout->addWidget(urlLineEdit, 0, 1);
|
||||
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
||||
|
@ -246,10 +265,14 @@ void LoadSetsPage::actLoadSetsFile()
|
|||
#endif
|
||||
|
||||
if (!fileLineEdit->text().isEmpty() && QFile::exists(fileLineEdit->text()))
|
||||
{
|
||||
dialog.selectFile(fileLineEdit->text());
|
||||
}
|
||||
|
||||
if (!dialog.exec())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fileLineEdit->setText(dialog.selectedFiles().at(0));
|
||||
}
|
||||
|
@ -258,7 +281,9 @@ bool LoadSetsPage::validatePage()
|
|||
{
|
||||
// once the import is finished, we call next(); skip validation
|
||||
if (wizard()->importer->getSets().count() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// else, try to import sets
|
||||
if (urlRadioButton->isChecked())
|
||||
|
@ -282,7 +307,9 @@ bool LoadSetsPage::validatePage()
|
|||
setEnabled(false);
|
||||
|
||||
downloadSetsFile(url);
|
||||
} else if(fileRadioButton->isChecked()) {
|
||||
}
|
||||
else if (fileRadioButton->isChecked())
|
||||
{
|
||||
QFile setsFile(fileLineEdit->text());
|
||||
if (!setsFile.exists())
|
||||
{
|
||||
|
@ -290,8 +317,9 @@ bool LoadSetsPage::validatePage()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!setsFile.open(QIODevice::ReadOnly)) {
|
||||
QMessageBox::critical(0, tr("Error"), tr("Cannot open file '%1'.").arg(fileLineEdit->text()));
|
||||
if (!setsFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("Cannot open file '%1'.").arg(fileLineEdit->text()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -301,13 +329,16 @@ bool LoadSetsPage::validatePage()
|
|||
readSetsFromByteArray(setsFile.readAll());
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoadSetsPage::downloadSetsFile(QUrl url)
|
||||
{
|
||||
if (!nam)
|
||||
{
|
||||
nam = new QNetworkAccessManager(this);
|
||||
}
|
||||
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSetsFile()));
|
||||
|
@ -318,8 +349,8 @@ void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
|||
{
|
||||
if (total > 0)
|
||||
{
|
||||
progressBar->setMaximum(total);
|
||||
progressBar->setValue(received);
|
||||
progressBar->setMaximum(static_cast<int>(total));
|
||||
progressBar->setValue(static_cast<int>(received));
|
||||
}
|
||||
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
||||
}
|
||||
|
@ -327,9 +358,10 @@ void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
|||
void LoadSetsPage::actDownloadFinishedSetsFile()
|
||||
{
|
||||
// check for a reply
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||
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()));
|
||||
|
||||
wizard()->enableButtons();
|
||||
|
@ -340,7 +372,8 @@ void LoadSetsPage::actDownloadFinishedSetsFile()
|
|||
}
|
||||
|
||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (statusCode == 301 || statusCode == 302) {
|
||||
if (statusCode == 301 || statusCode == 302)
|
||||
{
|
||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||
qDebug() << "following redirect url:" << redirectUrl.toString();
|
||||
downloadSetsFile(redirectUrl);
|
||||
|
@ -353,9 +386,13 @@ void LoadSetsPage::actDownloadFinishedSetsFile()
|
|||
|
||||
// save allsets.json url, but only if the user customized it and download was successfull
|
||||
if (urlLineEdit->text() != QString(ALLSETS_URL))
|
||||
{
|
||||
wizard()->settings->setValue("allsetsurl", urlLineEdit->text());
|
||||
}
|
||||
else
|
||||
{
|
||||
wizard()->settings->remove("allsetsurl");
|
||||
}
|
||||
|
||||
readSetsFromByteArray(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
@ -376,14 +413,15 @@ void LoadSetsPage::readSetsFromByteArray(QByteArray data)
|
|||
{
|
||||
#ifdef HAS_ZLIB
|
||||
// zipped file
|
||||
QBuffer *inBuffer = new QBuffer(&data);
|
||||
QBuffer *outBuffer = new QBuffer(this);
|
||||
auto *inBuffer = new QBuffer(&data);
|
||||
auto *outBuffer = new QBuffer(this);
|
||||
QString fileName;
|
||||
UnZip::ErrorCode ec;
|
||||
UnZip uz;
|
||||
|
||||
ec = uz.openArchive(inBuffer);
|
||||
if (ec != UnZip::Ok) {
|
||||
if (ec != UnZip::Ok)
|
||||
{
|
||||
zipDownloadFailed(tr("Failed to open Zip archive: %1.").arg(uz.formatError(ec)));
|
||||
return;
|
||||
}
|
||||
|
@ -397,7 +435,8 @@ void LoadSetsPage::readSetsFromByteArray(QByteArray data)
|
|||
|
||||
outBuffer->open(QBuffer::ReadWrite);
|
||||
ec = uz.extractFile(fileName, outBuffer);
|
||||
if (ec != UnZip::Ok) {
|
||||
if (ec != UnZip::Ok)
|
||||
{
|
||||
zipDownloadFailed(tr("Zip extraction failed: %1.").arg(uz.formatError(ec)));
|
||||
uz.closeArchive();
|
||||
return;
|
||||
|
@ -429,7 +468,8 @@ void LoadSetsPage::zipDownloadFailed(const QString &message)
|
|||
progressBar->hide();
|
||||
|
||||
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)
|
||||
{
|
||||
urlRadioButton->setChecked(true);
|
||||
|
@ -449,13 +489,14 @@ void LoadSetsPage::importFinished()
|
|||
if (watcher.future().result())
|
||||
{
|
||||
wizard()->next();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("The file was retrieved successfully, but it does not contain any sets data."));
|
||||
}
|
||||
}
|
||||
|
||||
SaveSetsPage::SaveSetsPage(QWidget *parent)
|
||||
: OracleWizardPage(parent)
|
||||
SaveSetsPage::SaveSetsPage(QWidget *parent) : OracleWizardPage(parent)
|
||||
{
|
||||
defaultPathCheckBox = new QCheckBox(this);
|
||||
defaultPathCheckBox->setChecked(true);
|
||||
|
@ -463,7 +504,7 @@ SaveSetsPage::SaveSetsPage(QWidget *parent)
|
|||
messageLog = new QTextEdit(this);
|
||||
messageLog->setReadOnly(true);
|
||||
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
auto *layout = new QGridLayout(this);
|
||||
layout->addWidget(defaultPathCheckBox, 0, 0);
|
||||
layout->addWidget(messageLog, 1, 0);
|
||||
|
||||
|
@ -472,7 +513,7 @@ SaveSetsPage::SaveSetsPage(QWidget *parent)
|
|||
|
||||
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()
|
||||
|
@ -482,8 +523,10 @@ void SaveSetsPage::initializePage()
|
|||
connect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
|
||||
|
||||
if (!wizard()->importer->startImport())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
||||
}
|
||||
}
|
||||
|
||||
void SaveSetsPage::retranslateUi()
|
||||
{
|
||||
|
@ -496,11 +539,15 @@ void SaveSetsPage::retranslateUi()
|
|||
|
||||
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>");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messageLog->append(tr("%1: %2 cards imported").arg(setName).arg(cardsImported));
|
||||
}
|
||||
|
||||
messageLog->verticalScrollBar()->setValue(messageLog->verticalScrollBar()->maximum());
|
||||
}
|
||||
|
||||
|
@ -511,39 +558,51 @@ bool SaveSetsPage::validatePage()
|
|||
QString windowName = tr("Save card database");
|
||||
QString fileType = tr("XML; card database (*.xml)");
|
||||
|
||||
do {
|
||||
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())) {
|
||||
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wizard()->importer->saveToFile(fileName))
|
||||
{
|
||||
ok = true;
|
||||
QMessageBox::information(this,
|
||||
tr("Success"),
|
||||
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));;
|
||||
if (defaultPathCheckBox->isChecked())
|
||||
{
|
||||
defaultPathCheckBox->setChecked(false);
|
||||
}
|
||||
}
|
||||
} while (!ok);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LoadTokensPage::LoadTokensPage(QWidget *parent)
|
||||
: OracleWizardPage(parent), nam(0)
|
||||
LoadSpoilersPage::LoadSpoilersPage(QWidget *parent) : OracleWizardPage(parent), nam(nullptr)
|
||||
{
|
||||
urlLabel = new QLabel(this);
|
||||
urlLineEdit = new QLineEdit(this);
|
||||
|
@ -554,7 +613,152 @@ LoadTokensPage::LoadTokensPage(QWidget *parent)
|
|||
urlButton = new QPushButton(this);
|
||||
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(urlLineEdit, 0, 1);
|
||||
layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
|
||||
|
@ -590,7 +794,9 @@ bool LoadTokensPage::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())
|
||||
|
@ -617,7 +823,9 @@ bool LoadTokensPage::validatePage()
|
|||
void LoadTokensPage::downloadTokensFile(QUrl url)
|
||||
{
|
||||
if (!nam)
|
||||
{
|
||||
nam = new QNetworkAccessManager(this);
|
||||
}
|
||||
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedTokensFile()));
|
||||
|
@ -628,8 +836,8 @@ void LoadTokensPage::actDownloadProgressTokensFile(qint64 received, qint64 total
|
|||
{
|
||||
if (total > 0)
|
||||
{
|
||||
progressBar->setMaximum(total);
|
||||
progressBar->setValue(received);
|
||||
progressBar->setMaximum(static_cast<int>(total));
|
||||
progressBar->setValue(static_cast<int>(received));
|
||||
}
|
||||
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / (1024 * 1024)));
|
||||
}
|
||||
|
@ -637,9 +845,10 @@ void LoadTokensPage::actDownloadProgressTokensFile(qint64 received, qint64 total
|
|||
void LoadTokensPage::actDownloadFinishedTokensFile()
|
||||
{
|
||||
// check for a reply
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
auto *reply = dynamic_cast<QNetworkReply *>(sender());
|
||||
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()));
|
||||
|
||||
wizard()->enableButtons();
|
||||
|
@ -650,7 +859,8 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
|||
}
|
||||
|
||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (statusCode == 301 || statusCode == 302) {
|
||||
if (statusCode == 301 || statusCode == 302)
|
||||
{
|
||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||
qDebug() << "following redirect url:" << redirectUrl.toString();
|
||||
downloadTokensFile(redirectUrl);
|
||||
|
@ -663,9 +873,13 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
|||
|
||||
// save tokens.xml url, but only if the user customized it and download was successfull
|
||||
if (urlLineEdit->text() != QString(TOKENS_URL))
|
||||
{
|
||||
wizard()->settings->setValue("tokensurl", urlLineEdit->text());
|
||||
}
|
||||
else
|
||||
{
|
||||
wizard()->settings->remove("tokensurl");
|
||||
}
|
||||
|
||||
wizard()->setTokensData(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
@ -678,13 +892,81 @@ void LoadTokensPage::actDownloadFinishedTokensFile()
|
|||
wizard()->next();
|
||||
}
|
||||
|
||||
SaveTokensPage::SaveTokensPage(QWidget *parent)
|
||||
: OracleWizardPage(parent)
|
||||
SaveSpoilersPage::SaveSpoilersPage(QWidget *parent) : OracleWizardPage(parent)
|
||||
{
|
||||
defaultPathCheckBox = new QCheckBox(this);
|
||||
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);
|
||||
|
||||
setLayout(layout);
|
||||
|
@ -706,32 +988,46 @@ bool SaveTokensPage::validatePage()
|
|||
QString windowName = tr("Save token database");
|
||||
QString fileType = tr("XML; token database (*.xml)");
|
||||
|
||||
do {
|
||||
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())) {
|
||||
if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wizard()->saveTokensToFile(fileName))
|
||||
{
|
||||
ok = true;
|
||||
QMessageBox::information(this,
|
||||
tr("Success"),
|
||||
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));;
|
||||
if (defaultPathCheckBox->isChecked())
|
||||
{
|
||||
defaultPathCheckBox->setChecked(false);
|
||||
}
|
||||
}
|
||||
} while (!ok);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QWizard>
|
||||
#include <QFutureWatcher>
|
||||
#include <QFuture>
|
||||
#include <utility>
|
||||
|
||||
class QCheckBox;
|
||||
class QGroupBox;
|
||||
|
@ -22,34 +23,36 @@ class OracleWizard : public QWizard
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OracleWizard(QWidget *parent = 0);
|
||||
void accept();
|
||||
explicit OracleWizard(QWidget *parent = nullptr);
|
||||
void accept() override;
|
||||
void enableButtons();
|
||||
void disableButtons();
|
||||
void retranslateUi();
|
||||
void setTokensData(QByteArray _tokensData) { tokensData = _tokensData; }
|
||||
void setTokensData(QByteArray _tokensData) { tokensData = std::move(_tokensData); }
|
||||
bool hasTokensData() { return !tokensData.isEmpty(); }
|
||||
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);
|
||||
};
|
||||
|
||||
private:
|
||||
QByteArray tokensData;
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event) override;
|
||||
};
|
||||
|
||||
class OracleWizardPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OracleWizardPage(QWidget *parent = 0): QWizardPage(parent) {};
|
||||
explicit OracleWizardPage(QWidget *parent = nullptr): QWizardPage(parent) {};
|
||||
virtual void retranslateUi() = 0;
|
||||
|
||||
protected:
|
||||
inline OracleWizard *wizard() { return (OracleWizard*) QWizardPage::wizard(); };
|
||||
};
|
||||
|
@ -58,14 +61,17 @@ class IntroPage : public OracleWizardPage
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
IntroPage(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
explicit IntroPage(QWidget *parent = nullptr);
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &qmFile);
|
||||
|
||||
private:
|
||||
QLabel *label, *languageLabel, *versionLabel;
|
||||
QComboBox *languageBox;
|
||||
|
||||
private slots:
|
||||
void languageBoxChanged(int index);
|
||||
};
|
||||
|
@ -74,13 +80,15 @@ class LoadSetsPage : public OracleWizardPage
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LoadSetsPage(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
explicit LoadSetsPage(QWidget *parent = nullptr);
|
||||
void retranslateUi() override;
|
||||
|
||||
protected:
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
void readSetsFromByteArray(QByteArray data);
|
||||
void downloadSetsFile(QUrl url);
|
||||
|
||||
private:
|
||||
QRadioButton *urlRadioButton;
|
||||
QRadioButton *fileRadioButton;
|
||||
|
@ -94,6 +102,7 @@ private:
|
|||
QNetworkAccessManager *nam;
|
||||
QFutureWatcher<bool> watcher;
|
||||
QFuture<bool> future;
|
||||
|
||||
private slots:
|
||||
void actLoadSetsFile();
|
||||
void actRestoreDefaultUrl();
|
||||
|
@ -107,37 +116,82 @@ class SaveSetsPage : public OracleWizardPage
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SaveSetsPage(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
explicit SaveSetsPage(QWidget *parent = nullptr);
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QTextEdit *messageLog;
|
||||
QCheckBox *defaultPathCheckBox;
|
||||
|
||||
protected:
|
||||
void initializePage();
|
||||
void cleanupPage();
|
||||
bool validatePage();
|
||||
void initializePage() override;
|
||||
void cleanupPage() override;
|
||||
bool validatePage() override;
|
||||
|
||||
private slots:
|
||||
void updateTotalProgress(int cardsImported, int setIndex, const QString &setName);
|
||||
};
|
||||
|
||||
class LoadTokensPage : public OracleWizardPage
|
||||
class LoadSpoilersPage : public OracleWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LoadTokensPage(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
protected:
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
void downloadTokensFile(QUrl url);
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LoadTokensPage(QWidget *parent = nullptr);
|
||||
void retranslateUi() override;
|
||||
|
||||
protected:
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
void downloadTokensFile(QUrl url);
|
||||
|
||||
private:
|
||||
QLabel *urlLabel;
|
||||
QLineEdit *urlLineEdit;
|
||||
QPushButton *urlButton;
|
||||
QLabel *progressLabel;
|
||||
QProgressBar *progressBar;
|
||||
QNetworkAccessManager *nam;
|
||||
|
||||
private slots:
|
||||
void actRestoreDefaultUrl();
|
||||
void actDownloadProgressTokensFile(qint64 received, qint64 total);
|
||||
|
@ -148,11 +202,14 @@ class SaveTokensPage : public OracleWizardPage
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SaveTokensPage(QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
explicit SaveTokensPage(QWidget *parent = nullptr);
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QCheckBox *defaultPathCheckBox;
|
||||
|
||||
protected:
|
||||
bool validatePage();
|
||||
bool validatePage() override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -14,6 +14,7 @@ SettingsCache::~SettingsCache() { delete cardDatabaseSettings; };
|
|||
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::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; }
|
||||
|
||||
SettingsCache *settingsCache;
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
QString getCustomCardDatabasePath() const;
|
||||
QString getCardDatabasePath() const;
|
||||
QString getTokenDatabasePath() const;
|
||||
QString getSpoilerCardDatabasePath() const;
|
||||
CardDatabaseSettings& cardDatabase() const;
|
||||
signals:
|
||||
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