Merge pull request #111 from Daenyth/better-invalid-db-ux
Don't be a jerk when card database isn't usable.
This commit is contained in:
commit
1260ccc531
4 changed files with 109 additions and 41 deletions
|
@ -14,7 +14,7 @@
|
|||
#include <QNetworkRequest>
|
||||
#include <QDebug>
|
||||
|
||||
const int CardDatabase::versionNeeded = 2;
|
||||
const int CardDatabase::versionNeeded = 3;
|
||||
|
||||
CardSet::CardSet(const QString &_shortName, const QString &_longName)
|
||||
: shortName(_shortName), longName(_longName)
|
||||
|
@ -457,7 +457,7 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
|
|||
}
|
||||
|
||||
CardDatabase::CardDatabase(QObject *parent)
|
||||
: QObject(parent), loadSuccess(false), noCard(0)
|
||||
: QObject(parent), loadStatus(NotLoaded), noCard(0)
|
||||
{
|
||||
connect(settingsCache, SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
||||
connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase()));
|
||||
|
@ -636,13 +636,13 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
|||
}
|
||||
}
|
||||
|
||||
bool CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
||||
LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
if (!file.isOpen())
|
||||
return false;
|
||||
|
||||
return FileError;
|
||||
|
||||
if (tokens) {
|
||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
||||
while (i.hasNext()) {
|
||||
|
@ -659,7 +659,7 @@ bool CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
|||
delete setIt.value();
|
||||
}
|
||||
setHash.clear();
|
||||
|
||||
|
||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
|
@ -675,9 +675,12 @@ bool CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
|||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name() != "cockatrice_carddatabase")
|
||||
return false;
|
||||
if (xml.attributes().value("version").toString().toInt() < versionNeeded)
|
||||
return false;
|
||||
return Invalid;
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version < versionNeeded) {
|
||||
qDebug() << "loadFromFile(): Version too old: " << version;
|
||||
return VersionTooOld;
|
||||
}
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement)
|
||||
break;
|
||||
|
@ -689,7 +692,10 @@ bool CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
|||
}
|
||||
}
|
||||
qDebug() << cardHash.size() << "cards in" << setHash.size() << "sets loaded";
|
||||
return !cardHash.isEmpty();
|
||||
|
||||
if (cardHash.isEmpty()) return NoCards;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
|
||||
|
@ -747,13 +753,13 @@ void CardDatabase::picDownloadHqChanged()
|
|||
}
|
||||
}
|
||||
|
||||
bool CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
||||
LoadStatus CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
||||
{
|
||||
bool tempLoadSuccess = false;
|
||||
LoadStatus tempLoadStatus = NotLoaded;
|
||||
if (!path.isEmpty())
|
||||
tempLoadSuccess = loadFromFile(path, tokens);
|
||||
|
||||
if (tempLoadSuccess) {
|
||||
tempLoadStatus = loadFromFile(path, tokens);
|
||||
|
||||
if (tempLoadStatus == Ok) {
|
||||
SetList allSets;
|
||||
QHashIterator<QString, CardSet *> setsIterator(setHash);
|
||||
while (setsIterator.hasNext())
|
||||
|
@ -761,14 +767,17 @@ bool CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
|||
allSets.sortByKey();
|
||||
for (int i = 0; i < allSets.size(); ++i)
|
||||
allSets[i]->setSortKey(i);
|
||||
|
||||
|
||||
emit cardListChanged();
|
||||
}
|
||||
|
||||
if (!tokens)
|
||||
loadSuccess = tempLoadSuccess;
|
||||
|
||||
return tempLoadSuccess;
|
||||
|
||||
if (!tokens) {
|
||||
loadStatus = tempLoadStatus;
|
||||
qDebug() << "loadCardDatabase(): Status = " << loadStatus;
|
||||
}
|
||||
|
||||
|
||||
return tempLoadStatus;
|
||||
}
|
||||
|
||||
void CardDatabase::loadCardDatabase()
|
||||
|
|
|
@ -158,16 +158,18 @@ signals:
|
|||
void cardInfoChanged(CardInfo *card);
|
||||
};
|
||||
|
||||
enum LoadStatus { Ok, VersionTooOld, Invalid, NotLoaded, FileError, NoCards };
|
||||
|
||||
class CardDatabase : public QObject {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
QHash<QString, CardInfo *> cardHash;
|
||||
QHash<QString, CardSet *> setHash;
|
||||
bool loadSuccess;
|
||||
CardInfo *noCard;
|
||||
|
||||
QThread *pictureLoaderThread;
|
||||
PictureLoader *pictureLoader;
|
||||
LoadStatus loadStatus;
|
||||
private:
|
||||
static const int versionNeeded;
|
||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||
|
@ -182,22 +184,23 @@ public:
|
|||
CardSet *getSet(const QString &setName);
|
||||
QList<CardInfo *> getCardList() const { return cardHash.values(); }
|
||||
SetList getSetList() const;
|
||||
bool loadFromFile(const QString &fileName, bool tokens = false);
|
||||
LoadStatus loadFromFile(const QString &fileName, bool tokens = false);
|
||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
||||
QStringList getAllColors() const;
|
||||
QStringList getAllMainCardTypes() const;
|
||||
bool getLoadSuccess() const { return loadSuccess; }
|
||||
LoadStatus getLoadStatus() const { return loadStatus; }
|
||||
bool getLoadSuccess() const { return loadStatus == Ok; }
|
||||
void cacheCardPixmaps(const QStringList &cardNames);
|
||||
void loadImage(CardInfo *card);
|
||||
public slots:
|
||||
void clearPixmapCache();
|
||||
bool loadCardDatabase(const QString &path, bool tokens = false);
|
||||
LoadStatus loadCardDatabase(const QString &path, bool tokens = false);
|
||||
private slots:
|
||||
void imageLoaded(CardInfo *card, QImage image);
|
||||
void picDownloadChanged();
|
||||
void picDownloadHqChanged();
|
||||
void picsPathChanged();
|
||||
|
||||
|
||||
void loadCardDatabase();
|
||||
void loadTokenDatabase();
|
||||
signals:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QInputDialog>
|
||||
#include <QSpinBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDebug>
|
||||
#include "carddatabase.h"
|
||||
#include "dlg_settings.h"
|
||||
#include "main.h"
|
||||
|
@ -704,17 +705,65 @@ void DlgSettings::changeEvent(QEvent *event)
|
|||
|
||||
void DlgSettings::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (!db->getLoadSuccess())
|
||||
if (QMessageBox::critical(this, tr("Error"), tr("Your card database is invalid. Would you like to go back and set the correct path?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
bool showLoadError = true;
|
||||
QString loadErrorMessage = tr("Unknown Error loading card database");
|
||||
LoadStatus loadStatus = db->getLoadStatus();
|
||||
qDebug() << "Card Database load status: " << loadStatus;
|
||||
switch(loadStatus) {
|
||||
case Ok:
|
||||
showLoadError = false;
|
||||
break;
|
||||
case Invalid:
|
||||
loadErrorMessage =
|
||||
tr("Your card database is invalid.\n\n"
|
||||
"Cockatrice may not function correctly with an invalid database\n\n"
|
||||
"You may need to rerun oracle to update your card database.\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
break;
|
||||
case VersionTooOld:
|
||||
loadErrorMessage =
|
||||
tr("Your card database version is too old.\n\n"
|
||||
"This can cause problems loading card information or images\n\n"
|
||||
"Usually this can be fixed by rerunning oracle to to update your card database.\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
break;
|
||||
case NotLoaded:
|
||||
loadErrorMessage =
|
||||
tr("Your card database did not finish loading\n\n"
|
||||
"Please file a ticket at http://github.com/Daenyth/Cockatrice/issues with your cards.xml attached\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
break;
|
||||
case FileError:
|
||||
loadErrorMessage =
|
||||
tr("File Error loading your card database.\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
break;
|
||||
case NoCards:
|
||||
loadErrorMessage =
|
||||
tr("Your card database was loaded but contains no cards.\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
break;
|
||||
default:
|
||||
loadErrorMessage =
|
||||
tr("Unknown card database load status\n\n"
|
||||
"Please file a ticket at http://github.com/Daenyth/Cockatrice/issues\n\n"
|
||||
"Would you like to change your database location setting?");
|
||||
|
||||
break;
|
||||
}
|
||||
if (showLoadError)
|
||||
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) {
|
||||
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) {
|
||||
event->ignore();
|
||||
return;
|
||||
|
|
|
@ -74,10 +74,18 @@ void installNewTranslator()
|
|||
qApp->installTranslator(translator);
|
||||
}
|
||||
|
||||
bool settingsValid()
|
||||
{
|
||||
return QDir(settingsCache->getDeckPath()).exists() &&
|
||||
!settingsCache->getDeckPath().isEmpty() &&
|
||||
QDir(settingsCache->getPicsPath()).exists() &&
|
||||
!settingsCache->getPicsPath().isEmpty();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
||||
if (app.arguments().contains("--debug-output"))
|
||||
qInstallMsgHandler(myMessageOutput);
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -97,7 +105,7 @@ int main(int argc, char *argv[])
|
|||
QCoreApplication::setOrganizationName("Cockatrice");
|
||||
QCoreApplication::setOrganizationDomain("cockatrice.de");
|
||||
QCoreApplication::setApplicationName("Cockatrice");
|
||||
|
||||
|
||||
if (translationPath.isEmpty()) {
|
||||
#ifdef Q_OS_MAC
|
||||
QDir translationsDir = baseDir;
|
||||
|
@ -108,7 +116,7 @@ int main(int argc, char *argv[])
|
|||
translationPath = app.applicationDirPath() + "/translations";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
rng = new RNG_SFMT;
|
||||
settingsCache = new SettingsCache;
|
||||
db = new CardDatabase;
|
||||
|
@ -119,7 +127,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
bool startMainProgram = true;
|
||||
const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
||||
if (!db->getLoadSuccess())
|
||||
if (db->loadCardDatabase(dataDir + "/cards.xml"))
|
||||
|
@ -138,30 +145,30 @@ int main(int argc, char *argv[])
|
|||
QDir().mkpath(dataDir + "/pics");
|
||||
settingsCache->setPicsPath(dataDir + "/pics");
|
||||
}
|
||||
if (!db->getLoadSuccess() || !QDir(settingsCache->getDeckPath()).exists() || settingsCache->getDeckPath().isEmpty() || settingsCache->getPicsPath().isEmpty() || !QDir(settingsCache->getPicsPath()).exists()) {
|
||||
if (!settingsValid() || db->getLoadStatus() != Ok) {
|
||||
qDebug("main(): invalid settings or load status");
|
||||
DlgSettings dlgSettings;
|
||||
dlgSettings.show();
|
||||
app.exec();
|
||||
startMainProgram = (db->getLoadSuccess() && QDir(settingsCache->getDeckPath()).exists() && !settingsCache->getDeckPath().isEmpty() && QDir(settingsCache->getPicsPath()).exists() && !settingsCache->getPicsPath().isEmpty());
|
||||
}
|
||||
|
||||
if (startMainProgram) {
|
||||
|
||||
if (settingsValid()) {
|
||||
qDebug("main(): starting main program");
|
||||
soundEngine = new SoundEngine;
|
||||
qDebug("main(): SoundEngine constructor finished");
|
||||
|
||||
MainWindow ui;
|
||||
qDebug("main(): MainWindow constructor finished");
|
||||
|
||||
|
||||
QIcon icon(":/resources/appicon.svg");
|
||||
ui.setWindowIcon(icon);
|
||||
|
||||
|
||||
ui.show();
|
||||
qDebug("main(): ui.show() finished");
|
||||
|
||||
|
||||
app.exec();
|
||||
}
|
||||
|
||||
|
||||
qDebug("Event loop finished, terminating...");
|
||||
delete db;
|
||||
delete settingsCache;
|
||||
|
@ -169,6 +176,6 @@ int main(int argc, char *argv[])
|
|||
PingPixmapGenerator::clear();
|
||||
CountryPixmapGenerator::clear();
|
||||
UserLevelPixmapGenerator::clear();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue