Merge branch 'master' into mod_notify_onbanwarn
This commit is contained in:
commit
54ebb6a508
62 changed files with 31523 additions and 21910 deletions
|
@ -14,10 +14,7 @@
|
|||
|
||||
# Cockatrice
|
||||
|
||||
Cockatrice is an open-source multiplatform software for playing card games,
|
||||
such as Magic: The Gathering, over a network. It is fully client-server based
|
||||
to prevent any kind of cheating, though it supports single-player games without
|
||||
a network interface as well. Both client and server are written in Qt, supporting both Qt4 and Qt5.<br>
|
||||
Cockatrice is an open-source multiplatform supported program for playing tabletop card games over a network. The program's server design prevents any kind of client modifications to gain an unfair advantage in a game. The client also has a built in single-player mode where you can brew without being connected to a server. This project is written in C++/Qt with support for both Qt4 and Qt5.<br>
|
||||
|
||||
|
||||
# Downloads
|
||||
|
|
|
@ -2,8 +2,10 @@ set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
|
|||
set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h")
|
||||
INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
|
||||
|
||||
set( hstring "extern const char *VERSION_STRING\;\n" )
|
||||
set( cppstring "const char * VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;\n")
|
||||
set( hstring "extern const char *VERSION_STRING\;
|
||||
extern const char *VERSION_DATE\;\n" )
|
||||
set( cppstring "const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n")
|
||||
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring} )
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring} )
|
||||
|
|
|
@ -16,7 +16,8 @@ SET(cockatrice_SOURCES
|
|||
src/dlg_edit_tokens.cpp
|
||||
src/dlg_edit_user.cpp
|
||||
src/dlg_register.cpp
|
||||
src/abstractclient.cpp
|
||||
src/dlg_update.cpp
|
||||
src/abstractclient.cpp
|
||||
src/remoteclient.cpp
|
||||
src/main.cpp
|
||||
src/window_main.cpp
|
||||
|
@ -107,6 +108,8 @@ SET(cockatrice_SOURCES
|
|||
src/settings/messagesettings.cpp
|
||||
src/settings/gamefilterssettings.cpp
|
||||
src/settings/layoutssettings.cpp
|
||||
src/update_checker.cpp
|
||||
src/update_downloader.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
|
|
181
cockatrice/src/dlg_update.cpp
Normal file
181
cockatrice/src/dlg_update.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
#define HUMAN_DOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice/_latestVersion"
|
||||
#define API_DOWNLOAD_BASE_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
||||
#define DATE_LENGTH 10
|
||||
#define MAX_DATE_LENGTH 100
|
||||
#define SHORT_SHA1_HASH_LENGTH 7
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QProgressDialog>
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QApplication>
|
||||
|
||||
#include "dlg_update.h"
|
||||
#include "window_main.h"
|
||||
|
||||
DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
||||
|
||||
//Handle layout
|
||||
text = new QLabel(this);
|
||||
progress = new QProgressBar(this);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||
ok = new QPushButton("Ok", this);
|
||||
manualDownload = new QPushButton("Update Anyway", this);
|
||||
enableUpdateButton(false); //Unless we know there's an update available, you can't install
|
||||
gotoDownload = new QPushButton("Open Download Page", this);
|
||||
buttonBox->addButton(manualDownload, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(gotoDownload, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(ok, QDialogButtonBox::AcceptRole);
|
||||
|
||||
connect(gotoDownload, SIGNAL(clicked()), this, SLOT(gotoDownloadPage()));
|
||||
connect(manualDownload, SIGNAL(clicked()), this, SLOT(downloadUpdate()));
|
||||
connect(ok, SIGNAL(clicked()), this, SLOT(closeDialog()));
|
||||
|
||||
QVBoxLayout *parentLayout = new QVBoxLayout(this);
|
||||
parentLayout->addWidget(text);
|
||||
parentLayout->addWidget(progress);
|
||||
parentLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(parentLayout);
|
||||
|
||||
//Check for SSL (this probably isn't necessary)
|
||||
if (!QSslSocket::supportsSsl()) {
|
||||
enableUpdateButton(false);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Error"),
|
||||
tr("Cockatrice was not built with SSL support, so cannot download updates! "
|
||||
"Please visit the download page and update manually."));
|
||||
}
|
||||
|
||||
//Initialize the checker and downloader class
|
||||
uDownloader = new UpdateDownloader(this);
|
||||
connect(uDownloader, SIGNAL(downloadSuccessful(QUrl)), this, SLOT(downloadSuccessful(QUrl)));
|
||||
connect(uDownloader, SIGNAL(progressMade(qint64, qint64)),
|
||||
this, SLOT(downloadProgressMade(qint64, qint64)));
|
||||
connect(uDownloader, SIGNAL(error(QString)),
|
||||
this, SLOT(downloadError(QString)));
|
||||
|
||||
uChecker = new UpdateChecker(this);
|
||||
connect(uChecker, SIGNAL(finishedCheck(bool, bool, QVariantMap * )),
|
||||
this, SLOT(finishedUpdateCheck(bool, bool, QVariantMap * )));
|
||||
connect(uChecker, SIGNAL(error(QString)),
|
||||
this, SLOT(updateCheckError(QString)));
|
||||
|
||||
//Check for updates
|
||||
beginUpdateCheck();
|
||||
}
|
||||
|
||||
|
||||
void DlgUpdate::closeDialog() {
|
||||
accept();
|
||||
}
|
||||
|
||||
|
||||
void DlgUpdate::gotoDownloadPage() {
|
||||
QUrl openUrl(HUMAN_DOWNLOAD_URL);
|
||||
QDesktopServices::openUrl(openUrl);
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadUpdate() {
|
||||
setLabel("Downloading update...");
|
||||
enableUpdateButton(false);
|
||||
uDownloader->beginDownload(updateUrl);
|
||||
}
|
||||
|
||||
void DlgUpdate::beginUpdateCheck() {
|
||||
progress->setMinimum(0);
|
||||
progress->setMaximum(0);
|
||||
setLabel("Checking for updates...");
|
||||
uChecker->check();
|
||||
}
|
||||
|
||||
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVariantMap *build) {
|
||||
|
||||
QString commitHash, commitDate;
|
||||
|
||||
//Update the UI to say we've finished
|
||||
progress->setMaximum(100);
|
||||
setLabel("Finished checking for updates.");
|
||||
|
||||
//If there are no available builds, then they can't auto update.
|
||||
enableUpdateButton(isCompatible);
|
||||
|
||||
//If there is an update, save its URL and work out its name
|
||||
if (isCompatible) {
|
||||
QString endUrl = (*build)["path"].toString();
|
||||
updateUrl = API_DOWNLOAD_BASE_URL + endUrl;
|
||||
commitHash = (*build)["sha1"].toString().left(SHORT_SHA1_HASH_LENGTH);
|
||||
commitDate = (*build)["created"].toString().remove(DATE_LENGTH, MAX_DATE_LENGTH);
|
||||
}
|
||||
|
||||
//Give the user the appropriate message
|
||||
if (needToUpdate) {
|
||||
if (isCompatible) {
|
||||
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this, "Update Available",
|
||||
"A new build (commit " + commitHash + ") from " + commitDate +
|
||||
" is available. Download?",
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes)
|
||||
downloadUpdate();
|
||||
}
|
||||
else {
|
||||
QMessageBox::information(this, "Cockatrice Update",
|
||||
tr("Your version of Cockatrice is out of date, but there are no packages"
|
||||
" available for your operating system. You may have to use a developer build or build from source"
|
||||
" yourself. Please visit the download page."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
//If there's no need to update, tell them that. However we still allow them to run the
|
||||
//downloader themselves if there's a compatible build
|
||||
QMessageBox::information(this, tr("Cockatrice Update"), tr("Your version of Cockatrice is up to date."));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DlgUpdate::enableUpdateButton(bool enable) {
|
||||
manualDownload->setEnabled(enable);
|
||||
}
|
||||
|
||||
void DlgUpdate::setLabel(QString newText) {
|
||||
text->setText(newText);
|
||||
}
|
||||
|
||||
void DlgUpdate::updateCheckError(QString errorString) {
|
||||
setLabel("Error");
|
||||
QMessageBox::critical(this, tr("Update Error"), "An error occurred while checking for updates: " + errorString);
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadError(QString errorString) {
|
||||
setLabel("Error");
|
||||
enableUpdateButton(true);
|
||||
QMessageBox::critical(this, tr("Update Error"), "An error occurred while downloading an update: " + errorString);
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadSuccessful(QUrl filepath) {
|
||||
setLabel("Installing...");
|
||||
//Try to open the installer. If it opens, quit Cockatrice
|
||||
if (QDesktopServices::openUrl(filepath))
|
||||
{
|
||||
QMetaObject::invokeMethod((MainWindow*) parent(), "close", Qt::QueuedConnection);
|
||||
close();
|
||||
} else {
|
||||
setLabel("Error");
|
||||
QMessageBox::critical(this, tr("Update Error"), "Unable to open the installer. You might be able to manually update"
|
||||
" by closing Cockatrice and running the installer at " + filepath.toLocalFile() + ".");
|
||||
}
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadProgressMade(qint64 bytesRead, qint64 totalBytes) {
|
||||
progress->setMaximum(totalBytes);
|
||||
progress->setValue(bytesRead);
|
||||
}
|
37
cockatrice/src/dlg_update.h
Normal file
37
cockatrice/src/dlg_update.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef DLG_UPDATE_H
|
||||
#define DLG_UPDATE_H
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include "update_checker.h"
|
||||
#include "update_downloader.h"
|
||||
|
||||
class DlgUpdate : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgUpdate(QWidget *parent);
|
||||
|
||||
private slots:
|
||||
void finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVariantMap *build);
|
||||
void gotoDownloadPage();
|
||||
void downloadUpdate();
|
||||
void updateCheckError(QString errorString);
|
||||
void downloadSuccessful(QUrl filepath);
|
||||
void downloadProgressMade(qint64 bytesRead, qint64 totalBytes);
|
||||
void downloadError(QString errorString);
|
||||
void closeDialog();
|
||||
private:
|
||||
QUrl updateUrl;
|
||||
void enableUpdateButton(bool enable);
|
||||
void beginUpdateCheck();
|
||||
void setLabel(QString text);
|
||||
QLabel *text;
|
||||
QProgressBar *progress;
|
||||
QPushButton *manualDownload, *gotoDownload, *ok;
|
||||
QPushButton *cancel;
|
||||
UpdateChecker *uChecker;
|
||||
UpdateDownloader *uDownloader;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -88,10 +88,10 @@ CardSet *PictureToLoad::getCurrentSet() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
QStringList PictureLoader::md5Blacklist = QStringList()
|
||||
QStringList PictureLoaderWorker::md5Blacklist = QStringList()
|
||||
<< "db0c48db407a907c16ade38de048a441"; // card back returned by gatherer when card is not found
|
||||
|
||||
PictureLoader::PictureLoader()
|
||||
PictureLoaderWorker::PictureLoaderWorker()
|
||||
: QObject(0),
|
||||
downloadRunning(false), loadQueueRunning(false)
|
||||
{
|
||||
|
@ -110,12 +110,12 @@ PictureLoader::PictureLoader()
|
|||
moveToThread(pictureLoaderThread);
|
||||
}
|
||||
|
||||
PictureLoader::~PictureLoader()
|
||||
PictureLoaderWorker::~PictureLoaderWorker()
|
||||
{
|
||||
pictureLoaderThread->deleteLater();
|
||||
}
|
||||
|
||||
void PictureLoader::processLoadQueue()
|
||||
void PictureLoaderWorker::processLoadQueue()
|
||||
{
|
||||
if (loadQueueRunning)
|
||||
return;
|
||||
|
@ -160,7 +160,7 @@ void PictureLoader::processLoadQueue()
|
|||
}
|
||||
}
|
||||
|
||||
bool PictureLoader::cardImageExistsOnDisk(QString & setName, QString & correctedCardname)
|
||||
bool PictureLoaderWorker::cardImageExistsOnDisk(QString & setName, QString & correctedCardname)
|
||||
{
|
||||
QImage image;
|
||||
QImageReader imgReader;
|
||||
|
@ -194,7 +194,7 @@ bool PictureLoader::cardImageExistsOnDisk(QString & setName, QString & corrected
|
|||
return false;
|
||||
}
|
||||
|
||||
QString PictureLoader::getPicUrl()
|
||||
QString PictureLoaderWorker::getPicUrl()
|
||||
{
|
||||
if (!picDownload) return QString("");
|
||||
|
||||
|
@ -242,7 +242,7 @@ QString PictureLoader::getPicUrl()
|
|||
return picUrl;
|
||||
}
|
||||
|
||||
void PictureLoader::startNextPicDownload()
|
||||
void PictureLoaderWorker::startNextPicDownload()
|
||||
{
|
||||
if (cardsToDownload.isEmpty()) {
|
||||
cardBeingDownloaded = 0;
|
||||
|
@ -267,7 +267,7 @@ void PictureLoader::startNextPicDownload()
|
|||
}
|
||||
}
|
||||
|
||||
void PictureLoader::picDownloadFailed()
|
||||
void PictureLoaderWorker::picDownloadFailed()
|
||||
{
|
||||
if (cardBeingDownloaded.nextSet())
|
||||
{
|
||||
|
@ -283,13 +283,13 @@ void PictureLoader::picDownloadFailed()
|
|||
}
|
||||
}
|
||||
|
||||
bool PictureLoader::imageIsBlackListed(const QByteArray &picData)
|
||||
bool PictureLoaderWorker::imageIsBlackListed(const QByteArray &picData)
|
||||
{
|
||||
QString md5sum = QCryptographicHash::hash(picData, QCryptographicHash::Md5).toHex();
|
||||
return md5Blacklist.contains(md5sum);
|
||||
}
|
||||
|
||||
void PictureLoader::picDownloadFinished(QNetworkReply *reply)
|
||||
void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error()) {
|
||||
qDebug() << "Download failed:" << reply->errorString();
|
||||
|
@ -349,7 +349,7 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply)
|
|||
startNextPicDownload();
|
||||
}
|
||||
|
||||
void PictureLoader::enqueueImageLoad(CardInfo *card)
|
||||
void PictureLoaderWorker::enqueueImageLoad(CardInfo *card)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
|
@ -367,20 +367,31 @@ void PictureLoader::enqueueImageLoad(CardInfo *card)
|
|||
emit startLoadQueue();
|
||||
}
|
||||
|
||||
void PictureLoader::picDownloadChanged()
|
||||
void PictureLoaderWorker::picDownloadChanged()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
picDownload = settingsCache->getPicDownload();
|
||||
|
||||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
void PictureLoader::picsPathChanged()
|
||||
void PictureLoaderWorker::picsPathChanged()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
picsPath = settingsCache->getPicsPath();
|
||||
}
|
||||
|
||||
QPixmapCache::clear();
|
||||
PictureLoader::PictureLoader()
|
||||
: QObject(0)
|
||||
{
|
||||
worker = new PictureLoaderWorker;
|
||||
connect(settingsCache, SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
||||
connect(settingsCache, SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
||||
|
||||
connect(worker, SIGNAL(imageLoaded(CardInfo *, const QImage &)), this, SLOT(imageLoaded(CardInfo *, const QImage &)));
|
||||
}
|
||||
|
||||
PictureLoader::~PictureLoader()
|
||||
{
|
||||
worker->deleteLater();
|
||||
}
|
||||
|
||||
void PictureLoader::internalGetCardBackPixmap(QPixmap &pixmap, QSize size)
|
||||
|
@ -388,7 +399,7 @@ void PictureLoader::internalGetCardBackPixmap(QPixmap &pixmap, QSize size)
|
|||
QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height());
|
||||
if(!QPixmapCache::find(backCacheKey, &pixmap))
|
||||
{
|
||||
qDebug() << "cache fail for" << backCacheKey;
|
||||
qDebug() << "cache fail for" << backCacheKey;
|
||||
pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
QPixmapCache::insert(backCacheKey, pixmap);
|
||||
}
|
||||
|
@ -425,7 +436,7 @@ void PictureLoader::getPixmap(QPixmap &pixmap, CardInfo *card, QSize size)
|
|||
if(card)
|
||||
{
|
||||
// add the card to the load queue
|
||||
getInstance().enqueueImageLoad(card);
|
||||
getInstance().worker->enqueueImageLoad(card);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,6 +482,16 @@ void PictureLoader::cacheCardPixmaps(QList<CardInfo *> cards)
|
|||
if(QPixmapCache::find(key, &tmp))
|
||||
continue;
|
||||
|
||||
getInstance().enqueueImageLoad(card);
|
||||
getInstance().worker->enqueueImageLoad(card);
|
||||
}
|
||||
}
|
||||
|
||||
void PictureLoader::picDownloadChanged()
|
||||
{
|
||||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
void PictureLoader::picsPathChanged()
|
||||
{
|
||||
QPixmapCache::clear();
|
||||
}
|
|
@ -28,6 +28,42 @@ public:
|
|||
bool nextSet();
|
||||
};
|
||||
|
||||
class PictureLoaderWorker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PictureLoaderWorker();
|
||||
~PictureLoaderWorker();
|
||||
|
||||
void enqueueImageLoad(CardInfo *card);
|
||||
private:
|
||||
static QStringList md5Blacklist;
|
||||
|
||||
QThread *pictureLoaderThread;
|
||||
QString picsPath;
|
||||
QList<PictureToLoad> loadQueue;
|
||||
QMutex mutex;
|
||||
QNetworkAccessManager *networkManager;
|
||||
QList<PictureToLoad> cardsToDownload;
|
||||
PictureToLoad cardBeingLoaded;
|
||||
PictureToLoad cardBeingDownloaded;
|
||||
bool picDownload, downloadRunning, loadQueueRunning;
|
||||
void startNextPicDownload();
|
||||
QString getPicUrl();
|
||||
bool cardImageExistsOnDisk(QString & setName, QString & correctedCardname);
|
||||
bool imageIsBlackListed(const QByteArray &picData);
|
||||
private slots:
|
||||
void picDownloadFinished(QNetworkReply *reply);
|
||||
void picDownloadFailed();
|
||||
|
||||
void picDownloadChanged();
|
||||
void picsPathChanged();
|
||||
public slots:
|
||||
void processLoadQueue();
|
||||
signals:
|
||||
void startLoadQueue();
|
||||
void imageLoaded(CardInfo *card, const QImage &image);
|
||||
};
|
||||
|
||||
class PictureLoader : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -43,24 +79,8 @@ private:
|
|||
PictureLoader(PictureLoader const&);
|
||||
void operator=(PictureLoader const&);
|
||||
|
||||
static QStringList md5Blacklist;
|
||||
|
||||
QThread *pictureLoaderThread;
|
||||
QString picsPath;
|
||||
QList<PictureToLoad> loadQueue;
|
||||
QMutex mutex;
|
||||
QNetworkAccessManager *networkManager;
|
||||
QList<PictureToLoad> cardsToDownload;
|
||||
PictureToLoad cardBeingLoaded;
|
||||
PictureToLoad cardBeingDownloaded;
|
||||
bool picDownload, downloadRunning, loadQueueRunning;
|
||||
void startNextPicDownload();
|
||||
void imageLoaded(CardInfo *card, const QImage &image);
|
||||
QString getPicUrl();
|
||||
bool cardImageExistsOnDisk(QString & setName, QString & correctedCardname);
|
||||
bool imageIsBlackListed(const QByteArray &picData);
|
||||
PictureLoaderWorker * worker;
|
||||
public:
|
||||
void enqueueImageLoad(CardInfo *card);
|
||||
static void getPixmap(QPixmap &pixmap, CardInfo *card, QSize size);
|
||||
static void clearPixmapCache(CardInfo *card);
|
||||
static void clearPixmapCache();
|
||||
|
@ -68,15 +88,9 @@ public:
|
|||
protected:
|
||||
static void internalGetCardBackPixmap(QPixmap &pixmap, QSize size);
|
||||
private slots:
|
||||
void picDownloadFinished(QNetworkReply *reply);
|
||||
void picDownloadFailed();
|
||||
|
||||
void picDownloadChanged();
|
||||
void picsPathChanged();
|
||||
public slots:
|
||||
void processLoadQueue();
|
||||
signals:
|
||||
void startLoadQueue();
|
||||
void imageLoaded(CardInfo *card, const QImage &image);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,3 +57,43 @@ void LayoutsSettings::setDeckEditorFilterSize(const QSize &value)
|
|||
{
|
||||
setValue(value,"layouts/deckEditor_FilterSize");
|
||||
}
|
||||
|
||||
void LayoutsSettings::setGamePlayAreaGeometry(const QByteArray &value)
|
||||
{
|
||||
setValue(value,"layouts/gameplayarea_geometry");
|
||||
}
|
||||
|
||||
void LayoutsSettings::setGamePlayAreaState(const QByteArray &value)
|
||||
{
|
||||
setValue(value,"layouts/gameplayarea_state");
|
||||
}
|
||||
|
||||
const QByteArray LayoutsSettings::getGamePlayAreaLayoutState()
|
||||
{
|
||||
return getValue("layouts/gameplayarea_state").toByteArray();
|
||||
}
|
||||
|
||||
const QByteArray LayoutsSettings::getGamePlayAreaGeometry()
|
||||
{
|
||||
return getValue("layouts/gameplayarea_geometry").toByteArray();
|
||||
}
|
||||
|
||||
void LayoutsSettings::setReplayPlayAreaGeometry(const QByteArray &value)
|
||||
{
|
||||
setValue(value,"layouts/replayplayarea_geometry");
|
||||
}
|
||||
|
||||
void LayoutsSettings::setReplayPlayAreaState(const QByteArray &value)
|
||||
{
|
||||
setValue(value,"layouts/replayplayarea_state");
|
||||
}
|
||||
|
||||
const QByteArray LayoutsSettings::getReplayPlayAreaLayoutState()
|
||||
{
|
||||
return getValue("layouts/replayplayarea_state").toByteArray();
|
||||
}
|
||||
|
||||
const QByteArray LayoutsSettings::getReplayPlayAreaGeometry()
|
||||
{
|
||||
return getValue("layouts/replayplayarea_geometry").toByteArray();
|
||||
}
|
||||
|
|
|
@ -15,12 +15,20 @@ public:
|
|||
void setDeckEditorCardSize(const QSize &value);
|
||||
void setDeckEditorDeckSize(const QSize &value);
|
||||
void setDeckEditorFilterSize(const QSize &value);
|
||||
void setGamePlayAreaGeometry(const QByteArray &value);
|
||||
void setGamePlayAreaState(const QByteArray &value);
|
||||
void setReplayPlayAreaGeometry(const QByteArray &value);
|
||||
void setReplayPlayAreaState(const QByteArray &value);
|
||||
|
||||
const QByteArray getDeckEditorLayoutState();
|
||||
const QByteArray getDeckEditorGeometry();
|
||||
const QSize getDeckEditorCardSize();
|
||||
const QSize getDeckEditorDeckSize();
|
||||
const QSize getDeckEditorFilterSize();
|
||||
const QByteArray getGamePlayAreaLayoutState();
|
||||
const QByteArray getGamePlayAreaGeometry();
|
||||
const QByteArray getReplayPlayAreaLayoutState();
|
||||
const QByteArray getReplayPlayAreaGeometry();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -612,4 +612,4 @@ void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
|
|||
{
|
||||
notifyAboutUpdates = _notifyaboutupdate;
|
||||
settings->setValue("personal/updatenotification", notifyAboutUpdates);
|
||||
}
|
||||
}
|
|
@ -243,4 +243,5 @@ void ShortcutsSettings::fillDefaultShorcuts()
|
|||
defaultShortCuts["Player/phase9"] = parseSequenceString("F9");
|
||||
defaultShortCuts["tab_room/aClearChat"] = parseSequenceString("F12");
|
||||
defaultShortCuts["DlgLoadDeckFromClipboard/refreshButton"] = parseSequenceString("F5");
|
||||
defaultShortCuts["Player/aResetLayout"] = parseSequenceString("");
|
||||
}
|
||||
|
|
|
@ -170,6 +170,8 @@ void SoundEngine::themeChangedSlot()
|
|||
<< "player_join" << "player_leave" << "player_disconnect" << "player_reconnect" << "player_concede"
|
||||
// Spectator
|
||||
<< "spectator_join" << "spectator_leave"
|
||||
// Buddy
|
||||
<< "buddy_join" << "buddy_leave"
|
||||
// Chat & UI
|
||||
<< "chat_mention" << "all_mention" << "private_message";
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
Tab::Tab(TabSupervisor *_tabSupervisor, QWidget *parent)
|
||||
: QWidget(parent), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0)
|
||||
: QMainWindow(parent), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
void Tab::showCardInfoPopup(const QPoint &pos, const QString &cardName)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef TAB_H
|
||||
#define TAB_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMainWindow>
|
||||
|
||||
class QMenu;
|
||||
class TabSupervisor;
|
||||
class CardInfoWidget;
|
||||
|
||||
class Tab : public QWidget {
|
||||
class Tab : public QMainWindow {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void userEvent(bool globalEvent = true);
|
||||
|
|
|
@ -83,7 +83,10 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
|
|||
mainLayout->addWidget(lockButton);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(mainLayout);
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(mainLayout);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
void TabAdmin::retranslateUi()
|
||||
|
|
|
@ -52,30 +52,6 @@ void SearchLineEdit::keyPressEvent(QKeyEvent *event)
|
|||
QLineEdit::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void TabDeckEditor::createShowHideDocksButtons()
|
||||
{
|
||||
btnFilter = new QPushButton(QPixmap("theme:icons/view"),QString());
|
||||
btnFilter->setObjectName("btnFilter");
|
||||
btnFilter->setCheckable(true);
|
||||
btnFilter->setChecked(true);
|
||||
btnFilter->setMaximumWidth(30);
|
||||
searchLayout->addWidget(btnFilter);
|
||||
|
||||
btnDeck = new QPushButton(QPixmap("theme:hand"),QString());
|
||||
btnDeck->setObjectName("btnDeck");
|
||||
btnDeck->setCheckable(true);
|
||||
btnDeck->setChecked(true);
|
||||
btnDeck->setMaximumWidth(30);
|
||||
searchLayout->addWidget(btnDeck);
|
||||
|
||||
btnCard = new QPushButton(QPixmap("theme:cardback"),QString());
|
||||
btnCard->setObjectName("btnCard");
|
||||
btnCard->setCheckable(true);
|
||||
btnCard->setChecked(true);
|
||||
btnCard->setMaximumWidth(30);
|
||||
searchLayout->addWidget(btnCard);
|
||||
}
|
||||
|
||||
void TabDeckEditor::createDeckDock()
|
||||
{
|
||||
deckModel = new DeckListModel(this);
|
||||
|
@ -160,7 +136,7 @@ void TabDeckEditor::createDeckDock()
|
|||
rightFrame->addWidget(deckView, 10);
|
||||
rightFrame->addLayout(deckToolbarLayout);
|
||||
|
||||
deckDock = new QDockWidget(MainWindow);
|
||||
deckDock = new QDockWidget(this);
|
||||
deckDock->setObjectName("deckDock");
|
||||
|
||||
deckDock->setMinimumSize(QSize(200, 41));
|
||||
|
@ -171,8 +147,8 @@ void TabDeckEditor::createDeckDock()
|
|||
deckDockContents->setLayout(rightFrame);
|
||||
deckDock->setWidget(deckDockContents);
|
||||
|
||||
connect(btnDeck,SIGNAL(toggled(bool)),deckDock,SLOT(setVisible(bool)));
|
||||
deckDock->installEventFilter(this);
|
||||
connect(deckDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabDeckEditor::createCardInfoDock()
|
||||
|
@ -183,7 +159,7 @@ void TabDeckEditor::createCardInfoDock()
|
|||
cardInfoFrame->setObjectName("cardInfoFrame");
|
||||
cardInfoFrame->addWidget(cardInfo);
|
||||
|
||||
cardInfoDock = new QDockWidget(MainWindow);
|
||||
cardInfoDock = new QDockWidget(this);
|
||||
cardInfoDock->setObjectName("cardInfoDock");
|
||||
|
||||
cardInfoDock->setMinimumSize(QSize(200, 41));
|
||||
|
@ -194,8 +170,8 @@ void TabDeckEditor::createCardInfoDock()
|
|||
cardInfoDockContents->setLayout(cardInfoFrame);
|
||||
cardInfoDock->setWidget(cardInfoDockContents);
|
||||
|
||||
connect(btnCard,SIGNAL(toggled(bool)),cardInfoDock,SLOT(setVisible(bool)));
|
||||
cardInfoDock->installEventFilter(this);
|
||||
connect(cardInfoDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabDeckEditor::createFiltersDock()
|
||||
|
@ -243,17 +219,17 @@ void TabDeckEditor::createFiltersDock()
|
|||
filterFrame->setObjectName("filterFrame");
|
||||
filterFrame->addWidget(filterBox);
|
||||
|
||||
filterDock = new QDockWidget(MainWindow);
|
||||
filterDock = new QDockWidget(this);
|
||||
filterDock->setObjectName("filterDock");
|
||||
|
||||
filterDock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
|
||||
QWidget *filterDockContents = new QWidget(MainWindow);
|
||||
QWidget *filterDockContents = new QWidget(this);
|
||||
filterDockContents->setObjectName("filterDockContents");
|
||||
filterDockContents->setLayout(filterFrame);
|
||||
filterDock->setWidget(filterDockContents);
|
||||
|
||||
connect(btnFilter,SIGNAL(toggled(bool)),filterDock,SLOT(setVisible(bool)));
|
||||
filterDock->installEventFilter(this);
|
||||
connect(filterDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabDeckEditor::createMenus()
|
||||
|
@ -297,9 +273,6 @@ void TabDeckEditor::createMenus()
|
|||
aEditTokens = new QAction(QString(), this);
|
||||
connect(aEditTokens, SIGNAL(triggered()), this, SLOT(actEditTokens()));
|
||||
|
||||
aResetLayout = new QAction(QString(), this);
|
||||
connect(aResetLayout,SIGNAL(triggered()),this,SLOT(restartLayout()));
|
||||
|
||||
deckMenu = new QMenu(this);
|
||||
deckMenu->addAction(aNewDeck);
|
||||
deckMenu->addAction(aLoadDeck);
|
||||
|
@ -313,8 +286,6 @@ void TabDeckEditor::createMenus()
|
|||
deckMenu->addSeparator();
|
||||
deckMenu->addAction(aAnalyzeDeck);
|
||||
deckMenu->addSeparator();
|
||||
deckMenu->addAction(aResetLayout);
|
||||
deckMenu->addSeparator();
|
||||
deckMenu->addAction(aClose);
|
||||
addTabMenu(deckMenu);
|
||||
|
||||
|
@ -338,6 +309,41 @@ void TabDeckEditor::createMenus()
|
|||
dbMenu->addAction(aOpenCustomsetsFolder);
|
||||
#endif
|
||||
addTabMenu(dbMenu);
|
||||
|
||||
viewMenu = new QMenu(this);
|
||||
|
||||
cardInfoDockMenu = viewMenu->addMenu(QString());
|
||||
deckDockMenu = viewMenu->addMenu(QString());
|
||||
filterDockMenu = viewMenu->addMenu(QString());
|
||||
|
||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockVisible->setCheckable(true);
|
||||
connect(aCardInfoDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||
aDeckDockVisible->setCheckable(true);
|
||||
connect(aDeckDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aDeckDockFloating = deckDockMenu->addAction(QString());
|
||||
aDeckDockFloating->setCheckable(true);
|
||||
connect(aDeckDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
aFilterDockVisible = filterDockMenu->addAction(QString());
|
||||
aFilterDockVisible->setCheckable(true);
|
||||
connect(aFilterDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aFilterDockFloating = filterDockMenu->addAction(QString());
|
||||
aFilterDockFloating->setCheckable(true);
|
||||
connect(aFilterDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
aResetLayout = viewMenu->addAction(QString());
|
||||
connect(aResetLayout,SIGNAL(triggered()),this,SLOT(restartLayout()));
|
||||
viewMenu->addAction(aResetLayout);
|
||||
|
||||
addTabMenu(viewMenu);
|
||||
}
|
||||
|
||||
void TabDeckEditor::createCentralFrame()
|
||||
|
@ -414,41 +420,43 @@ void TabDeckEditor::createCentralFrame()
|
|||
searchLayout->setObjectName("searchLayout");
|
||||
searchLayout->addWidget(deckEditToolBar);
|
||||
searchLayout->addWidget(searchEdit);
|
||||
createShowHideDocksButtons();
|
||||
|
||||
centralFrame = new QVBoxLayout;
|
||||
centralFrame->setObjectName("centralFrame");
|
||||
centralFrame->addLayout(searchLayout);
|
||||
centralFrame->addWidget(databaseView);
|
||||
|
||||
centralWidget = new QWidget(MainWindow);
|
||||
centralWidget = new QWidget(this);
|
||||
centralWidget->setObjectName("centralWidget");
|
||||
centralWidget->setLayout(centralFrame);
|
||||
MainWindow->setCentralWidget(centralWidget);
|
||||
MainWindow->setDockOptions(QMainWindow::AnimatedDocks|QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
mainLayout->setObjectName("mainLayout");
|
||||
mainLayout->addWidget(MainWindow);
|
||||
setLayout(mainLayout);
|
||||
setCentralWidget(centralWidget);
|
||||
setDockOptions(QMainWindow::AnimatedDocks|QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks);
|
||||
}
|
||||
|
||||
void TabDeckEditor::restartLayout()
|
||||
{
|
||||
btnDeck->setChecked(true);
|
||||
btnFilter->setChecked(true);
|
||||
btnCard->setChecked(true);
|
||||
deckDock->setVisible(true);
|
||||
cardInfoDock->setVisible(true);
|
||||
filterDock->setVisible(true);
|
||||
|
||||
deckDock->setFloating(false);
|
||||
cardInfoDock->setFloating(false);
|
||||
filterDock->setFloating(false);
|
||||
|
||||
MainWindow->addDockWidget(static_cast<Qt::DockWidgetArea>(2), deckDock);
|
||||
MainWindow->addDockWidget(static_cast<Qt::DockWidgetArea>(2), cardInfoDock);
|
||||
MainWindow->addDockWidget(static_cast<Qt::DockWidgetArea>(2), filterDock);
|
||||
aCardInfoDockVisible->setChecked(true);
|
||||
aDeckDockVisible->setChecked(true);
|
||||
aFilterDockVisible->setChecked(true);
|
||||
|
||||
MainWindow->splitDockWidget(cardInfoDock, deckDock, Qt::Horizontal);
|
||||
MainWindow->splitDockWidget(cardInfoDock, filterDock, Qt::Vertical);
|
||||
aCardInfoDockFloating->setChecked(false);
|
||||
aDeckDockFloating->setChecked(false);
|
||||
aFilterDockFloating->setChecked(false);
|
||||
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), deckDock);
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), cardInfoDock);
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), filterDock);
|
||||
|
||||
splitDockWidget(cardInfoDock, deckDock, Qt::Horizontal);
|
||||
splitDockWidget(cardInfoDock, filterDock, Qt::Vertical);
|
||||
|
||||
deckDock->setMinimumWidth(360);
|
||||
deckDock->setMaximumWidth(360);
|
||||
|
@ -496,12 +504,20 @@ void TabDeckEditor::refreshShortcuts()
|
|||
|
||||
void TabDeckEditor::loadLayout()
|
||||
{
|
||||
MainWindow->restoreState(settingsCache->layouts().getDeckEditorLayoutState());
|
||||
MainWindow->restoreGeometry(settingsCache->layouts().getDeckEditorGeometry());
|
||||
restoreState(settingsCache->layouts().getDeckEditorLayoutState());
|
||||
restoreGeometry(settingsCache->layouts().getDeckEditorGeometry());
|
||||
|
||||
btnCard->setChecked(!cardInfoDock->isHidden());
|
||||
btnFilter->setChecked(!filterDock->isHidden());
|
||||
btnDeck->setChecked(!deckDock->isHidden());
|
||||
aCardInfoDockVisible->setChecked(cardInfoDock->isVisible());
|
||||
aFilterDockVisible->setChecked(filterDock->isVisible());
|
||||
aDeckDockVisible->setChecked(deckDock->isVisible());
|
||||
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||
|
||||
aCardInfoDockFloating->setChecked(cardInfoDock->isFloating());
|
||||
aFilterDockFloating->setChecked(filterDock->isFloating());
|
||||
aDeckDockFloating->setChecked(deckDock->isFloating());
|
||||
|
||||
cardInfoDock->setMinimumSize(settingsCache->layouts().getDeckEditorCardSize());
|
||||
cardInfoDock->setMaximumSize(settingsCache->layouts().getDeckEditorCardSize());
|
||||
|
@ -518,8 +534,7 @@ void TabDeckEditor::loadLayout()
|
|||
TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor, QWidget *parent)
|
||||
: Tab(_tabSupervisor, parent), modified(false)
|
||||
{
|
||||
MainWindow = new QMainWindow;
|
||||
MainWindow->setObjectName("MainWindow");
|
||||
setObjectName("TabDeckEditor");
|
||||
|
||||
createMenus();
|
||||
|
||||
|
@ -587,13 +602,25 @@ void TabDeckEditor::retranslateUi()
|
|||
aEditSets->setText(tr("&Edit sets..."));
|
||||
aEditTokens->setText(tr("Edit &tokens..."));
|
||||
|
||||
btnCard->setToolTip(tr("Show/Hide card information"));
|
||||
btnDeck->setToolTip(tr("Show/Hide deck"));
|
||||
btnFilter->setToolTip(tr("Show/Hide filters"));
|
||||
aResetLayout->setText(tr("Reset layout"));
|
||||
cardInfoDock->setWindowTitle(tr("Card Info"));
|
||||
deckDock->setWindowTitle(tr("Deck"));
|
||||
filterDock->setWindowTitle(tr("Filters"));
|
||||
|
||||
viewMenu->setTitle(tr("&View"));
|
||||
cardInfoDockMenu->setTitle(tr("Card Info"));
|
||||
deckDockMenu->setTitle(tr("Deck"));
|
||||
filterDockMenu->setTitle(tr("Filters"));
|
||||
|
||||
aCardInfoDockVisible->setText(tr("Visible"));
|
||||
aCardInfoDockFloating->setText(tr("Floating"));
|
||||
|
||||
aDeckDockVisible->setText(tr("Visible"));
|
||||
aDeckDockFloating->setText(tr("Floating"));
|
||||
|
||||
aFilterDockVisible->setText(tr("Visible"));
|
||||
aFilterDockFloating->setText(tr("Floating"));
|
||||
|
||||
aResetLayout->setText(tr("Reset layout"));
|
||||
}
|
||||
|
||||
QString TabDeckEditor::getTabText() const
|
||||
|
@ -998,28 +1025,6 @@ void TabDeckEditor::setPriceTagFeatureEnabled(int /* enabled */)
|
|||
deckModel->pricesUpdated();
|
||||
}
|
||||
|
||||
bool TabDeckEditor::eventFilter(QObject * o, QEvent * e)
|
||||
{
|
||||
if(e->type() == QEvent::Close)
|
||||
{
|
||||
if(o == cardInfoDock)
|
||||
btnCard->setChecked(false);
|
||||
else if(o == deckDock)
|
||||
btnDeck->setChecked(false);
|
||||
else if(o == filterDock)
|
||||
btnFilter->setChecked(false);
|
||||
}
|
||||
if( o == this && e->type() == QEvent::Hide){
|
||||
settingsCache->layouts().setDeckEditorLayoutState(MainWindow->saveState());
|
||||
settingsCache->layouts().setDeckEditorGeometry(MainWindow->saveGeometry());
|
||||
settingsCache->layouts().setDeckEditorCardSize(cardInfoDock->size());
|
||||
settingsCache->layouts().setDeckEditorFilterSize(filterDock->size());
|
||||
settingsCache->layouts().setDeckEditorDeckSize(deckDock->size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void TabDeckEditor::actUpdatePrices()
|
||||
{
|
||||
|
@ -1105,3 +1110,99 @@ void TabDeckEditor::checkFirstRunDetected()
|
|||
actEditSets();
|
||||
}
|
||||
}
|
||||
|
||||
// Method uses to sync docks state with menu items state
|
||||
bool TabDeckEditor::eventFilter(QObject * o, QEvent * e)
|
||||
{
|
||||
if(e->type() == QEvent::Close)
|
||||
{
|
||||
if(o == cardInfoDock)
|
||||
{
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if(o == deckDock) {
|
||||
aDeckDockVisible->setChecked(false);
|
||||
aDeckDockFloating->setEnabled(false);
|
||||
} else if(o == filterDock) {
|
||||
aFilterDockVisible->setChecked(false);
|
||||
aFilterDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
if( o == this && e->type() == QEvent::Hide){
|
||||
settingsCache->layouts().setDeckEditorLayoutState(saveState());
|
||||
settingsCache->layouts().setDeckEditorGeometry(saveGeometry());
|
||||
settingsCache->layouts().setDeckEditorCardSize(cardInfoDock->size());
|
||||
settingsCache->layouts().setDeckEditorFilterSize(filterDock->size());
|
||||
settingsCache->layouts().setDeckEditorDeckSize(deckDock->size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabDeckEditor::dockVisibleTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if(o == aCardInfoDockVisible)
|
||||
{
|
||||
cardInfoDock->setVisible(aCardInfoDockVisible->isChecked());
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aDeckDockVisible)
|
||||
{
|
||||
deckDock->setVisible(aDeckDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aFilterDockVisible)
|
||||
{
|
||||
filterDock->setVisible(aFilterDockVisible->isChecked());
|
||||
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditor::dockFloatingTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if(o == aCardInfoDockFloating)
|
||||
{
|
||||
cardInfoDock->setFloating(aCardInfoDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aDeckDockFloating)
|
||||
{
|
||||
deckDock->setFloating(aDeckDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aFilterDockFloating)
|
||||
{
|
||||
filterDock->setFloating(aFilterDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditor::dockTopLevelChanged(bool topLevel)
|
||||
{
|
||||
QObject *o = sender();
|
||||
if(o == cardInfoDock)
|
||||
{
|
||||
aCardInfoDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == deckDock)
|
||||
{
|
||||
aDeckDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == filterDock)
|
||||
{
|
||||
aFilterDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ class CardInfo;
|
|||
class QGroupBox;
|
||||
class QHBoxLayout;
|
||||
class QPushButton;
|
||||
class QMainWindow;
|
||||
class QDockWidget;
|
||||
|
||||
class SearchLineEdit : public QLineEdit {
|
||||
|
@ -79,12 +78,15 @@ class TabDeckEditor : public Tab {
|
|||
void filterRemove(QAction *action);
|
||||
void setPriceTagFeatureEnabled(int enabled);
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e);
|
||||
void loadLayout();
|
||||
void restartLayout();
|
||||
void freeDocksSize();
|
||||
void refreshShortcuts();
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e);
|
||||
void dockVisibleTriggered();
|
||||
void dockFloatingTriggered();
|
||||
void dockTopLevelChanged(bool topLevel);
|
||||
private:
|
||||
CardInfo *currentCardInfo() const;
|
||||
void addCardHelper(QString zoneName);
|
||||
|
@ -113,19 +115,16 @@ private:
|
|||
QTreeView *filterView;
|
||||
QWidget *filterBox;
|
||||
|
||||
QMenu *deckMenu, *dbMenu;
|
||||
QMenu *deckMenu, *dbMenu, *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu;
|
||||
QAction *aNewDeck, *aLoadDeck, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, *aSaveDeckToClipboard, *aPrintDeck, *aAnalyzeDeck, *aClose, *aOpenCustomFolder, *aOpenCustomsetsFolder;
|
||||
QAction *aEditSets, *aEditTokens, *aClearFilterAll, *aClearFilterOne;
|
||||
QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement;// *aUpdatePrices;
|
||||
QAction *aResetLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating, *aFilterDockVisible, *aFilterDockFloating;
|
||||
|
||||
bool modified;
|
||||
QMainWindow *MainWindow;
|
||||
QVBoxLayout *centralFrame;
|
||||
QHBoxLayout *searchLayout;
|
||||
QPushButton *btnFilter;
|
||||
QPushButton *btnDeck;
|
||||
QPushButton *btnCard;
|
||||
QDockWidget *cardInfoDock;
|
||||
QDockWidget *deckDock;
|
||||
QDockWidget *filterDock;
|
||||
|
@ -138,7 +137,6 @@ public:
|
|||
void setDeck(DeckLoader *_deckLoader);
|
||||
void setModified(bool _windowModified);
|
||||
bool confirmClose();
|
||||
void createShowHideDocksButtons();
|
||||
void createDeckDock();
|
||||
void createCardInfoDock();
|
||||
void createFiltersDock();
|
||||
|
|
|
@ -110,7 +110,10 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c
|
|||
rightToolBar->addAction(aDeleteRemoteDeck);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(hbox);
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(hbox);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
void TabDeckStorage::retranslateUi()
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include <QToolButton>
|
||||
#include <QDebug>
|
||||
#include <QCompleter>
|
||||
#include <QDockWidget>
|
||||
#include <QWidget>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include "dlg_creategame.h"
|
||||
#include "tab_game.h"
|
||||
|
@ -35,6 +37,7 @@
|
|||
#include "pictureloader.h"
|
||||
#include "replay_timeline_widget.h"
|
||||
#include "lineeditcompleter.h"
|
||||
#include "window_sets.h"
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include "pending_command.h"
|
||||
|
@ -93,7 +96,7 @@ void ToggleButton::setState(bool _state)
|
|||
}
|
||||
|
||||
DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
|
||||
: QWidget(parent), playerId(_playerId)
|
||||
: QWidget(0), parentGame(parent), playerId(_playerId)
|
||||
{
|
||||
loadLocalButton = new QPushButton;
|
||||
loadRemoteButton = new QPushButton;
|
||||
|
@ -202,6 +205,9 @@ void TabGame::refreshShortcuts()
|
|||
if (aCloseReplay) {
|
||||
aCloseReplay->setShortcuts(settingsCache->shortcuts().getShortcut("Player/aCloseReplay"));
|
||||
}
|
||||
if (aResetLayout) {
|
||||
aResetLayout->setShortcuts(settingsCache->shortcuts().getShortcut("Player/aResetLayout"));
|
||||
}
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadLocalDeck()
|
||||
|
@ -222,20 +228,20 @@ void DeckViewContainer::loadLocalDeck()
|
|||
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck(deck.writeToString_Native().toStdString());
|
||||
PendingCommand *pend = static_cast<TabGame *>(parent())->prepareGameCommand(cmd);
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &)));
|
||||
static_cast<TabGame *>(parent())->sendGameCommand(pend, playerId);
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadRemoteDeck()
|
||||
{
|
||||
DlgLoadRemoteDeck dlg(static_cast<TabGame *>(parent())->getClientForPlayer(playerId));
|
||||
DlgLoadRemoteDeck dlg(parentGame->getClientForPlayer(playerId));
|
||||
if (dlg.exec()) {
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck_id(dlg.getDeckId());
|
||||
PendingCommand *pend = static_cast<TabGame *>(parent())->prepareGameCommand(cmd);
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &)));
|
||||
static_cast<TabGame *>(parent())->sendGameCommand(pend, playerId);
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,7 +257,7 @@ void DeckViewContainer::readyStart()
|
|||
{
|
||||
Command_ReadyStart cmd;
|
||||
cmd.set_ready(!readyStartButton->getState());
|
||||
static_cast<TabGame *>(parent())->sendGameCommand(cmd, playerId);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardLockButtonClicked()
|
||||
|
@ -259,7 +265,7 @@ void DeckViewContainer::sideboardLockButtonClicked()
|
|||
Command_SetSideboardLock cmd;
|
||||
cmd.set_locked(sideboardLockButton->getState());
|
||||
|
||||
static_cast<TabGame *>(parent())->sendGameCommand(cmd, playerId);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardPlanChanged()
|
||||
|
@ -268,7 +274,7 @@ void DeckViewContainer::sideboardPlanChanged()
|
|||
const QList<MoveCard_ToZone> &newPlan = deckView->getSideboardPlan();
|
||||
for (int i = 0; i < newPlan.size(); ++i)
|
||||
cmd.add_move_list()->CopyFrom(newPlan[i]);
|
||||
static_cast<TabGame *>(parent())->sendGameCommand(cmd, playerId);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::setReadyStart(bool ready)
|
||||
|
@ -310,11 +316,10 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
|||
sayLabel(0),
|
||||
sayEdit(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
// THIS CTOR IS USED ON REPLAY
|
||||
gameInfo.CopyFrom(replay->game_info());
|
||||
gameInfo.set_spectators_omniscient(true);
|
||||
|
||||
|
||||
// Create list: event number -> time [ms]
|
||||
// Distribute simultaneous events evenly across 1 second.
|
||||
unsigned int lastEventTimestamp = 0;
|
||||
|
@ -323,106 +328,41 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
|||
int j = i + 1;
|
||||
while ((j < eventCount) && (replay->event_list(j).seconds_elapsed() == lastEventTimestamp))
|
||||
++j;
|
||||
|
||||
|
||||
const int numberEventsThisSecond = j - i;
|
||||
for (int k = 0; k < numberEventsThisSecond; ++k)
|
||||
replayTimeline.append(replay->event_list(i + k).seconds_elapsed() * 1000 + (int) ((qreal) k / (qreal) numberEventsThisSecond * 1000));
|
||||
|
||||
|
||||
if (j < eventCount)
|
||||
lastEventTimestamp = replay->event_list(j).seconds_elapsed();
|
||||
i += numberEventsThisSecond - 1;
|
||||
}
|
||||
|
||||
phasesToolbar = new PhasesToolbar;
|
||||
|
||||
scene = new GameScene(phasesToolbar, this);
|
||||
gameView = new GameView(scene);
|
||||
gameView->hide();
|
||||
|
||||
cardInfo = new CardFrame();
|
||||
playerListWidget = new PlayerListWidget(0, 0, this);
|
||||
playerListWidget->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
||||
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
|
||||
deckViewContainerLayout = new QVBoxLayout;
|
||||
createCardInfoDock(true);
|
||||
createPlayerListDock(true);
|
||||
createMessageDock(true);
|
||||
createPlayAreaWidget(true);
|
||||
createDeckViewContainerWidget(true);
|
||||
createReplayDock();
|
||||
|
||||
QVBoxLayout *messageLogLayout = new QVBoxLayout;
|
||||
messageLogLayout->setContentsMargins(0, 0, 0, 0);
|
||||
messageLogLayout->addWidget(messageLog);
|
||||
|
||||
QWidget *messageLogLayoutWidget = new QWidget;
|
||||
messageLogLayoutWidget->setLayout(messageLogLayout);
|
||||
|
||||
timelineWidget = new ReplayTimelineWidget;
|
||||
timelineWidget->setTimeline(replayTimeline);
|
||||
connect(timelineWidget, SIGNAL(processNextEvent()), this, SLOT(replayNextEvent()));
|
||||
connect(timelineWidget, SIGNAL(replayFinished()), this, SLOT(replayFinished()));
|
||||
|
||||
replayStartButton = new QToolButton;
|
||||
replayStartButton->setIconSize(QSize(32, 32));
|
||||
replayStartButton->setIcon(QPixmap("theme:replay/start"));
|
||||
connect(replayStartButton, SIGNAL(clicked()), this, SLOT(replayStartButtonClicked()));
|
||||
replayPauseButton = new QToolButton;
|
||||
replayPauseButton->setIconSize(QSize(32, 32));
|
||||
replayPauseButton->setEnabled(false);
|
||||
replayPauseButton->setIcon(QPixmap("theme:replay/pause"));
|
||||
connect(replayPauseButton, SIGNAL(clicked()), this, SLOT(replayPauseButtonClicked()));
|
||||
replayFastForwardButton = new QToolButton;
|
||||
replayFastForwardButton->setIconSize(QSize(32, 32));
|
||||
replayFastForwardButton->setEnabled(false);
|
||||
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
||||
replayFastForwardButton->setCheckable(true);
|
||||
connect(replayFastForwardButton, SIGNAL(toggled(bool)), this, SLOT(replayFastForwardButtonToggled(bool)));
|
||||
|
||||
splitter = new QSplitter(Qt::Vertical);
|
||||
splitter->addWidget(cardInfo);
|
||||
splitter->addWidget(playerListWidget);
|
||||
splitter->addWidget(messageLogLayoutWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, cardInfoDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, playerListDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, replayDock);
|
||||
|
||||
mainLayout = new QHBoxLayout;
|
||||
mainLayout->addWidget(gameView, 10);
|
||||
mainLayout->addLayout(deckViewContainerLayout, 10);
|
||||
mainLayout->addWidget(splitter);
|
||||
|
||||
QHBoxLayout *replayControlLayout = new QHBoxLayout;
|
||||
replayControlLayout->addWidget(timelineWidget, 10);
|
||||
replayControlLayout->addWidget(replayStartButton);
|
||||
replayControlLayout->addWidget(replayPauseButton);
|
||||
replayControlLayout->addWidget(replayFastForwardButton);
|
||||
|
||||
QVBoxLayout *superMainLayout = new QVBoxLayout;
|
||||
superMainLayout->addLayout(mainLayout);
|
||||
superMainLayout->addLayout(replayControlLayout);
|
||||
|
||||
aNextPhase = 0;
|
||||
aNextTurn = 0;
|
||||
aRemoveLocalArrows = 0;
|
||||
aRotateViewCW = 0;
|
||||
aRotateViewCCW = 0;
|
||||
aGameInfo = 0;
|
||||
aConcede = 0;
|
||||
aLeaveGame = 0;
|
||||
aCloseReplay = new QAction(this);
|
||||
connect(aCloseReplay, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
|
||||
phasesMenu = 0;
|
||||
gameMenu = new QMenu(this);
|
||||
gameMenu->addAction(aCloseReplay);
|
||||
addTabMenu(gameMenu);
|
||||
|
||||
mainWidget = new QStackedWidget(this);
|
||||
mainWidget->addWidget(deckViewContainerWidget);
|
||||
mainWidget->addWidget(gamePlayAreaWidget);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
createReplayMenuItems();
|
||||
createViewMenuItems();
|
||||
retranslateUi();
|
||||
connect(&settingsCache->shortcuts(), SIGNAL(shortCutchanged()),this,SLOT(refreshShortcuts()));
|
||||
refreshShortcuts();
|
||||
setLayout(superMainLayout);
|
||||
|
||||
splitter->restoreState(settingsCache->getTabGameSplitterSizes());
|
||||
splitter->setChildrenCollapsible(false);
|
||||
|
||||
messageLog->logReplayStarted(gameInfo.game_id());
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
||||
}
|
||||
|
||||
TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event, const QMap<int, QString> &_roomGameTypes)
|
||||
|
@ -438,139 +378,39 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
|||
currentPhase(-1),
|
||||
activeCard(0),
|
||||
gameClosed(false),
|
||||
replay(0)
|
||||
replay(0),
|
||||
replayDock(0)
|
||||
{
|
||||
// THIS CTOR IS USED ON GAMES
|
||||
gameInfo.set_started(false);
|
||||
|
||||
gameTimer = new QTimer(this);
|
||||
gameTimer->setInterval(1000);
|
||||
connect(gameTimer, SIGNAL(timeout()), this, SLOT(incrementGameTime()));
|
||||
gameTimer->start();
|
||||
|
||||
phasesToolbar = new PhasesToolbar;
|
||||
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this, SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
|
||||
|
||||
scene = new GameScene(phasesToolbar, this);
|
||||
gameView = new GameView(scene);
|
||||
gameView->hide();
|
||||
|
||||
cardInfo = new CardFrame();
|
||||
playerListWidget = new PlayerListWidget(tabSupervisor, clients.first(), this);
|
||||
playerListWidget->setFocusPolicy(Qt::NoFocus);
|
||||
connect(playerListWidget, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
|
||||
timeElapsedLabel = new QLabel;
|
||||
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||
connect(messageLog, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
||||
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
connect(settingsCache, SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||
sayLabel = new QLabel;
|
||||
sayEdit = new LineEditCompleter;
|
||||
sayLabel->setBuddy(sayEdit);
|
||||
|
||||
QHBoxLayout *hLayout = new QHBoxLayout;
|
||||
hLayout->addWidget(sayLabel);
|
||||
hLayout->addWidget(sayEdit);
|
||||
|
||||
deckViewContainerLayout = new QVBoxLayout;
|
||||
createCardInfoDock();
|
||||
createPlayerListDock();
|
||||
createMessageDock();
|
||||
createPlayAreaWidget();
|
||||
createDeckViewContainerWidget();
|
||||
|
||||
QVBoxLayout *messageLogLayout = new QVBoxLayout;
|
||||
messageLogLayout->setContentsMargins(0, 0, 0, 0);
|
||||
messageLogLayout->addWidget(timeElapsedLabel);
|
||||
messageLogLayout->addWidget(messageLog);
|
||||
messageLogLayout->addLayout(hLayout);
|
||||
|
||||
QWidget *messageLogLayoutWidget = new QWidget;
|
||||
messageLogLayoutWidget->setLayout(messageLogLayout);
|
||||
|
||||
splitter = new QSplitter(Qt::Vertical);
|
||||
splitter->addWidget(cardInfo);
|
||||
splitter->addWidget(playerListWidget);
|
||||
splitter->addWidget(messageLogLayoutWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, cardInfoDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, playerListDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock);
|
||||
|
||||
mainLayout = new QHBoxLayout;
|
||||
mainLayout->addWidget(gameView, 10);
|
||||
mainLayout->addLayout(deckViewContainerLayout, 10);
|
||||
mainLayout->addWidget(splitter);
|
||||
|
||||
if (spectator && !gameInfo.spectators_can_chat() && tabSupervisor->getAdminLocked()) {
|
||||
sayLabel->hide();
|
||||
sayEdit->hide();
|
||||
}
|
||||
connect(tabSupervisor, SIGNAL(adminLockChanged(bool)), this, SLOT(adminLockChanged(bool)));
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
|
||||
mainWidget = new QStackedWidget(this);
|
||||
mainWidget->addWidget(deckViewContainerWidget);
|
||||
mainWidget->addWidget(gamePlayAreaWidget);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
// Menu actions
|
||||
aNextPhase = new QAction(this);
|
||||
connect(aNextPhase, SIGNAL(triggered()), this, SLOT(actNextPhase()));
|
||||
aNextTurn = new QAction(this);
|
||||
connect(aNextTurn, SIGNAL(triggered()), this, SLOT(actNextTurn()));
|
||||
aRemoveLocalArrows = new QAction(this);
|
||||
connect(aRemoveLocalArrows, SIGNAL(triggered()), this, SLOT(actRemoveLocalArrows()));
|
||||
aRotateViewCW = new QAction(this);
|
||||
connect(aRotateViewCW, SIGNAL(triggered()), this, SLOT(actRotateViewCW()));
|
||||
aRotateViewCCW = new QAction(this);
|
||||
connect(aRotateViewCCW, SIGNAL(triggered()), this, SLOT(actRotateViewCCW()));
|
||||
aGameInfo = new QAction(this);
|
||||
connect(aGameInfo, SIGNAL(triggered()), this, SLOT(actGameInfo()));
|
||||
aConcede = new QAction(this);
|
||||
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
|
||||
aLeaveGame = new QAction(this);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aCloseReplay = 0;
|
||||
|
||||
phasesMenu = new QMenu(this);
|
||||
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
||||
QAction *temp = new QAction(QString(), this);
|
||||
connect(temp, SIGNAL(triggered()), this, SLOT(actPhaseAction()));
|
||||
phasesMenu->addAction(temp);
|
||||
phaseActions.append(temp);
|
||||
}
|
||||
|
||||
phasesMenu->addSeparator();
|
||||
phasesMenu->addAction(aNextPhase);
|
||||
|
||||
gameMenu = new QMenu(this);
|
||||
playersSeparator = gameMenu->addSeparator();
|
||||
gameMenu->addMenu(phasesMenu);
|
||||
gameMenu->addAction(aNextTurn);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aRemoveLocalArrows);
|
||||
gameMenu->addAction(aRotateViewCW);
|
||||
gameMenu->addAction(aRotateViewCCW);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aGameInfo);
|
||||
gameMenu->addAction(aConcede);
|
||||
gameMenu->addAction(aLeaveGame);
|
||||
addTabMenu(gameMenu);
|
||||
|
||||
createMenuItems();
|
||||
createViewMenuItems();
|
||||
retranslateUi();
|
||||
connect(&settingsCache->shortcuts(), SIGNAL(shortCutchanged()),this,SLOT(refreshShortcuts()));
|
||||
refreshShortcuts();
|
||||
setLayout(mainLayout);
|
||||
|
||||
splitter->restoreState(settingsCache->getTabGameSplitterSizes());
|
||||
splitter->setChildrenCollapsible(false);
|
||||
|
||||
messageLog->logGameJoined(gameInfo.game_id());
|
||||
|
||||
// append game to rooms game list for others to see
|
||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
||||
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
||||
|
||||
completer = new QCompleter(autocompleteUserList, sayEdit);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer->setMaxVisibleItems(5);
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
completer->setFilterMode(Qt::MatchStartsWith);
|
||||
#endif
|
||||
|
||||
sayEdit->setCompleter(completer);
|
||||
actCompleterChanged();
|
||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
||||
}
|
||||
|
||||
void TabGame::addMentionTag(QString value) {
|
||||
|
@ -585,21 +425,34 @@ void TabGame::emitUserEvent() {
|
|||
|
||||
TabGame::~TabGame()
|
||||
{
|
||||
delete replay;
|
||||
settingsCache->setTabGameSplitterSizes(splitter->saveState());
|
||||
if(replay)
|
||||
{
|
||||
settingsCache->layouts().setReplayPlayAreaState(saveState());
|
||||
settingsCache->layouts().setReplayPlayAreaGeometry(saveGeometry());
|
||||
delete replay;
|
||||
} else {
|
||||
settingsCache->layouts().setGamePlayAreaState(saveState());
|
||||
settingsCache->layouts().setGamePlayAreaGeometry(saveGeometry());
|
||||
}
|
||||
|
||||
QMapIterator<int, Player *> i(players);
|
||||
while (i.hasNext())
|
||||
delete i.next().value();
|
||||
players.clear();
|
||||
|
||||
delete deckViewContainerLayout;
|
||||
|
||||
emit gameClosing(this);
|
||||
}
|
||||
|
||||
void TabGame::retranslateUi()
|
||||
{
|
||||
QString tabText = getTabText() + " - ";
|
||||
|
||||
cardInfoDock->setWindowTitle((cardInfoDock->isWindow() ? tabText : QString()) + tr("Card Info"));
|
||||
playerListDock->setWindowTitle((playerListDock->isWindow() ? tabText : QString()) + tr("Player List"));
|
||||
messageLayoutDock->setWindowTitle((messageLayoutDock->isWindow() ? tabText : QString()) + tr("Messages"));
|
||||
if(replayDock)
|
||||
replayDock->setWindowTitle((replayDock->isWindow() ? tabText : QString()) + tr("Replay Timeline"));
|
||||
|
||||
if (phasesMenu) {
|
||||
for (int i = 0; i < phaseActions.size(); ++i)
|
||||
phaseActions[i]->setText(phasesToolbar->getLongPhaseName(i));
|
||||
|
@ -633,9 +486,33 @@ void TabGame::retranslateUi()
|
|||
if (aCloseReplay) {
|
||||
aCloseReplay->setText(tr("C&lose replay"));
|
||||
}
|
||||
|
||||
if (sayLabel)
|
||||
if (sayLabel){
|
||||
sayLabel->setText(tr("&Say:"));
|
||||
}
|
||||
|
||||
viewMenu->setTitle(tr("&View"));
|
||||
cardInfoDockMenu->setTitle(tr("Card Info"));
|
||||
messageLayoutDockMenu->setTitle(tr("Messages"));
|
||||
playerListDockMenu->setTitle(tr("Player List"));
|
||||
|
||||
aCardInfoDockVisible->setText(tr("Visible"));
|
||||
aCardInfoDockFloating->setText(tr("Floating"));
|
||||
|
||||
aMessageLayoutDockVisible->setText(tr("Visible"));
|
||||
aMessageLayoutDockFloating->setText(tr("Floating"));
|
||||
|
||||
aPlayerListDockVisible->setText(tr("Visible"));
|
||||
aPlayerListDockFloating->setText(tr("Floating"));
|
||||
|
||||
if(replayDock)
|
||||
{
|
||||
replayDockMenu->setTitle(tr("Replay Timeline"));
|
||||
aReplayDockVisible->setText(tr("Visible"));
|
||||
aReplayDockFloating->setText(tr("Floating"));
|
||||
}
|
||||
|
||||
aResetLayout->setText(tr("Reset layout"));
|
||||
|
||||
cardInfo->retranslateUi();
|
||||
|
||||
QMapIterator<int, Player *> i(players);
|
||||
|
@ -955,8 +832,9 @@ void TabGame::startGame(bool resuming)
|
|||
i.value()->setReadyStart(false);
|
||||
i.value()->hide();
|
||||
}
|
||||
mainLayout->removeItem(deckViewContainerLayout);
|
||||
|
||||
|
||||
mainWidget->setCurrentWidget(gamePlayAreaWidget);
|
||||
|
||||
if (!resuming) {
|
||||
QMapIterator<int, Player *> playerIterator(players);
|
||||
while (playerIterator.hasNext())
|
||||
|
@ -966,7 +844,6 @@ void TabGame::startGame(bool resuming)
|
|||
playerListWidget->setGameStarted(true, resuming);
|
||||
gameInfo.set_started(true);
|
||||
static_cast<GameScene *>(gameView->scene())->rearrange();
|
||||
gameView->show();
|
||||
if(sayEdit && players.size() > 1)
|
||||
sayEdit->setFocus();
|
||||
}
|
||||
|
@ -981,12 +858,12 @@ void TabGame::stopGame()
|
|||
i.next();
|
||||
i.value()->show();
|
||||
}
|
||||
mainLayout->insertLayout(1, deckViewContainerLayout, 10);
|
||||
|
||||
mainWidget->setCurrentWidget(deckViewContainerWidget);
|
||||
|
||||
playerListWidget->setActivePlayer(-1);
|
||||
playerListWidget->setGameStarted(false, false);
|
||||
gameInfo.set_started(false);
|
||||
gameView->hide();
|
||||
}
|
||||
|
||||
void TabGame::closeGame()
|
||||
|
@ -1335,3 +1212,478 @@ void TabGame::updateCardMenu(AbstractCardItem *card)
|
|||
p = players.value(localPlayerId);
|
||||
p->updateCardMenu(static_cast<CardItem *>(card));
|
||||
}
|
||||
|
||||
void TabGame::createMenuItems()
|
||||
{
|
||||
aNextPhase = new QAction(this);
|
||||
connect(aNextPhase, SIGNAL(triggered()), this, SLOT(actNextPhase()));
|
||||
aNextTurn = new QAction(this);
|
||||
connect(aNextTurn, SIGNAL(triggered()), this, SLOT(actNextTurn()));
|
||||
aRemoveLocalArrows = new QAction(this);
|
||||
connect(aRemoveLocalArrows, SIGNAL(triggered()), this, SLOT(actRemoveLocalArrows()));
|
||||
aRotateViewCW = new QAction(this);
|
||||
connect(aRotateViewCW, SIGNAL(triggered()), this, SLOT(actRotateViewCW()));
|
||||
aRotateViewCCW = new QAction(this);
|
||||
connect(aRotateViewCCW, SIGNAL(triggered()), this, SLOT(actRotateViewCCW()));
|
||||
aGameInfo = new QAction(this);
|
||||
connect(aGameInfo, SIGNAL(triggered()), this, SLOT(actGameInfo()));
|
||||
aConcede = new QAction(this);
|
||||
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
|
||||
aLeaveGame = new QAction(this);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aCloseReplay = 0;
|
||||
|
||||
phasesMenu = new QMenu(this);
|
||||
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
||||
QAction *temp = new QAction(QString(), this);
|
||||
connect(temp, SIGNAL(triggered()), this, SLOT(actPhaseAction()));
|
||||
phasesMenu->addAction(temp);
|
||||
phaseActions.append(temp);
|
||||
}
|
||||
|
||||
phasesMenu->addSeparator();
|
||||
phasesMenu->addAction(aNextPhase);
|
||||
|
||||
gameMenu = new QMenu(this);
|
||||
playersSeparator = gameMenu->addSeparator();
|
||||
gameMenu->addMenu(phasesMenu);
|
||||
gameMenu->addAction(aNextTurn);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aRemoveLocalArrows);
|
||||
gameMenu->addAction(aRotateViewCW);
|
||||
gameMenu->addAction(aRotateViewCCW);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aGameInfo);
|
||||
gameMenu->addAction(aConcede);
|
||||
gameMenu->addAction(aLeaveGame);
|
||||
addTabMenu(gameMenu);
|
||||
}
|
||||
|
||||
void TabGame::createReplayMenuItems()
|
||||
{
|
||||
aNextPhase = 0;
|
||||
aNextTurn = 0;
|
||||
aRemoveLocalArrows = 0;
|
||||
aRotateViewCW = 0;
|
||||
aRotateViewCCW = 0;
|
||||
aResetLayout = 0;
|
||||
aGameInfo = 0;
|
||||
aConcede = 0;
|
||||
aLeaveGame = 0;
|
||||
aCloseReplay = new QAction(this);
|
||||
connect(aCloseReplay, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
|
||||
phasesMenu = 0;
|
||||
gameMenu = new QMenu(this);
|
||||
gameMenu->addAction(aCloseReplay);
|
||||
addTabMenu(gameMenu);
|
||||
}
|
||||
|
||||
void TabGame::createViewMenuItems()
|
||||
{
|
||||
viewMenu = new QMenu(this);
|
||||
|
||||
cardInfoDockMenu = viewMenu->addMenu(QString());
|
||||
messageLayoutDockMenu = viewMenu->addMenu(QString());
|
||||
playerListDockMenu = viewMenu->addMenu(QString());
|
||||
|
||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockVisible->setCheckable(true);
|
||||
connect(aCardInfoDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
aMessageLayoutDockVisible = messageLayoutDockMenu->addAction(QString());
|
||||
aMessageLayoutDockVisible->setCheckable(true);
|
||||
connect(aMessageLayoutDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aMessageLayoutDockFloating = messageLayoutDockMenu->addAction(QString());
|
||||
aMessageLayoutDockFloating->setCheckable(true);
|
||||
connect(aMessageLayoutDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
aPlayerListDockVisible = playerListDockMenu->addAction(QString());
|
||||
aPlayerListDockVisible->setCheckable(true);
|
||||
connect(aPlayerListDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aPlayerListDockFloating = playerListDockMenu->addAction(QString());
|
||||
aPlayerListDockFloating->setCheckable(true);
|
||||
connect(aPlayerListDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
|
||||
if(replayDock)
|
||||
{
|
||||
replayDockMenu = viewMenu->addMenu(QString());
|
||||
|
||||
aReplayDockVisible = replayDockMenu->addAction(QString());
|
||||
aReplayDockVisible->setCheckable(true);
|
||||
connect(aReplayDockVisible,SIGNAL(triggered()),this,SLOT(dockVisibleTriggered()));
|
||||
aReplayDockFloating = replayDockMenu->addAction(QString());
|
||||
aReplayDockFloating->setCheckable(true);
|
||||
connect(aReplayDockFloating,SIGNAL(triggered()),this,SLOT(dockFloatingTriggered()));
|
||||
}
|
||||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
aResetLayout = viewMenu->addAction(QString());
|
||||
connect(aResetLayout,SIGNAL(triggered()),this,SLOT(actResetLayout()));
|
||||
viewMenu->addAction(aResetLayout);
|
||||
|
||||
addTabMenu(viewMenu);
|
||||
}
|
||||
|
||||
void TabGame::loadLayout()
|
||||
{
|
||||
if(replayDock)
|
||||
{
|
||||
restoreGeometry(settingsCache->layouts().getReplayPlayAreaGeometry());
|
||||
restoreState(settingsCache->layouts().getReplayPlayAreaLayoutState());
|
||||
} else {
|
||||
restoreGeometry(settingsCache->layouts().getGamePlayAreaGeometry());
|
||||
restoreState(settingsCache->layouts().getGamePlayAreaLayoutState());
|
||||
}
|
||||
|
||||
aCardInfoDockVisible->setChecked(cardInfoDock->isVisible());
|
||||
aMessageLayoutDockVisible->setChecked(messageLayoutDock->isVisible());
|
||||
aPlayerListDockVisible->setChecked(playerListDock->isVisible());
|
||||
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
aMessageLayoutDockFloating->setEnabled(aMessageLayoutDockVisible->isChecked());
|
||||
aPlayerListDockFloating->setEnabled(aPlayerListDockVisible->isChecked());
|
||||
|
||||
aCardInfoDockFloating->setChecked(cardInfoDock->isFloating());
|
||||
aMessageLayoutDockFloating->setChecked(messageLayoutDock->isFloating());
|
||||
aPlayerListDockFloating->setChecked(playerListDock->isFloating());
|
||||
|
||||
if(replayDock)
|
||||
{
|
||||
aReplayDockVisible->setChecked(replayDock->isVisible());
|
||||
aReplayDockFloating->setEnabled(aReplayDockVisible->isChecked());
|
||||
aReplayDockFloating->setChecked(replayDock->isFloating());
|
||||
}
|
||||
}
|
||||
|
||||
void TabGame::actResetLayout()
|
||||
{
|
||||
cardInfoDock->setVisible(true);
|
||||
playerListDock->setVisible(true);
|
||||
messageLayoutDock->setVisible(true);
|
||||
|
||||
cardInfoDock->setFloating(false);
|
||||
playerListDock->setFloating(false);
|
||||
messageLayoutDock->setFloating(false);
|
||||
|
||||
aCardInfoDockVisible->setChecked(true);
|
||||
aPlayerListDockVisible->setChecked(true);
|
||||
aMessageLayoutDockVisible->setChecked(true);
|
||||
|
||||
aCardInfoDockFloating->setChecked(false);
|
||||
aPlayerListDockFloating->setChecked(false);
|
||||
aMessageLayoutDockFloating->setChecked(false);
|
||||
|
||||
addDockWidget(Qt::RightDockWidgetArea, cardInfoDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, playerListDock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock);
|
||||
|
||||
if(replayDock)
|
||||
{
|
||||
replayDock->setVisible(true);
|
||||
replayDock->setFloating(false);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, replayDock);
|
||||
aReplayDockVisible->setChecked(true);
|
||||
aReplayDockFloating->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TabGame::createPlayAreaWidget(bool bReplay)
|
||||
{
|
||||
phasesToolbar = new PhasesToolbar;
|
||||
if(!bReplay)
|
||||
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this, SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
|
||||
scene = new GameScene(phasesToolbar, this);
|
||||
gameView = new GameView(scene);
|
||||
|
||||
gamePlayAreaVBox = new QVBoxLayout;
|
||||
gamePlayAreaVBox->addWidget(gameView);
|
||||
|
||||
gamePlayAreaWidget = new QWidget;
|
||||
gamePlayAreaWidget->setObjectName("gamePlayAreaWidget");
|
||||
gamePlayAreaWidget->setLayout(gamePlayAreaVBox);
|
||||
}
|
||||
|
||||
void TabGame::createReplayDock()
|
||||
{
|
||||
timelineWidget = new ReplayTimelineWidget;
|
||||
timelineWidget->setTimeline(replayTimeline);
|
||||
connect(timelineWidget, SIGNAL(processNextEvent()), this, SLOT(replayNextEvent()));
|
||||
connect(timelineWidget, SIGNAL(replayFinished()), this, SLOT(replayFinished()));
|
||||
|
||||
replayStartButton = new QToolButton;
|
||||
replayStartButton->setIconSize(QSize(32, 32));
|
||||
replayStartButton->setIcon(QPixmap("theme:replay/start"));
|
||||
connect(replayStartButton, SIGNAL(clicked()), this, SLOT(replayStartButtonClicked()));
|
||||
replayPauseButton = new QToolButton;
|
||||
replayPauseButton->setIconSize(QSize(32, 32));
|
||||
replayPauseButton->setEnabled(false);
|
||||
replayPauseButton->setIcon(QPixmap("theme:replay/pause"));
|
||||
connect(replayPauseButton, SIGNAL(clicked()), this, SLOT(replayPauseButtonClicked()));
|
||||
replayFastForwardButton = new QToolButton;
|
||||
replayFastForwardButton->setIconSize(QSize(32, 32));
|
||||
replayFastForwardButton->setEnabled(false);
|
||||
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
||||
replayFastForwardButton->setCheckable(true);
|
||||
connect(replayFastForwardButton, SIGNAL(toggled(bool)), this, SLOT(replayFastForwardButtonToggled(bool)));
|
||||
|
||||
replayControlLayout = new QHBoxLayout;
|
||||
replayControlLayout->addWidget(timelineWidget, 10);
|
||||
replayControlLayout->addWidget(replayStartButton);
|
||||
replayControlLayout->addWidget(replayPauseButton);
|
||||
replayControlLayout->addWidget(replayFastForwardButton);
|
||||
|
||||
replayControlWidget = new QWidget();
|
||||
replayControlWidget->setObjectName("replayControlWidget");
|
||||
replayControlWidget->setLayout(replayControlLayout);
|
||||
|
||||
replayDock = new QDockWidget(this);
|
||||
replayDock->setObjectName("replayDock");
|
||||
replayDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
replayDock->setWidget(replayControlWidget);
|
||||
replayDock->setFloating(false);
|
||||
|
||||
replayDock->installEventFilter(this);
|
||||
connect(replayDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabGame::createDeckViewContainerWidget(bool bReplay)
|
||||
{
|
||||
Q_UNUSED(bReplay);
|
||||
|
||||
deckViewContainerWidget = new QWidget();
|
||||
deckViewContainerWidget->setObjectName("deckViewContainerWidget");
|
||||
deckViewContainerLayout = new QVBoxLayout;
|
||||
deckViewContainerWidget->setLayout(deckViewContainerLayout);
|
||||
}
|
||||
|
||||
void TabGame::createCardInfoDock(bool bReplay)
|
||||
{
|
||||
Q_UNUSED(bReplay);
|
||||
|
||||
cardInfo = new CardFrame();
|
||||
cardHInfoLayout = new QHBoxLayout;
|
||||
cardVInfoLayout = new QVBoxLayout;
|
||||
cardVInfoLayout->setContentsMargins(0, 0, 0, 0);
|
||||
cardVInfoLayout->addWidget(cardInfo);
|
||||
cardVInfoLayout->addLayout(cardHInfoLayout);
|
||||
|
||||
cardBoxLayoutWidget = new QWidget;
|
||||
cardBoxLayoutWidget->setLayout(cardVInfoLayout);
|
||||
|
||||
cardInfoDock = new QDockWidget(this);
|
||||
cardInfoDock->setObjectName("cardInfoDock");
|
||||
cardInfoDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
cardInfoDock->setWidget(cardBoxLayoutWidget);
|
||||
cardInfoDock->setFloating(false);
|
||||
|
||||
cardInfoDock->installEventFilter(this);
|
||||
connect(cardInfoDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabGame::createPlayerListDock(bool bReplay)
|
||||
{
|
||||
if(bReplay)
|
||||
{
|
||||
playerListWidget = new PlayerListWidget(0, 0, this);
|
||||
} else {
|
||||
playerListWidget = new PlayerListWidget(tabSupervisor, clients.first(), this);
|
||||
connect(playerListWidget, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
}
|
||||
playerListWidget->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
playerListDock = new QDockWidget(this);
|
||||
playerListDock->setObjectName("playerListDock");
|
||||
playerListDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
playerListDock->setWidget(playerListWidget);
|
||||
playerListDock->setFloating(false);
|
||||
|
||||
playerListDock->installEventFilter(this);
|
||||
connect(playerListDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
void TabGame::createMessageDock(bool bReplay)
|
||||
{
|
||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
||||
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
|
||||
if(!bReplay)
|
||||
{
|
||||
connect(messageLog, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
connect(settingsCache, SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||
|
||||
timeElapsedLabel = new QLabel;
|
||||
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||
gameTimer = new QTimer(this);
|
||||
gameTimer->setInterval(1000);
|
||||
connect(gameTimer, SIGNAL(timeout()), this, SLOT(incrementGameTime()));
|
||||
gameTimer->start();
|
||||
|
||||
sayLabel = new QLabel;
|
||||
sayEdit = new LineEditCompleter;
|
||||
sayLabel->setBuddy(sayEdit);
|
||||
completer = new QCompleter(autocompleteUserList, sayEdit);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer->setMaxVisibleItems(5);
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
completer->setFilterMode(Qt::MatchStartsWith);
|
||||
#endif
|
||||
|
||||
sayEdit->setCompleter(completer);
|
||||
actCompleterChanged();
|
||||
|
||||
if (spectator && !gameInfo.spectators_can_chat() && tabSupervisor->getAdminLocked()) {
|
||||
sayLabel->hide();
|
||||
sayEdit->hide();
|
||||
}
|
||||
connect(tabSupervisor, SIGNAL(adminLockChanged(bool)), this, SLOT(adminLockChanged(bool)));
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
|
||||
|
||||
sayHLayout = new QHBoxLayout;
|
||||
sayHLayout->addWidget(sayLabel);
|
||||
sayHLayout->addWidget(sayEdit);
|
||||
|
||||
}
|
||||
|
||||
messageLogLayout = new QVBoxLayout;
|
||||
messageLogLayout->setContentsMargins(0, 0, 0, 0);
|
||||
if(!bReplay)
|
||||
messageLogLayout->addWidget(timeElapsedLabel);
|
||||
messageLogLayout->addWidget(messageLog);
|
||||
if(!bReplay)
|
||||
messageLogLayout->addLayout(sayHLayout);
|
||||
|
||||
messageLogLayoutWidget = new QWidget;
|
||||
messageLogLayoutWidget->setLayout(messageLogLayout);
|
||||
|
||||
messageLayoutDock = new QDockWidget(this);
|
||||
messageLayoutDock->setObjectName("messageLayoutDock");
|
||||
messageLayoutDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
messageLayoutDock->setWidget(messageLogLayoutWidget);
|
||||
messageLayoutDock->setFloating(false);
|
||||
|
||||
messageLayoutDock->installEventFilter(this);
|
||||
connect(messageLayoutDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
}
|
||||
|
||||
// Method uses to sync docks state with menu items state
|
||||
bool TabGame::eventFilter(QObject * o, QEvent * e)
|
||||
{
|
||||
if(e->type() == QEvent::Close)
|
||||
{
|
||||
if(o == cardInfoDock)
|
||||
{
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if(o == messageLayoutDock) {
|
||||
aMessageLayoutDockVisible->setChecked(false);
|
||||
aMessageLayoutDockFloating->setEnabled(false);
|
||||
} else if(o == playerListDock) {
|
||||
aPlayerListDockVisible->setChecked(false);
|
||||
aPlayerListDockFloating->setEnabled(false);
|
||||
} else if(o == replayDock) {
|
||||
aReplayDockVisible->setChecked(false);
|
||||
aReplayDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabGame::dockVisibleTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if(o == aCardInfoDockVisible)
|
||||
{
|
||||
cardInfoDock->setVisible(aCardInfoDockVisible->isChecked());
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aMessageLayoutDockVisible)
|
||||
{
|
||||
messageLayoutDock->setVisible(aMessageLayoutDockVisible->isChecked());
|
||||
aMessageLayoutDockFloating->setEnabled(aMessageLayoutDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aPlayerListDockVisible)
|
||||
{
|
||||
playerListDock->setVisible(aPlayerListDockVisible->isChecked());
|
||||
aPlayerListDockFloating->setEnabled(aPlayerListDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aReplayDockVisible)
|
||||
{
|
||||
replayDock->setVisible(aReplayDockVisible->isChecked());
|
||||
aReplayDockFloating->setEnabled(aReplayDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabGame::dockFloatingTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if(o == aCardInfoDockFloating)
|
||||
{
|
||||
cardInfoDock->setFloating(aCardInfoDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aMessageLayoutDockFloating)
|
||||
{
|
||||
messageLayoutDock->setFloating(aMessageLayoutDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aPlayerListDockFloating)
|
||||
{
|
||||
playerListDock->setFloating(aPlayerListDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == aReplayDockFloating)
|
||||
{
|
||||
replayDock->setFloating(aReplayDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabGame::dockTopLevelChanged(bool topLevel)
|
||||
{
|
||||
retranslateUi();
|
||||
|
||||
QObject *o = sender();
|
||||
if(o == cardInfoDock)
|
||||
{
|
||||
aCardInfoDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == messageLayoutDock)
|
||||
{
|
||||
aMessageLayoutDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == playerListDock)
|
||||
{
|
||||
aPlayerListDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if(o == replayDock)
|
||||
{
|
||||
aReplayDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ class GameReplay;
|
|||
class ServerInfo_User;
|
||||
class PendingCommand;
|
||||
class LineEditCompleter;
|
||||
class QDockWidget;
|
||||
class QStackedWidget;
|
||||
|
||||
class ToggleButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
|
@ -77,6 +79,7 @@ private:
|
|||
QPushButton *loadLocalButton, *loadRemoteButton;
|
||||
ToggleButton *readyStartButton, *sideboardLockButton;
|
||||
DeckView *deckView;
|
||||
TabGame *parentGame;
|
||||
int playerId;
|
||||
private slots:
|
||||
void loadLocalDeck();
|
||||
|
@ -90,7 +93,7 @@ private slots:
|
|||
signals:
|
||||
void newCardAdded(AbstractCardItem *card);
|
||||
public:
|
||||
DeckViewContainer(int _playerId, TabGame *parent = 0);
|
||||
DeckViewContainer(int _playerId, TabGame *parent);
|
||||
void retranslateUi();
|
||||
void setButtonsVisible(bool _visible);
|
||||
void setReadyStart(bool ready);
|
||||
|
@ -121,6 +124,7 @@ private:
|
|||
QStringList gameTypes;
|
||||
QCompleter *completer;
|
||||
QStringList autocompleteUserList;
|
||||
QStackedWidget * mainWidget;
|
||||
|
||||
// Replay related members
|
||||
GameReplay *replay;
|
||||
|
@ -128,8 +132,7 @@ private:
|
|||
QList<int> replayTimeline;
|
||||
ReplayTimelineWidget *timelineWidget;
|
||||
QToolButton *replayStartButton, *replayPauseButton, *replayFastForwardButton;
|
||||
|
||||
QSplitter *splitter;
|
||||
|
||||
CardFrame *cardInfo;
|
||||
PlayerListWidget *playerListWidget;
|
||||
QLabel *timeElapsedLabel;
|
||||
|
@ -140,13 +143,14 @@ private:
|
|||
GameScene *scene;
|
||||
GameView *gameView;
|
||||
QMap<int, DeckViewContainer *> deckViewContainers;
|
||||
QVBoxLayout *deckViewContainerLayout;
|
||||
QHBoxLayout *mainLayout;
|
||||
ZoneViewLayout *zoneLayout;
|
||||
QVBoxLayout *cardVInfoLayout, *messageLogLayout, *gamePlayAreaVBox, *deckViewContainerLayout;
|
||||
QHBoxLayout *cardHInfoLayout, *sayHLayout, *mainHLayout, *replayControlLayout;
|
||||
QWidget *cardBoxLayoutWidget, *messageLogLayoutWidget, *gamePlayAreaWidget, *deckViewContainerWidget, *replayControlWidget;
|
||||
QDockWidget *cardInfoDock, *messageLayoutDock, *playerListDock, *replayDock;
|
||||
QAction *playersSeparator;
|
||||
QMenu *gameMenu;
|
||||
QMenu *phasesMenu;
|
||||
QAction *aGameInfo, *aConcede, *aLeaveGame, *aCloseReplay, *aNextPhase, *aNextTurn, *aRemoveLocalArrows, *aRotateViewCW, *aRotateViewCCW;
|
||||
QMenu *gameMenu, *phasesMenu, *viewMenu, *cardInfoDockMenu, *messageLayoutDockMenu, *playerListDockMenu, *replayDockMenu;
|
||||
QAction *aGameInfo, *aConcede, *aLeaveGame, *aCloseReplay, *aNextPhase, *aNextTurn, *aRemoveLocalArrows, *aRotateViewCW, *aRotateViewCCW, *aResetLayout, *aResetReplayLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aMessageLayoutDockVisible, *aMessageLayoutDockFloating, *aPlayerListDockVisible, *aPlayerListDockFloating, *aReplayDockVisible, *aReplayDockFloating;
|
||||
QList<QAction *> phaseActions;
|
||||
|
||||
Player *addPlayer(int playerId, const ServerInfo_User &info);
|
||||
|
@ -171,6 +175,15 @@ private:
|
|||
void eventSetActivePhase(const Event_SetActivePhase &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventPing(const Event_Ping &event, int eventPlayerId, const GameEventContext &context);
|
||||
void emitUserEvent();
|
||||
void createMenuItems();
|
||||
void createReplayMenuItems();
|
||||
void createViewMenuItems();
|
||||
void createCardInfoDock(bool bReplay=false);
|
||||
void createPlayerListDock(bool bReplay=false);
|
||||
void createMessageDock(bool bReplay=false);
|
||||
void createPlayAreaWidget(bool bReplay=false);
|
||||
void createDeckViewContainerWidget(bool bReplay=false);
|
||||
void createReplayDock();
|
||||
signals:
|
||||
void gameClosing(TabGame *tab);
|
||||
void playerAdded(Player *player);
|
||||
|
@ -207,7 +220,14 @@ private slots:
|
|||
|
||||
void refreshShortcuts();
|
||||
|
||||
void loadLayout();
|
||||
void actCompleterChanged();
|
||||
void actResetLayout();
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e);
|
||||
void dockVisibleTriggered();
|
||||
void dockFloatingTriggered();
|
||||
void dockTopLevelChanged(bool topLevel);
|
||||
public:
|
||||
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event, const QMap<int, QString> &_roomGameTypes);
|
||||
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QRadioButton>
|
||||
#include <QTabWidget>
|
||||
#include "tab_logs.h"
|
||||
#include "abstractclient.h"
|
||||
#include "window_sets.h"
|
||||
|
@ -23,7 +24,27 @@
|
|||
TabLog::TabLog(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent)
|
||||
: Tab(_tabSupervisor, parent), client(_client)
|
||||
{
|
||||
MainWindow = new QMainWindow;
|
||||
roomTable = new QTableWidget();
|
||||
roomTable->setColumnCount(6);
|
||||
roomTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
roomTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
gameTable = new QTableWidget();
|
||||
gameTable->setColumnCount(6);
|
||||
gameTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
gameTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
chatTable = new QTableWidget();
|
||||
chatTable->setColumnCount(6);
|
||||
chatTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
chatTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
QTabWidget *tabManager = new QTabWidget();
|
||||
tabManager->addTab(roomTable, tr("Room Logs"));
|
||||
tabManager->addTab(gameTable, tr("Game Logs"));
|
||||
tabManager->addTab(chatTable, tr("Chat Logs"));
|
||||
setCentralWidget(tabManager);
|
||||
|
||||
createDock();
|
||||
restartLayout();
|
||||
clearClicked();
|
||||
|
@ -212,7 +233,7 @@ void TabLog::createDock()
|
|||
buttonGroupBox = new QGroupBox(tr(""));
|
||||
buttonGroupBox->setLayout(buttonGrid);
|
||||
|
||||
mainLayout = new QVBoxLayout(MainWindow);
|
||||
mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addWidget(criteriaGroupBox);
|
||||
mainLayout->addWidget(locationGroupBox);
|
||||
mainLayout->addWidget(rangeGroupBox);
|
||||
|
@ -221,116 +242,94 @@ void TabLog::createDock()
|
|||
mainLayout->addWidget(buttonGroupBox);
|
||||
mainLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
searchDockContents = new QWidget(MainWindow);
|
||||
searchDockContents = new QWidget(this);
|
||||
searchDockContents->setLayout(mainLayout);
|
||||
|
||||
searchDock = new QDockWidget(MainWindow);
|
||||
searchDock = new QDockWidget(this);
|
||||
searchDock->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
|
||||
searchDock->setWidget(searchDockContents);
|
||||
|
||||
QVBoxLayout *mainVLayoutContent = new QVBoxLayout;
|
||||
QHBoxLayout *mainHLayoutContent = new QHBoxLayout;
|
||||
mainHLayoutContent->addWidget(MainWindow);
|
||||
mainHLayoutContent->addLayout(mainVLayoutContent);
|
||||
setLayout(mainHLayoutContent);
|
||||
}
|
||||
|
||||
void TabLog::viewLogHistory_processResponse(const Response &resp)
|
||||
{
|
||||
const Response_ViewLogHistory &response = resp.GetExtension(Response_ViewLogHistory::ext);
|
||||
if (resp.response_code() == Response::RespOk) {
|
||||
|
||||
if (response.log_message_size() > 0) {
|
||||
|
||||
int j = 0;
|
||||
QTableWidget *roomTable = new QTableWidget();
|
||||
roomTable->setWindowTitle(tr("Room Logs"));
|
||||
roomTable->setRowCount(response.log_message_size());
|
||||
roomTable->setColumnCount(6);
|
||||
roomTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
roomTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
int k = 0;
|
||||
QTableWidget *gameTable = new QTableWidget();
|
||||
gameTable->setWindowTitle(tr("Game Logs"));
|
||||
gameTable->setRowCount(response.log_message_size());
|
||||
gameTable->setColumnCount(6);
|
||||
gameTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
gameTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
int l = 0;
|
||||
QTableWidget *chatTable = new QTableWidget();
|
||||
chatTable->setWindowTitle(tr("Chat Logs"));
|
||||
chatTable->setRowCount(response.log_message_size());
|
||||
chatTable->setColumnCount(6);
|
||||
chatTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
chatTable->setHorizontalHeaderLabels(QString(tr("Time;SenderName;SenderIP;Message;TargetID;TargetName")).split(";"));
|
||||
|
||||
ServerInfo_ChatMessage message; for (int i = 0; i < response.log_message_size(); ++i) {
|
||||
message = response.log_message(i);
|
||||
if (QString::fromStdString(message.target_type()) == "room") {
|
||||
roomTable->setItem(j, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
roomTable->setItem(j, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
roomTable->setItem(j, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
roomTable->setItem(j, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
roomTable->setItem(j, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
roomTable->setItem(j, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++j;
|
||||
}
|
||||
|
||||
if (QString::fromStdString(message.target_type()) == "game") {
|
||||
gameTable->setItem(k, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
gameTable->setItem(k, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
gameTable->setItem(k, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
gameTable->setItem(k, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
gameTable->setItem(k, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
gameTable->setItem(k, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++k;
|
||||
}
|
||||
|
||||
if (QString::fromStdString(message.target_type()) == "chat") {
|
||||
chatTable->setItem(l, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
chatTable->setItem(l, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
chatTable->setItem(l, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
chatTable->setItem(l, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
chatTable->setItem(l, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
chatTable->setItem(l, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
roomTable->setRowCount(j);
|
||||
roomTable->resizeColumnsToContents();
|
||||
gameTable->setRowCount(k);
|
||||
gameTable->resizeColumnsToContents();
|
||||
chatTable->setRowCount(l);
|
||||
chatTable->resizeColumnsToContents();
|
||||
|
||||
if (mainRoom->isChecked()) {
|
||||
roomTable->resize(600, 200);
|
||||
roomTable->show();
|
||||
}
|
||||
|
||||
if (gameRoom->isChecked()) {
|
||||
gameTable->resize(600, 200);
|
||||
gameTable->show();
|
||||
}
|
||||
|
||||
if (privateChat->isChecked()) {
|
||||
chatTable->resize(600, 200);
|
||||
chatTable->show();
|
||||
}
|
||||
|
||||
} else
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Message History"), tr("There are no messages for the selected filters."));
|
||||
|
||||
} else
|
||||
if (resp.response_code() != Response::RespOk) {
|
||||
QMessageBox::critical(static_cast<QWidget *>(parent()), tr("Message History"), tr("Failed to collect message history information."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.log_message_size() == 0) {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Message History"), tr("There are no messages for the selected filters."));
|
||||
return;
|
||||
}
|
||||
|
||||
int roomCounter = 0, gameCounter = 0, chatCounter = 0;
|
||||
roomTable->setRowCount(roomCounter);
|
||||
gameTable->setRowCount(gameCounter);
|
||||
chatTable->setRowCount(chatCounter);
|
||||
|
||||
for (int i = 0; i < response.log_message_size(); ++i)
|
||||
{
|
||||
ServerInfo_ChatMessage message = response.log_message(i);
|
||||
if (QString::fromStdString(message.target_type()) == "room") {
|
||||
roomTable->insertRow(roomCounter);
|
||||
roomTable->setItem(roomCounter, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
roomTable->setItem(roomCounter, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
roomTable->setItem(roomCounter, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
roomTable->setItem(roomCounter, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
roomTable->setItem(roomCounter, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
roomTable->setItem(roomCounter, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++roomCounter;
|
||||
}
|
||||
|
||||
if (QString::fromStdString(message.target_type()) == "game") {
|
||||
gameTable->insertRow(gameCounter);
|
||||
gameTable->setItem(gameCounter, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
gameTable->setItem(gameCounter, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
gameTable->setItem(gameCounter, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
gameTable->setItem(gameCounter, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
gameTable->setItem(gameCounter, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
gameTable->setItem(gameCounter, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++gameCounter;
|
||||
}
|
||||
|
||||
if (QString::fromStdString(message.target_type()) == "chat") {
|
||||
chatTable->insertRow(chatCounter);
|
||||
chatTable->setItem(chatCounter, 0, new QTableWidgetItem(QString::fromStdString(message.time())));
|
||||
chatTable->setItem(chatCounter, 1, new QTableWidgetItem(QString::fromStdString(message.sender_name())));
|
||||
chatTable->setItem(chatCounter, 2, new QTableWidgetItem(QString::fromStdString(message.sender_ip())));
|
||||
chatTable->setItem(chatCounter, 3, new QTableWidgetItem(QString::fromStdString(message.message())));
|
||||
chatTable->setItem(chatCounter, 4, new QTableWidgetItem(QString::fromStdString(message.target_id())));
|
||||
chatTable->setItem(chatCounter, 5, new QTableWidgetItem(QString::fromStdString(message.target_name())));
|
||||
++chatCounter;
|
||||
}
|
||||
}
|
||||
|
||||
if (roomCounter) {
|
||||
roomTable->show();
|
||||
roomTable->resizeColumnsToContents();
|
||||
} else {
|
||||
roomTable->hide();
|
||||
}
|
||||
|
||||
if (gameCounter) {
|
||||
gameTable->resizeColumnsToContents();
|
||||
gameTable->show();
|
||||
} else {
|
||||
gameTable->hide();
|
||||
}
|
||||
|
||||
if (chatCounter) {
|
||||
chatTable->resizeColumnsToContents();
|
||||
chatTable->show();
|
||||
} else {
|
||||
chatTable->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void TabLog::restartLayout()
|
||||
{
|
||||
searchDock->setFloating(false);
|
||||
MainWindow->addDockWidget(Qt::TopDockWidgetArea, searchDock);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, searchDock);
|
||||
searchDock->setVisible(true);
|
||||
}
|
|
@ -16,10 +16,10 @@ class QLabel;
|
|||
class QDockWidget;
|
||||
class QWidget;
|
||||
class QGridLayout;
|
||||
class QTableWidget;
|
||||
class CommandContainer;
|
||||
class Response;
|
||||
class AbstractClient;
|
||||
class QMainWindow;
|
||||
|
||||
class TabLog : public Tab {
|
||||
Q_OBJECT
|
||||
|
@ -36,7 +36,7 @@ private:
|
|||
QGridLayout *criteriaGrid, *locationGrid, *rangeGrid, *maxResultsGrid, *descriptionGrid, *buttonGrid;
|
||||
QGroupBox *criteriaGroupBox, *locationGroupBox, *rangeGroupBox, *maxResultsGroupBox, *descriptionGroupBox, *buttonGroupBox;
|
||||
QVBoxLayout *mainLayout;
|
||||
QMainWindow *MainWindow;
|
||||
QTableWidget *roomTable, *gameTable, *chatTable;
|
||||
|
||||
void createDock();
|
||||
signals:
|
||||
|
|
|
@ -39,7 +39,10 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
|||
addTabMenu(messageMenu);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(vbox);
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(vbox);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
TabMessage::~TabMessage()
|
||||
|
|
|
@ -106,7 +106,10 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client)
|
|||
rightToolBar->addAction(aDeleteRemoteReplay);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(hbox);
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(hbox);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this, SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
|
||||
}
|
||||
|
|
|
@ -104,9 +104,6 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI
|
|||
roomMenu->addAction(aLeaveRoom);
|
||||
addTabMenu(roomMenu);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(hbox);
|
||||
|
||||
const int userListSize = info.user_list_size();
|
||||
for (int i = 0; i < userListSize; ++i){
|
||||
userList->processUserInfo(info.user_list(i), true);
|
||||
|
@ -130,6 +127,12 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI
|
|||
actCompleterChanged();
|
||||
connect(&settingsCache->shortcuts(), SIGNAL(shortCutchanged()),this,SLOT(refreshShortcuts()));
|
||||
refreshShortcuts();
|
||||
|
||||
retranslateUi();
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(hbox);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
TabRoom::~TabRoom()
|
||||
|
|
|
@ -140,8 +140,12 @@ TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWi
|
|||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(roomSelector);
|
||||
vbox->addWidget(serverInfoBox);
|
||||
|
||||
setLayout(vbox);
|
||||
|
||||
retranslateUi();
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(vbox);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
void TabServer::retranslateUi()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "userlist.h"
|
||||
#include "userinfobox.h"
|
||||
#include "abstractclient.h"
|
||||
#include "soundengine.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
@ -74,7 +75,11 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, AbstractClient *_clien
|
|||
mainLayout->addLayout(ignorePanel);
|
||||
mainLayout->addLayout(vbox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
retranslateUi();
|
||||
|
||||
QWidget * mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(mainLayout);
|
||||
setCentralWidget(mainWidget);
|
||||
}
|
||||
|
||||
void TabUserLists::addToBuddyList()
|
||||
|
@ -146,12 +151,19 @@ void TabUserLists::processUserJoinedEvent(const Event_UserJoined &event)
|
|||
ignoreList->sortItems();
|
||||
buddyList->sortItems();
|
||||
|
||||
if (buddyList->getUsers().keys().contains(userName))
|
||||
soundEngine->playSound("buddy_join");
|
||||
|
||||
emit userJoined(info);
|
||||
}
|
||||
|
||||
void TabUserLists::processUserLeftEvent(const Event_UserLeft &event)
|
||||
{
|
||||
QString userName = QString::fromStdString(event.name());
|
||||
|
||||
if (buddyList->getUsers().keys().contains(userName))
|
||||
soundEngine->playSound("buddy_leave");
|
||||
|
||||
if (allUsersList->deleteUser(userName)) {
|
||||
ignoreList->setUserOnline(userName, false);
|
||||
buddyList->setUserOnline(userName, false);
|
||||
|
|
121
cockatrice/src/update_checker.cpp
Normal file
121
cockatrice/src/update_checker.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// Created by miguel on 28/12/15.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "update_checker.h"
|
||||
#include "version_string.h"
|
||||
#include "qt-json/json.h"
|
||||
|
||||
#define LATEST_FILES_URL "https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files"
|
||||
|
||||
UpdateChecker::UpdateChecker(QObject *parent) : QObject(parent){
|
||||
//Parse the commit date. We'll use this to check for new versions
|
||||
//We know the format because it's based on `git log` which is documented here:
|
||||
// https://git-scm.com/docs/git-log#_commit_formatting
|
||||
buildDate = QDate::fromString(VERSION_DATE, "yyyy-MM-dd");
|
||||
latestFilesUrl = QUrl(LATEST_FILES_URL);
|
||||
response = NULL;
|
||||
netMan = new QNetworkAccessManager(this);
|
||||
build = NULL;
|
||||
}
|
||||
|
||||
UpdateChecker::~UpdateChecker()
|
||||
{
|
||||
delete build;
|
||||
}
|
||||
|
||||
void UpdateChecker::check()
|
||||
{
|
||||
response = netMan->get(QNetworkRequest(latestFilesUrl));
|
||||
connect(response, SIGNAL(finished()),
|
||||
this, SLOT(fileListFinished()));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant build)
|
||||
{
|
||||
return build
|
||||
.toMap()["name"]
|
||||
.toString()
|
||||
.contains("osx");
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant build)
|
||||
{
|
||||
return build
|
||||
.toMap()["name"]
|
||||
.toString()
|
||||
.contains("qt5.exe");
|
||||
}
|
||||
#else
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant build)
|
||||
{
|
||||
return build
|
||||
.toMap()["name"]
|
||||
.toString()
|
||||
.contains("qt4.exe");
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant)
|
||||
{
|
||||
//If the OS doesn't fit one of the above #defines, then it will never match
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QDate UpdateChecker::dateFromBuild(QVariant build)
|
||||
{
|
||||
QString formatString = "yyyy-MM-dd";
|
||||
QString dateString = build.toMap()["date"].toString();
|
||||
dateString = dateString.remove(formatString.length(), dateString.length());
|
||||
|
||||
return QDate::fromString(dateString, formatString);
|
||||
}
|
||||
|
||||
QDate UpdateChecker::findOldestBuild(QVariantList allBuilds)
|
||||
{
|
||||
//Map the build array into an array of dates
|
||||
std::vector<QDate> dateArray(allBuilds.size());
|
||||
std::transform(allBuilds.begin(), allBuilds.end(), dateArray.begin(), dateFromBuild);
|
||||
|
||||
//Return the first date
|
||||
return *std::min_element(dateArray.begin(), dateArray.end());
|
||||
}
|
||||
|
||||
QVariantMap *UpdateChecker::findCompatibleBuild(QVariantList allBuilds) {
|
||||
|
||||
QVariantList::iterator result = std::find_if(allBuilds.begin(), allBuilds.end(), downloadMatchesCurrentOS);
|
||||
|
||||
//If there is no compatible version, return NULL
|
||||
if (result == allBuilds.end())
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
QVariantMap *ret = new QVariantMap;
|
||||
*ret = (*result).toMap();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::fileListFinished() {
|
||||
try {
|
||||
QVariantList builds = QtJson::Json::parse(response->readAll()).toList();
|
||||
build = findCompatibleBuild(builds);
|
||||
QDate bintrayBuildDate = findOldestBuild(builds);
|
||||
|
||||
bool needToUpdate = bintrayBuildDate > buildDate;
|
||||
bool compatibleVersion = build != NULL;
|
||||
|
||||
emit finishedCheck(needToUpdate, compatibleVersion, build);
|
||||
}
|
||||
catch (const std::exception &exc){
|
||||
emit error(exc.what());
|
||||
}
|
||||
}
|
38
cockatrice/src/update_checker.h
Normal file
38
cockatrice/src/update_checker.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Created by miguel on 28/12/15.
|
||||
//
|
||||
|
||||
#ifndef COCKATRICE_UPDATECHECKER_H
|
||||
#define COCKATRICE_UPDATECHECKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QDate>
|
||||
#include <QtNetwork>
|
||||
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UpdateChecker(QObject *parent);
|
||||
~UpdateChecker();
|
||||
void check();
|
||||
signals:
|
||||
void finishedCheck(bool needToUpdate, bool isCompatible, QVariantMap *build);
|
||||
void error(QString errorString);
|
||||
private:
|
||||
static QVariantMap *findCompatibleBuild();
|
||||
static QDate findOldestBuild(QVariantList allBuilds);
|
||||
static QDate dateFromBuild(QVariant build);
|
||||
static QVariantMap *findCompatibleBuild(QVariantList allBuilds);
|
||||
static bool downloadMatchesCurrentOS(QVariant build);
|
||||
QVariantMap *build;
|
||||
QUrl latestFilesUrl;
|
||||
QDate buildDate;
|
||||
QNetworkAccessManager *netMan;
|
||||
QNetworkReply *response;
|
||||
private slots:
|
||||
void fileListFinished();
|
||||
};
|
||||
|
||||
|
||||
#endif //COCKATRICE_UPDATECHECKER_H
|
66
cockatrice/src/update_downloader.cpp
Normal file
66
cockatrice/src/update_downloader.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <QUrl>
|
||||
|
||||
#include "update_downloader.h"
|
||||
|
||||
UpdateDownloader::UpdateDownloader(QObject *parent) : QObject(parent) {
|
||||
netMan = new QNetworkAccessManager(this);
|
||||
}
|
||||
|
||||
void UpdateDownloader::beginDownload(QUrl downloadUrl) {
|
||||
|
||||
//Save the original URL because we need it for the filename
|
||||
if (originalUrl.isEmpty())
|
||||
originalUrl = downloadUrl;
|
||||
|
||||
response = netMan->get(QNetworkRequest(downloadUrl));
|
||||
connect(response, SIGNAL(finished()),
|
||||
this, SLOT(fileFinished()));
|
||||
connect(response, SIGNAL(readyRead()),
|
||||
this, SLOT(fileReadyRead()));
|
||||
connect(response, SIGNAL(downloadProgress(qint64, qint64)),
|
||||
this, SLOT(downloadProgress(qint64, qint64)));
|
||||
connect(response, SIGNAL(error(QNetworkReply::NetworkError)),
|
||||
this, SLOT(downloadError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
void UpdateDownloader::downloadError(QNetworkReply::NetworkError) {
|
||||
emit error(response->errorString().toUtf8());
|
||||
}
|
||||
|
||||
void UpdateDownloader::fileFinished() {
|
||||
//If we finished but there's a redirect, follow it
|
||||
QVariant redirect = response->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
if (!redirect.isNull())
|
||||
{
|
||||
beginDownload(redirect.toUrl());
|
||||
return;
|
||||
}
|
||||
|
||||
//Handle any errors we had
|
||||
if (response->error())
|
||||
{
|
||||
emit error(response->errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
//Work out the file name of the download
|
||||
QString fileName = QDir::temp().path() + QDir::separator() + originalUrl.toString().section('/', -1);
|
||||
|
||||
//Save the build in a temporary directory
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
emit error("Could not open the file for reading.");
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(response->readAll());
|
||||
file.close();
|
||||
|
||||
//Emit the success signal with a URL to the download file
|
||||
emit downloadSuccessful(QUrl::fromLocalFile(fileName));
|
||||
}
|
||||
|
||||
void UpdateDownloader::downloadProgress(qint64 bytesRead, qint64 totalBytes) {
|
||||
emit progressMade(bytesRead, totalBytes);
|
||||
}
|
||||
|
33
cockatrice/src/update_downloader.h
Normal file
33
cockatrice/src/update_downloader.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Created by miguel on 28/12/15.
|
||||
//
|
||||
|
||||
#ifndef COCKATRICE_UPDATEDOWNLOADER_H
|
||||
#define COCKATRICE_UPDATEDOWNLOADER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QDate>
|
||||
#include <QtNetwork>
|
||||
|
||||
class UpdateDownloader : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UpdateDownloader(QObject *parent);
|
||||
void beginDownload(QUrl url);
|
||||
signals:
|
||||
void downloadSuccessful(QUrl filepath);
|
||||
void progressMade(qint64 bytesRead, qint64 totalBytes);
|
||||
void error(QString errorString);
|
||||
private:
|
||||
QUrl originalUrl;
|
||||
QNetworkAccessManager *netMan;
|
||||
QNetworkReply *response;
|
||||
private slots:
|
||||
void fileFinished();
|
||||
void downloadProgress(qint64 bytesRead, qint64 totalBytes);
|
||||
void downloadError(QNetworkReply::NetworkError);
|
||||
};
|
||||
|
||||
|
||||
#endif //COCKATRICE_UPDATEDOWNLOADER_H
|
|
@ -30,6 +30,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QApplication>
|
||||
#include <QtNetwork>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QtGui/qtextdocument.h> // for Qt::escape()
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include "dlg_connect.h"
|
||||
#include "dlg_register.h"
|
||||
#include "dlg_settings.h"
|
||||
#include "dlg_update.h"
|
||||
#include "tab_supervisor.h"
|
||||
#include "remoteclient.h"
|
||||
#include "localserver.h"
|
||||
|
@ -48,12 +50,14 @@
|
|||
#include "settingscache.h"
|
||||
#include "tab_game.h"
|
||||
#include "version_string.h"
|
||||
#include "update_checker.h"
|
||||
|
||||
#include "pb/game_replay.pb.h"
|
||||
#include "pb/room_commands.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
#include "pb/event_server_shutdown.pb.h"
|
||||
|
||||
#define GITHUB_PAGES_URL "https://cockatrice.github.io"
|
||||
#define GITHUB_CONTRIBUTORS_URL "https://github.com/Cockatrice/Cockatrice/graphs/contributors?type=c"
|
||||
#define GITHUB_CONTRIBUTE_URL "https://github.com/Cockatrice/Cockatrice#cockatrice"
|
||||
#define GITHUB_TRANSLATOR_RECOGNIZE_URL "https://github.com/Cockatrice/Cockatrice/wiki/Translators"
|
||||
|
@ -62,6 +66,8 @@
|
|||
#define GITHUB_TROUBLESHOOTING_URL "https://github.com/Cockatrice/Cockatrice/wiki/Troubleshooting"
|
||||
#define GITHUB_FAQ_URL "https://github.com/Cockatrice/Cockatrice/wiki/Frequently-Asked-Questions"
|
||||
|
||||
#define DOWNLOAD_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
||||
|
||||
const QString MainWindow::appName = "Cockatrice";
|
||||
|
||||
void MainWindow::updateTabMenu(const QList<QMenu *> &newMenuList)
|
||||
|
@ -273,6 +279,7 @@ void MainWindow::actAbout()
|
|||
QMessageBox::about(this, tr("About Cockatrice"), QString(
|
||||
"<font size=\"8\"><b>Cockatrice</b></font><br>"
|
||||
+ tr("Version %1").arg(VERSION_STRING)
|
||||
+ "<br><br><b><a href='" + GITHUB_PAGES_URL + "'>" + tr("Cockatrice Webpage") + "</a></b><br>"
|
||||
+ "<br><br><b>" + tr("Project Manager:") + "</b><br>Gavin Bisesi<br><br>"
|
||||
+ "<b>" + tr("Past Project Managers:") + "</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br><br>"
|
||||
+ "<b>" + tr("Developers:") + "</b><br>"
|
||||
|
@ -288,6 +295,12 @@ void MainWindow::actAbout()
|
|||
));
|
||||
}
|
||||
|
||||
void MainWindow::actUpdate()
|
||||
{
|
||||
DlgUpdate dlg(this);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::serverTimeout()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Server timeout"));
|
||||
|
@ -495,6 +508,7 @@ void MainWindow::retranslateUi()
|
|||
#endif
|
||||
|
||||
aAbout->setText(tr("&About Cockatrice"));
|
||||
aUpdate->setText(tr("&Update Cockatrice"));
|
||||
helpMenu->setTitle(tr("&Help"));
|
||||
aCheckCardUpdates->setText(tr("Check for card updates..."));
|
||||
tabSupervisor->retranslateUi();
|
||||
|
@ -525,6 +539,8 @@ void MainWindow::createActions()
|
|||
|
||||
aAbout = new QAction(this);
|
||||
connect(aAbout, SIGNAL(triggered()), this, SLOT(actAbout()));
|
||||
aUpdate = new QAction(this);
|
||||
connect(aUpdate, SIGNAL(triggered()), this, SLOT(actUpdate()));
|
||||
|
||||
aCheckCardUpdates = new QAction(this);
|
||||
connect(aCheckCardUpdates, SIGNAL(triggered()), this, SLOT(actCheckCardUpdates()));
|
||||
|
@ -566,6 +582,7 @@ void MainWindow::createMenus()
|
|||
|
||||
helpMenu = menuBar()->addMenu(QString());
|
||||
helpMenu->addAction(aAbout);
|
||||
helpMenu->addAction(aUpdate);
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
#include <QSystemTrayIcon>
|
||||
#include <QProcess>
|
||||
#include <QMessageBox>
|
||||
#include <QtNetwork>
|
||||
|
||||
#include "abstractclient.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "update_checker.h"
|
||||
|
||||
class TabSupervisor;
|
||||
class RemoteClient;
|
||||
|
@ -66,6 +69,7 @@ private slots:
|
|||
void actExit();
|
||||
|
||||
void actAbout();
|
||||
void actUpdate();
|
||||
|
||||
void iconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
|
@ -90,7 +94,7 @@ private:
|
|||
QList<QMenu *> tabMenus;
|
||||
QMenu *cockatriceMenu, *helpMenu;
|
||||
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aFullScreen, *aSettings, *aExit,
|
||||
*aAbout, *aCheckCardUpdates, *aRegister;
|
||||
*aAbout, *aCheckCardUpdates, *aRegister, *aUpdate;
|
||||
TabSupervisor *tabSupervisor;
|
||||
|
||||
QMenu *trayIconMenu;
|
||||
|
@ -105,6 +109,7 @@ private:
|
|||
|
||||
QMessageBox serverShutdownMessageBox;
|
||||
QProcess * cardUpdateProcess;
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -608,7 +608,6 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoo
|
|||
ServerInfo_ChatMessage chatMessage;
|
||||
for (int i = 0; i < chatHistory.size(); ++i) {
|
||||
chatMessage = chatHistory.at(i);
|
||||
qDebug() << QString::fromStdString(chatMessage.message()).simplified();
|
||||
Event_RoomSay roomChatHistory;
|
||||
roomChatHistory.set_message(chatMessage.sender_name() + ": " + chatMessage.message());
|
||||
roomChatHistory.set_message_type(Event_RoomSay::ChatHistory);
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Dieser Assistent wird eine Liste aller Editionen, Karten und Spielsteine, die von Cockatrice genutzt werden, importieren.
|
||||
Sie müssen eine URL oder einen Dateinamen als Quelle angeben.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -91,7 +92,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Do you want to try to download a fresh copy of the uncompressed file instead?</source>
|
||||
<translation>Möchtest du stattdessen eine neue Kopie der nicht komprimierten Datei herunerladen?</translation>
|
||||
<translation>Möchtest du stattdessen eine neue Kopie der nicht komprimierten Datei herunterladen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The file was retrieved successfully, but it does not contain any sets data.</source>
|
||||
|
@ -99,19 +100,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Bitte geben Sie eine Quelle für die Liste von Editionen und Karten an. Sie können eine URL Adresse zum Herunterladen angeben oder eine Datei von Ihrem Computer verwenden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Download URL:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Standard-URL wiederherstellen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Die eingegebene URL ist nicht gültig.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -138,19 +139,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Bitte geben Sie eine Quelle für die Liste der Spielsteine an. Sie können eine URL Adresse zum Herunterladen angeben oder eine Datei von Ihrem Computer verwenden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Download URL:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Standard-URL wiederherstellen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Die eingegebene URL ist nicht gültig.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Este asistente importará la lista de los sets y cartas que serán usadas por Cockatrice.
|
||||
Necesitarás especificar la URL o el nombre de archivo que será usado como origen.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -99,58 +100,58 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Por favor especifica un origen para la lista de sets y cartas. Puedes especificar la URL de donde descargarla o usar un archivo existente de tu ordenador.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>URL de descarga:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Restablecer URL predeterminada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>La URL suministrada no es válida.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoadTokensPage</name>
|
||||
<message>
|
||||
<source>Tokens source selection</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Selección de origen de tokens</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Downloading (0MB)</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Descargando (0MB)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Downloading (%1MB)</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Descargando (%1MB)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Network error: %1.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Error de red: %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Por favor especifica un origen para la lista de tokens. Puedes especificar la URL de donde descargarla o usar un archivo existente en tu ordenador.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>URL de descarga:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Restablecer URL predeterminada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>La URL suministrada no es válida.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -228,40 +229,41 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
<name>SaveTokensPage</name>
|
||||
<message>
|
||||
<source>Tokens imported</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Tokens importados</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The tokens has been imported. Press "Save" to save the imported tokens to the Cockatrice tokens database.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Los tokens han sido importados. Pulsa "Guardar" para guardar los tokens importados en la base de datos de tokens de Cockatrice.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save to the default path (recommended)</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Guardar en la ruta por defecto (recomendado)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save token database</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Base de datos de tokens:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML; token database (*.xml)</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>XML; base de datos de tokens (*.xml)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Success</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Éxito</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The token database has been saved successfully to
|
||||
%1</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>La base de datos de cartas ha sido guardada correctamente en
|
||||
%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The file could not be saved to %1</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>El archivo no ha podido ser guardado en %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Cet assistant va importer la liste des éditions, cartes et jetons qui seront utilisés par Cockatrice.
|
||||
Vous devrez spécifier une URL ou un fichier qui sera utilisé comme source.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -31,7 +32,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Choose file...</source>
|
||||
<translation>Choisir un fichier...</translation>
|
||||
<translation>Choisissez un fichier...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Load sets file</source>
|
||||
|
@ -79,11 +80,11 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Zip extraction failed: the Zip archive doesn't contain exactly one file.</source>
|
||||
<translation>Ce fichier ne peut être enregistré au répertoire</translation>
|
||||
<translation>Extraction zip échouée: l'archive zip contient plus qu'un fichier.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Zip extraction failed: %1.</source>
|
||||
<translation>l'extraction du zip à échoué : %1.</translation>
|
||||
<translation>L'extraction du zip a échoué : %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sorry, this version of Oracle does not support zipped files.</source>
|
||||
|
@ -99,30 +100,30 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Spécifiez une source pour la liste des éditions et des cartes. Vous pouvez spécifier une URL qui sera téléchargée ou utiliser un fichier existant sur votre ordinateur.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>URL de téléchargement:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Restaurer l'URL par défaut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>L'URL fournie n'est pas valable</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoadTokensPage</name>
|
||||
<message>
|
||||
<source>Tokens source selection</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>sélection de la source des jetons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Érreur</translation>
|
||||
<translation>Erreur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Downloading (0MB)</source>
|
||||
|
@ -138,19 +139,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Spécifiez une source pour la liste des jetons. Vous pouvez spécifier une URL qui sera téléchargée ou utiliser un fichier existant sur votre ordinateur.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>URL de téléchargement:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Restorer l'URL par défaut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>L'URL fournie n'est pas valide.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -228,11 +229,11 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
<name>SaveTokensPage</name>
|
||||
<message>
|
||||
<source>Tokens imported</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Jetons importés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The tokens has been imported. Press "Save" to save the imported tokens to the Cockatrice tokens database.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Les jetons ont été importés. Pressez sur "Sauvegarder" pour sauver les jetons importés dans la base de données des jetons Cockatrice.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save to the default path (recommended)</source>
|
||||
|
@ -253,7 +254,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
<message>
|
||||
<source>The token database has been saved successfully to
|
||||
%1</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>La base de donnée de jetons a été correctement sauvegardée dans %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
|
@ -261,7 +262,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>The file could not be saved to %1</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Le fichier n'a pas pu être sauvegardé dans %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Questo wizard importerà la lista dei set e delle carte che verranno usate da Cockatrice.<br/>Dovrai specificare un indirizzo url o il nome di un file che verrà utilizzato come sorgente.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -99,19 +99,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Specifica una sorgente per la lista dei set e delle carte. Puoi specificare un indirizzo url da cui scaricare il file o alternativamente usare un file già presente nel tuo computer.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Indirizzo download:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Usa l'indirizzo predefinito</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>L'indirizzo specificato non è valido.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -138,19 +138,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Specifica una sorgente per la lista delle pedine. Puoi specificare un indirizzo url da cui scaricare il file o alternativamente usare un file già presente nel tuo computer.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Indirizzo download:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Usa l'indirizzo predefinito</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>L'indirizzo specificato non è valido.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>このウィザードでは、Cockatriceが使用するカードセットやトークンのリストをインポートします。
|
||||
ソースとして使用するURLまたはファイルを指定した後、利用可能リストから入れたいセットを選択します。</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -99,19 +100,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>カードセットとカードのリストのソースファイルを指定してください。ダウンロード可能なURLか、コンピューターに保存したソースファイルを指定することができます(通常はデフォルトのURLからダウンロードで構いません)。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>ダウンロードURL:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>デフォルトのURLを復元</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>指定されたURLは無効です。</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -138,19 +139,19 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>トークンのソースファイルを指定してください。ダウンロード可能なURLか、コンピューターに保存したソースファイルを指定することができます(通常はデフォルトのURLからダウンロードで構いません)。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>ダウンロードURL:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>デフォルトのURLを復元</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>指定されたURLは無効です。</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -16,14 +16,15 @@
|
|||
<message>
|
||||
<source>This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice.
|
||||
You will need to specify a URL or a filename that will be used as a source.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>오라클은 코카트리스에서 사용할 확장판의 목록과 카드들의 정보를 갱신하는 프로그램입니다.
|
||||
판본 목록 파일이 있는 웹 주소나 파일을 입력하신 후에 읽어온 목록에서 원하는 확장판을 선택해 불러올 수 있습니다.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoadSetsPage</name>
|
||||
<message>
|
||||
<source>Source selection</source>
|
||||
<translation>판본 목록 파일 주소 입력</translation>
|
||||
<translation>확장판 목록 파일 주소 입력</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Local file:</source>
|
||||
|
@ -35,15 +36,15 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Load sets file</source>
|
||||
<translation>판본 목록 파일 불러오기</translation>
|
||||
<translation>확장판 목록 파일 불러오기</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sets JSON file (*.json *.zip)</source>
|
||||
<translation>판본 목록 JSON 파일 (*.json *.zip)</translation>
|
||||
<translation>확장판 목록 JSON 파일 (*.json *.zip)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sets JSON file (*.json)</source>
|
||||
<translation>판본 목록 JSON 파일 (*.json)</translation>
|
||||
<translation>확장판 목록 JSON 파일 (*.json)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
|
@ -55,7 +56,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please choose a file.</source>
|
||||
<translation>판본 목록 파일을 선택해 주세요.</translation>
|
||||
<translation>확장판 목록 파일을 선택해 주세요.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot open file '%1'.</source>
|
||||
|
@ -79,7 +80,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Zip extraction failed: the Zip archive doesn't contain exactly one file.</source>
|
||||
<translation>압축 풀기 실패 : 압축 파일에 판본 목록 파일 이외의 파일이 있습니다.</translation>
|
||||
<translation>압축 풀기 실패 : 압축 파일에 확장판 목록 파일 이외의 파일이 있습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Zip extraction failed: %1.</source>
|
||||
|
@ -91,27 +92,28 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Do you want to try to download a fresh copy of the uncompressed file instead?</source>
|
||||
<translation>압축되지 않은 판본 목록을 대신 내려받으시겠습니까?</translation>
|
||||
<translation>압축되지 않은 확장판 목록을 대신 내려받으시겠습니까?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The file was retrieved successfully, but it does not contain any sets data.</source>
|
||||
<translation>파일을 성공적으로 다운로드 하였으나 판본 정보가 들어있지 않습니다.</translation>
|
||||
<translation>파일을 성공적으로 다운로드 하였으나 확장판 정보가 들어있지 않습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>확장판 목록 및 카드 정보가 들어있는 파일의 위치를 입력해 주세요.
|
||||
다운로드 할 수 있는 웹 주소나 컴퓨터에 저장되어 있는 파일을 선택 할 수 있습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>웹 주소:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>기본 주소로 복원</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>잘못된 주소를 입력하셨습니다.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -138,26 +140,27 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Please specify a source for the list of tokens. You can specify a URL address that will be downloaded or use an existing file from your computer.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>토큰 목록 및 정보가 들어있는 파일의 위치를 입력해 주세요.
|
||||
다운로드 할 수 있는 웹 주소나 컴퓨터에 저장되어 있는 파일을 선택 할 수 있습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Download URL:</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>웹 주소:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restore default URL</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>기본 주소로 복원</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The provided URL is not valid.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>잘못된 주소를 입력하셨습니다.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OracleImporter</name>
|
||||
<message>
|
||||
<source>Dummy set containing tokens</source>
|
||||
<translation>토큰 정보가 들어있는 더미 판본</translation>
|
||||
<translation>토큰 정보가 들어있는 더미 확장판</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -175,11 +178,11 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
<name>SaveSetsPage</name>
|
||||
<message>
|
||||
<source>Sets imported</source>
|
||||
<translation>판본 불러오기 완료</translation>
|
||||
<translation>확장판 불러오기 완료</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The following sets has been imported. Press "Save" to save the imported cards to the Cockatrice database.</source>
|
||||
<translation>아래와 같이 판본을 불러왔습니다.
|
||||
<translation>아래와 같이 확장판을 불러왔습니다.
|
||||
"저장" 버튼을 눌러 코카트리스에서 사용할 수 있는 카드 데이터베이스를 저장하실 수 있습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -192,7 +195,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>No set has been imported.</source>
|
||||
<translation>아무 판본도 불러오지 못했습니다.</translation>
|
||||
<translation>아무 확장판도 불러오지 못했습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Import finished: %1 cards.</source>
|
||||
|
|
|
@ -122,7 +122,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Fout</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Downloading (0MB)</source>
|
||||
|
@ -257,7 +257,7 @@ You will need to specify a URL or a filename that will be used as a source.</sou
|
|||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Fout</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The file could not be saved to %1</source>
|
||||
|
|
BIN
sounds/Default/buddy_join.wav
Normal file
BIN
sounds/Default/buddy_join.wav
Normal file
Binary file not shown.
BIN
sounds/Default/buddy_leave.wav
Normal file
BIN
sounds/Default/buddy_leave.wav
Normal file
Binary file not shown.
Loading…
Reference in a new issue