Merge branch 'master' of git://cockatrice.git.sourceforge.net/gitroot/cockatrice/cockatrice

This commit is contained in:
Max-Wilhelm Bruker 2011-01-21 18:03:28 +01:00
commit 6cebad2513
13 changed files with 262 additions and 356 deletions

View file

@ -28,7 +28,6 @@ HEADERS += src/abstractcounter.h \
src/handcounter.h \
src/carddatabase.h \
src/gameview.h \
src/deck_picturecacher.h \
src/decklistmodel.h \
src/dlg_load_deck_from_clipboard.h \
src/dlg_load_remote_deck.h \
@ -111,7 +110,6 @@ SOURCES += src/abstractcounter.cpp \
src/handcounter.cpp \
src/carddatabase.cpp \
src/gameview.cpp \
src/deck_picturecacher.cpp \
src/decklistmodel.cpp \
src/dlg_load_deck_from_clipboard.cpp \
src/dlg_load_remote_deck.cpp \

View file

@ -60,6 +60,62 @@ void SetList::sortByKey()
qSort(begin(), end(), CompareFunctor());
}
PictureLoadingThread::PictureLoadingThread(QObject *parent)
: QThread(parent)
{
}
PictureLoadingThread::~PictureLoadingThread()
{
quit();
wait();
}
void PictureLoadingThread::run()
{
forever {
mutex.lock();
if (loadQueue.isEmpty()) {
mutex.unlock();
return;
}
CardInfo *card = loadQueue.takeFirst();
QString correctedName = card->getCorrectedName();
QString picsPath = _picsPath;
SetList sortedSets = card->getSets();
mutex.unlock();
sortedSets.sortByKey();
QImage image;
for (int i = 0; i < sortedSets.size(); i++) {
if (image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName)))
break;
if (image.load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName).arg(1)))
break;
}
if (image.isNull())
image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg("downloadedPics").arg(correctedName));
emit imageLoaded(card, image);
}
}
void PictureLoadingThread::loadImage(CardInfo *card)
{
QMutexLocker locker(&mutex);
loadQueue.append(card);
if (!isRunning())
start(LowPriority);
}
void PictureLoadingThread::setPicsPath(const QString &path)
{
QMutexLocker locker(&mutex);
_picsPath = path;
}
CardInfo::CardInfo(CardDatabase *_db, const QString &_name, const QString &_manacost, const QString &_cardtype, const QString &_powtough, const QString &_text, const QStringList &_colors, bool _cipt, int _tableRow, const SetList &_sets, const QString &_picURL)
: db(_db), name(_name), sets(_sets), manacost(_manacost), cardtype(_cardtype), powtough(_powtough), text(_text), colors(_colors), picURL(_picURL), cipt(_cipt), tableRow(_tableRow), pixmap(NULL)
{
@ -119,34 +175,22 @@ QPixmap *CardInfo::loadPixmap()
if (pixmap)
return pixmap;
pixmap = new QPixmap();
QString picsPath = settingsCache->getPicsPath();
if (!QDir(picsPath).exists())
return pixmap;
if (getName().isEmpty()) {
pixmap->load(settingsCache->getCardBackPicturePath());
return pixmap;
}
SetList sortedSets = sets;
sortedSets.sortByKey();
db->loadImage(this);
return pixmap;
}
QString debugOutput = QString("CardDatabase: loading pixmap for '%1' from ").arg(getName());
for (int i = 0; i < sortedSets.size(); i++)
debugOutput.append(QString("%1, ").arg(sortedSets[i]->getShortName()));
qDebug(debugOutput.toLatin1());
QString correctedName = getCorrectedName();
for (int i = 0; i < sortedSets.size(); i++) {
if (pixmap->load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName)))
return pixmap;
if (pixmap->load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(sortedSets[i]->getShortName()).arg(correctedName).arg(1)))
return pixmap;
}
if (pixmap->load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg("downloadedPics").arg(correctedName)))
return pixmap;
if (settingsCache->getPicDownload())
void CardInfo::imageLoaded(const QImage &image)
{
if (!image.isNull()) {
*pixmap = QPixmap::fromImage(image);
emit pixmapUpdated();
} else if (settingsCache->getPicDownload())
db->startPicDownload(this);
return pixmap;
}
QPixmap *CardInfo::getPixmap(QSize size)
@ -244,6 +288,11 @@ CardDatabase::CardDatabase(QObject *parent)
loadCardDatabase();
loadingThread = new PictureLoadingThread(this);
loadingThread->setPicsPath(settingsCache->getPicsPath());
connect(loadingThread, SIGNAL(imageLoaded(CardInfo *, QImage)), this, SLOT(imageLoaded(CardInfo *, QImage)));
loadingThread->start();
noCard = new CardInfo(this);
noCard->loadPixmap(); // cache pixmap for card back
connect(settingsCache, SIGNAL(cardBackPicturePathChanged()), noCard, SLOT(updatePixmapCache()));
@ -532,3 +581,21 @@ QStringList CardDatabase::getAllMainCardTypes() const
types.insert(cardIterator.next().value()->getMainCardType());
return types.toList();
}
void CardDatabase::cacheCardPixmaps(const QStringList &cardNames)
{
qDebug("pixmapCache started");
for (int i = 0; i < cardNames.size(); ++i)
getCard(cardNames[i])->loadPixmap();
qDebug("pixmapCache finished");
}
void CardDatabase::loadImage(CardInfo *card)
{
loadingThread->loadImage(card);
}
void CardDatabase::imageLoaded(CardInfo *card, QImage image)
{
card->imageLoaded(image);
}

View file

@ -8,6 +8,8 @@
#include <QList>
#include <QXmlStreamReader>
#include <QNetworkRequest>
#include <QThread>
#include <QMutex>
class CardDatabase;
class CardInfo;
@ -35,6 +37,23 @@ public:
void sortByKey();
};
class PictureLoadingThread : public QThread {
Q_OBJECT
private:
QString _picsPath;
QList<CardInfo *> loadQueue;
QMutex mutex;
protected:
void run();
public:
PictureLoadingThread(QObject *parent);
~PictureLoadingThread();
void setPicsPath(const QString &path);
void loadImage(CardInfo *card);
signals:
void imageLoaded(CardInfo *card, const QImage &image);
};
class CardInfo : public QObject {
Q_OBJECT
private:
@ -85,6 +104,7 @@ public:
QPixmap *getPixmap(QSize size);
void clearPixmapCache();
void clearPixmapCacheMiss();
void imageLoaded(const QImage &image);
public slots:
void updatePixmapCache();
signals:
@ -102,6 +122,7 @@ protected:
bool downloadRunning;
bool loadSuccess;
CardInfo *noCard;
PictureLoadingThread *loadingThread;
private:
void loadCardsFromXml(QXmlStreamReader &xml);
void loadSetsFromXml(QXmlStreamReader &xml);
@ -120,6 +141,8 @@ public:
QStringList getAllColors() const;
QStringList getAllMainCardTypes() const;
bool getLoadSuccess() const { return loadSuccess; }
void cacheCardPixmaps(const QStringList &cardNames);
void loadImage(CardInfo *card);
public slots:
void clearPixmapCache();
bool loadCardDatabase(const QString &path);
@ -127,6 +150,7 @@ public slots:
private slots:
void picDownloadFinished(QNetworkReply *reply);
void picDownloadChanged();
void imageLoaded(CardInfo *card, QImage image);
};
#endif

View file

@ -1,29 +0,0 @@
#include <QProgressDialog>
#include "deck_picturecacher.h"
#include "decklist.h"
#include "carddatabase.h"
#include "main.h"
void Deck_PictureCacher::cacheHelper(InnerDecklistNode *item, QProgressDialog *progress)
{
for (int i = 0; i < item->size(); i++) {
DecklistCardNode *node = dynamic_cast<DecklistCardNode *>(item->at(i));
if (node) {
db->getCard(node->getName())->loadPixmap();
progress->setValue(progress->value() + 1);
} else
cacheHelper(dynamic_cast<InnerDecklistNode *>(item->at(i)), progress);
}
}
void Deck_PictureCacher::cachePictures(DeckList *deck, QWidget *parent)
{
int totalCards = deck->getRoot()->recursiveCount();
QProgressDialog progress(tr("Caching card pictures..."), QString(), 0, totalCards, parent);
progress.setMinimumDuration(1000);
progress.setWindowModality(Qt::WindowModal);
cacheHelper(deck->getRoot(), &progress);
}

View file

@ -1,19 +0,0 @@
#ifndef DECK_PICTURECACHER_H
#define DECK_PICTURECACHER_H
#include <QObject>
class InnerDecklistNode;
class QProgressDialog;
class DeckList;
class QWidget;
class Deck_PictureCacher : public QObject {
Q_OBJECT
private:
static void cacheHelper(InnerDecklistNode *item, QProgressDialog *progress);
public:
static void cachePictures(DeckList *deck, QWidget *parent);
};
#endif

View file

@ -18,7 +18,6 @@
#include "zoneviewwidget.h"
#include "deckview.h"
#include "decklist.h"
#include "deck_picturecacher.h"
#include "protocol_items.h"
#include "dlg_load_remote_deck.h"
#include "abstractclient.h"
@ -26,6 +25,7 @@
#include "arrowitem.h"
#include "main.h"
#include "settingscache.h"
#include "carddatabase.h"
ReadyStartButton::ReadyStartButton(QWidget *parent)
: QPushButton(parent), readyStart(false)
@ -131,7 +131,7 @@ void DeckViewContainer::deckSelectFinished(ProtocolResponse *r)
if (!resp)
return;
Deck_PictureCacher::cachePictures(resp->getDeck(), this);
db->cacheCardPixmaps(resp->getDeck()->getCardList());
deckView->setDeck(new DeckList(resp->getDeck()));
readyStartButton->setEnabled(true);
}
@ -508,7 +508,7 @@ void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventCont
}
player->processPlayerInfo(pl);
if (player->getLocal() && !pl->getDeck()->isEmpty()) {
Deck_PictureCacher::cachePictures(pl->getDeck(), this);
db->cacheCardPixmaps(pl->getDeck()->getCardList());
deckViewContainers.value(player->getId())->setDeck(new DeckList(pl->getDeck()));
}
}

View file

@ -22,7 +22,6 @@
#include "carddatabasemodel.h"
#include "decklistmodel.h"
#include "cardinfowidget.h"
#include "deck_picturecacher.h"
#include "dlg_cardsearch.h"
#include "dlg_load_deck_from_clipboard.h"
#include "main.h"
@ -467,7 +466,7 @@ void WndDeckEditor::setDeck(DeckList *_deck, const QString &_lastFileName, DeckL
deckView->expandAll();
setWindowModified(false);
Deck_PictureCacher::cachePictures(_deck, this);
db->cacheCardPixmaps(_deck->getCardList());
deckView->expandAll();
setWindowModified(false);
}

View file

@ -6,32 +6,32 @@
<message>
<location filename="../src/abstractcounter.cpp" line="56"/>
<source>&amp;Set counter...</source>
<translation type="unfinished">E&amp;stablecer contadores...</translation>
<translation>E&amp;stablecer contador...</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="63"/>
<source>Ctrl+L</source>
<translation type="unfinished">Ctrl+L</translation>
<translation>Ctrl+L</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="64"/>
<source>F11</source>
<translation type="unfinished">F11</translation>
<translation>F11</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="65"/>
<source>F12</source>
<translation type="unfinished">F12</translation>
<translation>F12</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>Set counter</source>
<translation type="unfinished">Establecer contador</translation>
<translation>Establecer contador</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>New value for counter &apos;%1&apos;:</source>
<translation type="unfinished">Nuevo valor para el contador &apos;%1&apos;:</translation>
<translation>Nuevo valor para el contador &apos;%1&apos;:</translation>
</message>
</context>
<context>
@ -175,12 +175,12 @@
<message>
<location filename="../src/carditem.cpp" line="175"/>
<source>&amp;Play</source>
<translation type="unfinished"></translation>
<translation>&amp;Jugar</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="176"/>
<source>&amp;Hide</source>
<translation type="unfinished"></translation>
<translation>&amp;Ocultar</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="178"/>
@ -1103,7 +1103,7 @@
<message>
<location filename="../src/tab_room.cpp" line="114"/>
<source>Show &amp;full games</source>
<translation type="unfinished"></translation>
<translation>Ver partidas &amp;sin plazas libres</translation>
</message>
<message>
<source>&amp;Show full games</source>
@ -1248,42 +1248,42 @@
<message>
<location filename="../src/window_main.cpp" line="158"/>
<source>Version %1</source>
<translation type="unfinished"></translation>
<translation>Versión %1</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="159"/>
<source>Authors:</source>
<translation type="unfinished"></translation>
<translation>Autores:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="160"/>
<source>Translators:</source>
<translation type="unfinished"></translation>
<translation>Traductores:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="161"/>
<source>Spanish:</source>
<translation type="unfinished"></translation>
<translation>Español:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="162"/>
<source>Portugese (Portugal):</source>
<translation type="unfinished"></translation>
<translation>Portugués (Portugal):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="163"/>
<source>Portugese (Brazil):</source>
<translation type="unfinished"></translation>
<translation>Portugués (Brasil):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="164"/>
<source>French:</source>
<translation type="unfinished"></translation>
<translation>Francés:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="165"/>
<source>Japanese:</source>
<translation type="unfinished"></translation>
<translation>Japonés:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="171"/>
@ -1499,7 +1499,7 @@
<message>
<location filename="../src/messagelogwidget.cpp" line="202"/>
<source>%1 gives %2 control over %3.</source>
<translation type="unfinished"></translation>
<translation>%1 entrega a %2 el control sobre %3.</translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="208"/>
@ -2165,7 +2165,7 @@
<message>
<location filename="../src/player.cpp" line="416"/>
<source>Put top card on &amp;bottom</source>
<translation type="unfinished"></translation>
<translation>Poner carta superior en la parte &amp;inferior</translation>
</message>
<message>
<location filename="../src/player.cpp" line="419"/>
@ -2337,32 +2337,32 @@
<message>
<location filename="../src/tab_server.cpp" line="51"/>
<source>Rooms</source>
<translation type="unfinished"></translation>
<translation>Salas</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="52"/>
<source>Joi&amp;n</source>
<translation type="unfinished">E&amp;ntrar</translation>
<translation>E&amp;ntrar</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="55"/>
<source>Room</source>
<translation type="unfinished"></translation>
<translation>Sala</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="56"/>
<source>Description</source>
<translation type="unfinished">Descripción</translation>
<translation>Descripción</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="57"/>
<source>Players</source>
<translation type="unfinished">Jugadores</translation>
<translation>Jugadores</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="58"/>
<source>Games</source>
<translation type="unfinished">Partidas</translation>
<translation>Partidas</translation>
</message>
</context>
<context>
@ -2390,37 +2390,37 @@
<message>
<location filename="../src/tab_admin.cpp" line="40"/>
<source>Update server &amp;message</source>
<translation type="unfinished"></translation>
<translation>Actualizar &amp;mensaje del servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="41"/>
<source>Server administration functions</source>
<translation type="unfinished"></translation>
<translation>Funciones de administración del servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="43"/>
<source>&amp;Unlock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Desbloquear funciones</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="44"/>
<source>&amp;Lock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Bloquear funciones</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Unlock administration functions</source>
<translation type="unfinished"></translation>
<translation>Desbloquear funciones de administración</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Do you really want to unlock the administration functions?</source>
<translation type="unfinished"></translation>
<translation>¿Realmente quieres desbloquear las funciones de administración?</translation>
</message>
<message>
<location filename="../src/tab_admin.h" line="26"/>
<source>Administration</source>
<translation type="unfinished"></translation>
<translation>Administración</translation>
</message>
</context>
<context>
@ -2626,32 +2626,32 @@ Por favor, introduzca un nombre:</translation>
<message>
<location filename="../src/tab_room.cpp" line="219"/>
<source>&amp;Say:</source>
<translation type="unfinished">&amp;Decir:</translation>
<translation>&amp;Decir:</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="220"/>
<source>Chat</source>
<translation type="unfinished"></translation>
<translation>Chat</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="221"/>
<source>&amp;Room</source>
<translation type="unfinished"></translation>
<translation>&amp;Sala</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="222"/>
<source>&amp;Leave room</source>
<translation type="unfinished"></translation>
<translation>&amp;Dejar sala</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="268"/>
<source>%1 has joined the room.</source>
<translation type="unfinished"></translation>
<translation>%1 se ha unido a la sala.</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="274"/>
<source>%1 has left the room.</source>
<translation type="unfinished"></translation>
<translation>%1 ha dejado la sala.</translation>
</message>
</context>
<context>
@ -2667,12 +2667,12 @@ Por favor, introduzca un nombre:</translation>
<message>
<location filename="../src/userinfobox.cpp" line="38"/>
<source>User information</source>
<translation type="unfinished"></translation>
<translation>Información del usuario</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="45"/>
<source>Real name:</source>
<translation type="unfinished"></translation>
<translation>Nombre real:</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="46"/>
@ -2687,22 +2687,22 @@ Por favor, introduzca un nombre:</translation>
<message>
<location filename="../src/userinfobox.cpp" line="65"/>
<source>Administrator</source>
<translation type="unfinished"></translation>
<translation>Administrador</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="67"/>
<source>Judge</source>
<translation type="unfinished"></translation>
<translation>Juez</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="69"/>
<source>Registered user</source>
<translation type="unfinished"></translation>
<translation>Usuario registrado</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="71"/>
<source>Unregistered user</source>
<translation type="unfinished"></translation>
<translation>Usuario no registrado</translation>
</message>
</context>
<context>
@ -2738,17 +2738,17 @@ Por favor, introduzca un nombre:</translation>
<message>
<location filename="../src/userlist.cpp" line="65"/>
<source>Users in this room: %1</source>
<translation type="unfinished"></translation>
<translation>Usuarios en esta sala: %1</translation>
</message>
<message>
<location filename="../src/userlist.cpp" line="119"/>
<source>User &amp;details</source>
<translation type="unfinished"></translation>
<translation>&amp;Detalles del usuario</translation>
</message>
<message>
<location filename="../src/userlist.cpp" line="120"/>
<source>Direct &amp;chat</source>
<translation type="unfinished"></translation>
<translation>&amp;Chat privado</translation>
</message>
</context>
<context>
@ -2837,14 +2837,15 @@ Por favor, introduzca un nombre:</translation>
<location filename="../src/window_deckeditor.cpp" line="312"/>
<location filename="../src/window_deckeditor.cpp" line="336"/>
<source>Error</source>
<translation type="unfinished">Error</translation>
<translation>Error</translation>
</message>
<message>
<location filename="../src/window_deckeditor.cpp" line="312"/>
<location filename="../src/window_deckeditor.cpp" line="336"/>
<source>The deck could not be saved.
Please check that the directory is writable and try again.</source>
<translation type="unfinished"></translation>
<translation>El mazo no puede guardarse
Por favor, compruebe que tiene permisos de escritura en el directorio e intentelo de nuevo.</translation>
</message>
<message>
<location filename="../src/window_deckeditor.cpp" line="318"/>
@ -2935,7 +2936,7 @@ Please check that the directory is writable and try again.</source>
<location filename="../src/window_deckeditor.cpp" line="254"/>
<source>The decklist has been modified.
Do you want to save the changes?</source>
<translation type="unfinished">La lista del mazo ha sido modificada
<translation>La lista del mazo ha sido modificada
¿Deseas guardar los cambios?</translation>
</message>
</context>

View file

@ -6,32 +6,32 @@
<message>
<location filename="../src/abstractcounter.cpp" line="56"/>
<source>&amp;Set counter...</source>
<translation type="unfinished">Alterar &amp;marcador...</translation>
<translation>Alterar &amp;marcador...</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="63"/>
<source>Ctrl+L</source>
<translation type="unfinished">Ctrl+L</translation>
<translation>Ctrl+L</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="64"/>
<source>F11</source>
<translation type="unfinished">F11</translation>
<translation>F11</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="65"/>
<source>F12</source>
<translation type="unfinished">F12</translation>
<translation>F12</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>Set counter</source>
<translation type="unfinished">Alterar marcador</translation>
<translation>Alterar marcador</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>New value for counter &apos;%1&apos;:</source>
<translation type="unfinished">Novo valor para o marcador &apos;%1&apos;:</translation>
<translation>Novo valor para o marcador &apos;%1&apos;:</translation>
</message>
</context>
<context>
@ -171,12 +171,12 @@
<message>
<location filename="../src/carditem.cpp" line="175"/>
<source>&amp;Play</source>
<translation type="unfinished"></translation>
<translation>&amp;Jogar</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="176"/>
<source>&amp;Hide</source>
<translation type="unfinished"></translation>
<translation>&amp;Ocultar</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="178"/>
@ -957,7 +957,7 @@
<message>
<location filename="../src/tab_room.cpp" line="114"/>
<source>Show &amp;full games</source>
<translation type="unfinished"></translation>
<translation>&amp;Mostrar os jogos cheios</translation>
</message>
<message>
<source>&amp;Show full games</source>
@ -1106,42 +1106,42 @@
<message>
<location filename="../src/window_main.cpp" line="158"/>
<source>Version %1</source>
<translation type="unfinished"></translation>
<translation>Versão %1</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="159"/>
<source>Authors:</source>
<translation type="unfinished"></translation>
<translation>Autores:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="160"/>
<source>Translators:</source>
<translation type="unfinished"></translation>
<translation>Tradutores:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="161"/>
<source>Spanish:</source>
<translation type="unfinished"></translation>
<translation>Espanhol:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="162"/>
<source>Portugese (Portugal):</source>
<translation type="unfinished"></translation>
<translation>Português (Portugal):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="163"/>
<source>Portugese (Brazil):</source>
<translation type="unfinished"></translation>
<translation>Português (Brasil):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="164"/>
<source>French:</source>
<translation type="unfinished"></translation>
<translation>Francês:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="165"/>
<source>Japanese:</source>
<translation type="unfinished"></translation>
<translation>Japonês:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="171"/>
@ -1357,7 +1357,7 @@
<message>
<location filename="../src/messagelogwidget.cpp" line="202"/>
<source>%1 gives %2 control over %3.</source>
<translation type="unfinished"></translation>
<translation>%1 controle para %2 sobre %3.</translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="208"/>
@ -2015,7 +2015,7 @@
<message>
<location filename="../src/player.cpp" line="416"/>
<source>Put top card on &amp;bottom</source>
<translation type="unfinished"></translation>
<translation>Colocar o card do topo no &amp;fundo</translation>
</message>
<message>
<location filename="../src/player.cpp" line="419"/>
@ -2175,32 +2175,32 @@
<message>
<location filename="../src/tab_server.cpp" line="51"/>
<source>Rooms</source>
<translation type="unfinished"></translation>
<translation>Salas</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="52"/>
<source>Joi&amp;n</source>
<translation type="unfinished">&amp;Entrar</translation>
<translation>&amp;Entrar</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="55"/>
<source>Room</source>
<translation type="unfinished"></translation>
<translation>Sala</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="56"/>
<source>Description</source>
<translation type="unfinished">Descrição</translation>
<translation>Descrição</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="57"/>
<source>Players</source>
<translation type="unfinished">Jogadores</translation>
<translation>Jogadores</translation>
</message>
<message>
<location filename="../src/tab_server.cpp" line="58"/>
<source>Games</source>
<translation type="unfinished">Jogos</translation>
<translation>Jogos</translation>
</message>
</context>
<context>
@ -2228,37 +2228,37 @@
<message>
<location filename="../src/tab_admin.cpp" line="40"/>
<source>Update server &amp;message</source>
<translation type="unfinished"></translation>
<translation>&amp;Atualizar mensagem do servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="41"/>
<source>Server administration functions</source>
<translation type="unfinished"></translation>
<translation>Funções do administrador do servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="43"/>
<source>&amp;Unlock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Desbloquear funções</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="44"/>
<source>&amp;Lock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Bloquear funções</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Unlock administration functions</source>
<translation type="unfinished"></translation>
<translation>Desbloquear funções do administrador</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Do you really want to unlock the administration functions?</source>
<translation type="unfinished"></translation>
<translation>Você quer mesmo desbloquear as funções do administrador?</translation>
</message>
<message>
<location filename="../src/tab_admin.h" line="26"/>
<source>Administration</source>
<translation type="unfinished"></translation>
<translation>Administração</translation>
</message>
</context>
<context>
@ -2464,32 +2464,32 @@ Por favor, entre um nome:</translation>
<message>
<location filename="../src/tab_room.cpp" line="219"/>
<source>&amp;Say:</source>
<translation type="unfinished">&amp;Falar:</translation>
<translation>&amp;Falar:</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="220"/>
<source>Chat</source>
<translation type="unfinished"></translation>
<translation>Chat</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="221"/>
<source>&amp;Room</source>
<translation type="unfinished"></translation>
<translation>&amp;Sala</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="222"/>
<source>&amp;Leave room</source>
<translation type="unfinished"></translation>
<translation>S&amp;air da sala</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="268"/>
<source>%1 has joined the room.</source>
<translation type="unfinished"></translation>
<translation>%1 entrou na sala.</translation>
</message>
<message>
<location filename="../src/tab_room.cpp" line="274"/>
<source>%1 has left the room.</source>
<translation type="unfinished"></translation>
<translation>%1 saiu da sala.</translation>
</message>
</context>
<context>
@ -2505,12 +2505,12 @@ Por favor, entre um nome:</translation>
<message>
<location filename="../src/userinfobox.cpp" line="38"/>
<source>User information</source>
<translation type="unfinished"></translation>
<translation>Informação do usuário</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="45"/>
<source>Real name:</source>
<translation type="unfinished"></translation>
<translation>Nome real:</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="46"/>
@ -2525,22 +2525,22 @@ Por favor, entre um nome:</translation>
<message>
<location filename="../src/userinfobox.cpp" line="65"/>
<source>Administrator</source>
<translation type="unfinished"></translation>
<translation>Administrador</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="67"/>
<source>Judge</source>
<translation type="unfinished"></translation>
<translation>Juiz</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="69"/>
<source>Registered user</source>
<translation type="unfinished"></translation>
<translation>Usuário registrado</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="71"/>
<source>Unregistered user</source>
<translation type="unfinished"></translation>
<translation>Usuário não registrado</translation>
</message>
</context>
<context>
@ -2576,17 +2576,17 @@ Por favor, entre um nome:</translation>
<message>
<location filename="../src/userlist.cpp" line="65"/>
<source>Users in this room: %1</source>
<translation type="unfinished"></translation>
<translation>Usuários nesta sala: %1</translation>
</message>
<message>
<location filename="../src/userlist.cpp" line="119"/>
<source>User &amp;details</source>
<translation type="unfinished"></translation>
<translation>&amp;Detalhes do usuário</translation>
</message>
<message>
<location filename="../src/userlist.cpp" line="120"/>
<source>Direct &amp;chat</source>
<translation type="unfinished"></translation>
<translation>&amp;Chat direto</translation>
</message>
</context>
<context>
@ -2675,14 +2675,15 @@ Por favor, entre um nome:</translation>
<location filename="../src/window_deckeditor.cpp" line="312"/>
<location filename="../src/window_deckeditor.cpp" line="336"/>
<source>Error</source>
<translation type="unfinished">Erro</translation>
<translation>Erro</translation>
</message>
<message>
<location filename="../src/window_deckeditor.cpp" line="312"/>
<location filename="../src/window_deckeditor.cpp" line="336"/>
<source>The deck could not be saved.
Please check that the directory is writable and try again.</source>
<translation type="unfinished"></translation>
<translation>O deck não pôde ser salvo.
Por favor, verifique se o diretório não é somente leitura e tente novamente.</translation>
</message>
<message>
<location filename="../src/window_deckeditor.cpp" line="318"/>

View file

@ -6,32 +6,32 @@
<message>
<location filename="../src/abstractcounter.cpp" line="56"/>
<source>&amp;Set counter...</source>
<translation type="unfinished">Definir &amp;marcador...</translation>
<translation>Definir &amp;marcador...</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="63"/>
<source>Ctrl+L</source>
<translation type="unfinished">Ctrl+L</translation>
<translation>Ctrl+L</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="64"/>
<source>F11</source>
<translation type="unfinished">F11</translation>
<translation>F11</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="65"/>
<source>F12</source>
<translation type="unfinished">F12</translation>
<translation>F12</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>Set counter</source>
<translation type="unfinished">Definir marcador</translation>
<translation>Definir marcador</translation>
</message>
<message>
<location filename="../src/abstractcounter.cpp" line="122"/>
<source>New value for counter &apos;%1&apos;:</source>
<translation type="unfinished">Novo valor para o marcador &apos;%1&apos;:</translation>
<translation>Novo valor para o marcador &apos;%1&apos;:</translation>
</message>
</context>
<context>
@ -176,7 +176,7 @@
<message>
<location filename="../src/carditem.cpp" line="176"/>
<source>&amp;Hide</source>
<translation type="unfinished"></translation>
<translation>Esco&amp;nder</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="178"/>
@ -550,7 +550,7 @@
<message>
<location filename="../src/tab_game.cpp" line="86"/>
<source>Ready to s&amp;tart</source>
<translation>Pronto para &amp;começar</translation>
<translation>&amp;Pronto para começar</translation>
</message>
<message>
<location filename="../src/tab_game.cpp" line="98"/>
@ -1130,12 +1130,12 @@
<message>
<location filename="../src/window_main.cpp" line="162"/>
<source>Portugese (Portugal):</source>
<translation type="unfinished"></translation>
<translation>Português (Portugal):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="163"/>
<source>Portugese (Brazil):</source>
<translation type="unfinished"></translation>
<translation>Português (Brasil):</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="164"/>
@ -1145,7 +1145,7 @@
<message>
<location filename="../src/window_main.cpp" line="165"/>
<source>Japanese:</source>
<translation type="unfinished"></translation>
<translation>Japonês:</translation>
</message>
<message>
<location filename="../src/window_main.cpp" line="171"/>
@ -2232,37 +2232,37 @@
<message>
<location filename="../src/tab_admin.cpp" line="40"/>
<source>Update server &amp;message</source>
<translation type="unfinished"></translation>
<translation>&amp;Actualizar mensagem do servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="41"/>
<source>Server administration functions</source>
<translation type="unfinished"></translation>
<translation>Funções do administrador do servidor</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="43"/>
<source>&amp;Unlock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Desbloquear funções</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="44"/>
<source>&amp;Lock functions</source>
<translation type="unfinished"></translation>
<translation>&amp;Bloquear funções</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Unlock administration functions</source>
<translation type="unfinished"></translation>
<translation>Desbloquear funções de administração</translation>
</message>
<message>
<location filename="../src/tab_admin.cpp" line="54"/>
<source>Do you really want to unlock the administration functions?</source>
<translation type="unfinished"></translation>
<translation>Quer mesmo desbloquear as funçõesde administração?</translation>
</message>
<message>
<location filename="../src/tab_admin.h" line="26"/>
<source>Administration</source>
<translation type="unfinished"></translation>
<translation>Administração</translation>
</message>
</context>
<context>
@ -2509,12 +2509,12 @@ Por favor introduza um nome:</translation>
<message>
<location filename="../src/userinfobox.cpp" line="38"/>
<source>User information</source>
<translation type="unfinished"></translation>
<translation>Informação do utilizador</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="45"/>
<source>Real name:</source>
<translation type="unfinished"></translation>
<translation>Nome real:</translation>
</message>
<message>
<location filename="../src/userinfobox.cpp" line="46"/>
@ -2585,12 +2585,12 @@ Por favor introduza um nome:</translation>
<message>
<location filename="../src/userlist.cpp" line="119"/>
<source>User &amp;details</source>
<translation type="unfinished"></translation>
<translation>Detalhes do &amp;utilizador</translation>
</message>
<message>
<location filename="../src/userlist.cpp" line="120"/>
<source>Direct &amp;chat</source>
<translation type="unfinished"></translation>
<translation>Conversação &amp;directa</translation>
</message>
</context>
<context>

View file

@ -468,6 +468,24 @@ void DeckList::cleanList()
setComments();
}
void DeckList::getCardListHelper(InnerDecklistNode *item, QSet<QString> &result) const
{
for (int i = 0; i < item->size(); ++i) {
DecklistCardNode *node = dynamic_cast<DecklistCardNode *>(item->at(i));
if (node)
result.insert(node->getName());
else
getCardListHelper(dynamic_cast<InnerDecklistNode *>(item->at(i)), result);
}
}
QStringList DeckList::getCardList() const
{
QSet<QString> result;
getCardListHelper(root, result);
return result.toList();
}
DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName)
{
InnerDecklistNode *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));

View file

@ -6,6 +6,7 @@
#include <QPair>
#include <QObject>
#include <QStringList>
#include <QSet>
#include "serializable_item.h"
class CardDatabase;
@ -115,6 +116,7 @@ private:
InnerDecklistNode *currentZone;
SideboardPlan *currentSideboardPlan;
QString currentElementText;
void getCardListHelper(InnerDecklistNode *node, QSet<QString> &result) const;
signals:
void deckLoaded();
public slots:
@ -149,6 +151,7 @@ public:
void cleanList();
bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); }
QStringList getCardList() const;
InnerDecklistNode *getRoot() const { return root; }
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);

View file

@ -1,157 +0,0 @@
1. Abstract
The Cockatrice protocol is a client/server protocol intended for communication between
a card game client and a suitable server. It is designed with the goal in mind to make
playing card games, such as Magic the Gathering, over a network easy while eliminating
the possibility of unfair play. Because of that, the server stores all hidden information
and transmits pieces of it to clients only when necessary.
2. Protocol structure
All communication is done over a TCP/IP connection. The protocol is text based.
Strings are encoded in UTF-8 and have UNIX-style line endings (\n).
There are four distinct types of messages:
- Command (section 3)
- Response (section 4)
- Event (section 5)
- List (section 6)
3. Commands
A command can only be sent from client to server and has the following structure:
{ID}|{command}|{parameter1}|{parameter2}...
"ID" is an arbitrary number to be chosen uniquely for each command.
"command" is a command identifier (see section 3).
It depends on the command identifier what has to be passed as parameters.
3.1 ping
Flags:
none
Parameters:
none
Valid response codes:
ok
No effect.
3.2 login
Flags:
none
Parameters:
User name (string)
Password (string)
Valid response codes:
ok
password
If the supplied credentials are correct, "ok" is returned and the connection state
is set to authenticated. (The server is not required to actually check the validity
of the credentials.)
Otherwise, "password" is returned.
3.3 list_games
Flags:
login needed
Parameters:
none
Valid response codes:
ok
If the connection state is unauthenticated, "login_needed" is returned.
Otherwise, "ok" is returned and for each game currently, a list_games event XXX is
sent to the client. The "accepts game list changes" flag of the connection is set.
3.4 create_game
Flags:
login needed
Parameters:
Description (string)
Password (string)
Number of players (int)
Valid response codes:
ok
A game with the given parameters is created. The client is set as creator of the
game and joins it automatically. The "accepts game list changes" flag of the connection
is unset.
3.5 join_game
Flags:
login needed
Parameters:
Game ID (int)
Password (string)
Valid response codes:
ok
password
If the password for the given game is correct, the client leaves the current game
(if any) and joins the given game. The "accepts game list changes" flag of the connection
is unset.
3.6 leave_game
Flags:
login needed
game needed
Parameters:
none
Valid response codes:
ok
The client leaves the current game.
3.7 list_players
Flags:
login needed
game needed
Parameters:
none
3.8 say
3.9 submit_deck
3.10 ready_start
3.11 shuffle
3.12 draw_cards
3.13 reveal_card
3.14 move_card
3.15 create_token
3.16 set_card_attr
3.17 inc_counter
3.18 add_counter
3.19 set_counter
3.20 del_counter
3.21 list_counters
3.22 list_zones
3.23 dump_zone
3.24 roll_dice
3.25 set_active_player
3.26 set_active_phase
4. Responses
After processing any command, the server sends a response to the client, indicating
whether the command was understood and valid.
A response can only be sent from server to client and has the following structure:
resp|{ID}|{resp-code}
{ID} is the identifier belonging to the command in question.
{resp-code} contains information about the processing of the command. It can have the
following values:
ok (Success)
login_needed (Error: Command requires login)
syntax (Error: Invalid command or parameters)
context (Error: Command cannot be applied here)
password (Error: Wrong login data)
The response code "syntax" is valid as a response to any command and is
hence not explicitly listed in section 3. The response code "login_needed" applies
to all commands with the "login needed" flag.