diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro
index 61a98550..d3e826a9 100644
--- a/cockatrice/cockatrice.pro
+++ b/cockatrice/cockatrice.pro
@@ -7,7 +7,8 @@ OBJECTS_DIR = build
RESOURCES = cockatrice.qrc
QT += network svg
-HEADERS += src/counter.h \
+HEADERS += src/abstractcounter.h \
+ src/counter_general.h \
src/dlg_creategame.h \
src/dlg_connect.h \
src/dlg_create_token.h \
@@ -16,6 +17,7 @@ HEADERS += src/counter.h \
src/remoteclient.h \
src/window_main.h \
src/cardzone.h \
+ src/selectzone.h \
src/player.h \
src/playertarget.h \
src/cardlist.h \
@@ -51,11 +53,14 @@ HEADERS += src/counter.h \
src/arrowtarget.h \
src/tab.h \
src/tab_server.h \
- src/tab_chatchannel.h \
+ src/tab_room.h \
src/tab_message.h \
src/tab_game.h \
src/tab_deck_storage.h \
src/tab_supervisor.h \
+ src/tab_admin.h \
+ src/userlist.h \
+ src/userinfobox.h \
src/remotedecklist_treewidget.h \
src/deckview.h \
src/playerlistwidget.h \
@@ -77,14 +82,15 @@ HEADERS += src/counter.h \
../common/server_arrow.h \
../common/server_card.h \
../common/server_cardzone.h \
- ../common/server_chatchannel.h \
+ ../common/server_room.h \
../common/server_counter.h \
../common/server_game.h \
../common/server_player.h \
../common/server_protocolhandler.h \
../common/server_arrowtarget.h
-SOURCES += src/counter.cpp \
+SOURCES += src/abstractcounter.cpp \
+ src/counter_general.cpp \
src/dlg_creategame.cpp \
src/dlg_connect.cpp \
src/dlg_create_token.cpp \
@@ -96,6 +102,7 @@ SOURCES += src/counter.cpp \
src/player.cpp \
src/playertarget.cpp \
src/cardzone.cpp \
+ src/selectzone.cpp \
src/cardlist.cpp \
src/abstractcarditem.cpp \
src/carditem.cpp \
@@ -128,11 +135,14 @@ SOURCES += src/counter.cpp \
src/arrowitem.cpp \
src/arrowtarget.cpp \
src/tab_server.cpp \
- src/tab_chatchannel.cpp \
+ src/tab_room.cpp \
src/tab_message.cpp \
src/tab_game.cpp \
src/tab_deck_storage.cpp \
src/tab_supervisor.cpp \
+ src/tab_admin.cpp \
+ src/userlist.cpp \
+ src/userinfobox.cpp \
src/remotedecklist_treewidget.cpp \
src/deckview.cpp \
src/playerlistwidget.cpp \
@@ -152,7 +162,7 @@ SOURCES += src/counter.cpp \
../common/server.cpp \
../common/server_card.cpp \
../common/server_cardzone.cpp \
- ../common/server_chatchannel.cpp \
+ ../common/server_room.cpp \
../common/server_game.cpp \
../common/server_player.cpp \
../common/server_protocolhandler.cpp
@@ -162,7 +172,9 @@ TRANSLATIONS += \
translations/cockatrice_en.ts \
translations/cockatrice_es.ts \
translations/cockatrice_pt.ts \
- translations/cockatrice_fr.ts
+ translations/cockatrice_pt-br.ts \
+ translations/cockatrice_fr.ts \
+ translations/cockatrice_jp.ts
win32 {
RC_FILE = cockatrice.rc
}
diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 1391fc83..bea7ad2c 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -28,7 +28,9 @@
translations/cockatrice_en.qm
translations/cockatrice_es.qm
translations/cockatrice_pt.qm
+ translations/cockatrice_pt-br.qm
translations/cockatrice_fr.qm
+ translations/cockatrice_jp.qm
resources/appicon.svg
resources/add_to_sideboard.svg
resources/decrement.svg
@@ -63,6 +65,7 @@
resources/countries/mx.svg
resources/countries/nl.svg
resources/countries/no.svg
+ resources/countries/ph.svg
resources/countries/pl.svg
resources/countries/pt.svg
resources/countries/ru.svg
diff --git a/cockatrice/resources/countries/br.svg b/cockatrice/resources/countries/br.svg
index 213c362f..a50a00bc 100644
--- a/cockatrice/resources/countries/br.svg
+++ b/cockatrice/resources/countries/br.svg
@@ -1,112 +1,47 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/ph.svg b/cockatrice/resources/countries/ph.svg
new file mode 100644
index 00000000..48752391
--- /dev/null
+++ b/cockatrice/resources/countries/ph.svg
@@ -0,0 +1,77 @@
+
+
+
+
diff --git a/cockatrice/src/abstractcarddragitem.h b/cockatrice/src/abstractcarddragitem.h
index 62f36436..047c4f55 100644
--- a/cockatrice/src/abstractcarddragitem.h
+++ b/cockatrice/src/abstractcarddragitem.h
@@ -20,6 +20,7 @@ public:
~AbstractCardDragItem();
QRectF boundingRect() const { return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT); }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ AbstractCardItem *getItem() const { return item; }
QPointF getHotSpot() const { return hotSpot; }
void addChildDrag(AbstractCardDragItem *child);
virtual void updatePosition(const QPointF &cursorScenePos) = 0;
diff --git a/cockatrice/src/abstractcarditem.h b/cockatrice/src/abstractcarditem.h
index 0f592d31..c07b78a0 100644
--- a/cockatrice/src/abstractcarditem.h
+++ b/cockatrice/src/abstractcarditem.h
@@ -11,7 +11,7 @@ class QTimer;
const int CARD_WIDTH = 72;
const int CARD_HEIGHT = 102;
-class AbstractCardItem : public QObject, public ArrowTarget {
+class AbstractCardItem : public ArrowTarget {
Q_OBJECT
protected:
CardInfo *info;
diff --git a/cockatrice/src/abstractclient.cpp b/cockatrice/src/abstractclient.cpp
index 924c9617..627f6ed6 100644
--- a/cockatrice/src/abstractclient.cpp
+++ b/cockatrice/src/abstractclient.cpp
@@ -32,11 +32,10 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
GenericEvent *genericEvent = qobject_cast(item);
if (genericEvent) {
switch (genericEvent->getItemId()) {
- case ItemId_Event_ListGames: emit listGamesEventReceived(qobject_cast(item)); break;
case ItemId_Event_UserJoined: emit userJoinedEventReceived(qobject_cast(item)); break;
case ItemId_Event_UserLeft: emit userLeftEventReceived(qobject_cast(item)); break;
case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast(item)); break;
- case ItemId_Event_ListChatChannels: emit listChatChannelsEventReceived(qobject_cast(item)); break;
+ case ItemId_Event_ListRooms: emit listRoomsEventReceived(qobject_cast(item)); break;
case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast(item)); break;
case ItemId_Event_Message: emit messageEventReceived(qobject_cast(item)); break;
}
@@ -53,11 +52,11 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
return;
}
- ChatEvent *chatEvent = qobject_cast(item);
- if (chatEvent) {
- emit chatEventReceived(chatEvent);
- if (chatEvent->getReceiverMayDelete())
- delete chatEvent;
+ RoomEvent *roomEvent = qobject_cast(item);
+ if (roomEvent) {
+ emit roomEventReceived(roomEvent);
+ if (roomEvent->getReceiverMayDelete())
+ delete roomEvent;
return;
}
}
@@ -75,4 +74,3 @@ void AbstractClient::sendCommand(Command *cmd)
{
sendCommandContainer(new CommandContainer(QList() << cmd));
}
-
diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h
index 601e55db..dae91752 100644
--- a/cockatrice/src/abstractclient.h
+++ b/cockatrice/src/abstractclient.h
@@ -10,13 +10,13 @@ class ProtocolItem;
class ProtocolResponse;
class TopLevelProtocolItem;
class CommandContainer;
-class ChatEvent;
+class RoomEvent;
class GameEventContainer;
class Event_ListGames;
class Event_UserJoined;
class Event_UserLeft;
class Event_ServerMessage;
-class Event_ListChatChannels;
+class Event_ListRooms;
class Event_GameJoined;
class Event_Message;
@@ -35,18 +35,18 @@ signals:
void statusChanged(ClientStatus _status);
void serverError(ResponseCode resp);
- // Chat events
- void chatEventReceived(ChatEvent *event);
+ // Room events
+ void roomEventReceived(RoomEvent *event);
// Game events
void gameEventContainerReceived(GameEventContainer *event);
// Generic events
- void listGamesEventReceived(Event_ListGames *event);
void userJoinedEventReceived(Event_UserJoined *event);
void userLeftEventReceived(Event_UserLeft *event);
void serverMessageEventReceived(Event_ServerMessage *event);
- void listChatChannelsEventReceived(Event_ListChatChannels *event);
+ void listRoomsEventReceived(Event_ListRooms *event);
void gameJoinedEventReceived(Event_GameJoined *event);
void messageEventReceived(Event_Message *event);
+ void userInfoChanged(ServerInfo_User *userInfo);
protected slots:
void processProtocolItem(ProtocolItem *item);
protected:
diff --git a/cockatrice/src/counter.cpp b/cockatrice/src/abstractcounter.cpp
similarity index 66%
rename from cockatrice/src/counter.cpp
rename to cockatrice/src/abstractcounter.cpp
index ee6d060a..aed566c8 100644
--- a/cockatrice/src/counter.cpp
+++ b/cockatrice/src/abstractcounter.cpp
@@ -1,16 +1,17 @@
-#include "counter.h"
+#include "abstractcounter.h"
#include "player.h"
#include "protocol_items.h"
#include
#include
#include
#include
+#include
-Counter::Counter(Player *_player, int _id, const QString &_name, QColor _color, int _radius, int _value, QGraphicsItem *parent)
- : QGraphicsItem(parent), player(_player), id(_id), name(_name), color(_color), radius(_radius), value(_value), aDec(0), aInc(0), dialogSemaphore(false), deleteAfterDialog(false)
+AbstractCounter::AbstractCounter(Player *_player, int _id, const QString &_name, bool _shownInCounterArea, int _value, QGraphicsItem *parent)
+ : QGraphicsItem(parent), player(_player), id(_id), name(_name), value(_value), hovered(false), aDec(0), aInc(0), dialogSemaphore(false), deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea)
{
- if (radius > Player::counterAreaWidth / 2)
- radius = Player::counterAreaWidth / 2;
+ setAcceptsHoverEvents(true);
+
if (player->getLocal()) {
menu = new QMenu(name);
aSet = new QAction(this);
@@ -36,12 +37,12 @@ Counter::Counter(Player *_player, int _id, const QString &_name, QColor _color,
retranslateUi();
}
-Counter::~Counter()
+AbstractCounter::~AbstractCounter()
{
delete menu;
}
-void Counter::delCounter()
+void AbstractCounter::delCounter()
{
if (dialogSemaphore)
deleteAfterDialog = true;
@@ -49,14 +50,14 @@ void Counter::delCounter()
deleteLater();
}
-void Counter::retranslateUi()
+void AbstractCounter::retranslateUi()
{
if (menu) {
aSet->setText(tr("&Set counter..."));
}
}
-void Counter::setShortcutsActive()
+void AbstractCounter::setShortcutsActive()
{
if (name == "life") {
aSet->setShortcut(tr("Ctrl+L"));
@@ -65,7 +66,7 @@ void Counter::setShortcutsActive()
}
}
-void Counter::setShortcutsInactive()
+void AbstractCounter::setShortcutsInactive()
{
if (name == "life") {
aSet->setShortcut(QKeySequence());
@@ -74,31 +75,13 @@ void Counter::setShortcutsInactive()
}
}
-QRectF Counter::boundingRect() const
-{
- return QRectF(0, 0, radius * 2, radius * 2);
-}
-
-void Counter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
-{
- painter->setBrush(QBrush(color));
- painter->drawEllipse(boundingRect());
- if (value) {
- QFont f("Serif");
- f.setPixelSize(radius * 0.8);
- f.setWeight(QFont::Bold);
- painter->setFont(f);
- painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(value));
- }
-}
-
-void Counter::setValue(int _value)
+void AbstractCounter::setValue(int _value)
{
value = _value;
update();
}
-void Counter::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void AbstractCounter::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
player->sendGameCommand(new Command_IncCounter(-1, id, 1));
@@ -114,13 +97,25 @@ void Counter::mousePressEvent(QGraphicsSceneMouseEvent *event)
event->ignore();
}
-void Counter::incrementCounter()
+void AbstractCounter::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ hovered = true;
+ update();
+}
+
+void AbstractCounter::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ hovered = false;
+ update();
+}
+
+void AbstractCounter::incrementCounter()
{
int delta = static_cast(sender())->data().toInt();
player->sendGameCommand(new Command_IncCounter(-1, id, delta));
}
-void Counter::setCounter()
+void AbstractCounter::setCounter()
{
bool ok;
dialogSemaphore = true;
diff --git a/cockatrice/src/counter.h b/cockatrice/src/abstractcounter.h
similarity index 61%
rename from cockatrice/src/counter.h
rename to cockatrice/src/abstractcounter.h
index 7d7f932b..6a4a4188 100644
--- a/cockatrice/src/counter.h
+++ b/cockatrice/src/abstractcounter.h
@@ -7,35 +7,36 @@ class Player;
class QMenu;
class QAction;
-class Counter : public QObject, public QGraphicsItem {
+class AbstractCounter : public QObject, public QGraphicsItem {
Q_OBJECT
-private:
+protected:
Player *player;
int id;
QString name;
- QColor color;
- int radius;
int value;
+ bool hovered;
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+private:
QAction *aSet, *aDec, *aInc;
QMenu *menu;
bool dialogSemaphore, deleteAfterDialog;
+ bool shownInCounterArea;
private slots:
void incrementCounter();
void setCounter();
-protected:
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
public:
- Counter(Player *_player, int _id, const QString &_name, QColor _color, int _radius, int _value, QGraphicsItem *parent = 0);
- ~Counter();
- QRectF boundingRect() const;
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ AbstractCounter(Player *_player, int _id, const QString &_name, bool _shownInCounterArea, int _value, QGraphicsItem *parent = 0);
+ ~AbstractCounter();
QMenu *getMenu() const { return menu; }
void retranslateUi();
int getId() const { return id; }
QString getName() const { return name; }
+ bool getShownInCounterArea() const { return shownInCounterArea; }
int getValue() const { return value; }
void setValue(int _value);
void delCounter();
diff --git a/cockatrice/src/abstractgraphicsitem.h b/cockatrice/src/abstractgraphicsitem.h
index ff13ff4f..2bb094d3 100644
--- a/cockatrice/src/abstractgraphicsitem.h
+++ b/cockatrice/src/abstractgraphicsitem.h
@@ -12,11 +12,12 @@ enum GraphicsItemType {
typeOther = QGraphicsItem::UserType + 6
};
-class AbstractGraphicsItem : public QGraphicsItem {
+class AbstractGraphicsItem : public QObject, public QGraphicsItem {
+ Q_OBJECT
protected:
void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter);
public:
- AbstractGraphicsItem(QGraphicsItem *parent = 0) : QGraphicsItem(parent) { }
+ AbstractGraphicsItem(QGraphicsItem *parent = 0) : QObject(), QGraphicsItem(parent) { }
};
#endif
diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp
index 146b0d1b..1dc1bf2f 100644
--- a/cockatrice/src/arrowitem.cpp
+++ b/cockatrice/src/arrowitem.cpp
@@ -13,7 +13,7 @@
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
: QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true)
{
- qDebug() << "ArrowItem constructor: startItem=" << startItem;
+ qDebug() << "ArrowItem constructor: startItem=" << static_cast(startItem);
setZValue(2000000005);
if (startItem)
@@ -154,7 +154,7 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QList colliding = scene()->items(endPos);
ArrowTarget *cursorItem = 0;
- int cursorItemZ = -1;
+ qreal cursorItemZ = -1;
for (int i = colliding.size() - 1; i >= 0; i--)
if (qgraphicsitem_cast(colliding.at(i)) || qgraphicsitem_cast(colliding.at(i)))
if (colliding.at(i)->zValue() > cursorItemZ) {
@@ -243,11 +243,14 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QList colliding = scene()->items(endPos);
ArrowTarget *cursorItem = 0;
+ qreal cursorItemZ = -1;
for (int i = colliding.size() - 1; i >= 0; i--)
- if (qgraphicsitem_cast(colliding.at(i))) {
- cursorItem = static_cast(colliding.at(i));
- break;
- }
+ if (qgraphicsitem_cast(colliding.at(i)))
+ if (colliding.at(i)->zValue() > cursorItemZ) {
+ cursorItem = static_cast(colliding.at(i));
+ cursorItemZ = cursorItem->zValue();
+ }
+
if ((cursorItem != targetItem) && targetItem)
targetItem->setBeingPointedAt(false);
if (!cursorItem) {
diff --git a/cockatrice/src/carddragitem.cpp b/cockatrice/src/carddragitem.cpp
index 5375bae0..56d6c2c6 100644
--- a/cockatrice/src/carddragitem.cpp
+++ b/cockatrice/src/carddragitem.cpp
@@ -72,17 +72,18 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
QPointF sp = pos();
sc->removeItem(this);
+ QList dragItemList;
CardZone *startZone = static_cast(item)->getZone();
if (currentZone && !(static_cast(item)->getAttachedTo() && (startZone == currentZone))) {
- if (!occupied)
- currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown);
+ dragItemList.append(this);
for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast(childDrags[i]);
if (!(static_cast(c->item)->getAttachedTo() && (startZone == currentZone)) && !c->occupied)
- currentZone->handleDropEvent(c->id, startZone, (sp - currentZone->scenePos() + c->getHotSpot()).toPoint(), faceDown);
+ dragItemList.append(c);
sc->removeItem(c);
}
}
+ currentZone->handleDropEvent(dragItemList, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown);
event->accept();
}
diff --git a/cockatrice/src/carddragitem.h b/cockatrice/src/carddragitem.h
index 82f1d66a..95cc71ce 100644
--- a/cockatrice/src/carddragitem.h
+++ b/cockatrice/src/carddragitem.h
@@ -13,6 +13,7 @@ private:
CardZone *currentZone;
public:
CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0);
+ int getId() const { return id; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void updatePosition(const QPointF &cursorScenePos);
protected:
diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp
index c3da70d8..5bd4d655 100644
--- a/cockatrice/src/carditem.cpp
+++ b/cockatrice/src/carditem.cpp
@@ -16,92 +16,71 @@
#include "settingscache.h"
#include "tab_game.h"
-CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, QGraphicsItem *parent)
- : AbstractCardItem(_name, _owner, parent), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0)
+CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, bool _revealedCard, QGraphicsItem *parent)
+ : AbstractCardItem(_name, _owner, parent), zone(0), id(_cardid), revealedCard(_revealedCard), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0)
{
owner->addCard(this);
- if (owner->getLocal()) {
- aTap = new QAction(this);
- aTap->setData(0);
- connect(aTap, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- aUntap = new QAction(this);
- aUntap->setData(1);
- connect(aUntap, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- aDoesntUntap = new QAction(this);
- aDoesntUntap->setData(2);
- connect(aDoesntUntap, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- aAttach = new QAction(this);
- connect(aAttach, SIGNAL(triggered()), owner, SLOT(actAttach()));
- aUnattach = new QAction(this);
- connect(aUnattach, SIGNAL(triggered()), owner, SLOT(actUnattach()));
- aSetPT = new QAction(this);
- connect(aSetPT, SIGNAL(triggered()), owner, SLOT(actSetPT()));
- aSetAnnotation = new QAction(this);
- connect(aSetAnnotation, SIGNAL(triggered()), owner, SLOT(actSetAnnotation()));
- aFlip = new QAction(this);
- aFlip->setData(3);
- connect(aFlip, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- aClone = new QAction(this);
- aClone->setData(4);
- connect(aClone, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- aMoveToTopLibrary = new QAction(this);
- aMoveToTopLibrary->setData(5);
- aMoveToBottomLibrary = new QAction(this);
- aMoveToBottomLibrary->setData(6);
- aMoveToGraveyard = new QAction(this);
- aMoveToGraveyard->setData(7);
- aMoveToExile = new QAction(this);
- aMoveToExile->setData(8);
- connect(aMoveToTopLibrary, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- connect(aMoveToBottomLibrary, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- connect(aMoveToGraveyard, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
- connect(aMoveToExile, SIGNAL(triggered()), owner, SLOT(cardMenuAction()));
+ aTap = new QAction(this);
+ aTap->setData(0);
+ connect(aTap, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ aUntap = new QAction(this);
+ aUntap->setData(1);
+ connect(aUntap, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ aDoesntUntap = new QAction(this);
+ aDoesntUntap->setData(2);
+ connect(aDoesntUntap, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ aAttach = new QAction(this);
+ connect(aAttach, SIGNAL(triggered()), this, SLOT(actAttach()));
+ aUnattach = new QAction(this);
+ connect(aUnattach, SIGNAL(triggered()), this, SLOT(actUnattach()));
+ aSetPT = new QAction(this);
+ connect(aSetPT, SIGNAL(triggered()), this, SLOT(actSetPT()));
+ aSetAnnotation = new QAction(this);
+ connect(aSetAnnotation, SIGNAL(triggered()), this, SLOT(actSetAnnotation()));
+ aFlip = new QAction(this);
+ aFlip->setData(3);
+ connect(aFlip, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ aClone = new QAction(this);
+ aClone->setData(4);
+ connect(aClone, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ aMoveToTopLibrary = new QAction(this);
+ aMoveToTopLibrary->setData(5);
+ aMoveToBottomLibrary = new QAction(this);
+ aMoveToBottomLibrary->setData(6);
+ aMoveToGraveyard = new QAction(this);
+ aMoveToGraveyard->setData(7);
+ aMoveToExile = new QAction(this);
+ aMoveToExile->setData(8);
+ connect(aMoveToTopLibrary, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ connect(aMoveToBottomLibrary, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ connect(aMoveToGraveyard, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+ connect(aMoveToExile, SIGNAL(triggered()), this, SLOT(cardMenuAction()));
+
+ aPlay = new QAction(this);
+ connect(aPlay, SIGNAL(triggered()), this, SLOT(actPlay()));
+ aHide = new QAction(this);
+ connect(aHide, SIGNAL(triggered()), this, SLOT(actHide()));
- cardMenu = new QMenu;
- cardMenu->addAction(aTap);
- cardMenu->addAction(aUntap);
- cardMenu->addAction(aDoesntUntap);
- cardMenu->addAction(aFlip);
- cardMenu->addSeparator();
- cardMenu->addAction(aAttach);
- cardMenu->addAction(aUnattach);
- cardMenu->addSeparator();
- cardMenu->addAction(aSetPT);
- cardMenu->addAction(aSetAnnotation);
- cardMenu->addSeparator();
- cardMenu->addAction(aClone);
- for (int i = 0; i < 3; ++i) {
- QAction *tempAddCounter = new QAction(this);
- tempAddCounter->setData(9 + i * 1000);
- QAction *tempRemoveCounter = new QAction(this);
- tempRemoveCounter->setData(10 + i * 1000);
- QAction *tempSetCounter = new QAction(this);
- tempSetCounter->setData(11 + i * 1000);
- aAddCounter.append(tempAddCounter);
- aRemoveCounter.append(tempRemoveCounter);
- aSetCounter.append(tempSetCounter);
- connect(tempAddCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger()));
- connect(tempRemoveCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger()));
- connect(tempSetCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger()));
-
- cardMenu->addSeparator();
- cardMenu->addAction(tempAddCounter);
- cardMenu->addAction(tempRemoveCounter);
- cardMenu->addAction(tempSetCounter);
- }
- cardMenu->addSeparator();
-
- moveMenu = cardMenu->addMenu(QString());
- moveMenu->addAction(aMoveToTopLibrary);
- moveMenu->addAction(aMoveToBottomLibrary);
- moveMenu->addAction(aMoveToGraveyard);
- moveMenu->addAction(aMoveToExile);
-
-
- retranslateUi();
- } else
- cardMenu = 0;
+ for (int i = 0; i < 3; ++i) {
+ QAction *tempAddCounter = new QAction(this);
+ tempAddCounter->setData(9 + i * 1000);
+ QAction *tempRemoveCounter = new QAction(this);
+ tempRemoveCounter->setData(10 + i * 1000);
+ QAction *tempSetCounter = new QAction(this);
+ tempSetCounter->setData(11 + i * 1000);
+ aAddCounter.append(tempAddCounter);
+ aRemoveCounter.append(tempRemoveCounter);
+ aSetCounter.append(tempSetCounter);
+ connect(tempAddCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger()));
+ connect(tempRemoveCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger()));
+ connect(tempSetCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger()));
+ }
+ cardMenu = new QMenu;
+ moveMenu = new QMenu;
+
+ retranslateUi();
+ updateCardMenu();
}
CardItem::~CardItem()
@@ -110,6 +89,8 @@ CardItem::~CardItem()
delete cardMenu;
cardMenu = 0;
+ delete moveMenu;
+ moveMenu = 0;
deleteDragItem();
}
@@ -139,37 +120,88 @@ void CardItem::deleteLater()
AbstractCardItem::deleteLater();
}
+void CardItem::setZone(CardZone *_zone)
+{
+ zone = _zone;
+ updateCardMenu();
+}
+
+void CardItem::updateCardMenu()
+{
+ cardMenu->clear();
+
+ if (revealedCard)
+ cardMenu->addAction(aHide);
+ else if (owner->getLocal()) {
+ if (zone) {
+ if (zone->getName() == "table") {
+ cardMenu->addAction(aTap);
+ cardMenu->addAction(aUntap);
+ cardMenu->addAction(aDoesntUntap);
+ cardMenu->addAction(aFlip);
+ cardMenu->addSeparator();
+ cardMenu->addAction(aAttach);
+ if (attachedTo)
+ cardMenu->addAction(aUnattach);
+ cardMenu->addSeparator();
+ cardMenu->addAction(aSetPT);
+ cardMenu->addAction(aSetAnnotation);
+ cardMenu->addSeparator();
+ cardMenu->addAction(aClone);
+
+ for (int i = 0; i < aAddCounter.size(); ++i) {
+ cardMenu->addSeparator();
+ cardMenu->addAction(aAddCounter[i]);
+ cardMenu->addAction(aRemoveCounter[i]);
+ cardMenu->addAction(aSetCounter[i]);
+ }
+ cardMenu->addSeparator();
+ } else {
+ cardMenu->addAction(aPlay);
+ }
+ }
+
+ moveMenu->clear();
+ moveMenu->addAction(aMoveToTopLibrary);
+ moveMenu->addAction(aMoveToBottomLibrary);
+ moveMenu->addAction(aMoveToGraveyard);
+ moveMenu->addAction(aMoveToExile);
+ cardMenu->addMenu(moveMenu);
+ }
+}
+
void CardItem::retranslateUi()
{
- if (owner->getLocal()) {
- aTap->setText(tr("&Tap"));
- aUntap->setText(tr("&Untap"));
- aDoesntUntap->setText(tr("Toggle &normal untapping"));
- aFlip->setText(tr("&Flip"));
- aClone->setText(tr("&Clone"));
- aAttach->setText(tr("&Attach to card..."));
- aAttach->setShortcut(tr("Ctrl+A"));
- aUnattach->setText(tr("Unattac&h"));
- aSetPT->setText(tr("Set &P/T..."));
- aSetAnnotation->setText(tr("&Set annotation..."));
- QStringList counterColors;
- counterColors.append(tr("red"));
- counterColors.append(tr("yellow"));
- counterColors.append(tr("green"));
- for (int i = 0; i < aAddCounter.size(); ++i)
- aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i]));
- for (int i = 0; i < aRemoveCounter.size(); ++i)
- aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i]));
- for (int i = 0; i < aSetCounter.size(); ++i)
- aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i]));
- aMoveToTopLibrary->setText(tr("&top of library"));
- aMoveToBottomLibrary->setText(tr("&bottom of library"));
- aMoveToGraveyard->setText(tr("&graveyard"));
- aMoveToGraveyard->setShortcut(tr("Ctrl+Del"));
- aMoveToExile->setText(tr("&exile"));
-
- moveMenu->setTitle(tr("&Move to"));
- }
+ aPlay->setText(tr("&Play"));
+ aHide->setText(tr("&Hide"));
+
+ aTap->setText(tr("&Tap"));
+ aUntap->setText(tr("&Untap"));
+ aDoesntUntap->setText(tr("Toggle &normal untapping"));
+ aFlip->setText(tr("&Flip"));
+ aClone->setText(tr("&Clone"));
+ aAttach->setText(tr("&Attach to card..."));
+ aAttach->setShortcut(tr("Ctrl+A"));
+ aUnattach->setText(tr("Unattac&h"));
+ aSetPT->setText(tr("Set &P/T..."));
+ aSetAnnotation->setText(tr("&Set annotation..."));
+ QStringList counterColors;
+ counterColors.append(tr("red"));
+ counterColors.append(tr("yellow"));
+ counterColors.append(tr("green"));
+ for (int i = 0; i < aAddCounter.size(); ++i)
+ aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i]));
+ for (int i = 0; i < aRemoveCounter.size(); ++i)
+ aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i]));
+ for (int i = 0; i < aSetCounter.size(); ++i)
+ aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i]));
+ aMoveToTopLibrary->setText(tr("&top of library"));
+ aMoveToBottomLibrary->setText(tr("&bottom of library"));
+ aMoveToGraveyard->setText(tr("&graveyard"));
+ aMoveToGraveyard->setShortcut(tr("Ctrl+Del"));
+ aMoveToExile->setText(tr("&exile"));
+
+ moveMenu->setTitle(tr("&Move to"));
}
void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -263,6 +295,8 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
if (zone)
zone->reorganizeCards();
+
+ updateCardMenu();
}
void CardItem::resetState()
@@ -376,7 +410,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
setCursor(Qt::OpenHandCursor);
}
-void CardItem::playCard(QGraphicsSceneMouseEvent *event)
+void CardItem::playCard(bool faceDown)
{
// Do nothing if the card belongs to another player
if (!owner->getLocal())
@@ -385,22 +419,22 @@ void CardItem::playCard(QGraphicsSceneMouseEvent *event)
TableZone *tz = qobject_cast(zone);
if (tz)
tz->toggleTapped();
- else {
- bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier);
- bool tapped = info->getCipt();
-
- zone->getPlayer()->playCard(this, faceDown, tapped);
- }
+ else
+ zone->getPlayer()->playCard(this, faceDown, info->getCipt());
}
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::RightButton) {
if (cardMenu)
- cardMenu->exec(event->screenPos());
+ if (!cardMenu->isEmpty())
+ cardMenu->exec(event->screenPos());
} else if ((event->button() == Qt::LeftButton) && !settingsCache->getDoubleClickToPlay()) {
setCursor(Qt::OpenHandCursor);
- playCard(event);
+ if (revealedCard)
+ actHide();
+ else
+ playCard(event->modifiers().testFlag(Qt::ShiftModifier));
}
AbstractCardItem::mouseReleaseEvent(event);
@@ -408,14 +442,18 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
- if (settingsCache->getDoubleClickToPlay())
- playCard(event);
+ if (settingsCache->getDoubleClickToPlay()) {
+ if (revealedCard)
+ actHide();
+ else
+ playCard(event->modifiers().testFlag(Qt::ShiftModifier));
+ }
event->accept();
}
QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
- if (change == ItemSelectedHasChanged) {
+ if ((change == ItemSelectedHasChanged) && owner) {
if (value == true)
owner->setCardMenu(cardMenu);
else if (owner->getCardMenu() == cardMenu)
@@ -423,3 +461,43 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
}
return QGraphicsItem::itemChange(change, value);
}
+
+void CardItem::cardMenuAction()
+{
+ owner->cardMenuAction(static_cast(sender()));
+}
+
+void CardItem::actAttach()
+{
+ owner->actAttach(static_cast(sender()));
+}
+
+void CardItem::actUnattach()
+{
+ owner->actUnattach(static_cast(sender()));
+}
+
+void CardItem::actSetPT()
+{
+ owner->actSetPT(static_cast(sender()));
+}
+
+void CardItem::actSetAnnotation()
+{
+ owner->actSetAnnotation(static_cast(sender()));
+}
+
+void CardItem::actCardCounterTrigger()
+{
+ owner->actCardCounterTrigger(static_cast(sender()));
+}
+
+void CardItem::actPlay()
+{
+ playCard(false);
+}
+
+void CardItem::actHide()
+{
+ zone->removeCard(this);
+}
\ No newline at end of file
diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h
index 52642abb..97b86774 100644
--- a/cockatrice/src/carditem.h
+++ b/cockatrice/src/carditem.h
@@ -17,6 +17,7 @@ class CardItem : public AbstractCardItem {
private:
CardZone *zone;
int id;
+ bool revealedCard;
bool attacking;
bool facedown;
QMap counters;
@@ -30,28 +31,40 @@ private:
QList attachedCards;
QList aAddCounter, aSetCounter, aRemoveCounter;
- QAction *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone,
+ QAction *aPlay,
+ *aHide,
+ *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone,
*aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile;
QMenu *cardMenu, *moveMenu;
- void playCard(QGraphicsSceneMouseEvent *event);
+ void playCard(bool faceDown);
void prepareDelete();
+private slots:
+ void cardMenuAction();
+ void actCardCounterTrigger();
+ void actAttach();
+ void actUnattach();
+ void actSetPT();
+ void actSetAnnotation();
+ void actPlay();
+ void actHide();
public slots:
void deleteLater();
public:
enum { Type = typeCard };
int type() const { return Type; }
- CardItem(Player *_owner, const QString &_name = QString(), int _cardid = -1, QGraphicsItem *parent = 0);
+ CardItem(Player *_owner, const QString &_name = QString(), int _cardid = -1, bool revealedCard = false, QGraphicsItem *parent = 0);
~CardItem();
void retranslateUi();
CardZone *getZone() const { return zone; }
- void setZone(CardZone *_zone) { zone = _zone; }
+ void setZone(CardZone *_zone);
QMenu *getCardMenu() const { return cardMenu; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QPoint getGridPoint() const { return gridPoint; }
void setGridPoint(const QPoint &_gridPoint) { gridPoint = _gridPoint; }
QPoint getGridPos() const { return gridPoint; }
Player *getOwner() const { return owner; }
+ void setOwner(Player *_owner) { owner = _owner; }
int getId() const { return id; }
void setId(int _id) { id = _id; }
bool getAttacking() const { return attacking; }
@@ -75,6 +88,7 @@ public:
const QList &getAttachedCards() const { return attachedCards; }
void resetState();
void processCardInfo(ServerInfo_Card *info);
+ void updateCardMenu();
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
void deleteDragItem();
diff --git a/cockatrice/src/cardzone.cpp b/cockatrice/src/cardzone.cpp
index 6052f34e..9f9c275a 100644
--- a/cockatrice/src/cardzone.cpp
+++ b/cockatrice/src/cardzone.cpp
@@ -157,16 +157,25 @@ CardItem *CardZone::takeCard(int position, int cardId, bool /*canResize*/)
return c;
}
+void CardZone::removeCard(CardItem *card)
+{
+ cards.removeAt(cards.indexOf(card));
+ reorganizeCards();
+ emit cardCountChanged();
+ player->deleteCard(card);
+}
+
void CardZone::moveAllToZone()
{
QList data = static_cast(sender())->data().toList();
QString targetZone = data[0].toString();
int targetX = data[1].toInt();
- // Cards need to be moved in reverse order so that the other
- // cards' list index doesn't change
- for (int i = cards.size() - 1; i >= 0; i--)
- player->sendGameCommand(new Command_MoveCard(-1, getName(), cards.at(i)->getId(), targetZone, targetX));
+ QList idList;
+ for (int i = 0; i < cards.size(); ++i)
+ idList.append(new CardId(cards[i]->getId()));
+
+ player->sendGameCommand(new Command_MoveCard(-1, getName(), idList, player->getId(), targetZone, targetX));
}
QPointF CardZone::closestGridPoint(const QPointF &point)
diff --git a/cockatrice/src/cardzone.h b/cockatrice/src/cardzone.h
index b8e834f6..0b1809bb 100644
--- a/cockatrice/src/cardzone.h
+++ b/cockatrice/src/cardzone.h
@@ -12,8 +12,9 @@ class ZoneViewZone;
class QMenu;
class QAction;
class QPainter;
+class CardDragItem;
-class CardZone : public QObject, public AbstractGraphicsItem {
+class CardZone : public AbstractGraphicsItem {
Q_OBJECT
protected:
Player *player;
@@ -34,7 +35,7 @@ public slots:
public:
enum { Type = typeZone };
int type() const { return Type; }
- virtual void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown) = 0;
+ virtual void handleDropEvent(const QList &dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown) = 0;
CardZone(Player *_player, const QString &_name, bool _hasCardAttr, bool _isShufflable, bool _contentsKnown, QGraphicsItem *parent = 0, bool isView = false);
~CardZone();
void retranslateUi();
@@ -53,6 +54,7 @@ public:
CardItem *getCard(int cardId, const QString &cardName);
// takeCard() finds a card by position and removes it from the zone and from all of its views.
virtual CardItem *takeCard(int position, int cardId, bool canResize = true);
+ void removeCard(CardItem *card);
ZoneViewZone *getView() const { return view; }
void setView(ZoneViewZone *_view) { view = _view; }
virtual void reorganizeCards() = 0;
diff --git a/cockatrice/src/counter_general.cpp b/cockatrice/src/counter_general.cpp
new file mode 100644
index 00000000..6b722834
--- /dev/null
+++ b/cockatrice/src/counter_general.cpp
@@ -0,0 +1,26 @@
+#include "counter_general.h"
+#include
+
+GeneralCounter::GeneralCounter(Player *_player, int _id, const QString &_name, const QColor &_color, int _radius, int _value, QGraphicsItem *parent)
+ : AbstractCounter(_player, _id, _name, true, _value, parent), color(_color), radius(_radius)
+{
+}
+
+QRectF GeneralCounter::boundingRect() const
+{
+ return QRectF(0, 0, radius * 2, radius * 2);
+}
+
+void GeneralCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
+{
+ painter->setBrush(QBrush(color));
+ painter->drawEllipse(boundingRect());
+ if (value) {
+ QFont f("Serif");
+ f.setPixelSize(radius * 0.8);
+ f.setWeight(QFont::Bold);
+ painter->setFont(f);
+ painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(value));
+ }
+}
+
diff --git a/cockatrice/src/counter_general.h b/cockatrice/src/counter_general.h
new file mode 100644
index 00000000..58468aa8
--- /dev/null
+++ b/cockatrice/src/counter_general.h
@@ -0,0 +1,17 @@
+#ifndef COUNTER_GENERAL_H
+#define COUNTER_GENERAL_H
+
+#include "abstractcounter.h"
+
+class GeneralCounter : public AbstractCounter {
+ Q_OBJECT
+private:
+ QColor color;
+ int radius;
+public:
+ GeneralCounter(Player *_player, int _id, const QString &_name, const QColor &_color, int _radius, int _value, QGraphicsItem *parent = 0);
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+};
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp
index 5cf957b6..e36a6815 100644
--- a/cockatrice/src/dlg_creategame.cpp
+++ b/cockatrice/src/dlg_creategame.cpp
@@ -11,8 +11,8 @@
#include "dlg_creategame.h"
#include "protocol_items.h"
-DlgCreateGame::DlgCreateGame(AbstractClient *_client, QWidget *parent)
- : QDialog(parent), client(_client)
+DlgCreateGame::DlgCreateGame(AbstractClient *_client, int _roomId, QWidget *parent)
+ : QDialog(parent), client(_client), roomId(_roomId)
{
descriptionLabel = new QLabel(tr("&Description:"));
descriptionEdit = new QLineEdit;
@@ -77,6 +77,7 @@ DlgCreateGame::DlgCreateGame(AbstractClient *_client, QWidget *parent)
void DlgCreateGame::actOK()
{
Command_CreateGame *createCommand = new Command_CreateGame(
+ roomId,
descriptionEdit->text(),
passwordEdit->text(),
maxPlayersEdit->value(),
diff --git a/cockatrice/src/dlg_creategame.h b/cockatrice/src/dlg_creategame.h
index af72fe18..dcd901df 100644
--- a/cockatrice/src/dlg_creategame.h
+++ b/cockatrice/src/dlg_creategame.h
@@ -14,13 +14,14 @@ class QSpinBox;
class DlgCreateGame : public QDialog {
Q_OBJECT
public:
- DlgCreateGame(AbstractClient *_client, QWidget *parent = 0);
+ DlgCreateGame(AbstractClient *_client, int _roomId, QWidget *parent = 0);
private slots:
void actOK();
void checkResponse(ResponseCode response);
void spectatorsAllowedChanged(int state);
private:
AbstractClient *client;
+ int roomId;
QGroupBox *spectatorsGroupBox;
QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel;
diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp
index bf332947..46ffeff7 100644
--- a/cockatrice/src/dlg_settings.cpp
+++ b/cockatrice/src/dlg_settings.cpp
@@ -228,17 +228,12 @@ AppearanceSettingsPage::AppearanceSettingsPage()
handGroupBox = new QGroupBox;
handGroupBox->setLayout(handGrid);
- economicalGridCheckBox = new QCheckBox;
- economicalGridCheckBox->setChecked(settingsCache->getEconomicalGrid());
- connect(economicalGridCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setEconomicalGrid(int)));
-
invertVerticalCoordinateCheckBox = new QCheckBox;
invertVerticalCoordinateCheckBox->setChecked(settingsCache->getInvertVerticalCoordinate());
connect(invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setInvertVerticalCoordinate(int)));
QGridLayout *tableGrid = new QGridLayout;
- tableGrid->addWidget(economicalGridCheckBox, 0, 0, 1, 2);
- tableGrid->addWidget(invertVerticalCoordinateCheckBox, 1, 0, 1, 2);
+ tableGrid->addWidget(invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
tableGroupBox = new QGroupBox;
tableGroupBox->setLayout(tableGrid);
@@ -279,7 +274,6 @@ void AppearanceSettingsPage::retranslateUi()
horizontalHandCheckBox->setText(tr("Display hand horizontally (wastes space)"));
tableGroupBox->setTitle(tr("Table grid layout"));
- economicalGridCheckBox->setText(tr("Economical layout"));
invertVerticalCoordinateCheckBox->setText(tr("Invert vertical coordinate"));
zoneViewGroupBox->setTitle(tr("Zone view layout"));
diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h
index a0b45ab6..abdac076 100644
--- a/cockatrice/src/dlg_settings.h
+++ b/cockatrice/src/dlg_settings.h
@@ -67,7 +67,7 @@ signals:
private:
QLabel *handBgLabel, *stackBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel;
QLineEdit *handBgEdit, *stackBgEdit, *tableBgEdit, *playerAreaBgEdit, *cardBackPicturePathEdit;
- QCheckBox *horizontalHandCheckBox, *economicalGridCheckBox, *invertVerticalCoordinateCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox;
+ QCheckBox *horizontalHandCheckBox, *invertVerticalCoordinateCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox;
QGroupBox *zoneBgGroupBox, *handGroupBox, *tableGroupBox, *zoneViewGroupBox;
public:
AppearanceSettingsPage();
diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp
index e92fb820..330ebef5 100644
--- a/cockatrice/src/gamescene.cpp
+++ b/cockatrice/src/gamescene.cpp
@@ -82,7 +82,7 @@ void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numb
}
}
- ZoneViewWidget *item = new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards);
+ ZoneViewWidget *item = new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards, false);
views.append(item);
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeZoneView(ZoneViewWidget *)));
addItem(item);
@@ -91,7 +91,7 @@ void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numb
void GameScene::addRevealedZoneView(Player *player, CardZone *zone, const QList &cardList)
{
- ZoneViewWidget *item = new ZoneViewWidget(player, zone, -2, cardList);
+ ZoneViewWidget *item = new ZoneViewWidget(player, zone, -2, true, cardList);
views.append(item);
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeZoneView(ZoneViewWidget *)));
addItem(item);
@@ -195,3 +195,18 @@ bool GameScene::event(QEvent *event)
}
return QGraphicsScene::event(event);
}
+
+void GameScene::startRubberBand(const QPointF &selectionOrigin)
+{
+ emit sigStartRubberBand(selectionOrigin);
+}
+
+void GameScene::resizeRubberBand(const QPointF &cursorPoint)
+{
+ emit sigResizeRubberBand(cursorPoint);
+}
+
+void GameScene::stopRubberBand()
+{
+ emit sigStopRubberBand();
+}
diff --git a/cockatrice/src/gamescene.h b/cockatrice/src/gamescene.h
index da35320e..67031fc2 100644
--- a/cockatrice/src/gamescene.h
+++ b/cockatrice/src/gamescene.h
@@ -23,6 +23,10 @@ public:
void retranslateUi();
const QRectF &getPlayersRect() const { return playersRect; }
void processViewSizeChange(const QSize &newSize);
+
+ void startRubberBand(const QPointF &selectionOrigin);
+ void resizeRubberBand(const QPointF &cursorPoint);
+ void stopRubberBand();
public slots:
void toggleZoneView(Player *player, const QString &zoneName, int numberCards);
void addRevealedZoneView(Player *player, CardZone *zone, const QList &cardList);
@@ -35,6 +39,10 @@ private slots:
void rearrange();
protected:
bool event(QEvent *event);
+signals:
+ void sigStartRubberBand(const QPointF &selectionOrigin);
+ void sigResizeRubberBand(const QPointF &cursorPoint);
+ void sigStopRubberBand();
};
#endif
diff --git a/cockatrice/src/gameview.cpp b/cockatrice/src/gameview.cpp
index fd716827..7b13ae11 100644
--- a/cockatrice/src/gameview.cpp
+++ b/cockatrice/src/gameview.cpp
@@ -2,17 +2,21 @@
#include "gamescene.h"
#include
#include
+#include
GameView::GameView(QGraphicsScene *scene, QWidget *parent)
- : QGraphicsView(scene, parent)
+ : QGraphicsView(scene, parent), rubberBand(0)
{
setBackgroundBrush(QBrush(QColor(0, 0, 0)));
setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing/* | QPainter::SmoothPixmapTransform*/);
- setDragMode(RubberBandDrag);
setFocusPolicy(Qt::NoFocus);
setViewportUpdateMode(BoundingRectViewportUpdate);
connect(scene, SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(updateSceneRect(const QRectF &)));
+
+ connect(scene, SIGNAL(sigStartRubberBand(const QPointF &)), this, SLOT(startRubberBand(const QPointF &)));
+ connect(scene, SIGNAL(sigResizeRubberBand(const QPointF &)), this, SLOT(resizeRubberBand(const QPointF &)));
+ connect(scene, SIGNAL(sigStopRubberBand()), this, SLOT(stopRubberBand()));
aCloseMostRecentZoneView = new QAction(this);
aCloseMostRecentZoneView->setShortcut(tr("Esc"));
@@ -35,3 +39,25 @@ void GameView::updateSceneRect(const QRectF &rect)
qDebug(QString("updateSceneRect = %1,%2").arg(rect.width()).arg(rect.height()).toLatin1());
fitInView(rect, Qt::KeepAspectRatio);
}
+
+void GameView::startRubberBand(const QPointF &_selectionOrigin)
+{
+ selectionOrigin = _selectionOrigin;
+ rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+ rubberBand->setGeometry(QRect(mapFromScene(selectionOrigin), QSize(0, 0)));
+ rubberBand->show();
+}
+
+void GameView::resizeRubberBand(const QPointF &cursorPoint)
+{
+ if (rubberBand)
+ rubberBand->setGeometry(QRect(mapFromScene(selectionOrigin), mapFromScene(cursorPoint)).normalized());
+}
+
+void GameView::stopRubberBand()
+{
+ if (rubberBand) {
+ rubberBand->deleteLater();
+ rubberBand = 0;
+ }
+}
diff --git a/cockatrice/src/gameview.h b/cockatrice/src/gameview.h
index c45e675e..84acf45e 100644
--- a/cockatrice/src/gameview.h
+++ b/cockatrice/src/gameview.h
@@ -3,12 +3,20 @@
#include
+class QRubberBand;
+
class GameView : public QGraphicsView {
Q_OBJECT
private:
QAction *aCloseMostRecentZoneView;
+ QRubberBand *rubberBand;
+ QPointF selectionOrigin;
protected:
void resizeEvent(QResizeEvent *event);
+private slots:
+ void startRubberBand(const QPointF &selectionOrigin);
+ void resizeRubberBand(const QPointF &cursorPoint);
+ void stopRubberBand();
public slots:
void updateSceneRect(const QRectF &rect);
public:
diff --git a/cockatrice/src/handcounter.h b/cockatrice/src/handcounter.h
index 9e942a64..46de6889 100644
--- a/cockatrice/src/handcounter.h
+++ b/cockatrice/src/handcounter.h
@@ -7,7 +7,7 @@
class QPainter;
class QPixmap;
-class HandCounter : public QObject, public AbstractGraphicsItem {
+class HandCounter : public AbstractGraphicsItem {
Q_OBJECT
private:
int number;
diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp
index d871c54d..258567e3 100644
--- a/cockatrice/src/handzone.cpp
+++ b/cockatrice/src/handzone.cpp
@@ -3,9 +3,10 @@
#include "settingscache.h"
#include "player.h"
#include "protocol_items.h"
+#include "carddragitem.h"
HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent)
- : CardZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight)
+ : SelectZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight)
{
connect(settingsCache, SIGNAL(handBgPathChanged()), this, SLOT(updateBgPixmap()));
updateBgPixmap();
@@ -36,9 +37,13 @@ void HandZone::addCardImpl(CardItem *card, int x, int /*y*/)
card->update();
}
-void HandZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
+void HandZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
{
- player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), cards.size(), -1, false));
+ QList idList;
+ for (int i = 0; i < dragItems.size(); ++i)
+ idList.append(new CardId(dragItems[i]->getId()));
+
+ player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), idList, player->getId(), getName(), cards.size(), -1, false));
}
QRectF HandZone::boundingRect() const
@@ -65,7 +70,7 @@ void HandZone::reorganizeCards()
const int xPadding = 5;
qreal totalWidth = boundingRect().width() - 2 * xPadding;
qreal cardWidth = cards.at(0)->boundingRect().width();
-
+
for (int i = 0; i < cardCount; i++) {
CardItem *c = cards.at(i);
diff --git a/cockatrice/src/handzone.h b/cockatrice/src/handzone.h
index 1392fa16..85dde951 100644
--- a/cockatrice/src/handzone.h
+++ b/cockatrice/src/handzone.h
@@ -1,9 +1,9 @@
#ifndef HANDZONE_H
#define HANDZONE_H
-#include "cardzone.h"
+#include "selectzone.h"
-class HandZone : public CardZone {
+class HandZone : public SelectZone {
Q_OBJECT
private:
qreal width, zoneHeight;
@@ -14,7 +14,7 @@ public slots:
void updateOrientation();
public:
HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0);
- void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
+ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void reorganizeCards();
diff --git a/cockatrice/src/localclient.cpp b/cockatrice/src/localclient.cpp
index b42b810c..87b215ba 100644
--- a/cockatrice/src/localclient.cpp
+++ b/cockatrice/src/localclient.cpp
@@ -7,6 +7,7 @@ LocalClient::LocalClient(LocalServerInterface *_lsi, const QString &_playerName,
{
connect(lsi, SIGNAL(itemToClient(ProtocolItem *)), this, SLOT(itemFromServer(ProtocolItem *)));
sendCommand(new Command_Login(_playerName, QString()));
+ sendCommand(new Command_JoinRoom(0));
}
LocalClient::~LocalClient()
diff --git a/cockatrice/src/localserver.cpp b/cockatrice/src/localserver.cpp
index 1af04676..da403f91 100644
--- a/cockatrice/src/localserver.cpp
+++ b/cockatrice/src/localserver.cpp
@@ -1,9 +1,11 @@
#include "localserver.h"
#include "localserverinterface.h"
+#include "server_room.h"
LocalServer::LocalServer(QObject *parent)
: Server(parent)
{
+ addRoom(new Server_Room(0, QString(), QString(), false, QString(), this));
}
LocalServer::~LocalServer()
diff --git a/cockatrice/src/localserverinterface.h b/cockatrice/src/localserverinterface.h
index 0f954844..f88d4940 100644
--- a/cockatrice/src/localserverinterface.h
+++ b/cockatrice/src/localserverinterface.h
@@ -16,6 +16,7 @@ private:
ResponseCode cmdDeckDel(Command_DeckDel * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
ResponseCode cmdDeckUpload(Command_DeckUpload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
ResponseCode cmdDeckDownload(Command_DeckDownload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
+ ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
public:
LocalServerInterface(LocalServer *_server);
~LocalServerInterface();
diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp
index 7e42c0b3..4ce4621d 100644
--- a/cockatrice/src/messagelogwidget.cpp
+++ b/cockatrice/src/messagelogwidget.cpp
@@ -181,7 +181,7 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
{
QString startName = startZone->getName();
QString targetName = targetZone->getName();
- if (((startName == "table") && (targetName == "table")) || ((startName == "hand") && (targetName == "hand")))
+ if (((startName == "table") && (targetName == "table") && (startZone == targetZone)) || ((startName == "hand") && (targetName == "hand")))
return;
QPair temp = getFromStr(startZone, cardName, oldX);
bool cardNameContainsStartZone = false;
@@ -190,6 +190,18 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
cardName = temp.first;
}
QString fromStr = temp.second;
+ QString cardStr;
+ if (cardNameContainsStartZone)
+ cardStr = cardName;
+ else if (cardName.isEmpty())
+ cardStr = tr("a card");
+ else
+ cardStr = QString("%1").arg(sanitizeHtml(cardName));
+
+ if ((startName == "table") && (targetName == "table")) {
+ append(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(targetZone->getPlayer()->getName())).arg(cardStr));
+ return;
+ }
QString finalStr;
if (targetName == "table")
@@ -214,14 +226,6 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
else if (targetName == "stack")
finalStr = tr("%1 plays %2%3.");
- QString cardStr;
- if (cardNameContainsStartZone)
- cardStr = cardName;
- else if (cardName.isEmpty())
- cardStr = tr("a card");
- else
- cardStr = QString("%1").arg(sanitizeHtml(cardName));
-
append(finalStr.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(newX));
}
diff --git a/cockatrice/src/phasestoolbar.cpp b/cockatrice/src/phasestoolbar.cpp
index f26e6a5f..2078113f 100644
--- a/cockatrice/src/phasestoolbar.cpp
+++ b/cockatrice/src/phasestoolbar.cpp
@@ -2,20 +2,24 @@
#include
#include
#include
+#include
#include "phasestoolbar.h"
#include "protocol_items.h"
PhaseButton::PhaseButton(const QIcon &icon, QAction *_doubleClickAction)
- : QPushButton(icon, QString()), active(false), doubleClickAction(_doubleClickAction), activePixmap(50, 50), inactivePixmap(50, 50)
+ : QPushButton(icon, QString()), active(false), activeAnimationCounter(0), doubleClickAction(_doubleClickAction), pixmap(50, 50)
{
setFocusPolicy(Qt::NoFocus);
setFixedSize(50, 50);
- updatePixmap(activePixmap, true);
- updatePixmap(inactivePixmap, false);
+ activeAnimationTimer = new QTimer(this);
+ connect(activeAnimationTimer, SIGNAL(timeout()), this, SLOT(updateAnimation()));
+ activeAnimationTimer->setSingleShot(false);
+
+ updatePixmap(pixmap);
}
-void PhaseButton::updatePixmap(QPixmap &pixmap, bool active)
+void PhaseButton::updatePixmap(QPixmap &pixmap)
{
pixmap.fill(Qt::transparent);
@@ -23,21 +27,44 @@ void PhaseButton::updatePixmap(QPixmap &pixmap, bool active)
int height = pixmap.height();
int width = pixmap.width();
- if (active)
- painter.setBrush(Qt::red);
- painter.setPen(Qt::gray);
- painter.drawRect(1, 1, width - 2, height - 2);
-
icon().paint(&painter, 5, 5, width - 10, height - 10);
}
void PhaseButton::paintEvent(QPaintEvent */*event*/)
{
QPainter painter(this);
- if (active)
- painter.drawPixmap(0, 0, size().width(), size().height(), activePixmap);
- else
- painter.drawPixmap(0, 0, size().width(), size().height(), inactivePixmap);
+
+ painter.setBrush(QColor(220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0)));
+ painter.setPen(Qt::gray);
+ painter.drawRect(1, 1, pixmap.width() - 2, pixmap.height() - 2);
+
+ painter.drawPixmap(0, 0, size().width(), size().height(), pixmap);
+
+// painter.setBrush(QColor(220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0), 255 * ((10 - activeAnimationCounter) / 15.0)));
+ painter.setBrush(QColor(0, 0, 0, 255 * ((10 - activeAnimationCounter) / 15.0)));
+ painter.setPen(Qt::gray);
+ painter.drawRect(1, 1, pixmap.width() - 2, pixmap.height() - 2);
+}
+
+void PhaseButton::setActive(bool _active)
+{
+ if (active == _active)
+ return;
+
+ active = _active;
+ activeAnimationTimer->start(50);
+}
+
+void PhaseButton::updateAnimation()
+{
+ if (active) {
+ if (++activeAnimationCounter >= 10)
+ activeAnimationTimer->stop();
+ } else {
+ if (--activeAnimationCounter <= 0)
+ activeAnimationTimer->stop();
+ }
+ update();
}
void PhaseButton::setPhaseText(const QString &_phaseText)
@@ -60,6 +87,9 @@ void PhaseButton::triggerDoubleClickAction()
PhasesToolbar::PhasesToolbar(QWidget *parent)
: QFrame(parent)
{
+ setBackgroundRole(QPalette::Shadow);
+ setAutoFillBackground(true);
+
QAction *aUntapAll = new QAction(this);
connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll()));
QAction *aDrawCard = new QAction(this);
diff --git a/cockatrice/src/phasestoolbar.h b/cockatrice/src/phasestoolbar.h
index 5f0acf8d..c685d50b 100644
--- a/cockatrice/src/phasestoolbar.h
+++ b/cockatrice/src/phasestoolbar.h
@@ -13,15 +13,19 @@ class PhaseButton : public QPushButton {
private:
QString phaseText;
bool active;
+ int activeAnimationCounter;
+ QTimer *activeAnimationTimer;
QAction *doubleClickAction;
- QPixmap activePixmap, inactivePixmap;
+ QPixmap pixmap;
- void updatePixmap(QPixmap &pixmap, bool active);
+ void updatePixmap(QPixmap &pixmap);
+private slots:
+ void updateAnimation();
public:
PhaseButton(const QIcon &icon, QAction *_doubleClickAction = 0);
void setPhaseText(const QString &_phaseText);
QString getPhaseText() const { return phaseText; }
- void setActive(bool _active) { active = _active; update(); }
+ void setActive(bool _active);
bool getActive() const { return active; }
void triggerDoubleClickAction();
protected:
diff --git a/cockatrice/src/pilezone.cpp b/cockatrice/src/pilezone.cpp
index e3278998..1c9df8f9 100644
--- a/cockatrice/src/pilezone.cpp
+++ b/cockatrice/src/pilezone.cpp
@@ -48,9 +48,13 @@ void PileZone::addCardImpl(CardItem *card, int x, int /*y*/)
card->setParentItem(this);
}
-void PileZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
+void PileZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
{
- player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false));
+ QList idList;
+ for (int i = 0; i < dragItems.size(); ++i)
+ idList.append(new CardId(dragItems[i]->getId()));
+
+ player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), idList, player->getId(), getName(), 0, 0, false));
}
void PileZone::reorganizeCards()
diff --git a/cockatrice/src/pilezone.h b/cockatrice/src/pilezone.h
index 0b786333..0e946066 100644
--- a/cockatrice/src/pilezone.h
+++ b/cockatrice/src/pilezone.h
@@ -9,7 +9,7 @@ public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void reorganizeCards();
- void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
+ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp
index c13c13bf..0d7ab7a4 100644
--- a/cockatrice/src/player.cpp
+++ b/cockatrice/src/player.cpp
@@ -1,7 +1,7 @@
#include "player.h"
#include "cardzone.h"
#include "playertarget.h"
-#include "counter.h"
+#include "counter_general.h"
#include "arrowitem.h"
#include "zoneviewzone.h"
#include "zoneviewwidget.h"
@@ -32,26 +32,28 @@ Player::Player(ServerInfo_User *info, int _id, bool _local, TabGame *_parent)
updateBgPixmap();
playerTarget = new PlayerTarget(this);
- playerTarget->setPos(QPointF(counterAreaWidth + (CARD_HEIGHT + 5 - playerTarget->boundingRect().width()) / 2.0, 5));
+ qreal avatarMargin = (counterAreaWidth + CARD_HEIGHT + 15 - playerTarget->boundingRect().width()) / 2.0;
+ playerTarget->setPos(QPointF(avatarMargin, avatarMargin));
PileZone *deck = new PileZone(this, "deck", true, false, this);
- QPointF base = QPointF(counterAreaWidth + (CARD_HEIGHT - CARD_WIDTH + 5) / 2.0, 5 + playerTarget->boundingRect().height() + 5 - (CARD_HEIGHT - CARD_WIDTH) / 2.0);
+ QPointF base = QPointF(counterAreaWidth + (CARD_HEIGHT - CARD_WIDTH + 15) / 2.0, 10 + playerTarget->boundingRect().height() + 5 - (CARD_HEIGHT - CARD_WIDTH) / 2.0);
deck->setPos(base);
qreal h = deck->boundingRect().width() + 5;
+ HandCounter *handCounter = new HandCounter(this);
+ handCounter->setPos(base + QPointF(0, h + 10));
+ qreal h2 = handCounter->boundingRect().height();
+
PileZone *grave = new PileZone(this, "grave", false, true, this);
- grave->setPos(base + QPointF(0, h));
+ grave->setPos(base + QPointF(0, h + h2 + 10));
PileZone *rfg = new PileZone(this, "rfg", false, true, this);
- rfg->setPos(base + QPointF(0, 2 * h));
+ rfg->setPos(base + QPointF(0, 2 * h + h2 + 10));
PileZone *sb = new PileZone(this, "sb", false, false, this);
sb->setVisible(false);
- HandCounter *handCounter = new HandCounter(this);
- handCounter->setPos(base + QPointF(0, 3 * h + 7));
-
table = new TableZone(this, this);
connect(table, SIGNAL(sizeChanged()), this, SLOT(updateBoundingRect()));
@@ -136,6 +138,8 @@ Player::Player(ServerInfo_User *info, int _id, bool _local, TabGame *_parent)
connect(aMoveTopCardsToGrave, SIGNAL(triggered()), this, SLOT(actMoveTopCardsToGrave()));
aMoveTopCardsToExile = new QAction(this);
connect(aMoveTopCardsToExile, SIGNAL(triggered()), this, SLOT(actMoveTopCardsToExile()));
+ aMoveTopCardToBottom = new QAction(this);
+ connect(aMoveTopCardToBottom, SIGNAL(triggered()), this, SLOT(actMoveTopCardToBottom()));
}
playerMenu = new QMenu(QString());
@@ -166,6 +170,7 @@ Player::Player(ServerInfo_User *info, int _id, bool _local, TabGame *_parent)
libraryMenu->addSeparator();
libraryMenu->addAction(aMoveTopCardsToGrave);
libraryMenu->addAction(aMoveTopCardsToExile);
+ libraryMenu->addAction(aMoveTopCardToBottom);
deck->setMenu(libraryMenu, aDrawCard);
} else {
handMenu = 0;
@@ -309,7 +314,7 @@ void Player::playerListActionTriggered()
void Player::rearrangeZones()
{
- QPointF base = QPointF(CARD_HEIGHT + counterAreaWidth + 5, 0);
+ QPointF base = QPointF(CARD_HEIGHT + counterAreaWidth + 15, 0);
if (settingsCache->getHorizontalHand()) {
if (mirrored) {
@@ -367,7 +372,7 @@ void Player::updateBgPixmap()
void Player::updateBoundingRect()
{
prepareGeometryChange();
- qreal width = CARD_HEIGHT + 5 + counterAreaWidth + stack->boundingRect().width();
+ qreal width = CARD_HEIGHT + 15 + counterAreaWidth + stack->boundingRect().width();
if (settingsCache->getHorizontalHand()) {
qreal handHeight = hand->isVisible() ? hand->boundingRect().height() : 0;
bRect = QRectF(0, 0, width + table->boundingRect().width(), table->boundingRect().height() + handHeight);
@@ -408,6 +413,7 @@ void Player::retranslateUi()
aShuffle->setText(tr("&Shuffle"));
aMoveTopCardsToGrave->setText(tr("Move top cards to &graveyard..."));
aMoveTopCardsToExile->setText(tr("Move top cards to &exile..."));
+ aMoveTopCardToBottom->setText(tr("Put top card on &bottom"));
handMenu->setTitle(tr("&Hand"));
mRevealHand->setTitle(tr("&Reveal to"));
@@ -422,7 +428,7 @@ void Player::retranslateUi()
aCreateAnotherToken->setText(tr("C&reate another token"));
sayMenu->setTitle(tr("S&ay"));
- QMapIterator counterIterator(counters);
+ QMapIterator counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->retranslateUi();
@@ -453,7 +459,7 @@ void Player::setShortcutsActive()
aCreateToken->setShortcut(tr("Ctrl+T"));
aCreateAnotherToken->setShortcut(tr("Ctrl+G"));
- QMapIterator counterIterator(counters);
+ QMapIterator counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->setShortcutsActive();
}
@@ -474,7 +480,7 @@ void Player::setShortcutsInactive()
aCreateToken->setShortcut(QKeySequence());
aCreateAnotherToken->setShortcut(QKeySequence());
- QMapIterator counterIterator(counters);
+ QMapIterator counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->setShortcutsInactive();
}
@@ -557,9 +563,10 @@ void Player::actMoveTopCardsToGrave()
const int maxCards = zones.value("deck")->getCards().size();
if (number > maxCards)
number = maxCards;
+ QList idList;
for (int i = 0; i < number; ++i)
- commandList.append(new Command_MoveCard(-1, "deck", 0, "grave", 0, 0, false));
- sendCommandContainer(new CommandContainer(commandList));
+ idList.append(new CardId(i));
+ sendGameCommand(new Command_MoveCard(-1, "deck", idList, getId(), "grave", 0, 0, false));
}
void Player::actMoveTopCardsToExile()
@@ -572,9 +579,15 @@ void Player::actMoveTopCardsToExile()
const int maxCards = zones.value("deck")->getCards().size();
if (number > maxCards)
number = maxCards;
+ QList idList;
for (int i = 0; i < number; ++i)
- commandList.append(new Command_MoveCard(-1, "deck", 0, "rfg", 0, 0, false));
- sendCommandContainer(new CommandContainer(commandList));
+ idList.append(new CardId(i));
+ sendGameCommand(new Command_MoveCard(-1, "deck", idList, getId(), "rfg", 0, 0, false));
+}
+
+void Player::actMoveTopCardToBottom()
+{
+ sendGameCommand(new Command_MoveCard(-1, "deck", QList() << new CardId(0), getId(), "deck", -1, 0, false));
}
void Player::actUntapAll()
@@ -743,7 +756,7 @@ void Player::eventCreateCounters(Event_CreateCounters *event)
void Player::eventSetCounter(Event_SetCounter *event)
{
- Counter *c = counters.value(event->getCounterId(), 0);
+ AbstractCounter *c = counters.value(event->getCounterId(), 0);
if (!c)
return;
int oldValue = c->getValue();
@@ -781,7 +794,10 @@ void Player::eventStopDumpZone(Event_StopDumpZone *event)
void Player::eventMoveCard(Event_MoveCard *event)
{
CardZone *startZone = zones.value(event->getStartZone(), 0);
- CardZone *targetZone = zones.value(event->getTargetZone(), 0);
+ Player *targetPlayer = static_cast(parent())->getPlayers().value(event->getTargetPlayerId());
+ if (!targetPlayer)
+ return;
+ CardZone *targetZone = targetPlayer->getZones().value(event->getTargetZone(), 0);
if (!startZone || !targetZone)
return;
@@ -798,9 +814,12 @@ void Player::eventMoveCard(Event_MoveCard *event)
return;
card->setName(event->getCardName());
- if (card->getAttachedTo() && (startZone != targetZone))
+ if (card->getAttachedTo() && (startZone != targetZone)) {
+ CardItem *parentCard = card->getAttachedTo();
card->setAttachedTo(0);
-
+ parentCard->getZone()->reorganizeCards();
+ }
+
card->deleteDragItem();
card->setId(event->getNewCardId());
@@ -808,6 +827,13 @@ void Player::eventMoveCard(Event_MoveCard *event)
if (startZone != targetZone) {
card->setBeingPointedAt(false);
card->setHovered(false);
+
+ const QList &attachedCards = card->getAttachedCards();
+ for (int i = 0; i < attachedCards.size(); ++i)
+ attachedCards[i]->setParentItem(targetZone);
+
+ if (startZone->getPlayer() != targetZone->getPlayer())
+ card->setOwner(targetZone->getPlayer());
}
// The log event has to be sent before the card is added to the target zone
@@ -989,7 +1015,7 @@ QRectF Player::boundingRect() const
void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
- int totalWidth = CARD_HEIGHT + counterAreaWidth + 5;
+ int totalWidth = CARD_HEIGHT + counterAreaWidth + 15;
if (bgPixmap.isNull())
painter->fillRect(QRectF(0, 0, totalWidth, boundingRect().height()), QColor(200, 200, 200));
else
@@ -1064,10 +1090,10 @@ void Player::playCard(CardItem *c, bool faceDown, bool tapped)
{
CardInfo *ci = c->getInfo();
if (ci->getTableRow() == 3)
- stack->handleDropEvent(c->getId(), c->getZone(), QPoint(), false);
+ sendGameCommand(new Command_MoveCard(-1, c->getZone()->getName(), QList() << new CardId(c->getId()), getId(), "stack", 0, 0, false));
else {
QPoint gridPoint = QPoint(-1, 2 - ci->getTableRow());
- table->handleDropEventByGrid(c->getId(), c->getZone(), gridPoint, faceDown, tapped);
+ sendGameCommand(new Command_MoveCard(-1, c->getZone()->getName(), QList() << new CardId(c->getId()), getId(), "table", gridPoint.x(), gridPoint.y(), faceDown, tapped));
}
}
@@ -1089,14 +1115,22 @@ void Player::addZone(CardZone *z)
zones.insert(z->getName(), z);
}
-Counter *Player::addCounter(ServerInfo_Counter *counter)
+AbstractCounter *Player::addCounter(ServerInfo_Counter *counter)
{
return addCounter(counter->getId(), counter->getName(), counter->getColor().getQColor(), counter->getRadius(), counter->getCount());
}
-Counter *Player::addCounter(int counterId, const QString &name, QColor color, int radius, int value)
+AbstractCounter *Player::addCounter(int counterId, const QString &name, QColor color, int radius, int value)
{
- Counter *c = new Counter(this, counterId, name, color, radius, value, this);
+ qDebug() << "addCounter:" << getName() << counterId << name;
+ if (counters.contains(counterId))
+ return 0;
+
+ AbstractCounter *c;
+ if (name == "life")
+ c = playerTarget->addCounter(counterId, name, value);
+ else
+ c = new GeneralCounter(this, counterId, name, color, radius, value, this);
counters.insert(counterId, c);
if (countersMenu)
countersMenu->addMenu(c->getMenu());
@@ -1108,9 +1142,11 @@ Counter *Player::addCounter(int counterId, const QString &name, QColor color, in
void Player::delCounter(int counterId)
{
- Counter *c = counters.value(counterId, 0);
+ AbstractCounter *c = counters.value(counterId, 0);
if (!c)
return;
+ if (c->getName() == "life")
+ playerTarget->delCounter();
counters.remove(counterId);
c->delCounter();
rearrangeCounters();
@@ -1118,10 +1154,11 @@ void Player::delCounter(int counterId)
void Player::clearCounters()
{
- QMapIterator counterIterator(counters);
+ QMapIterator counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->delCounter();
counters.clear();
+ playerTarget->delCounter();
}
ArrowItem *Player::addArrow(ServerInfo_Arrow *arrow)
@@ -1182,15 +1219,16 @@ void Player::clearArrows()
void Player::rearrangeCounters()
{
- qreal marginTop = 15;
- qreal marginBottom = 15;
+ qreal marginTop = 80;
+ qreal marginBottom = 10;
// Determine total height of bounding rectangles
qreal totalHeight = 0;
- QMapIterator counterIterator(counters);
+ QMapIterator counterIterator(counters);
while (counterIterator.hasNext()) {
counterIterator.next();
- totalHeight += counterIterator.value()->boundingRect().height();
+ if (counterIterator.value()->getShownInCounterArea())
+ totalHeight += counterIterator.value()->boundingRect().height();
}
// Determine free space between objects
@@ -1204,8 +1242,11 @@ void Player::rearrangeCounters()
// Place objects
for (counterIterator.toFront(); counterIterator.hasNext(); ) {
- Counter *c = counterIterator.next().value();
+ AbstractCounter *c = counterIterator.next().value();
+ if (!c->getShownInCounterArea())
+ continue;
+
QRectF br = c->boundingRect();
c->setPos((counterAreaWidth - br.width()) / 2, y);
y += br.height() + padding;
@@ -1234,46 +1275,57 @@ bool Player::clearCardsToDelete()
return true;
}
-void Player::cardMenuAction()
+void Player::cardMenuAction(QAction *a)
{
- QAction *a = static_cast(sender());
QList sel = scene()->selectedItems();
+ QList cardList;
+ while (!sel.isEmpty())
+ cardList.append(qgraphicsitem_cast(sel.takeFirst()));
+
QList commandList;
- while (!sel.isEmpty()) {
- unsigned int i = (unsigned int) (((double) sel.size()) * qrand() / (RAND_MAX + 1.0));
- CardItem *card = qgraphicsitem_cast(sel.takeAt(i));
-
- switch (a->data().toInt()) {
- case 0:
- if (!card->getTapped())
- commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "1"));
- break;
- case 1:
- if (card->getTapped())
- commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "0"));
- break;
- case 2:
- commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap())));
- break;
- case 3: {
- QString zone = card->getZone()->getName();
- commandList.append(new Command_FlipCard(-1, zone, card->getId(), !card->getFaceDown()));
- break;
+ if (a->data().toInt() <= 4)
+ for (int i = 0; i < cardList.size(); ++i) {
+ CardItem *card = cardList[i];
+ switch (a->data().toInt()) {
+ case 0:
+ if (!card->getTapped())
+ commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "1"));
+ break;
+ case 1:
+ if (card->getTapped())
+ commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "0"));
+ break;
+ case 2:
+ commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap())));
+ break;
+ case 3: {
+ QString zone = card->getZone()->getName();
+ commandList.append(new Command_FlipCard(-1, zone, card->getId(), !card->getFaceDown()));
+ break;
+ }
+ case 4:
+ commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), true, -1, card->getGridPoint().y()));
+ break;
}
- case 4:
- commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y()));
- break;
+ }
+ else {
+ QList idList;
+ for (int i = 0; i < cardList.size(); ++i)
+ idList.append(new CardId(cardList[i]->getId()));
+ QString startZone = cardList[0]->getZone()->getName();
+
+ switch (a->data().toInt()) {
case 5:
- commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", 0, 0, false));
+ commandList.append(new Command_MoveCard(-1, startZone, idList, getId(), "deck", 0, 0, false));
break;
case 6:
- commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", -1, 0, false));
+ commandList.append(new Command_MoveCard(-1, startZone, idList, getId(), "deck", -1, 0, false));
break;
case 7:
- commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "grave", 0, 0, false));
+ commandList.append(new Command_MoveCard(-1, startZone, idList, getId(), "grave", 0, 0, false));
break;
case 8:
- commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "rfg", 0, 0, false));
+ commandList.append(new Command_MoveCard(-1, startZone, idList, getId(), "rfg", 0, 0, false));
break;
default: ;
}
@@ -1281,7 +1333,7 @@ void Player::cardMenuAction()
sendCommandContainer(new CommandContainer(commandList));
}
-void Player::actSetPT()
+void Player::actSetPT(QAction * /*a*/)
{
QString oldPT;
QListIterator i(scene()->selectedItems());
@@ -1306,7 +1358,7 @@ void Player::actSetPT()
}
}
-void Player::actSetAnnotation()
+void Player::actSetAnnotation(QAction * /*a*/)
{
QString oldAnnotation;
QListIterator i(scene()->selectedItems());
@@ -1332,24 +1384,22 @@ void Player::actSetAnnotation()
}
}
-void Player::actAttach()
+void Player::actAttach(QAction *a)
{
- CardItem *card = static_cast(sender()->parent());
+ CardItem *card = static_cast(a->parent());
ArrowAttachItem *arrow = new ArrowAttachItem(card);
scene()->addItem(arrow);
arrow->grabMouse();
}
-void Player::actUnattach()
+void Player::actUnattach(QAction *a)
{
- CardItem *card = static_cast(sender()->parent());
+ CardItem *card = static_cast(a->parent());
sendGameCommand(new Command_AttachCard(-1, card->getZone()->getName(), card->getId(), -1, QString(), -1));
}
-void Player::actCardCounterTrigger()
+void Player::actCardCounterTrigger(QAction *a)
{
- QAction *a = static_cast(sender());
-
int counterId = a->data().toInt() / 1000;
int action = a->data().toInt() % 1000;
switch (action) {
@@ -1412,7 +1462,7 @@ QString Player::getName() const
qreal Player::getMinimumWidth() const
{
- qreal result = table->getMinimumWidth() + CARD_HEIGHT + 5 + counterAreaWidth + stack->boundingRect().width();
+ qreal result = table->getMinimumWidth() + CARD_HEIGHT + 15 + counterAreaWidth + stack->boundingRect().width();
if (!settingsCache->getHorizontalHand())
result += hand->boundingRect().width();
return result;
@@ -1431,7 +1481,7 @@ void Player::processSceneSizeChange(const QSizeF &newSize)
// This will need to be changed if player areas are displayed side by side (e.g. 2x2 for a 4-player game)
qreal fullPlayerWidth = newSize.width();
- qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 5 - counterAreaWidth - stack->boundingRect().width();
+ qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width();
if (!settingsCache->getHorizontalHand())
tableWidth -= hand->boundingRect().width();
diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h
index ee91934f..49ccab69 100644
--- a/cockatrice/src/player.h
+++ b/cockatrice/src/player.h
@@ -11,7 +11,7 @@ class QMenu;
class QAction;
class ZoneViewZone;
class TabGame;
-class Counter;
+class AbstractCounter;
class ArrowItem;
class CardZone;
class StackZone;
@@ -84,6 +84,7 @@ public slots:
void actMulligan();
void actMoveTopCardsToGrave();
void actMoveTopCardsToExile();
+ void actMoveTopCardToBottom();
void actViewLibrary();
void actViewTopCards();
@@ -93,12 +94,12 @@ public slots:
void actSayMessage();
- void actAttach();
- void actUnattach();
- void actSetPT();
- void actSetAnnotation();
- void cardMenuAction();
- void actCardCounterTrigger();
+ void actAttach(QAction *action);
+ void actUnattach(QAction *action);
+ void actSetPT(QAction *action);
+ void actSetAnnotation(QAction *action);
+ void cardMenuAction(QAction *action);
+ void actCardCounterTrigger(QAction *action);
private slots:
void addPlayer(Player *player);
@@ -116,7 +117,7 @@ private:
QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary, *aMoveHandToGrave, *aMoveHandToRfg,
*aMoveGraveToTopLibrary, *aMoveGraveToBottomLibrary, *aMoveGraveToHand, *aMoveGraveToRfg,
*aMoveRfgToTopLibrary, *aMoveRfgToBottomLibrary, *aMoveRfgToHand, *aMoveRfgToGrave,
- *aViewLibrary, *aViewTopCards, *aMoveTopCardsToGrave, *aMoveTopCardsToExile,
+ *aViewLibrary, *aViewTopCards, *aMoveTopCardsToGrave, *aMoveTopCardsToExile, *aMoveTopCardToBottom,
*aViewGraveyard, *aViewRfg, *aViewSideboard,
*aDrawCard, *aDrawCards, *aMulligan, *aShuffle,
*aUntapAll, *aRollDie, *aCreateToken, *aCreateAnotherToken,
@@ -147,7 +148,7 @@ private:
QPixmap bgPixmap;
QRectF bRect;
- QMap counters;
+ QMap counters;
QMap arrows;
void rearrangeCounters();
@@ -173,7 +174,7 @@ private:
void eventDrawCards(Event_DrawCards *event);
void eventRevealCards(Event_RevealCards *event);
public:
- static const int counterAreaWidth = 65;
+ static const int counterAreaWidth = 55;
enum { Type = typeOther };
int type() const { return Type; }
@@ -185,8 +186,8 @@ public:
void deleteCard(CardItem *c);
void addZone(CardZone *z);
- Counter *addCounter(ServerInfo_Counter *counter);
- Counter *addCounter(int counterId, const QString &name, QColor color, int radius, int value);
+ AbstractCounter *addCounter(ServerInfo_Counter *counter);
+ AbstractCounter *addCounter(int counterId, const QString &name, QColor color, int radius, int value);
void delCounter(int counterId);
void clearCounters();
diff --git a/cockatrice/src/playertarget.cpp b/cockatrice/src/playertarget.cpp
index 1df53388..e4f5aa58 100644
--- a/cockatrice/src/playertarget.cpp
+++ b/cockatrice/src/playertarget.cpp
@@ -5,9 +5,49 @@
#include
#include
#include
+#include
+
+PlayerCounter::PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent)
+ : AbstractCounter(_player, _id, _name, false, _value, parent)
+{
+}
+
+QRectF PlayerCounter::boundingRect() const
+{
+ return QRectF(0, 0, 50, 30);
+}
+
+void PlayerCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
+{
+ const int radius = 8;
+ const qreal border = 1;
+ QPainterPath path(QPointF(50 - border / 2, border / 2));
+ path.lineTo(radius, border / 2);
+ path.arcTo(border / 2, border / 2, 2 * radius, 2 * radius, 90, 90);
+ path.lineTo(border / 2, 30 - border / 2);
+ path.lineTo(50 - border / 2, 30 - border / 2);
+ path.closeSubpath();
+
+ QPen pen(QColor(100, 100, 100));
+ pen.setWidth(border);
+ painter->setPen(pen);
+ painter->setBrush(hovered ? QColor(50, 50, 50, 160) : QColor(0, 0, 0, 160));
+
+ painter->drawPath(path);
+
+ QRectF translatedRect = painter->combinedTransform().mapRect(boundingRect());
+ QSize translatedSize = translatedRect.size().toSize();
+ painter->resetTransform();
+ QFont font("Serif");
+ font.setWeight(QFont::Bold);
+ font.setPixelSize(qMax((int) round(translatedSize.height() / 1.3), 9));
+ painter->setFont(font);
+ painter->setPen(Qt::white);
+ painter->drawText(translatedRect, Qt::AlignCenter, QString::number(value));
+}
PlayerTarget::PlayerTarget(Player *_owner)
- : ArrowTarget(_owner, _owner)
+ : ArrowTarget(_owner, _owner), playerCounter(0)
{
setCacheMode(DeviceCoordinateCache);
@@ -17,15 +57,17 @@ PlayerTarget::PlayerTarget(Player *_owner)
QRectF PlayerTarget::boundingRect() const
{
- return QRectF(0, 0, 100, 64);
+ return QRectF(0, 0, 160, 64);
}
void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
ServerInfo_User *info = owner->getUserInfo();
- painter->save();
- QRectF translatedRect = painter->combinedTransform().mapRect(boundingRect());
+ const qreal border = 2;
+
+ QRectF avatarBoundingRect = boundingRect().adjusted(border, border, -border, -border);
+ QRectF translatedRect = painter->combinedTransform().mapRect(avatarBoundingRect);
QSize translatedSize = translatedRect.size().toSize();
QPixmap cachedPixmap;
const QString cacheKey = "avatar" + QString::number(translatedSize.width()) + "_" + QString::number(info->getUserLevel()) + "_" + QString::number(fullPixmap.cacheKey());
@@ -34,16 +76,35 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
#else
if (!QPixmapCache::find(cacheKey, cachedPixmap)) {
#endif
+ cachedPixmap = QPixmap(translatedSize.width(), translatedSize.height());
+
+ QPainter tempPainter(&cachedPixmap);
+ QRadialGradient grad(translatedRect.center(), sqrt(translatedSize.width() * translatedSize.width() + translatedSize.height() * translatedSize.height()) / 2);
+ grad.setColorAt(1, Qt::black);
+ grad.setColorAt(0, QColor(180, 180, 180));
+ tempPainter.fillRect(QRectF(0, 0, translatedSize.width(), translatedSize.height()), grad);
+
+ QPixmap tempPixmap;
if (fullPixmap.isNull())
- cachedPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), info->getUserLevel());
+ tempPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), info->getUserLevel());
else
- cachedPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ tempPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ tempPainter.drawPixmap((translatedSize.width() - tempPixmap.width()) / 2, (translatedSize.height() - tempPixmap.height()) / 2, tempPixmap);
QPixmapCache::insert(cacheKey, cachedPixmap);
}
- painter->resetTransform();
+ painter->save();
+ painter->resetTransform();
painter->translate((translatedSize.width() - cachedPixmap.width()) / 2.0, 0);
- painter->drawPixmap(cachedPixmap.rect(), cachedPixmap, cachedPixmap.rect());
+ painter->drawPixmap(translatedRect, cachedPixmap, cachedPixmap.rect());
+ painter->restore();
+
+ QRectF nameRect = QRectF(0, boundingRect().height() - 20, 110, 20);
+ painter->fillRect(nameRect, QColor(0, 0, 0, 160));
+ QRectF translatedNameRect = painter->combinedTransform().mapRect(nameRect);
+
+ painter->save();
painter->resetTransform();
QString name = info->getName();
@@ -51,14 +112,35 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
name = name.mid(0, 10) + "...";
QFont font;
- font.setPixelSize(qMax(translatedSize.height() / 4, 9));
+ font.setPixelSize(qMax((int) round(translatedNameRect.height() / 1.5), 9));
painter->setFont(font);
- painter->setBackgroundMode(Qt::OpaqueMode);
- painter->setBackground(QColor(0, 0, 0, 100));
painter->setPen(Qt::white);
- painter->drawText(translatedRect, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWrapAnywhere, name);
+ painter->drawText(translatedNameRect, Qt::AlignVCenter | Qt::AlignLeft, " " + name);
painter->restore();
+ QPen pen(QColor(100, 100, 100));
+ pen.setWidth(border);
+ pen.setJoinStyle(Qt::RoundJoin);
+ painter->setPen(pen);
+ painter->drawRect(boundingRect().adjusted(border / 2, border / 2, -border / 2, -border / 2));
+
if (getBeingPointedAt())
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
}
+
+AbstractCounter *PlayerTarget::addCounter(int _counterId, const QString &_name, int _value)
+{
+ if (playerCounter)
+ return 0;
+
+ playerCounter = new PlayerCounter(owner, _counterId, _name, _value, this);
+ playerCounter->setPos(boundingRect().width() - playerCounter->boundingRect().width(), boundingRect().height() - playerCounter->boundingRect().height());
+ connect(playerCounter, SIGNAL(destroyed()), this, SLOT(delCounter()));
+
+ return playerCounter;
+}
+
+void PlayerTarget::delCounter()
+{
+ playerCounter = 0;
+}
\ No newline at end of file
diff --git a/cockatrice/src/playertarget.h b/cockatrice/src/playertarget.h
index 95dfd4b7..5957b517 100644
--- a/cockatrice/src/playertarget.h
+++ b/cockatrice/src/playertarget.h
@@ -2,14 +2,27 @@
#define PLAYERTARGET_H
#include "arrowtarget.h"
+#include "abstractcounter.h"
#include
#include
class Player;
+class PlayerCounter : public AbstractCounter {
+ Q_OBJECT
+public:
+ PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent = 0);
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+};
+
class PlayerTarget : public ArrowTarget {
+ Q_OBJECT
private:
QPixmap fullPixmap;
+ PlayerCounter *playerCounter;
+public slots:
+ void delCounter();
public:
enum { Type = typePlayerTarget };
int type() const { return Type; }
@@ -17,6 +30,8 @@ public:
PlayerTarget(Player *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ AbstractCounter *addCounter(int _counterId, const QString &_name, int _value);
};
#endif
\ No newline at end of file
diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp
index 4e3f9724..e378fb8b 100644
--- a/cockatrice/src/remoteclient.cpp
+++ b/cockatrice/src/remoteclient.cpp
@@ -21,7 +21,6 @@ RemoteClient::RemoteClient(QObject *parent)
xmlReader = new QXmlStreamReader;
xmlWriter = new QXmlStreamWriter;
- xmlWriter->setAutoFormatting(true);
xmlWriter->setDevice(socket);
}
@@ -42,12 +41,18 @@ void RemoteClient::slotConnected()
setStatus(StatusAwaitingWelcome);
}
-void RemoteClient::loginResponse(ResponseCode response)
+void RemoteClient::loginResponse(ProtocolResponse *response)
{
- if (response == RespOk)
+ if (response->getResponseCode() == RespOk) {
+ Response_Login *resp = qobject_cast(response);
+ if (!resp) {
+ disconnectFromServer();
+ return;
+ }
setStatus(StatusLoggedIn);
- else {
- emit serverError(response);
+ emit userInfoChanged(resp->getUserInfo());
+ } else {
+ emit serverError(response->getResponseCode());
setStatus(StatusDisconnecting);
}
}
@@ -78,7 +83,7 @@ void RemoteClient::readData()
setStatus(StatusLoggingIn);
Command_Login *cmdLogin = new Command_Login(userName, password);
- connect(cmdLogin, SIGNAL(finished(ResponseCode)), this, SLOT(loginResponse(ResponseCode)));
+ connect(cmdLogin, SIGNAL(finished(ProtocolResponse *)), this, SLOT(loginResponse(ProtocolResponse *)));
sendCommand(cmdLogin);
}
}
diff --git a/cockatrice/src/remoteclient.h b/cockatrice/src/remoteclient.h
index 10d7c417..30313fbb 100644
--- a/cockatrice/src/remoteclient.h
+++ b/cockatrice/src/remoteclient.h
@@ -2,7 +2,6 @@
#define REMOTECLIENT_H
#include
-#include "protocol_datastructures.h"
#include "abstractclient.h"
class QTimer;
@@ -22,7 +21,7 @@ private slots:
void readData();
void slotSocketError(QAbstractSocket::SocketError error);
void ping();
- void loginResponse(ResponseCode response);
+ void loginResponse(ProtocolResponse *response);
private:
static const int maxTimeout = 10;
diff --git a/cockatrice/src/selectzone.cpp b/cockatrice/src/selectzone.cpp
new file mode 100644
index 00000000..30156df6
--- /dev/null
+++ b/cockatrice/src/selectzone.cpp
@@ -0,0 +1,51 @@
+#include
+#include "selectzone.h"
+#include "gamescene.h"
+
+SelectZone::SelectZone(Player *_player, const QString &_name, bool _hasCardAttr, bool _isShufflable, bool _contentsKnown, QGraphicsItem *parent, bool isView)
+ : CardZone(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent, isView)
+{
+}
+
+void SelectZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->buttons().testFlag(Qt::LeftButton)) {
+ QPointF pos = event->pos();
+ if (pos.x() < 0)
+ pos.setX(0);
+ QRectF br = boundingRect();
+ if (pos.x() > br.width())
+ pos.setX(br.width());
+ if (pos.y() < 0)
+ pos.setY(0);
+ if (pos.y() > br.height())
+ pos.setY(br.height());
+
+ QRectF selectionRect = QRectF(selectionOrigin, pos).normalized();
+ for (int i = 0; i < cards.size(); ++i)
+ cards[i]->setSelected(selectionRect.intersects(cards[i]->mapRectToParent(cards[i]->boundingRect())));
+
+ static_cast(scene())->resizeRubberBand(scenePos() + pos);
+ event->accept();
+ }
+}
+
+void SelectZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ scene()->clearSelection();
+
+ selectionOrigin = event->pos();
+ static_cast(scene())->startRubberBand(event->scenePos());
+ event->accept();
+ } else
+ CardZone::mousePressEvent(event);
+}
+
+void SelectZone::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ selectionOrigin = QPoint();
+ static_cast(scene())->stopRubberBand();
+ event->accept();
+}
+
diff --git a/cockatrice/src/selectzone.h b/cockatrice/src/selectzone.h
new file mode 100644
index 00000000..23e82d1c
--- /dev/null
+++ b/cockatrice/src/selectzone.h
@@ -0,0 +1,18 @@
+#ifndef SELECTZONE_H
+#define SELECTZONE_H
+
+#include "cardzone.h"
+
+class SelectZone : public CardZone {
+ Q_OBJECT
+private:
+ QPointF selectionOrigin;
+protected:
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+public:
+ SelectZone(Player *_player, const QString &_name, bool _hasCardAttr, bool _isShufflable, bool _contentsKnown, QGraphicsItem *parent = 0, bool isView = false);
+};
+
+#endif
diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp
index 3023d911..0ac6a94b 100644
--- a/cockatrice/src/settingscache.cpp
+++ b/cockatrice/src/settingscache.cpp
@@ -21,7 +21,6 @@ SettingsCache::SettingsCache()
doubleClickToPlay = settings->value("interface/doubleclicktoplay", true).toBool();
cardInfoMinimized = settings->value("interface/cardinfominimized", false).toBool();
horizontalHand = settings->value("hand/horizontal", true).toBool();
- economicalGrid = settings->value("table/economic", false).toBool();
invertVerticalCoordinate = settings->value("table/invert_vertical", false).toBool();
tapAnimation = settings->value("cards/tapanimation", true).toBool();
@@ -117,13 +116,6 @@ void SettingsCache::setHorizontalHand(int _horizontalHand)
emit horizontalHandChanged();
}
-void SettingsCache::setEconomicalGrid(int _economicalGrid)
-{
- economicalGrid = _economicalGrid;
- settings->setValue("table/economic", economicalGrid);
- emit economicalGridChanged();
-}
-
void SettingsCache::setInvertVerticalCoordinate(int _invertVerticalCoordinate)
{
invertVerticalCoordinate = _invertVerticalCoordinate;
diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h
index 607c9187..196d9bab 100644
--- a/cockatrice/src/settingscache.h
+++ b/cockatrice/src/settingscache.h
@@ -18,7 +18,6 @@ signals:
void cardBackPicturePathChanged();
void picDownloadChanged();
void horizontalHandChanged();
- void economicalGridChanged();
void invertVerticalCoordinateChanged();
private:
QSettings *settings;
@@ -30,7 +29,6 @@ private:
bool doubleClickToPlay;
bool cardInfoMinimized;
bool horizontalHand;
- bool economicalGrid;
bool invertVerticalCoordinate;
bool tapAnimation;
bool zoneViewSortByName, zoneViewSortByType;
@@ -49,7 +47,6 @@ public:
bool getDoubleClickToPlay() const { return doubleClickToPlay; }
bool getCardInfoMinimized() const { return cardInfoMinimized; }
bool getHorizontalHand() const { return horizontalHand; }
- bool getEconomicalGrid() const { return economicalGrid; }
bool getInvertVerticalCoordinate() const { return invertVerticalCoordinate; }
bool getTapAnimation() const { return tapAnimation; }
bool getZoneViewSortByName() const { return zoneViewSortByName; }
@@ -68,7 +65,6 @@ public slots:
void setDoubleClickToPlay(int _doubleClickToPlay);
void setCardInfoMinimized(bool _cardInfoMinimized);
void setHorizontalHand(int _horizontalHand);
- void setEconomicalGrid(int _economicalGrid);
void setInvertVerticalCoordinate(int _invertVerticalCoordinate);
void setTapAnimation(int _tapAnimation);
void setZoneViewSortByName(int _zoneViewSortByName);
diff --git a/cockatrice/src/stackzone.cpp b/cockatrice/src/stackzone.cpp
index b164db1f..2a2cc4cb 100644
--- a/cockatrice/src/stackzone.cpp
+++ b/cockatrice/src/stackzone.cpp
@@ -5,9 +5,10 @@
#include "settingscache.h"
#include "player.h"
#include "protocol_items.h"
+#include "carddragitem.h"
StackZone::StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent)
- : CardZone(_p, "stack", false, false, true, parent), zoneHeight(_zoneHeight)
+ : SelectZone(_p, "stack", false, false, true, parent), zoneHeight(_zoneHeight)
{
connect(settingsCache, SIGNAL(stackBgPathChanged()), this, SLOT(updateBgPixmap()));
updateBgPixmap();
@@ -51,11 +52,16 @@ void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*optio
painter->fillRect(boundingRect(), QBrush(bgPixmap));
}
-void StackZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
+void StackZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
{
if (startZone == this)
return;
- player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false));
+
+ QList idList;
+ for (int i = 0; i < dragItems.size(); ++i)
+ idList.append(new CardId(dragItems[i]->getId()));
+
+ player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), idList, player->getId(), getName(), 0, 0, false));
}
void StackZone::reorganizeCards()
diff --git a/cockatrice/src/stackzone.h b/cockatrice/src/stackzone.h
index 7717a114..d03f151a 100644
--- a/cockatrice/src/stackzone.h
+++ b/cockatrice/src/stackzone.h
@@ -1,9 +1,9 @@
#ifndef STACKZONE_H
#define STACKZONE_H
-#include "cardzone.h"
+#include "selectzone.h"
-class StackZone : public CardZone {
+class StackZone : public SelectZone {
Q_OBJECT
private:
qreal zoneHeight;
@@ -12,7 +12,7 @@ private slots:
void updateBgPixmap();
public:
StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent = 0);
- void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
+ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void reorganizeCards();
diff --git a/cockatrice/src/tab_admin.cpp b/cockatrice/src/tab_admin.cpp
new file mode 100644
index 00000000..3c520077
--- /dev/null
+++ b/cockatrice/src/tab_admin.cpp
@@ -0,0 +1,66 @@
+#include
+#include
+#include
+#include
+#include "tab_admin.h"
+#include "abstractclient.h"
+#include "protocol_items.h"
+
+TabAdmin::TabAdmin(AbstractClient *_client, QWidget *parent)
+ : Tab(parent), client(_client)
+{
+ updateServerMessageButton = new QPushButton;
+ connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage()));
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(updateServerMessageButton);
+ vbox->addStretch();
+
+ adminGroupBox = new QGroupBox;
+ adminGroupBox->setLayout(vbox);
+ adminGroupBox->setEnabled(false);
+
+ unlockButton = new QPushButton;
+ connect(unlockButton, SIGNAL(clicked()), this, SLOT(actUnlock()));
+ lockButton = new QPushButton;
+ lockButton->setEnabled(false);
+ connect(lockButton, SIGNAL(clicked()), this, SLOT(actLock()));
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(adminGroupBox);
+ mainLayout->addWidget(unlockButton);
+ mainLayout->addWidget(lockButton);
+
+ retranslateUi();
+ setLayout(mainLayout);
+}
+
+void TabAdmin::retranslateUi()
+{
+ updateServerMessageButton->setText(tr("Update server &message"));
+ adminGroupBox->setTitle(tr("Server administration functions"));
+
+ unlockButton->setText(tr("&Unlock functions"));
+ lockButton->setText(tr("&Lock functions"));
+}
+
+void TabAdmin::actUpdateServerMessage()
+{
+ client->sendCommand(new Command_UpdateServerMessage());
+}
+
+void TabAdmin::actUnlock()
+{
+ if (QMessageBox::question(this, tr("Unlock administration functions"), tr("Do you really want to unlock the administration functions?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ adminGroupBox->setEnabled(true);
+ lockButton->setEnabled(true);
+ unlockButton->setEnabled(false);
+ }
+}
+
+void TabAdmin::actLock()
+{
+ adminGroupBox->setEnabled(false);
+ lockButton->setEnabled(false);
+ unlockButton->setEnabled(true);
+}
\ No newline at end of file
diff --git a/cockatrice/src/tab_admin.h b/cockatrice/src/tab_admin.h
new file mode 100644
index 00000000..f3d9b860
--- /dev/null
+++ b/cockatrice/src/tab_admin.h
@@ -0,0 +1,29 @@
+#ifndef TAB_ADMIN_H
+#define TAB_ADMIN_H
+
+#include "tab.h"
+
+class AbstractClient;
+
+class QGroupBox;
+class QPushButton;
+
+class TabAdmin : public Tab {
+ Q_OBJECT
+private:
+ AbstractClient *client;
+ QPushButton *updateServerMessageButton;
+ QGroupBox *adminGroupBox;
+ QPushButton *unlockButton, *lockButton;
+private slots:
+ void actUpdateServerMessage();
+
+ void actUnlock();
+ void actLock();
+public:
+ TabAdmin(AbstractClient *_client, QWidget *parent = 0);
+ void retranslateUi();
+ QString getTabText() const { return tr("Administration"); }
+};
+
+#endif
diff --git a/cockatrice/src/tab_chatchannel.cpp b/cockatrice/src/tab_chatchannel.cpp
deleted file mode 100644
index 515844f1..00000000
--- a/cockatrice/src/tab_chatchannel.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "tab_chatchannel.h"
-#include "abstractclient.h"
-#include "protocol_items.h"
-
-TabChatChannel::TabChatChannel(AbstractClient *_client, const QString &_channelName)
- : Tab(), client(_client), channelName(_channelName)
-{
- playerList = new QListWidget;
- playerList->setFixedWidth(150);
-
- textEdit = new QTextEdit;
- textEdit->setReadOnly(true);
- sayEdit = new QLineEdit;
- connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(textEdit);
- vbox->addWidget(sayEdit);
-
- QHBoxLayout *hbox = new QHBoxLayout;
- hbox->addLayout(vbox);
- hbox->addWidget(playerList);
-
- aLeaveChannel = new QAction(this);
- connect(aLeaveChannel, SIGNAL(triggered()), this, SLOT(actLeaveChannel()));
-
- tabMenu = new QMenu(this);
- tabMenu->addAction(aLeaveChannel);
-
- retranslateUi();
- setLayout(hbox);
-}
-
-TabChatChannel::~TabChatChannel()
-{
- emit channelClosing(this);
-}
-
-void TabChatChannel::retranslateUi()
-{
- tabMenu->setTitle(tr("C&hat channel"));
- aLeaveChannel->setText(tr("&Leave channel"));
-}
-
-QString TabChatChannel::sanitizeHtml(QString dirty) const
-{
- return dirty
- .replace("&", "&")
- .replace("<", "<")
- .replace(">", ">");
-}
-
-void TabChatChannel::sendMessage()
-{
- if (sayEdit->text().isEmpty())
- return;
-
- client->sendCommand(new Command_ChatSay(channelName, sayEdit->text()));
- sayEdit->clear();
-}
-
-void TabChatChannel::actLeaveChannel()
-{
- client->sendCommand(new Command_ChatLeaveChannel(channelName));
- deleteLater();
-}
-
-void TabChatChannel::processChatEvent(ChatEvent *event)
-{
- switch (event->getItemId()) {
- case ItemId_Event_ChatListPlayers: processListPlayersEvent(qobject_cast(event)); break;
- case ItemId_Event_ChatJoinChannel: processJoinChannelEvent(qobject_cast(event)); break;
- case ItemId_Event_ChatLeaveChannel: processLeaveChannelEvent(qobject_cast(event)); break;
- case ItemId_Event_ChatSay: processSayEvent(qobject_cast(event)); break;
- default: ;
- }
-}
-
-void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event)
-{
- const QList &players = event->getPlayerList();
- for (int i = 0; i < players.size(); ++i)
- playerList->addItem(players[i]->getName());
-}
-
-void TabChatChannel::processJoinChannelEvent(Event_ChatJoinChannel *event)
-{
- textEdit->append(tr("%1 has joined the channel.").arg(sanitizeHtml(event->getUserInfo()->getName())));
- playerList->addItem(event->getUserInfo()->getName());
- emit userEvent();
-}
-
-void TabChatChannel::processLeaveChannelEvent(Event_ChatLeaveChannel *event)
-{
- textEdit->append(tr("%1 has left the channel.").arg(sanitizeHtml(event->getPlayerName())));
- for (int i = 0; i < playerList->count(); ++i)
- if (playerList->item(i)->text() == event->getPlayerName()) {
- delete playerList->takeItem(i);
- break;
- }
- emit userEvent();
-}
-
-void TabChatChannel::processSayEvent(Event_ChatSay *event)
-{
- if (event->getPlayerName().isEmpty())
- textEdit->append(QString("%1getMessage())));
- else
- textEdit->append(QString("%1: %2").arg(sanitizeHtml(event->getPlayerName())).arg(sanitizeHtml(event->getMessage())));
- emit userEvent();
-}
diff --git a/cockatrice/src/tab_chatchannel.h b/cockatrice/src/tab_chatchannel.h
deleted file mode 100644
index 2c329199..00000000
--- a/cockatrice/src/tab_chatchannel.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef TAB_CHATCHANNEL_H
-#define TAB_CHATCHANNEL_H
-
-#include "tab.h"
-
-class AbstractClient;
-class QListWidget;
-class QTextEdit;
-class QLineEdit;
-class ChatEvent;
-class Event_ChatListPlayers;
-class Event_ChatJoinChannel;
-class Event_ChatLeaveChannel;
-class Event_ChatSay;
-
-class TabChatChannel : public Tab {
- Q_OBJECT
-private:
- AbstractClient *client;
- QString channelName;
-
- QListWidget *playerList;
- QTextEdit *textEdit;
- QLineEdit *sayEdit;
-
- QAction *aLeaveChannel;
- QString sanitizeHtml(QString dirty) const;
-signals:
- void channelClosing(TabChatChannel *tab);
-private slots:
- void sendMessage();
- void actLeaveChannel();
-
- void processListPlayersEvent(Event_ChatListPlayers *event);
- void processJoinChannelEvent(Event_ChatJoinChannel *event);
- void processLeaveChannelEvent(Event_ChatLeaveChannel *event);
- void processSayEvent(Event_ChatSay *event);
-public:
- TabChatChannel(AbstractClient *_client, const QString &_channelName);
- ~TabChatChannel();
- void retranslateUi();
- void processChatEvent(ChatEvent *event);
- QString getChannelName() const { return channelName; }
- QString getTabText() const { return channelName; }
-};
-
-#endif
diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp
index 8d9a9511..13719e78 100644
--- a/cockatrice/src/tab_game.cpp
+++ b/cockatrice/src/tab_game.cpp
@@ -169,6 +169,8 @@ TabGame::TabGame(QList &_clients, int _gameId, const QString &
cardInfo = new CardInfoWidget(CardInfoWidget::ModeGameTab);
playerListWidget = new PlayerListWidget;
playerListWidget->setFocusPolicy(Qt::NoFocus);
+ timeElapsedLabel = new QLabel;
+ timeElapsedLabel->setAlignment(Qt::AlignCenter);
messageLog = new MessageLogWidget;
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
@@ -190,6 +192,7 @@ TabGame::TabGame(QList &_clients, int _gameId, const QString &
QVBoxLayout *verticalLayout = new QVBoxLayout;
verticalLayout->addWidget(cardInfo);
verticalLayout->addWidget(playerListWidget, 1);
+ verticalLayout->addWidget(timeElapsedLabel);
verticalLayout->addWidget(messageLog, 5);
verticalLayout->addLayout(hLayout);
@@ -651,6 +654,13 @@ void TabGame::eventPing(Event_Ping *event, GameEventContext * /*context*/)
const QList &pingList = event->getPingList();
for (int i = 0; i < pingList.size(); ++i)
playerListWidget->updatePing(pingList[i]->getPlayerId(), pingList[i]->getPingTime());
+
+ int seconds = event->getSecondsElapsed();
+ int minutes = seconds / 60;
+ seconds -= minutes * 60;
+ int hours = minutes / 60;
+ minutes -= hours * 60;
+ timeElapsedLabel->setText(QString::number(hours).rightJustified(2, '0') + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0'));
}
void TabGame::newCardAdded(AbstractCardItem *card)
diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h
index db7ebd0b..0a022adf 100644
--- a/cockatrice/src/tab_game.h
+++ b/cockatrice/src/tab_game.h
@@ -99,6 +99,7 @@ private:
CardInfoWidget *infoPopup;
CardInfoWidget *cardInfo;
PlayerListWidget *playerListWidget;
+ QLabel *timeElapsedLabel;
MessageLogWidget *messageLog;
QLabel *sayLabel;
QLineEdit *sayEdit;
diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp
new file mode 100644
index 00000000..8b7fb13b
--- /dev/null
+++ b/cockatrice/src/tab_room.cpp
@@ -0,0 +1,282 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dlg_creategame.h"
+#include "tab_room.h"
+#include "userlist.h"
+#include "abstractclient.h"
+#include "protocol_items.h"
+#include "gamesmodel.h"
+
+#include
+
+GameSelector::GameSelector(AbstractClient *_client, int _roomId, QWidget *parent)
+ : QGroupBox(parent), client(_client), roomId(_roomId)
+{
+ gameListView = new QTreeView;
+ gameListModel = new GamesModel(this);
+ gameListProxyModel = new GamesProxyModel(this);
+ gameListProxyModel->setSourceModel(gameListModel);
+ gameListView->setModel(gameListProxyModel);
+ gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+
+ showFullGamesCheckBox = new QCheckBox;
+ createButton = new QPushButton;
+ joinButton = new QPushButton;
+ spectateButton = new QPushButton;
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addWidget(showFullGamesCheckBox);
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(createButton);
+ buttonLayout->addWidget(joinButton);
+ buttonLayout->addWidget(spectateButton);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(gameListView);
+ mainLayout->addLayout(buttonLayout);
+
+ retranslateUi();
+ setLayout(mainLayout);
+
+ setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount());
+ setMinimumHeight(400);
+
+ connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
+ connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
+ connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
+ connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin()));
+}
+
+void GameSelector::showFullGamesChanged(int state)
+{
+ gameListProxyModel->setFullGamesVisible(state);
+}
+
+void GameSelector::actCreate()
+{
+ DlgCreateGame dlg(client, roomId, this);
+ dlg.exec();
+}
+
+void GameSelector::checkResponse(ResponseCode response)
+{
+ createButton->setEnabled(true);
+ joinButton->setEnabled(true);
+ spectateButton->setEnabled(true);
+
+ switch (response) {
+ case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break;
+ case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break;
+ case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break;
+ case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break;
+ default: ;
+ }
+}
+
+void GameSelector::actJoin()
+{
+ bool spectator = sender() == spectateButton;
+
+ QModelIndex ind = gameListView->currentIndex();
+ if (!ind.isValid())
+ return;
+ ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt());
+ QString password;
+ if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) {
+ bool ok;
+ password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
+ if (!ok)
+ return;
+ }
+
+ Command_JoinGame *commandJoinGame = new Command_JoinGame(roomId, game->getGameId(), password, spectator);
+ connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
+ client->sendCommand(commandJoinGame);
+
+ createButton->setEnabled(false);
+ joinButton->setEnabled(false);
+ spectateButton->setEnabled(false);
+}
+
+void GameSelector::retranslateUi()
+{
+ setTitle(tr("Games"));
+ showFullGamesCheckBox->setText(tr("Show &full games"));
+ createButton->setText(tr("C&reate"));
+ joinButton->setText(tr("&Join"));
+ spectateButton->setText(tr("J&oin as spectator"));
+}
+
+void GameSelector::processGameInfo(ServerInfo_Game *info)
+{
+ gameListModel->updateGameList(info);
+}
+
+ChatView::ChatView(const QString &_ownName, QWidget *parent)
+ : QTextEdit(parent), ownName(_ownName)
+{
+ setTextInteractionFlags(Qt::TextSelectableByMouse);
+
+ QTextTableFormat format;
+ format.setBorderStyle(QTextFrameFormat::BorderStyle_None);
+ table = textCursor().insertTable(1, 3, format);
+}
+
+void ChatView::appendMessage(const QString &sender, const QString &message)
+{
+ QTextCursor cellCursor = table->cellAt(table->rows() - 1, 0).lastCursorPosition();
+ cellCursor.insertText(QDateTime::currentDateTime().toString("[hh:mm]"));
+ QTextTableCell senderCell = table->cellAt(table->rows() - 1, 1);
+ QTextCharFormat senderFormat;
+ if (sender == ownName) {
+ senderFormat.setFontWeight(QFont::Bold);
+ senderFormat.setForeground(Qt::red);
+ } else
+ senderFormat.setForeground(Qt::blue);
+ senderCell.setFormat(senderFormat);
+ cellCursor = senderCell.lastCursorPosition();
+ cellCursor.insertText(sender);
+ QTextTableCell messageCell = table->cellAt(table->rows() - 1, 2);
+ QTextCharFormat messageFormat;
+ if (sender.isEmpty())
+ messageFormat.setForeground(Qt::darkGreen);
+ messageCell.setFormat(messageFormat);
+ cellCursor = messageCell.lastCursorPosition();
+ cellCursor.insertText(message);
+
+ table->appendRows(1);
+
+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+}
+
+TabRoom::TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info)
+ : Tab(), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName)
+{
+ gameSelector = new GameSelector(client, roomId);
+ userList = new UserList(client, false);
+ connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
+
+ chatView = new ChatView(ownName);
+ sayLabel = new QLabel;
+ sayEdit = new QLineEdit;
+ sayLabel->setBuddy(sayEdit);
+ connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
+
+ QHBoxLayout *sayHbox = new QHBoxLayout;
+ sayHbox->addWidget(sayLabel);
+ sayHbox->addWidget(sayEdit);
+
+ QVBoxLayout *chatVbox = new QVBoxLayout;
+ chatVbox->addWidget(chatView);
+ chatVbox->addLayout(sayHbox);
+
+ chatGroupBox = new QGroupBox;
+ chatGroupBox->setLayout(chatVbox);
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(gameSelector);
+ vbox->addWidget(chatGroupBox);
+
+ QHBoxLayout *hbox = new QHBoxLayout;
+ hbox->addLayout(vbox, 3);
+ hbox->addWidget(userList, 1);
+
+ aLeaveRoom = new QAction(this);
+ connect(aLeaveRoom, SIGNAL(triggered()), this, SLOT(actLeaveRoom()));
+
+ tabMenu = new QMenu(this);
+ tabMenu->addAction(aLeaveRoom);
+
+ retranslateUi();
+ setLayout(hbox);
+
+ const QList users = info->getUserList();
+ for (int i = 0; i < users.size(); ++i)
+ userList->processUserInfo(users[i]);
+
+ const QList games = info->getGameList();
+ for (int i = 0; i < games.size(); ++i)
+ gameSelector->processGameInfo(games[i]);
+}
+
+TabRoom::~TabRoom()
+{
+ emit roomClosing(this);
+}
+
+void TabRoom::retranslateUi()
+{
+ sayLabel->setText(tr("&Say:"));
+ chatGroupBox->setTitle(tr("Chat"));
+ tabMenu->setTitle(tr("&Room"));
+ aLeaveRoom->setText(tr("&Leave room"));
+}
+
+QString TabRoom::sanitizeHtml(QString dirty) const
+{
+ return dirty
+ .replace("&", "&")
+ .replace("<", "<")
+ .replace(">", ">");
+}
+
+void TabRoom::sendMessage()
+{
+ if (sayEdit->text().isEmpty())
+ return;
+
+ client->sendCommand(new Command_RoomSay(roomId, sayEdit->text()));
+ sayEdit->clear();
+}
+
+void TabRoom::actLeaveRoom()
+{
+ client->sendCommand(new Command_LeaveRoom(roomId));
+ deleteLater();
+}
+
+void TabRoom::processRoomEvent(RoomEvent *event)
+{
+ switch (event->getItemId()) {
+ case ItemId_Event_ListGames: processListGamesEvent(qobject_cast(event)); break;
+ case ItemId_Event_JoinRoom: processJoinRoomEvent(qobject_cast(event)); break;
+ case ItemId_Event_LeaveRoom: processLeaveRoomEvent(qobject_cast(event)); break;
+ case ItemId_Event_RoomSay: processSayEvent(qobject_cast(event)); break;
+ default: ;
+ }
+}
+
+void TabRoom::processListGamesEvent(Event_ListGames *event)
+{
+ const QList &gameList = event->getGameList();
+ for (int i = 0; i < gameList.size(); ++i)
+ gameSelector->processGameInfo(gameList[i]);
+}
+
+void TabRoom::processJoinRoomEvent(Event_JoinRoom *event)
+{
+ chatView->appendMessage(QString(), tr("%1 has joined the room.").arg(event->getUserInfo()->getName()));
+ userList->processUserInfo(event->getUserInfo());
+}
+
+void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event)
+{
+ chatView->appendMessage(QString(), tr("%1 has left the room.").arg(event->getPlayerName()));
+ userList->deleteUser(event->getPlayerName());
+}
+
+void TabRoom::processSayEvent(Event_RoomSay *event)
+{
+ chatView->appendMessage(event->getPlayerName(), event->getMessage());
+ emit userEvent();
+}
diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h
new file mode 100644
index 00000000..fd4f8f5c
--- /dev/null
+++ b/cockatrice/src/tab_room.h
@@ -0,0 +1,100 @@
+#ifndef TAB_ROOM_H
+#define TAB_ROOM_H
+
+#include "tab.h"
+#include "protocol_datastructures.h"
+#include
+#include
+
+class AbstractClient;
+class UserList;
+class QLabel;
+class QTextEdit;
+class QLineEdit;
+class QTreeView;
+class QPushButton;
+class QTextTable;
+class QCheckBox;
+class GamesModel;
+class GamesProxyModel;
+class RoomEvent;
+class ServerInfo_Room;
+class ServerInfo_Game;
+class Event_ListGames;
+class Event_JoinRoom;
+class Event_LeaveRoom;
+class Event_RoomSay;
+
+class GameSelector : public QGroupBox {
+ Q_OBJECT
+private slots:
+ void showFullGamesChanged(int state);
+ void actCreate();
+ void actJoin();
+ void checkResponse(ResponseCode response);
+signals:
+ void gameJoined(int gameId);
+private:
+ AbstractClient *client;
+ int roomId;
+
+ QTreeView *gameListView;
+ GamesModel *gameListModel;
+ GamesProxyModel *gameListProxyModel;
+ QPushButton *createButton, *joinButton, *spectateButton;
+ QCheckBox *showFullGamesCheckBox;
+public:
+ GameSelector(AbstractClient *_client, int _roomId, QWidget *parent = 0);
+ void retranslateUi();
+ void processGameInfo(ServerInfo_Game *info);
+};
+
+class ChatView : public QTextEdit {
+ Q_OBJECT;
+private:
+ QTextTable *table;
+ QString ownName;
+public:
+ ChatView(const QString &_ownName, QWidget *parent = 0);
+ void appendMessage(const QString &sender, const QString &message);
+};
+
+class TabRoom : public Tab {
+ Q_OBJECT
+private:
+ AbstractClient *client;
+ int roomId;
+ QString roomName;
+ QString ownName;
+
+ GameSelector *gameSelector;
+ UserList *userList;
+ ChatView *chatView;
+ QLabel *sayLabel;
+ QLineEdit *sayEdit;
+ QGroupBox *chatGroupBox;
+
+ QAction *aLeaveRoom;
+ QString sanitizeHtml(QString dirty) const;
+signals:
+ void roomClosing(TabRoom *tab);
+ void openMessageDialog(const QString &userName, bool focus);
+private slots:
+ void sendMessage();
+ void actLeaveRoom();
+
+ void processListGamesEvent(Event_ListGames *event);
+ void processJoinRoomEvent(Event_JoinRoom *event);
+ void processLeaveRoomEvent(Event_LeaveRoom *event);
+ void processSayEvent(Event_RoomSay *event);
+public:
+ TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info);
+ ~TabRoom();
+ void retranslateUi();
+ void processRoomEvent(RoomEvent *event);
+ int getRoomId() const { return roomId; }
+ QString getChannelName() const { return roomName; }
+ QString getTabText() const { return roomName; }
+};
+
+#endif
diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp
index 04eb7e1b..5c4766c2 100644
--- a/cockatrice/src/tab_server.cpp
+++ b/cockatrice/src/tab_server.cpp
@@ -10,126 +10,25 @@
#include
#include
#include "tab_server.h"
-#include "gamesmodel.h"
-#include "dlg_creategame.h"
#include "abstractclient.h"
#include "protocol.h"
#include "protocol_items.h"
-#include "pixmapgenerator.h"
+#include "userlist.h"
+#include "userinfobox.h"
+//#include "pixmapgenerator.h"
#include
-GameSelector::GameSelector(AbstractClient *_client, QWidget *parent)
+RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent), client(_client)
{
- gameListView = new QTreeView;
- gameListModel = new GamesModel(this);
- gameListProxyModel = new GamesProxyModel(this);
- gameListProxyModel->setSourceModel(gameListModel);
- gameListView->setModel(gameListProxyModel);
- gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
-
- showFullGamesCheckBox = new QCheckBox;
- createButton = new QPushButton;
- joinButton = new QPushButton;
- spectateButton = new QPushButton;
- QHBoxLayout *buttonLayout = new QHBoxLayout;
- buttonLayout->addWidget(showFullGamesCheckBox);
- buttonLayout->addStretch();
- buttonLayout->addWidget(createButton);
- buttonLayout->addWidget(joinButton);
- buttonLayout->addWidget(spectateButton);
-
- QVBoxLayout *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(gameListView);
- mainLayout->addLayout(buttonLayout);
-
- retranslateUi();
- setLayout(mainLayout);
-
- setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount());
- setMinimumHeight(400);
-
- connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
- connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
- connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
- connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin()));
-
- connect(client, SIGNAL(listGamesEventReceived(Event_ListGames *)), this, SLOT(processListGamesEvent(Event_ListGames *)));
- client->sendCommand(new Command_ListGames);
-}
-
-void GameSelector::showFullGamesChanged(int state)
-{
- gameListProxyModel->setFullGamesVisible(state);
-}
-
-void GameSelector::actCreate()
-{
- DlgCreateGame dlg(client, this);
- dlg.exec();
-}
-
-void GameSelector::checkResponse(ResponseCode response)
-{
- createButton->setEnabled(true);
- joinButton->setEnabled(true);
- spectateButton->setEnabled(true);
-
- switch (response) {
- case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break;
- case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break;
- case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break;
- case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break;
- default: ;
- }
-}
-
-void GameSelector::actJoin()
-{
- bool spectator = sender() == spectateButton;
-
- QModelIndex ind = gameListView->currentIndex();
- if (!ind.isValid())
- return;
- ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt());
- QString password;
- if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) {
- bool ok;
- password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
- if (!ok)
- return;
- }
-
- Command_JoinGame *commandJoinGame = new Command_JoinGame(game->getGameId(), password, spectator);
- connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
- client->sendCommand(commandJoinGame);
-
- createButton->setEnabled(false);
- joinButton->setEnabled(false);
- spectateButton->setEnabled(false);
-}
-
-void GameSelector::retranslateUi()
-{
- setTitle(tr("Games"));
- showFullGamesCheckBox->setText(tr("&Show full games"));
- createButton->setText(tr("C&reate"));
- joinButton->setText(tr("&Join"));
- spectateButton->setText(tr("J&oin as spectator"));
-}
-
-void GameSelector::processListGamesEvent(Event_ListGames *event)
-{
- const QList &gamesToUpdate = event->getGameList();
- for (int i = 0; i < gamesToUpdate.size(); ++i)
- gameListModel->updateGameList(gamesToUpdate[i]);
-}
-
-ChatChannelSelector::ChatChannelSelector(AbstractClient *_client, QWidget *parent)
- : QGroupBox(parent), client(_client)
-{
- channelList = new QTreeWidget;
- channelList->setRootIsDecorated(false);
+ roomList = new QTreeWidget;
+ roomList->setRootIsDecorated(false);
+ roomList->setColumnCount(4);
+ roomList->header()->setStretchLastSection(false);
+ roomList->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+ roomList->header()->setResizeMode(1, QHeaderView::Stretch);
+ roomList->header()->setResizeMode(2, QHeaderView::ResizeToContents);
+ roomList->header()->setResizeMode(3, QHeaderView::ResizeToContents);
joinButton = new QPushButton;
connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked()));
@@ -137,281 +36,111 @@ ChatChannelSelector::ChatChannelSelector(AbstractClient *_client, QWidget *paren
buttonLayout->addStretch();
buttonLayout->addWidget(joinButton);
QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(channelList);
+ vbox->addWidget(roomList);
vbox->addLayout(buttonLayout);
retranslateUi();
setLayout(vbox);
- connect(client, SIGNAL(listChatChannelsEventReceived(Event_ListChatChannels *)), this, SLOT(processListChatChannelsEvent(Event_ListChatChannels *)));
- client->sendCommand(new Command_ListChatChannels);
+ connect(client, SIGNAL(listRoomsEventReceived(Event_ListRooms *)), this, SLOT(processListRoomsEvent(Event_ListRooms *)));
+ client->sendCommand(new Command_ListRooms);
}
-void ChatChannelSelector::retranslateUi()
+void RoomSelector::retranslateUi()
{
- setTitle(tr("Chat channels"));
+ setTitle(tr("Rooms"));
joinButton->setText(tr("Joi&n"));
- QTreeWidgetItem *header = channelList->headerItem();
- header->setText(0, tr("Channel"));
+ QTreeWidgetItem *header = roomList->headerItem();
+ header->setText(0, tr("Room"));
header->setText(1, tr("Description"));
header->setText(2, tr("Players"));
+ header->setText(3, tr("Games"));
header->setTextAlignment(2, Qt::AlignRight);
+ header->setTextAlignment(3, Qt::AlignRight);
}
-void ChatChannelSelector::processListChatChannelsEvent(Event_ListChatChannels *event)
+void RoomSelector::processListRoomsEvent(Event_ListRooms *event)
{
- const QList &channelsToUpdate = event->getChannelList();
- for (int i = 0; i < channelsToUpdate.size(); ++i) {
- ServerInfo_ChatChannel *channel = channelsToUpdate[i];
+ const QList &roomsToUpdate = event->getRoomList();
+ for (int i = 0; i < roomsToUpdate.size(); ++i) {
+ ServerInfo_Room *room = roomsToUpdate[i];
- for (int j = 0; j < channelList->topLevelItemCount(); ++j) {
- QTreeWidgetItem *twi = channelList->topLevelItem(j);
- if (twi->text(0) == channel->getName()) {
- twi->setText(1, channel->getDescription());
- twi->setText(2, QString::number(channel->getPlayerCount()));
+ for (int j = 0; j < roomList->topLevelItemCount(); ++j) {
+ QTreeWidgetItem *twi = roomList->topLevelItem(j);
+ if (twi->data(0, Qt::UserRole).toInt() == room->getRoomId()) {
+ twi->setData(0, Qt::DisplayRole, room->getName());
+ twi->setData(1, Qt::DisplayRole, room->getDescription());
+ twi->setData(2, Qt::DisplayRole, room->getPlayerCount());
+ twi->setData(3, Qt::DisplayRole, room->getGameCount());
return;
}
}
- QTreeWidgetItem *twi = new QTreeWidgetItem(QStringList() << channel->getName() << channel->getDescription() << QString::number(channel->getPlayerCount()));
+ QTreeWidgetItem *twi = new QTreeWidgetItem;
+ twi->setData(0, Qt::UserRole, room->getRoomId());
+ twi->setData(0, Qt::DisplayRole, room->getName());
+ twi->setData(1, Qt::DisplayRole, room->getDescription());
+ twi->setData(2, Qt::DisplayRole, room->getPlayerCount());
+ twi->setData(3, Qt::DisplayRole, room->getGameCount());
twi->setTextAlignment(2, Qt::AlignRight);
- channelList->addTopLevelItem(twi);
- channelList->resizeColumnToContents(0);
- channelList->resizeColumnToContents(1);
- channelList->resizeColumnToContents(2);
- if (channel->getAutoJoin())
- joinChannel(channel->getName());
+ twi->setTextAlignment(3, Qt::AlignRight);
+ roomList->addTopLevelItem(twi);
+ if (room->getAutoJoin())
+ joinRoom(room->getRoomId(), false);
}
}
-void ChatChannelSelector::joinChannel(const QString &channelName)
+void RoomSelector::joinRoom(int id, bool setCurrent)
{
- Command_ChatJoinChannel *command = new Command_ChatJoinChannel(channelName);
- connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(joinFinished(ResponseCode)));
+ Command_JoinRoom *command = new Command_JoinRoom(id);
+ command->setExtraData(setCurrent);
+ connect(command, SIGNAL(finished(ProtocolResponse *)), this, SLOT(joinFinished(ProtocolResponse *)));
client->sendCommand(command);
}
-void ChatChannelSelector::joinClicked()
+void RoomSelector::joinClicked()
{
- QTreeWidgetItem *twi = channelList->currentItem();
+ QTreeWidgetItem *twi = roomList->currentItem();
if (!twi)
return;
- QString channelName = twi->text(0);
- joinChannel(channelName);
+ joinRoom(twi->data(0, Qt::UserRole).toInt(), true);
}
-void ChatChannelSelector::joinFinished(ResponseCode resp)
+void RoomSelector::joinFinished(ProtocolResponse *r)
{
- if (resp != RespOk)
+ if (r->getResponseCode() != RespOk)
return;
-
- Command_ChatJoinChannel *command = qobject_cast(sender());
- QString channelName = command->getChannel();
-
- emit channelJoined(channelName);
-}
-
-ServerMessageLog::ServerMessageLog(AbstractClient *_client, QWidget *parent)
- : QGroupBox(parent)
-{
- textEdit = new QTextEdit;
- textEdit->setReadOnly(true);
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(textEdit);
-
- setLayout(vbox);
- retranslateUi();
-
- connect(_client, SIGNAL(serverMessageEventReceived(Event_ServerMessage *)), this, SLOT(processServerMessageEvent(Event_ServerMessage *)));
-}
-
-void ServerMessageLog::retranslateUi()
-{
- setTitle(tr("Server messages"));
-}
-
-void ServerMessageLog::processServerMessageEvent(Event_ServerMessage *event)
-{
- textEdit->append(event->getMessage());
-}
-
-UserListTWI::UserListTWI()
- : QTreeWidgetItem(Type)
-{
-}
-
-bool UserListTWI::operator<(const QTreeWidgetItem &other) const
-{
- // Equal user level => sort by name
- if (data(0, Qt::UserRole) == other.data(0, Qt::UserRole))
- return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower();
- // Else sort by user level
- return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt();
-}
-
-UserList::UserList(AbstractClient *_client, QWidget *parent)
- : QGroupBox(parent)
-{
- userTree = new QTreeWidget;
- userTree->setColumnCount(3);
- userTree->header()->setResizeMode(QHeaderView::ResizeToContents);
- userTree->setHeaderHidden(true);
- userTree->setRootIsDecorated(false);
- userTree->setIconSize(QSize(20, 12));
- connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(userTree);
-
- setLayout(vbox);
-
- retranslateUi();
-
- connect(_client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *)));
- connect(_client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *)));
-
- Command_ListUsers *cmd = new Command_ListUsers;
- connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
- _client->sendCommand(cmd);
-}
-
-void UserList::retranslateUi()
-{
- setTitle(tr("Users online: %1").arg(userTree->topLevelItemCount()));
-}
-
-void UserList::processUserInfo(ServerInfo_User *user)
-{
- QTreeWidgetItem *item = 0;
- for (int i = 0; i < userTree->topLevelItemCount(); ++i) {
- QTreeWidgetItem *temp = userTree->topLevelItem(i);
- if (temp->data(2, Qt::UserRole) == user->getName()) {
- item = temp;
- break;
- }
- }
- if (!item) {
- item = new UserListTWI;
- userTree->addTopLevelItem(item);
- retranslateUi();
- }
- item->setData(0, Qt::UserRole, user->getUserLevel());
- item->setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, user->getUserLevel())));
- item->setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry())));
- item->setData(2, Qt::UserRole, user->getName());
- item->setData(2, Qt::DisplayRole, user->getName());
-}
-
-void UserList::processResponse(ProtocolResponse *response)
-{
- Response_ListUsers *resp = qobject_cast(response);
+ Response_JoinRoom *resp = qobject_cast(r);
if (!resp)
return;
- const QList &respList = resp->getUserList();
- for (int i = 0; i < respList.size(); ++i)
- processUserInfo(respList[i]);
-
- userTree->sortItems(1, Qt::AscendingOrder);
+ emit roomJoined(resp->getRoomInfo(), static_cast(sender())->getExtraData().toBool());
}
-void UserList::processUserJoinedEvent(Event_UserJoined *event)
-{
- processUserInfo(event->getUserInfo());
- userTree->sortItems(1, Qt::AscendingOrder);
-}
-
-void UserList::processUserLeftEvent(Event_UserLeft *event)
-{
- for (int i = 0; i < userTree->topLevelItemCount(); ++i)
- if (userTree->topLevelItem(i)->data(2, Qt::UserRole) == event->getUserName()) {
- emit userLeft(event->getUserName());
- delete userTree->takeTopLevelItem(i);
- retranslateUi();
- break;
- }
-}
-
-void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
-{
- emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
-}
-
-UserInfoBox::UserInfoBox(AbstractClient *_client, QWidget *parent)
- : QWidget(parent)
-{
- avatarLabel = new QLabel;
- nameLabel = new QLabel;
- QFont nameFont = nameLabel->font();
- nameFont.setBold(true);
- nameFont.setPointSize(nameFont.pointSize() * 1.5);
- nameLabel->setFont(nameFont);
- countryLabel1 = new QLabel;
- countryLabel2 = new QLabel;
- userLevelLabel1 = new QLabel;
- userLevelLabel2 = new QLabel;
-
- QGridLayout *mainLayout = new QGridLayout;
- mainLayout->addWidget(avatarLabel, 0, 0, 3, 1);
- mainLayout->addWidget(nameLabel, 0, 1, 1, 2);
- mainLayout->addWidget(countryLabel1, 1, 1, 1, 1);
- mainLayout->addWidget(countryLabel2, 1, 2, 1, 1);
- mainLayout->addWidget(userLevelLabel1, 2, 1, 1, 1);
- mainLayout->addWidget(userLevelLabel2, 2, 2, 1, 1);
-
- setLayout(mainLayout);
-
- Command_GetUserInfo *cmd = new Command_GetUserInfo;
- connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
- _client->sendCommand(cmd);
-}
-
-void UserInfoBox::retranslateUi()
-{
- countryLabel1->setText(tr("Location:"));
- userLevelLabel1->setText(tr("User level:"));
-}
-
-void UserInfoBox::processResponse(ProtocolResponse *response)
-{
- Response_GetUserInfo *resp = qobject_cast(response);
- if (!resp)
- return;
- ServerInfo_User *user = resp->getUserInfo();
-
- QPixmap avatarPixmap;
- if (!avatarPixmap.loadFromData(user->getAvatarBmp()))
- avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, user->getUserLevel());
- avatarLabel->setPixmap(avatarPixmap);
-
- nameLabel->setText(user->getName());
- countryLabel2->setPixmap(CountryPixmapGenerator::generatePixmap(15, user->getCountry()));
- userLevelLabel2->setPixmap(UserLevelPixmapGenerator::generatePixmap(15, user->getUserLevel()));
-}
-
-TabServer::TabServer(AbstractClient *_client, QWidget *parent)
+TabServer::TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent)
: Tab(parent), client(_client)
{
- gameSelector = new GameSelector(client);
- chatChannelSelector = new ChatChannelSelector(client);
- serverMessageLog = new ServerMessageLog(client);
- userInfoBox = new UserInfoBox(client);
- userList = new UserList(client);
+ roomSelector = new RoomSelector(client);
+ serverInfoBox = new QTextBrowser;
+ userInfoBox = new UserInfoBox(_client, false);
+ userInfoBox->updateInfo(userInfo);
+ userList = new UserList(client, true);
- connect(gameSelector, SIGNAL(gameJoined(int)), this, SIGNAL(gameJoined(int)));
- connect(chatChannelSelector, SIGNAL(channelJoined(const QString &)), this, SIGNAL(chatChannelJoined(const QString &)));
+ connect(roomSelector, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SIGNAL(roomJoined(ServerInfo_Room *, bool)));
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
- connect(userList, SIGNAL(userLeft(const QString &)), this, SIGNAL(userLeft(const QString &)));
- QHBoxLayout *hbox = new QHBoxLayout;
- hbox->addWidget(chatChannelSelector);
- hbox->addWidget(serverMessageLog);
+ connect(client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *)));
+ connect(client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *)));
+ connect(client, SIGNAL(serverMessageEventReceived(Event_ServerMessage *)), this, SLOT(processServerMessageEvent(Event_ServerMessage *)));
+
+ Command_ListUsers *cmd = new Command_ListUsers;
+ connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processListUsersResponse(ProtocolResponse *)));
+ client->sendCommand(cmd);
QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(gameSelector);
- vbox->addLayout(hbox);
+ vbox->addWidget(roomSelector);
+ vbox->addWidget(serverInfoBox);
QVBoxLayout *vbox2 = new QVBoxLayout;
vbox2->addWidget(userInfoBox);
@@ -426,9 +155,38 @@ TabServer::TabServer(AbstractClient *_client, QWidget *parent)
void TabServer::retranslateUi()
{
- gameSelector->retranslateUi();
- chatChannelSelector->retranslateUi();
- serverMessageLog->retranslateUi();
+ roomSelector->retranslateUi();
userInfoBox->retranslateUi();
userList->retranslateUi();
}
+
+void TabServer::processServerMessageEvent(Event_ServerMessage *event)
+{
+ serverInfoBox->setHtml(event->getMessage());
+ emit userEvent();
+}
+
+void TabServer::processListUsersResponse(ProtocolResponse *response)
+{
+ Response_ListUsers *resp = qobject_cast(response);
+ if (!resp)
+ return;
+
+ const QList &respList = resp->getUserList();
+ for (int i = 0; i < respList.size(); ++i)
+ userList->processUserInfo(respList[i]);
+
+ userList->sortItems();
+}
+
+void TabServer::processUserJoinedEvent(Event_UserJoined *event)
+{
+ userList->processUserInfo(event->getUserInfo());
+ userList->sortItems();
+}
+
+void TabServer::processUserLeftEvent(Event_UserLeft *event)
+{
+ if (userList->deleteUser(event->getUserName()))
+ emit userLeft(event->getUserName());
+}
\ No newline at end of file
diff --git a/cockatrice/src/tab_server.h b/cockatrice/src/tab_server.h
index 3ddd89cd..0bdf4570 100644
--- a/cockatrice/src/tab_server.h
+++ b/cockatrice/src/tab_server.h
@@ -3,132 +3,62 @@
#include
#include
+#include
#include "tab.h"
-#include "protocol_datastructures.h"
class AbstractClient;
-class QTreeView;
-class QTreeWidget;
-class QTreeWidgetItem;
-class QPushButton;
-class QCheckBox;
class QTextEdit;
class QLabel;
+class UserList;
+class QPushButton;
+class UserInfoBox;
-class GamesModel;
-class GamesProxyModel;
-
-class Event_ListGames;
-class Event_ListChatChannels;
+class Event_ListRooms;
class Event_ServerMessage;
class Event_UserJoined;
class Event_UserLeft;
class ProtocolResponse;
+class ServerInfo_User;
+class ServerInfo_Room;
-class GameSelector : public QGroupBox {
- Q_OBJECT
-public:
- GameSelector(AbstractClient *_client, QWidget *parent = 0);
- void retranslateUi();
-private slots:
- void processListGamesEvent(Event_ListGames *event);
- void showFullGamesChanged(int state);
- void actCreate();
- void actJoin();
- void checkResponse(ResponseCode response);
-signals:
- void gameJoined(int gameId);
-private:
- AbstractClient *client;
-
- QTreeView *gameListView;
- GamesModel *gameListModel;
- GamesProxyModel *gameListProxyModel;
- QPushButton *createButton, *joinButton, *spectateButton;
- QCheckBox *showFullGamesCheckBox;
-};
-
-class ChatChannelSelector : public QGroupBox {
+class RoomSelector : public QGroupBox {
Q_OBJECT
private:
- QTreeWidget *channelList;
+ QTreeWidget *roomList;
QPushButton *joinButton;
AbstractClient *client;
- void joinChannel(const QString &channelName);
+ void joinRoom(int id, bool setCurrent);
private slots:
- void processListChatChannelsEvent(Event_ListChatChannels *event);
+ void processListRoomsEvent(Event_ListRooms *event);
void joinClicked();
- void joinFinished(ResponseCode resp);
+ void joinFinished(ProtocolResponse *resp);
signals:
- void channelJoined(const QString &channelName);
+ void roomJoined(ServerInfo_Room *info, bool setCurrent);
public:
- ChatChannelSelector(AbstractClient *_client, QWidget *parent = 0);
- void retranslateUi();
-};
-
-class ServerMessageLog : public QGroupBox {
- Q_OBJECT
-private:
- QTextEdit *textEdit;
-private slots:
- void processServerMessageEvent(Event_ServerMessage *event);
-public:
- ServerMessageLog(AbstractClient *_client, QWidget *parent = 0);
- void retranslateUi();
-};
-
-class UserListTWI : public QTreeWidgetItem {
-public:
- UserListTWI();
- bool operator<(const QTreeWidgetItem &other) const;
-};
-
-class UserList : public QGroupBox {
- Q_OBJECT
-private:
- QTreeWidget *userTree;
- void processUserInfo(ServerInfo_User *user);
-private slots:
- void processResponse(ProtocolResponse *response);
- void processUserJoinedEvent(Event_UserJoined *event);
- void processUserLeftEvent(Event_UserLeft *event);
- void userClicked(QTreeWidgetItem *item, int column);
-signals:
- void openMessageDialog(const QString &userName, bool focus);
- void userLeft(const QString &userName);
-public:
- UserList(AbstractClient *_client, QWidget *parent = 0);
- void retranslateUi();
-};
-
-class UserInfoBox : public QWidget {
- Q_OBJECT
-private:
- QLabel *avatarLabel, *nameLabel, *countryLabel1, *countryLabel2, *userLevelLabel1, *userLevelLabel2;
-private slots:
- void processResponse(ProtocolResponse *response);
-public:
- UserInfoBox(AbstractClient *_client, QWidget *parent = 0);
+ RoomSelector(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
};
class TabServer : public Tab {
Q_OBJECT
signals:
- void chatChannelJoined(const QString &channelName);
- void gameJoined(int gameId);
+ void roomJoined(ServerInfo_Room *info, bool setCurrent);
void openMessageDialog(const QString &userName, bool focus);
void userLeft(const QString &userName);
+private slots:
+ void processListUsersResponse(ProtocolResponse *response);
+ void processUserJoinedEvent(Event_UserJoined *event);
+ void processUserLeftEvent(Event_UserLeft *event);
+ void processServerMessageEvent(Event_ServerMessage *event);
private:
AbstractClient *client;
- GameSelector *gameSelector;
- ChatChannelSelector *chatChannelSelector;
- ServerMessageLog *serverMessageLog;
+ RoomSelector *roomSelector;
+ QTextBrowser *serverInfoBox;
UserList *userList;
UserInfoBox *userInfoBox;
public:
- TabServer(AbstractClient *_client, QWidget *parent = 0);
+ TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent = 0);
void retranslateUi();
QString getTabText() const { return tr("Server"); }
};
diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp
index b5075470..70f712b2 100644
--- a/cockatrice/src/tab_supervisor.cpp
+++ b/cockatrice/src/tab_supervisor.cpp
@@ -2,16 +2,17 @@
#include "tab_supervisor.h"
#include "abstractclient.h"
#include "tab_server.h"
-#include "tab_chatchannel.h"
+#include "tab_room.h"
#include "tab_game.h"
#include "tab_deck_storage.h"
+#include "tab_admin.h"
#include "tab_message.h"
#include "protocol_items.h"
#include "pixmapgenerator.h"
#include
TabSupervisor:: TabSupervisor(QWidget *parent)
- : QTabWidget(parent), client(0), tabServer(0), tabDeckStorage(0)
+ : QTabWidget(parent), client(0), tabServer(0), tabDeckStorage(0), tabAdmin(0)
{
tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg");
setElideMode(Qt::ElideRight);
@@ -32,9 +33,9 @@ void TabSupervisor::retranslateUi()
tabs.append(tabServer);
if (tabDeckStorage)
tabs.append(tabDeckStorage);
- QMapIterator chatChannelIterator(chatChannelTabs);
- while (chatChannelIterator.hasNext())
- tabs.append(chatChannelIterator.next().value());
+ QMapIterator roomIterator(roomTabs);
+ while (roomIterator.hasNext())
+ tabs.append(roomIterator.next().value());
QMapIterator gameIterator(gameTabs);
while (gameIterator.hasNext())
tabs.append(gameIterator.next().value());
@@ -51,24 +52,35 @@ void TabSupervisor::myAddTab(Tab *tab)
addTab(tab, tab->getTabText());
}
-void TabSupervisor::start(AbstractClient *_client)
+void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo)
{
client = _client;
- connect(client, SIGNAL(chatEventReceived(ChatEvent *)), this, SLOT(processChatEvent(ChatEvent *)));
+ userName = userInfo->getName();
+
+ connect(client, SIGNAL(roomEventReceived(RoomEvent *)), this, SLOT(processRoomEvent(RoomEvent *)));
connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
connect(client, SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(gameJoined(Event_GameJoined *)));
connect(client, SIGNAL(messageEventReceived(Event_Message *)), this, SLOT(processMessageEvent(Event_Message *)));
connect(client, SIGNAL(maxPingTime(int, int)), this, SLOT(updatePingTime(int, int)));
- tabServer = new TabServer(client);
- connect(tabServer, SIGNAL(chatChannelJoined(const QString &)), this, SLOT(addChatChannelTab(const QString &)));
+ tabServer = new TabServer(client, userInfo);
+ connect(tabServer, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SLOT(addRoomTab(ServerInfo_Room *, bool)));
connect(tabServer, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
connect(tabServer, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &)));
myAddTab(tabServer);
updatePingTime(0, -1);
- tabDeckStorage = new TabDeckStorage(client);
- myAddTab(tabDeckStorage);
+ if (userInfo->getUserLevel() & ServerInfo_User::IsRegistered) {
+ tabDeckStorage = new TabDeckStorage(client);
+ myAddTab(tabDeckStorage);
+ } else
+ tabDeckStorage = 0;
+
+ if (userInfo->getUserLevel() & ServerInfo_User::IsAdmin) {
+ tabAdmin = new TabAdmin(client);
+ myAddTab(tabAdmin);
+ } else
+ tabAdmin = 0;
retranslateUi();
}
@@ -107,10 +119,10 @@ void TabSupervisor::stop()
tabDeckStorage->deleteLater();
tabDeckStorage = 0;
- QMapIterator chatChannelIterator(chatChannelTabs);
- while (chatChannelIterator.hasNext())
- chatChannelIterator.next().value()->deleteLater();
- chatChannelTabs.clear();
+ QMapIterator roomIterator(roomTabs);
+ while (roomIterator.hasNext())
+ roomIterator.next().value()->deleteLater();
+ roomTabs.clear();
QMapIterator gameIterator(gameTabs);
while (gameIterator.hasNext())
@@ -122,6 +134,8 @@ void TabSupervisor::updatePingTime(int value, int max)
{
if (!tabServer)
return;
+ if (tabServer->getContentsChanged())
+ return;
setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max)));
}
@@ -144,7 +158,7 @@ void TabSupervisor::localGameJoined(Event_GameJoined *event)
setCurrentWidget(tab);
for (int i = 1; i < localClients.size(); ++i) {
- Command_JoinGame *cmd = new Command_JoinGame(event->getGameId());
+ Command_JoinGame *cmd = new Command_JoinGame(0, event->getGameId());
localClients[i]->sendCommand(cmd);
}
}
@@ -160,29 +174,33 @@ void TabSupervisor::gameLeft(TabGame *tab)
stop();
}
-void TabSupervisor::addChatChannelTab(const QString &channelName)
+void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent)
{
- TabChatChannel *tab = new TabChatChannel(client, channelName);
- connect(tab, SIGNAL(channelClosing(TabChatChannel *)), this, SLOT(chatChannelLeft(TabChatChannel *)));
+ TabRoom *tab = new TabRoom(client, userName, info);
+ connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *)));
myAddTab(tab);
- chatChannelTabs.insert(channelName, tab);
- setCurrentWidget(tab);
+ roomTabs.insert(info->getRoomId(), tab);
+ if (setCurrent)
+ setCurrentWidget(tab);
}
-void TabSupervisor::chatChannelLeft(TabChatChannel *tab)
+void TabSupervisor::roomLeft(TabRoom *tab)
{
emit setMenu(0);
- chatChannelTabs.remove(tab->getChannelName());
+ roomTabs.remove(tab->getRoomId());
removeTab(indexOf(tab));
}
-TabMessage *TabSupervisor::addMessageTab(const QString &userName, bool focus)
+TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus)
{
- TabMessage *tab = new TabMessage(client, userName);
+ if (receiverName == userName)
+ return 0;
+
+ TabMessage *tab = new TabMessage(client, receiverName);
connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *)));
myAddTab(tab);
- messageTabs.insert(userName, tab);
+ messageTabs.insert(receiverName, tab);
if (focus)
setCurrentWidget(tab);
return tab;
@@ -206,11 +224,11 @@ void TabSupervisor::tabUserEvent()
QApplication::alert(this);
}
-void TabSupervisor::processChatEvent(ChatEvent *event)
+void TabSupervisor::processRoomEvent(RoomEvent *event)
{
- TabChatChannel *tab = chatChannelTabs.value(event->getChannel(), 0);
+ TabRoom *tab = roomTabs.value(event->getRoomId(), 0);
if (tab)
- tab->processChatEvent(event);
+ tab->processRoomEvent(event);
}
void TabSupervisor::processGameEventContainer(GameEventContainer *cont)
@@ -230,6 +248,8 @@ void TabSupervisor::processMessageEvent(Event_Message *event)
tab = messageTabs.value(event->getReceiverName());
if (!tab)
tab = addMessageTab(event->getSenderName(), false);
+ if (!tab)
+ return;
tab->processMessageEvent(event);
}
diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h
index 7d1965f8..f10140ec 100644
--- a/cockatrice/src/tab_supervisor.h
+++ b/cockatrice/src/tab_supervisor.h
@@ -8,24 +8,29 @@ class QMenu;
class AbstractClient;
class Tab;
class TabServer;
-class TabChatChannel;
+class TabRoom;
class TabGame;
class TabDeckStorage;
+class TabAdmin;
class TabMessage;
-class ChatEvent;
+class RoomEvent;
class GameEventContainer;
class Event_GameJoined;
class Event_Message;
+class ServerInfo_Room;
+class ServerInfo_User;
class TabSupervisor : public QTabWidget {
Q_OBJECT
private:
+ QString userName;
QIcon *tabChangedIcon;
AbstractClient *client;
QList localClients;
TabServer *tabServer;
TabDeckStorage *tabDeckStorage;
- QMap chatChannelTabs;
+ TabAdmin *tabAdmin;
+ QMap roomTabs;
QMap gameTabs;
QMap messageTabs;
void myAddTab(Tab *tab);
@@ -33,7 +38,7 @@ public:
TabSupervisor(QWidget *parent = 0);
~TabSupervisor();
void retranslateUi();
- void start(AbstractClient *_client);
+ void start(AbstractClient *_client, ServerInfo_User *userInfo);
void startLocal(const QList &_clients);
void stop();
int getGameCount() const { return gameTabs.size(); }
@@ -46,13 +51,13 @@ private slots:
void gameJoined(Event_GameJoined *event);
void localGameJoined(Event_GameJoined *event);
void gameLeft(TabGame *tab);
- void addChatChannelTab(const QString &channelName);
- void chatChannelLeft(TabChatChannel *tab);
+ void addRoomTab(ServerInfo_Room *info, bool setCurrent);
+ void roomLeft(TabRoom *tab);
TabMessage *addMessageTab(const QString &userName, bool focus);
void processUserLeft(const QString &userName);
void talkLeft(TabMessage *tab);
void tabUserEvent();
- void processChatEvent(ChatEvent *event);
+ void processRoomEvent(RoomEvent *event);
void processGameEventContainer(GameEventContainer *cont);
void processMessageEvent(Event_Message *event);
};
diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp
index 4d52cf93..bb74b403 100644
--- a/cockatrice/src/tablezone.cpp
+++ b/cockatrice/src/tablezone.cpp
@@ -7,19 +7,16 @@
#include "protocol_items.h"
#include "settingscache.h"
#include "arrowitem.h"
+#include "carddragitem.h"
TableZone::TableZone(Player *_p, QGraphicsItem *parent)
- : CardZone(_p, "table", true, false, true, parent), active(false)
+ : SelectZone(_p, "table", true, false, true, parent), active(false)
{
connect(settingsCache, SIGNAL(tableBgPathChanged()), this, SLOT(updateBgPixmap()));
- connect(settingsCache, SIGNAL(economicalGridChanged()), this, SLOT(reorganizeCards()));
connect(settingsCache, SIGNAL(invertVerticalCoordinateChanged()), this, SLOT(reorganizeCards()));
updateBgPixmap();
- if (settingsCache->getEconomicalGrid())
- height = 2 * boxLineWidth + (int) (11.0 / 3 * CARD_HEIGHT + 2 * paddingY);
- else
- height = 2 * boxLineWidth + 3 * CARD_HEIGHT + 2 * paddingY;
+ height = 2 * boxLineWidth + 3 * (CARD_HEIGHT + 20) + 2 * paddingY;
width = minWidth + 2 * marginX + 2 * boxLineWidth;
currentMinimumWidth = minWidth;
@@ -52,7 +49,7 @@ void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*optio
else
painter->fillRect(boundingRect(), QBrush(bgPixmap));
painter->setPen(QColor(255, 255, 255, 40));
- qreal separatorY = 2 * (CARD_HEIGHT + paddingY) + boxLineWidth - paddingY / 2;
+ qreal separatorY = 2 * (CARD_HEIGHT + 20 + paddingY) + boxLineWidth - paddingY / 2;
if (isInverted())
separatorY = height - separatorY;
painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
@@ -88,14 +85,18 @@ void TableZone::addCardImpl(CardItem *card, int _x, int _y)
card->update();
}
-void TableZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown)
+void TableZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown)
{
- handleDropEventByGrid(cardId, startZone, mapToGrid(dropPoint), faceDown);
+ handleDropEventByGrid(dragItems, startZone, mapToGrid(dropPoint), faceDown);
}
-void TableZone::handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown, bool tapped)
+void TableZone::handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint, bool faceDown, bool tapped)
{
- player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), gridPoint.x(), gridPoint.y(), faceDown, tapped));
+ QList idList;
+ for (int i = 0; i < dragItems.size(); ++i)
+ idList.append(new CardId(dragItems[i]->getId()));
+
+ startZone->getPlayer()->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), idList, player->getId(), getName(), gridPoint.x(), gridPoint.y(), faceDown, tapped));
}
void TableZone::reorganizeCards()
@@ -103,13 +104,27 @@ void TableZone::reorganizeCards()
QList arrowsToUpdate;
// Calculate table grid distortion so that the mapping functions work properly
- gridPointWidth.clear();
+ QMap gridPointStackCount;
for (int i = 0; i < cards.size(); ++i) {
- QPoint gridPoint = cards[i]->getGridPos();
+ const QPoint &gridPoint = cards[i]->getGridPos();
if (gridPoint.x() == -1)
continue;
- gridPointWidth.insert(gridPoint.x() + gridPoint.y() * 1000, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0));
+ const int key = gridPoint.x() / 3 + gridPoint.y() * 1000;
+ gridPointStackCount.insert(key, gridPointStackCount.value(key, 0) + 1);
+ }
+ gridPointWidth.clear();
+ for (int i = 0; i < cards.size(); ++i) {
+ const QPoint &gridPoint = cards[i]->getGridPos();
+ if (gridPoint.x() == -1)
+ continue;
+
+ const int key = gridPoint.x() / 3 + gridPoint.y() * 1000;
+ const int stackCount = gridPointStackCount.value(key, 0);
+ if (stackCount == 1)
+ gridPointWidth.insert(key, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0));
+ else
+ gridPointWidth.insert(key, CARD_WIDTH * (1 + (stackCount - 1) / 3.0));
}
for (int i = 0; i < cards.size(); ++i) {
@@ -213,22 +228,21 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const
return getCardFromGrid(gridPoint);
}
-QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const
+QPointF TableZone::mapFromGrid(QPoint gridPoint) const
{
qreal x, y;
- if ((gridPoint.y() == 2) && (settingsCache->getEconomicalGrid())) {
- x = marginX + (CARD_WIDTH * gridPoint.x() + CARD_WIDTH * (gridPoint.x() / 3)) / 2;
- y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() + (gridPoint.x() % 3 * CARD_HEIGHT) / 3;
- } else {
- x = marginX + 0.5 * CARD_WIDTH * gridPoint.x();
- for (int i = 0; i < gridPoint.x(); ++i)
- x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH);
-
- y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y();
- }
+ x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0;
+ for (int i = 0; i < gridPoint.x() / 3; ++i)
+ x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX;
+
+ if (isInverted())
+ gridPoint.setY(2 - gridPoint.y());
+
+ y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10;
+/*
if (isInverted())
y = height - CARD_HEIGHT - y;
-
+*/
return QPointF(x, y);
}
@@ -236,9 +250,9 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
{
qreal x = mapPoint.x() - marginX;
qreal y = mapPoint.y();
- if (isInverted())
+/* if (isInverted())
y = height - y;
- y += paddingY / 2 - boxLineWidth;
+*/ y -= boxLineWidth;
if (x < 0)
x = 0;
@@ -249,27 +263,32 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
else if (y > height - CARD_HEIGHT)
y = height - CARD_HEIGHT;
- int resultY = (int) (y / (CARD_HEIGHT + paddingY));
+ int resultY = round(y / (CARD_HEIGHT + paddingY + 20));
+ if (isInverted())
+ resultY = 2 - resultY;
- if ((resultY == 2) && (settingsCache->getEconomicalGrid()))
- return QPoint(
- (int) (x * 2 / CARD_WIDTH - floor(x / (2 * CARD_WIDTH))),
- 2
- );
- else {
- int resultX = -1;
- qreal tempX = 0;
- do {
- ++resultX;
- tempX += gridPointWidth.value(resultY * 1000 + resultX, CARD_WIDTH) + 0.5 * CARD_WIDTH;
- } while (tempX < x + 1);
- return QPoint(resultX, resultY);
- }
+ int baseX = -1;
+ qreal oldTempX = 0, tempX = 0;
+ do {
+ ++baseX;
+ oldTempX = tempX;
+ tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + paddingX;
+ } while (tempX < x + 1);
+
+ qreal xdiff = x - oldTempX;
+ int resultX = baseX * 3 + qMin((int) floor(xdiff * 3 / CARD_WIDTH), 2);
+ return QPoint(resultX, resultY);
}
QPointF TableZone::closestGridPoint(const QPointF &point)
{
- return mapFromGrid(mapToGrid(point + QPoint(CARD_WIDTH / 2, CARD_HEIGHT / 2)));
+ QPoint gridPoint = mapToGrid(point + QPoint(1, 1));
+ gridPoint.setX((gridPoint.x() / 3) * 3);
+ if (getCardFromGrid(gridPoint))
+ gridPoint.setX(gridPoint.x() + 1);
+ if (getCardFromGrid(gridPoint))
+ gridPoint.setX(gridPoint.x() + 1);
+ return mapFromGrid(gridPoint);
}
void TableZone::setWidth(qreal _width)
diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h
index 9f9f0650..b6566b4e 100644
--- a/cockatrice/src/tablezone.h
+++ b/cockatrice/src/tablezone.h
@@ -1,15 +1,16 @@
#ifndef TABLEZONE_H
#define TABLEZONE_H
-#include "cardzone.h"
+#include "selectzone.h"
-class TableZone : public CardZone {
+class TableZone : public SelectZone {
Q_OBJECT
signals:
void sizeChanged();
private:
static const int boxLineWidth = 10;
- static const int paddingY = 20;
+ static const int paddingX = 35;
+ static const int paddingY = 10;
static const int marginX = 20;
static const int minWidth = 15 * CARD_WIDTH / 2;
@@ -28,11 +29,11 @@ public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void toggleTapped();
- void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false);
- void handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false);
+ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false);
+ void handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false);
CardItem *getCardFromGrid(const QPoint &gridPoint) const;
CardItem *getCardFromCoords(const QPointF &point) const;
- QPointF mapFromGrid(const QPoint &gridPoint) const;
+ QPointF mapFromGrid(QPoint gridPoint) const;
QPoint mapToGrid(const QPointF &mapPoint) const;
QPointF closestGridPoint(const QPointF &point);
CardItem *takeCard(int position, int cardId, bool canResize = true);
diff --git a/cockatrice/src/userinfobox.cpp b/cockatrice/src/userinfobox.cpp
new file mode 100644
index 00000000..40b4b012
--- /dev/null
+++ b/cockatrice/src/userinfobox.cpp
@@ -0,0 +1,91 @@
+#include "userinfobox.h"
+#include "protocol_datastructures.h"
+#include "pixmapgenerator.h"
+#include "protocol_items.h"
+#include "abstractclient.h"
+#include
+#include
+
+UserInfoBox::UserInfoBox(AbstractClient *_client, bool _fullInfo, QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags), client(_client), fullInfo(_fullInfo)
+{
+ avatarLabel = new QLabel;
+ nameLabel = new QLabel;
+ QFont nameFont = nameLabel->font();
+ nameFont.setBold(true);
+ nameFont.setPointSize(nameFont.pointSize() * 1.5);
+ nameLabel->setFont(nameFont);
+ realNameLabel1 = new QLabel;
+ realNameLabel2 = new QLabel;
+ countryLabel1 = new QLabel;
+ countryLabel2 = new QLabel;
+ userLevelLabel1 = new QLabel;
+ userLevelLabel2 = new QLabel;
+ userLevelLabel3 = new QLabel;
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addWidget(avatarLabel, 0, 0, 1, 3, Qt::AlignCenter);
+ mainLayout->addWidget(nameLabel, 1, 0, 1, 3);
+ mainLayout->addWidget(realNameLabel1, 2, 0, 1, 1);
+ mainLayout->addWidget(realNameLabel2, 2, 1, 1, 2);
+ mainLayout->addWidget(countryLabel1, 3, 0, 1, 1);
+ mainLayout->addWidget(countryLabel2, 3, 1, 1, 2);
+ mainLayout->addWidget(userLevelLabel1, 4, 0, 1, 1);
+ mainLayout->addWidget(userLevelLabel2, 4, 1, 1, 1);
+ mainLayout->addWidget(userLevelLabel3, 4, 2, 1, 1);
+ mainLayout->setColumnStretch(2, 10);
+
+ setWindowTitle(tr("User information"));
+ setLayout(mainLayout);
+ retranslateUi();
+}
+
+void UserInfoBox::retranslateUi()
+{
+ realNameLabel1->setText(tr("Real name:"));
+ countryLabel1->setText(tr("Location:"));
+ userLevelLabel1->setText(tr("User level:"));
+}
+
+void UserInfoBox::updateInfo(ServerInfo_User *user)
+{
+ int userLevel = user->getUserLevel();
+
+ QPixmap avatarPixmap;
+ if (!avatarPixmap.loadFromData(user->getAvatarBmp()))
+ avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel);
+ avatarLabel->setPixmap(avatarPixmap);
+
+ nameLabel->setText(user->getName());
+ realNameLabel2->setText(user->getRealName());
+ countryLabel2->setPixmap(CountryPixmapGenerator::generatePixmap(15, user->getCountry()));
+ userLevelLabel2->setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel));
+ QString userLevelText;
+ if (userLevel & ServerInfo_User::IsAdmin)
+ userLevelText = tr("Administrator");
+ else if (userLevel & ServerInfo_User::IsJudge)
+ userLevelText = tr("Judge");
+ else if (userLevel & ServerInfo_User::IsRegistered)
+ userLevelText = tr("Registered user");
+ else
+ userLevelText = tr("Unregistered user");
+ userLevelLabel3->setText(userLevelText);
+}
+
+void UserInfoBox::updateInfo(const QString &userName)
+{
+ Command_GetUserInfo *command = new Command_GetUserInfo(userName);
+ connect(command, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
+ client->sendCommand(command);
+}
+
+void UserInfoBox::processResponse(ProtocolResponse *r)
+{
+ Response_GetUserInfo *response = qobject_cast(r);
+ if (!response)
+ return;
+
+ updateInfo(response->getUserInfo());
+ setFixedSize(sizeHint());
+ show();
+}
\ No newline at end of file
diff --git a/cockatrice/src/userinfobox.h b/cockatrice/src/userinfobox.h
new file mode 100644
index 00000000..adf5f832
--- /dev/null
+++ b/cockatrice/src/userinfobox.h
@@ -0,0 +1,27 @@
+#ifndef USERINFOBOX_H
+#define USERINFOBOX_H
+
+#include
+
+class QLabel;
+class ServerInfo_User;
+class AbstractClient;
+class ProtocolResponse;
+
+class UserInfoBox : public QWidget {
+ Q_OBJECT
+private:
+ AbstractClient *client;
+ bool fullInfo;
+ QLabel *avatarLabel, *nameLabel, *realNameLabel1, *realNameLabel2, *countryLabel1, *countryLabel2, *userLevelLabel1, *userLevelLabel2, *userLevelLabel3;
+public:
+ UserInfoBox(AbstractClient *_client, bool fullInfo, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ void retranslateUi();
+private slots:
+ void processResponse(ProtocolResponse *r);
+public slots:
+ void updateInfo(ServerInfo_User *user);
+ void updateInfo(const QString &userName);
+};
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp
new file mode 100644
index 00000000..dbf8bf6e
--- /dev/null
+++ b/cockatrice/src/userlist.cpp
@@ -0,0 +1,145 @@
+#include "userlist.h"
+#include "abstractclient.h"
+#include "pixmapgenerator.h"
+#include "userinfobox.h"
+#include
+#include
+#include
+#include
+
+UserListItemDelegate::UserListItemDelegate(QObject *const parent)
+ : QItemDelegate(parent)
+{
+}
+
+bool UserListItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ if ((event->type() == QEvent::MouseButtonPress) && index.isValid()) {
+ QMouseEvent *const mouseEvent = static_cast(event);
+ if (mouseEvent->button() == Qt::RightButton) {
+ static_cast(parent())->showContextMenu(mouseEvent->globalPos(), index);
+ return true;
+ }
+ }
+ return QItemDelegate::editorEvent(event, model, option, index);
+}
+
+UserListTWI::UserListTWI()
+ : QTreeWidgetItem(Type)
+{
+}
+
+bool UserListTWI::operator<(const QTreeWidgetItem &other) const
+{
+ // Equal user level => sort by name
+ if (data(0, Qt::UserRole) == other.data(0, Qt::UserRole))
+ return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower();
+ // Else sort by user level
+ return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt();
+}
+
+UserList::UserList(AbstractClient *_client, bool _global, QWidget *parent)
+ : QGroupBox(parent), client(_client), global(_global)
+{
+ itemDelegate = new UserListItemDelegate(this);
+
+ userTree = new QTreeWidget;
+ userTree->setColumnCount(3);
+ userTree->header()->setResizeMode(QHeaderView::ResizeToContents);
+ userTree->setHeaderHidden(true);
+ userTree->setRootIsDecorated(false);
+ userTree->setIconSize(QSize(20, 12));
+ userTree->setItemDelegate(itemDelegate);
+ connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(userTree);
+
+ setLayout(vbox);
+
+ retranslateUi();
+}
+
+void UserList::retranslateUi()
+{
+ titleStr = global ? tr("Users online: %1") : tr("Users in this room: %1");
+ updateCount();
+}
+
+void UserList::processUserInfo(ServerInfo_User *user)
+{
+ QTreeWidgetItem *item = 0;
+ for (int i = 0; i < userTree->topLevelItemCount(); ++i) {
+ QTreeWidgetItem *temp = userTree->topLevelItem(i);
+ if (temp->data(2, Qt::UserRole) == user->getName()) {
+ item = temp;
+ break;
+ }
+ }
+ if (!item) {
+ item = new UserListTWI;
+ userTree->addTopLevelItem(item);
+ retranslateUi();
+ }
+ item->setData(0, Qt::UserRole, user->getUserLevel());
+ item->setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, user->getUserLevel())));
+ item->setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry())));
+ item->setData(2, Qt::UserRole, user->getName());
+ item->setData(2, Qt::DisplayRole, user->getName());
+}
+
+bool UserList::deleteUser(const QString &userName)
+{
+ for (int i = 0; i < userTree->topLevelItemCount(); ++i)
+ if (userTree->topLevelItem(i)->data(2, Qt::UserRole) == userName) {
+ delete userTree->takeTopLevelItem(i);
+ updateCount();
+ return true;
+ }
+
+ return false;
+}
+
+void UserList::updateCount()
+{
+ setTitle(titleStr.arg(userTree->topLevelItemCount()));
+}
+
+void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
+{
+ emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
+}
+
+void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
+{
+ const QString &userName = index.sibling(index.row(), 2).data(Qt::UserRole).toString();
+
+ QAction *aUserName = new QAction(userName, this);
+ aUserName->setEnabled(false);
+ QAction *aDetails = new QAction(tr("User &details"), this);
+ QAction *aChat = new QAction(tr("Direct &chat"), this);
+
+ QMenu *menu = new QMenu(this);
+ menu->addAction(aUserName);
+ menu->addSeparator();
+ menu->addAction(aDetails);
+ menu->addAction(aChat);
+
+ QAction *actionClicked = menu->exec(pos);
+ if (actionClicked == aDetails) {
+ UserInfoBox *infoWidget = new UserInfoBox(client, true, this, Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
+ infoWidget->setAttribute(Qt::WA_DeleteOnClose);
+ infoWidget->updateInfo(userName);
+ } else if (actionClicked == aChat)
+ emit openMessageDialog(userName, true);
+
+ delete menu;
+ delete aUserName;
+ delete aDetails;
+ delete aChat;
+}
+
+void UserList::sortItems()
+{
+ userTree->sortItems(1, Qt::AscendingOrder);
+}
diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h
new file mode 100644
index 00000000..86726d67
--- /dev/null
+++ b/cockatrice/src/userlist.h
@@ -0,0 +1,46 @@
+#ifndef USERLIST_H
+#define USERLIST_H
+
+#include
+#include
+#include
+
+class QTreeWidget;
+class ServerInfo_User;
+class AbstractClient;
+
+class UserListItemDelegate : public QItemDelegate {
+public:
+ UserListItemDelegate(QObject *const parent);
+ bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
+};
+
+class UserListTWI : public QTreeWidgetItem {
+public:
+ UserListTWI();
+ bool operator<(const QTreeWidgetItem &other) const;
+};
+
+class UserList : public QGroupBox {
+ Q_OBJECT
+private:
+ AbstractClient *client;
+ QTreeWidget *userTree;
+ UserListItemDelegate *itemDelegate;
+ bool global;
+ QString titleStr;
+ void updateCount();
+private slots:
+ void userClicked(QTreeWidgetItem *item, int column);
+signals:
+ void openMessageDialog(const QString &userName, bool focus);
+public:
+ UserList(AbstractClient *_client, bool _global, QWidget *parent = 0);
+ void retranslateUi();
+ void processUserInfo(ServerInfo_User *user);
+ bool deleteUser(const QString &userName);
+ void showContextMenu(const QPoint &pos, const QModelIndex &index);
+ void sortItems();
+};
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/window_deckeditor.cpp b/cockatrice/src/window_deckeditor.cpp
index 3b091026..e9f2f44e 100644
--- a/cockatrice/src/window_deckeditor.cpp
+++ b/cockatrice/src/window_deckeditor.cpp
@@ -308,8 +308,9 @@ bool WndDeckEditor::actSaveDeck()
else if (deckModel->getDeckList()->saveToFile(lastFileName, lastFileFormat)) {
setWindowModified(false);
return true;
- } else
- return false;
+ }
+ QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
+ return false;
}
bool WndDeckEditor::actSaveDeckAs()
@@ -332,6 +333,7 @@ bool WndDeckEditor::actSaveDeckAs()
setWindowModified(false);
return true;
}
+ QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
return false;
}
diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp
index d4c11b59..671738a9 100644
--- a/cockatrice/src/window_main.cpp
+++ b/cockatrice/src/window_main.cpp
@@ -64,15 +64,18 @@ void MainWindow::statusChanged(ClientStatus _status)
aConnect->setEnabled(false);
aDisconnect->setEnabled(true);
break;
- case StatusLoggedIn: {
- tabSupervisor->start(client);
+ case StatusLoggedIn:
break;
- }
default:
break;
}
}
+void MainWindow::userInfoReceived(ServerInfo_User *info)
+{
+ tabSupervisor->start(client, info);
+}
+
// Actions
void MainWindow::actConnect()
@@ -110,7 +113,7 @@ void MainWindow::actSinglePlayer()
}
tabSupervisor->startLocal(localClients);
- Command_CreateGame *createCommand = new Command_CreateGame(QString(), QString(), numberPlayers, false, false, false, false);
+ Command_CreateGame *createCommand = new Command_CreateGame(0, QString(), QString(), numberPlayers, false, false, false, false);
mainClient->sendCommand(createCommand);
}
@@ -150,7 +153,17 @@ void MainWindow::actExit()
void MainWindow::actAbout()
{
- QMessageBox::about(this, tr("About Cockatrice"), trUtf8("Cockatrice
Version %1
Authors:
Max-Wilhelm Bruker
Marcus Schütz
Marius van Zundert
Translators:
Spanish: Gocho
Portugese: Milton Gonçalves
").arg(versionString));
+ QMessageBox::about(this, tr("About Cockatrice"), QString(
+ "Cockatrice
"
+ + tr("Version %1").arg(versionString)
+ + "
" + tr("Authors:") + "
Max-Wilhelm Bruker
Marcus Schütz
"
+ + "" + tr("Translators:") + "
"
+ + tr("Spanish:") + " VÃctor MartÃnez
"
+ + tr("Portugese (Portugal):") + " Milton Gonçalves
"
+ + tr("Portugese (Brazil):") + " Thiago Queiroz
"
+ + tr("French:") + " Yannick Hammer
"
+ + tr("Japanese:") + " Takumi Nakase
"
+ ));
}
void MainWindow::serverTimeout()
@@ -260,6 +273,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus)));
connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int)));
+ connect(client, SIGNAL(userInfoChanged(ServerInfo_User *)), this, SLOT(userInfoReceived(ServerInfo_User *)));
tabSupervisor = new TabSupervisor;
connect(tabSupervisor, SIGNAL(setMenu(QMenu *)), this, SLOT(updateTabMenu(QMenu *)));
diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h
index adb4e20e..e6bcb155 100644
--- a/cockatrice/src/window_main.h
+++ b/cockatrice/src/window_main.h
@@ -28,6 +28,7 @@ class TabSupervisor;
class RemoteClient;
class LocalClient;
class LocalServer;
+class ServerInfo_User;
class MainWindow : public QMainWindow {
Q_OBJECT
@@ -38,6 +39,7 @@ private slots:
void serverError(ResponseCode r);
void socketError(const QString &errorStr);
void protocolVersionMismatch(int localVersion, int remoteVersion);
+ void userInfoReceived(ServerInfo_User *userInfo);
void localGameEnded();
void actConnect();
diff --git a/cockatrice/src/zoneviewwidget.cpp b/cockatrice/src/zoneviewwidget.cpp
index 7179be78..2f124fed 100644
--- a/cockatrice/src/zoneviewwidget.cpp
+++ b/cockatrice/src/zoneviewwidget.cpp
@@ -9,7 +9,7 @@
#include "protocol_items.h"
#include "settingscache.h"
-ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards, const QList &cardList)
+ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards, bool _revealZone, const QList &cardList)
: QGraphicsWidget(0, Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint | Qt::WindowTitleHint/* | Qt::WindowCloseButtonHint*/), player(_player)
{
setAttribute(Qt::WA_DeleteOnClose);
@@ -48,7 +48,7 @@ ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberC
extraHeight = vbox->sizeHint(Qt::PreferredSize).height();
resize(150, 150);
- zone = new ZoneViewZone(player, _origZone, numberCards, this);
+ zone = new ZoneViewZone(player, _origZone, numberCards, _revealZone, this);
connect(zone, SIGNAL(optimumRectChanged()), this, SLOT(resizeToZoneContents()));
connect(zone, SIGNAL(beingDeleted()), this, SLOT(zoneDeleted()));
vbox->addItem(zone);
diff --git a/cockatrice/src/zoneviewwidget.h b/cockatrice/src/zoneviewwidget.h
index 71dcd754..afa63eb3 100644
--- a/cockatrice/src/zoneviewwidget.h
+++ b/cockatrice/src/zoneviewwidget.h
@@ -30,7 +30,7 @@ private slots:
void resizeToZoneContents();
void zoneDeleted();
public:
- ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards = 0, const QList &cardList = QList());
+ ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards = 0, bool _revealZone = false, const QList &cardList = QList());
ZoneViewZone *getZone() const { return zone; }
void retranslateUi();
protected:
diff --git a/cockatrice/src/zoneviewzone.cpp b/cockatrice/src/zoneviewzone.cpp
index e7fc9e13..5e3f1edc 100644
--- a/cockatrice/src/zoneviewzone.cpp
+++ b/cockatrice/src/zoneviewzone.cpp
@@ -3,18 +3,21 @@
#include "zoneviewzone.h"
#include "player.h"
#include "protocol_items.h"
+#include "carddragitem.h"
-ZoneViewZone::ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards, QGraphicsItem *parent)
- : CardZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), sortByName(false), sortByType(false)
+ZoneViewZone::ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards, bool _revealZone, QGraphicsItem *parent)
+ : SelectZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), revealZone(_revealZone), sortByName(false), sortByType(false)
{
- origZone->setView(this);
+ if (!revealZone)
+ origZone->setView(this);
}
ZoneViewZone::~ZoneViewZone()
{
emit beingDeleted();
qDebug("ZoneViewZone destructor");
- origZone->setView(NULL);
+ if (!revealZone)
+ origZone->setView(NULL);
}
QRectF ZoneViewZone::boundingRect() const
@@ -30,7 +33,7 @@ void ZoneViewZone::initializeCards(const QList &cardList)
{
if (!cardList.isEmpty()) {
for (int i = 0; i < cardList.size(); ++i)
- addCard(new CardItem(player, cardList[i]->getName(), cardList[i]->getId(), this), false, i);
+ addCard(new CardItem(player, cardList[i]->getName(), cardList[i]->getId(), revealZone, this), false, i);
reorganizeCards();
} else if (!origZone->contentsKnown()) {
Command_DumpZone *command = new Command_DumpZone(-1, player->getId(), name, numberCards);
@@ -41,7 +44,7 @@ void ZoneViewZone::initializeCards(const QList &cardList)
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
for (int i = 0; i < number; i++) {
CardItem *card = c.at(i);
- addCard(new CardItem(player, card->getName(), card->getId(), this), false, i);
+ addCard(new CardItem(player, card->getName(), card->getId(), revealZone, this), false, i);
}
reorganizeCards();
}
@@ -55,7 +58,7 @@ void ZoneViewZone::zoneDumpReceived(ProtocolResponse *r)
const QList &respCardList = resp->getZone()->getCardList();
for (int i = 0; i < respCardList.size(); i++) {
- CardItem *card = new CardItem(player, respCardList[i]->getName(), respCardList[i]->getId(), this);
+ CardItem *card = new CardItem(player, respCardList[i]->getName(), respCardList[i]->getId(), revealZone, this);
addCard(card, false, i);
}
@@ -84,7 +87,6 @@ void ZoneViewZone::reorganizeCards()
cols = 2;
qDebug() << "reorganizeCards: rows=" << rows << "cols=" << cols;
- qDebug() << "SORT BY NAME:" << sortByName << "SORT BY TYPE:" << sortByType;
CardList cardsToDisplay(cards);
if (sortByName || sortByType)
@@ -122,9 +124,13 @@ void ZoneViewZone::addCardImpl(CardItem *card, int x, int /*y*/)
card->update();
}
-void ZoneViewZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
+void ZoneViewZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/)
{
- player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false));
+ QList idList;
+ for (int i = 0; i < dragItems.size(); ++i)
+ idList.append(new CardId(dragItems[i]->getId()));
+
+ player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), idList, player->getId(), getName(), 0, 0, false));
}
void ZoneViewZone::removeCard(int position)
diff --git a/cockatrice/src/zoneviewzone.h b/cockatrice/src/zoneviewzone.h
index e331b7a2..b6fe2bfd 100644
--- a/cockatrice/src/zoneviewzone.h
+++ b/cockatrice/src/zoneviewzone.h
@@ -1,23 +1,24 @@
#ifndef ZONEVIEWERZONE_H
#define ZONEVIEWERZONE_H
-#include "cardzone.h"
+#include "selectzone.h"
#include
class ZoneViewWidget;
class ProtocolResponse;
class ServerInfo_Card;
-class ZoneViewZone : public CardZone, public QGraphicsLayoutItem {
+class ZoneViewZone : public SelectZone, public QGraphicsLayoutItem {
Q_OBJECT
private:
QRectF bRect, optimumRect;
int minRows, numberCards;
- void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
+ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
CardZone *origZone;
+ bool revealZone;
bool sortByName, sortByType;
public:
- ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards = -1, QGraphicsItem *parent = 0);
+ ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards = -1, bool _revealZone = false, QGraphicsItem *parent = 0);
~ZoneViewZone();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts
index f12aa06d..dae8f4bd 100644
--- a/cockatrice/translations/cockatrice_de.ts
+++ b/cockatrice/translations/cockatrice_de.ts
@@ -24,60 +24,92 @@
%1 sieht sich %2's %3 an
+
+ AbstractCounter
+
+
+ &Set counter...
+ Zähler &setzen...
+
+
+
+ Ctrl+L
+ Ctrl+L
+
+
+
+ F11
+ F11
+
+
+
+ F12
+ F12
+
+
+
+ Set counter
+ Zähler setzen
+
+
+
+ New value for counter '%1':
+ Neuer Wert für den Zähler '%1':
+
+
AppearanceSettingsPage
-
+
Zone background pictures
Hintergrundbilder für Kartenzonen
-
+
Path to hand background:
Hintergrundbild für die Hand:
-
+
Path to stack background:
Hintergrundbild für den Stapel:
-
+
Path to table background:
Hintergrundbild für das Spielfeld:
-
+
Path to player info background:
Hintergrundbild für den Spielerbereich:
-
+
Path to picture of card back:
Pfad zum Bild der Kartenrückseite:
-
+
Hand layout
Kartenhand
-
+
Display hand horizontally (wastes space)
Hand horizonal anzeigen (verschwendet Platz)
-
+
Table grid layout
Spielfeldraster
-
Economical layout
- Platzsparende Anordnung
+ Platzsparende Anordnung
-
+
Invert vertical coordinate
Vertikale Koordinate umkehren
@@ -86,17 +118,17 @@
Platzsparende Anordnung
-
+
Zone view layout
Aussehen des Zonenbetrachters
-
+
Sort by name
nach Namen sortieren
-
+
Sort by type
nach Kartentypen sortieren
@@ -105,11 +137,11 @@
standardmäßig alphabetisch sortieren
-
-
-
-
-
+
+
+
+
+
Choose path
Pfad auswählen
@@ -176,112 +208,122 @@
CardItem
-
+
+ &Play
+ &Ausspielen
+
+
+
+ &Hide
+ &Verstecken
+
+
+
&Tap
&Tappen
-
+
&Untap
E&nttappen
-
+
Toggle &normal untapping
N&ormales Enttappen umschalten
-
+
&Flip
&Umdrehen
-
+
&Clone
&Kopieren
-
+
&Attach to card...
&An Karte anlegen...
-
+
Ctrl+A
Ctrl+A
-
+
Unattac&h
&Von Karte lösen
-
+
Set &P/T...
&Kampfwerte setzen...
-
+
&Set annotation...
&Hinweis setzen...
-
+
red
rot
-
+
yellow
gelb
-
+
green
grün
-
+
&Add counter (%1)
Zählmarke &hinzufügen (%1)
-
+
&Remove counter (%1)
Zählmarke &entfernen (%1)
-
+
&Set counters (%1)...
Zählmarken &setzen (%1)...
-
+
&top of library
&auf die Bibliothek
-
+
&bottom of library
&unter die Bibliothek
-
+
&graveyard
in den &Friedhof
-
+
Ctrl+Del
Ctrl+Del
-
+
&exile
ins &Exil
-
+
&Move to
&Verschieben
@@ -613,29 +655,24 @@
ChatChannelSelector
-
Chat channels
- Chaträume
+ Chaträume
-
Joi&n
- Teil&nehmen
+ Teil&nehmen
-
Channel
- Raum
+ Raum
-
Description
- Beschreibung
+ Beschreibung
-
Players
- Spieler
+ Spieler
@@ -660,34 +697,28 @@
Counter
-
&Set counter...
- Zähler &setzen...
+ Zähler &setzen...
-
Ctrl+L
- Ctrl+L
+ Ctrl+L
-
F11
- F11
+ F11
-
F12
- F12
+ F12
-
Set counter
- Zähler setzen
+ Zähler setzen
-
New value for counter '%1':
- Neuer Wert für den Zähler '%1':
+ Neuer Wert für den Zähler '%1':
@@ -887,7 +918,7 @@
Spiel erstellen
-
+
Error
Fehler
@@ -896,7 +927,7 @@
Ungültige Anzahl an Spielern.
-
+
Server error.
Serverfehler.
@@ -1069,9 +1100,9 @@
DlgSettings
-
-
-
+
+
+
Error
Fehler
@@ -1088,47 +1119,47 @@
Der Pfad zum Kartenbilderverzeichnis ist ungültig.
-
+
Your card database is invalid. Would you like to go back and set the correct path?
Ihre Kartendatenbank ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen?
-
+
The path to your deck directory is invalid. Would you like to go back and set the correct path?
Der Pfad zu Ihrem Deckordner ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen?
-
+
The path to your card pictures directory is invalid. Would you like to go back and set the correct path?
Der Pfad zu Ihrem Kartenbilderordner ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen?
-
+
Settings
Einstellungen
-
+
General
Allgemeines
-
+
Appearance
Erscheinungsbild
-
+
User interface
Bedienung
-
+
Messages
Nachrichten
-
+
&Close
S&chließen
@@ -1394,20 +1425,20 @@
GameSelector
-
+
C&reate
Spiel e&rstellen
-
+
&Join
&Teilnehmen
-
-
-
-
+
+
+
+
Error
Fehler
@@ -1416,47 +1447,51 @@
XXX
-
+
Wrong password.
Falsches Passwort.
-
+
Spectators are not allowed in this game.
In diesem Spiel sind keine Zuschauer zugelassen.
-
+
The game is already full.
Das Spiel ist bereits voll.
-
+
The game does not exist any more.
Dieses Spiel gibt es nicht mehr.
-
+
Join game
Spiel beitreten
-
+
Password:
Passwort:
-
+
Games
Spiele
-
- &Show full games
+
+ Show &full games
&Volle Spiele anzeigen
-
+ &Show full games
+ &Volle Spiele anzeigen
+
+
+
J&oin as spectator
&Zuschauen
@@ -1464,7 +1499,7 @@
GameView
-
+
Esc
Esc
@@ -1575,106 +1610,141 @@
MainWindow
-
+
Number of players
Spieleranzahl
-
+
Please enter the number of players.
Bitte die Spieleranzahl eingeben:
-
-
+
+
Player %1
Spieler %1
-
+
About Cockatrice
-
-
-
-
- <font size="8"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Authors:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Translators:</b><br>Spanish: Gocho<br>Portugese: Milton Gonçalves<br>
-
+ Über Cockatrice
+ Version %1
+ Version %1
+
+
+
+ Authors:
+ Autoren:
+
+
+
+ Translators:
+ Übersetzer:
+
+
+
+ Spanish:
+ Spanisch:
+
+
+
+ Portugese (Portugal):
+ Portugiesisch (Portugal):
+
+
+
+ Portugese (Brazil):
+ Portugiesisch (Brasilien):
+
+
+ French:
+ Französisch:
+
+
+
+ Japanese:
+ Japanisch:
+
+
-
+
+
+
Error
Fehler
-
+
Server timeout
Server Zeitüberschreitung
-
+
Invalid login data.
Ungültige Anmeldedaten.
-
+
Socket error: %1
Netzwerkfehler: %1
-
+
Protocol version mismatch. Local version: %1, remote version: %2.
Protokollversionen stimmen nicht überein. Lokale Version: %1, Serverversion: %2.
-
+
Connecting to %1...
Verbinde zu %1...
-
+
Disconnected
nicht verbunden
-
+
Logged in at %1
Angemeldet bei %1
-
+
&Connect...
&Verbinden...
-
+
&Disconnect
Verbindung &trennen
-
+
Start &local game...
&Lokales Spiel starten...
-
+
&About Cockatrice
-
+ &Über Cockatrice
-
+
&Help
-
+ &Hilfe
-
+
Are you sure?
Sind Sie sicher?
-
+
There are still open games. Are you sure you want to quit?
Es gibt noch offene Spiele. Wollen Sie das Programm wirklich beenden?
@@ -1691,27 +1761,27 @@
Spiel ver&lassen
-
+
&Deck editor
&Deck-Editor
-
+
&Full screen
&Vollbild
-
+
Ctrl+F
Ctrl+F
-
+
&Settings...
&Einstellungen...
-
+
&Exit
&Beenden
@@ -1724,7 +1794,7 @@
Esc
-
+
&Cockatrice
&Cockatrice
@@ -1808,8 +1878,8 @@
%1 zieht %2 Karten
-
-
+
+
a card
eine Karte
@@ -2023,107 +2093,112 @@
vom Stapel
-
+
+ %1 gives %2 control over %3.
+ %1 überlässt %2 die Kontrolle über %3.
+
+
+
%1 puts %2 into play%3.
%1 bringt %2%3 ins Spiel.
-
+
%1 puts %2%3 into graveyard.
%1 legt %2%3 auf den Friedhof.
-
+
%1 exiles %2%3.
%1 schickt %2%3 ins Exil.
-
+
%1 moves %2%3 to hand.
%1 nimmt %2%3 auf die Hand.
-
+
%1 puts %2%3 into his library.
%1 legt %2%3 in seine Bibliothek.
-
+
%1 puts %2%3 on bottom of his library.
%1 legt %2%3 unter seine Bibliothek.
-
+
%1 puts %2%3 on top of his library.
%1 legt %2%3 auf die Bibliothek.
-
+
%1 puts %2%3 into his library at position %4.
%1 legt %2%3 in seine Bibliothek an %4. Stelle.
-
+
%1 moves %2%3 to sideboard.
%1 legt %2%3 in sein Sideboard.
-
+
%1 plays %2%3.
%1 spielt %2%3 aus.
-
+
%1 flips %2 face-down.
%1 wendet %2 auf die Rückseite.
-
+
%1 flips %2 face-up.
%1 wendet %2 auf die Vorderseite.
-
+
%1 destroys %2.
%1 zerstört %2.
-
+
%1 attaches %2 to %3's %4.
%1 legt %2 an %3s %4 an.
-
+
%1 unattaches %2.
%1 löst %2 ab.
-
+
%1 creates token: %2%3.
%1 erstellt Token: %2%3.
-
+
%1 points from %2's %3 to %4.
%1 zeigt von %2s %3 auf %4.
-
+
%1 randomly reveals %2%3 to %4.
%1 zeigt %4 zufällig %2%3 vor.
-
+
%1 randomly reveals %2%3.
%1 zeigt zufällig %2%3 offen vor.
-
+
%1 reveals %2%3 to %4.
%1 zeigt %4 %2%3 vor.
-
+
%1 reveals %2%3.
%1 zeigt %2%3 offen vor.
@@ -2132,12 +2207,12 @@
%1 erstellt einen Spielstein: %2 (%3).
-
+
%1 points from %2's %3 to %4's %5.
%1 zeigt von %2s %3 auf %4s %5.
-
+
%1 places %n counter(s) (%2) on %3 (now %4).
%1 legt eine Marke (%2) auf %3 (jetzt %4).
@@ -2145,7 +2220,7 @@
-
+
%1 removes %n counter(s) (%2) from %3 (now %4).
%1 entfernt eine Marke (%2) von %3 (jetzt %4).
@@ -2153,37 +2228,37 @@
-
+
red
rot
-
+
yellow
gelb
-
+
green
grün
-
+
%1 sets counter %2 to %3 (%4%5).
%1 setzt Zähler %2 auf %3 (%4%5).
-
+
%1 sets PT of %2 to %3.
%1 setzt Kampfwerte von %2 auf %3.
-
+
%1 sets annotation of %2 to %3.
%1 versieht %2 mit dem Hinweis %3.
-
+
%1 is looking at the top %2 cards %3.
%1 sieht sich die obersten %2 Karten %3 an.
@@ -2280,7 +2355,7 @@
%1 entfernt %2 Zählmarken von %3 (jetzt %4).
-
+
%1 %2 %3.
%1 %2 %3.
@@ -2293,22 +2368,22 @@
%1 sieht sich die obersten %2 Karten %3 an.
-
+
%1 is looking at %2.
%1 sieht sich %2 an.
-
+
%1 stops looking at %2.
%1 sieht sich %2 nicht mehr an.
-
+
%1 reveals %2 to %3.
%1 zeigt %3 %2.
-
+
%1 reveals %2.
%1 zeigt %2 offen vor.
@@ -2329,7 +2404,7 @@
%1 zeigt %2 aus %3 offen vor.
-
+
ending phase
die Zugendphase
@@ -2358,57 +2433,57 @@
%1 sieht sich %2s %3 nicht mehr an
-
+
It is now %1's turn.
%1 ist am Zug.
-
+
untap step
das Enttappsegment
-
+
upkeep step
das Versorgungssegment
-
+
draw step
das Ziehsegment
-
+
first main phase
die erste Hauptphase
-
+
beginning of combat step
das Anfangssegment der Kampfphase
-
+
declare attackers step
das Angreifer-Deklarieren-Segment
-
+
declare blockers step
das Blocker-Deklarieren-Segment
-
+
combat damage step
das Kampfschadenssegment
-
+
end of combat step
das Endsegment der Kampfphase
-
+
second main phase
die zweite Hauptphase
@@ -2417,7 +2492,7 @@
das Ende-des-Zuges-Segment
-
+
It is now the %1.
Es ist nun %1.
@@ -2426,12 +2501,12 @@
%1 bewegt %2 %3 nach %4
-
+
taps
tappt
-
+
untaps
enttappt
@@ -2456,7 +2531,7 @@
%1 entfernt %2 Zählmarken von %3 (jetzt %4)
-
+
his permanents
seine bleibenden Karten
@@ -2469,12 +2544,12 @@
%1 setzt Zähler "%2" auf %3 (%4%5)
-
+
%1 sets %2 to not untap normally.
%1 setzt %2 auf explizites Enttappen.
-
+
%1 sets %2 to untap normally.
%1 setzt %2 auf normales Enttappen.
@@ -2490,12 +2565,12 @@
MessagesSettingsPage
-
+
&Add
&Hinzufügen
-
+
&Remove
&Entfernen
@@ -2508,12 +2583,12 @@
Entfernen
-
+
Add message
Nachricht hinzufügen
-
+
Message:
Nachricht:
@@ -2521,57 +2596,57 @@
PhasesToolbar
-
+
Untap step
Enttappsegment
-
+
Upkeep step
Versorgungssegment
-
+
Draw step
Ziehsegment
-
+
First main phase
erste Hauptphase
-
+
Beginning of combat step
Anfangssegment der Kampfphase
-
+
Declare attackers step
Angreifer-Deklarieren-Segment
-
+
Declare blockers step
Blocker-Deklarieren-Segment
-
+
Combat damage step
Kampfschadenssegment
-
+
End of combat step
Endsegment der Kampfphase
-
+
Second main phase
zweite Hauptphase
-
+
End of turn step
Ende-des-Zuges-Segment
@@ -2579,21 +2654,21 @@
Player
-
-
-
+
+
+
Move to &top of library
Oben auf die Biblio&thek legen
-
-
-
+
+
+
Move to &bottom of library
Unter die &Bibliothek legen
-
+
&View library
&Zeige Bibliothek
@@ -2602,32 +2677,32 @@
Oberste Karten in den F&riedhof legen...
-
+
Move top cards to &exile...
Oberste Karten ins &Exil schicken...
-
+
F3
F3
-
+
View &top cards of library...
Zeige die oberen Kar&ten der Bibliothek...
-
+
&View graveyard
&Zeige Friedhof
-
+
&All players
&allen Spielern
-
+
F4
F4
@@ -2636,63 +2711,68 @@
Zeige ent&fernte Karten
-
+
&View sideboard
Zeige &Sideboard
-
+
Player "%1"
Spieler "%1"
-
-
+
+
Move to &graveyard
Auf den &Friedhof legen
-
+
Reveal &library to
&Bibliothek jemandem zeigen
-
+
Reveal t&op card to
&Oberste Karte jemandem zeigen
-
+
Take &mulligan
&Mulligan nehmen
-
+
Move top cards to &graveyard...
Oberste Karten auf den F&riedhof legen...
-
+
+ Put top card on &bottom
+ Oberste Karte nach &unten legen
+
+
+
&Hand
&Hand
-
+
&Reveal to
Jemandem &zeigen
-
+
Reveal r&andom card to
Z&ufällige Karte jemandem zeigen
-
+
&Library
Bib&liothek
-
+
&Graveyard
&Friedhof
@@ -2701,7 +2781,7 @@
Entfe&rnte Karten
-
+
&Sideboard
&Sideboard
@@ -2714,33 +2794,33 @@
&Hinweis setzen...
-
+
View top cards of library
Zeige die obersten Karten der Bibliothek
-
+
Number of cards:
Anzahl der Karten:
-
+
&Draw card
Karte &ziehen
-
+
&View exile
&Zeige Exil
-
+
&Exile
&Exil
-
-
+
+
Move to &hand
auf die &Hand nehmen
@@ -2749,28 +2829,28 @@
auf den &Friedhof legen
-
-
+
+
Move to &exile
ins &Exil schicken
-
+
Ctrl+W
Ctrl+W
-
+
Ctrl+D
Ctrl+D
-
+
D&raw cards...
Ka&rten ziehen...
-
+
Ctrl+E
Ctrl+E
@@ -2779,32 +2859,32 @@
&Mulligan nehmen...
-
+
Ctrl+M
Ctrl+M
-
+
&Shuffle
Mi&schen
-
+
Ctrl+S
Ctrl+S
-
+
&Counters
&Zähler
-
+
&Untap all permanents
&Enttappe alle bleibenden Karten
-
+
Ctrl+U
Ctrl+U
@@ -2833,42 +2913,42 @@
Ctrl+L
-
+
R&oll die...
&Würfeln...
-
+
Ctrl+I
Ctrl+I
-
+
&Create token...
Spiels&tein erstellen...
-
+
Ctrl+T
Ctrl+T
-
+
C&reate another token
&Noch einen Spielstein erstellen
-
+
Ctrl+G
Ctrl+G
-
+
S&ay
S&agen
-
+
C&ard
&Karte
@@ -2961,50 +3041,50 @@
F10
-
+
Draw cards
Karten ziehen
-
-
-
-
+
+
+
+
Number:
Anzahl:
-
+
Move top cards to grave
Oberste Karten in den Friedhof legen
-
+
Move top cards to exile
Oberste Karten ins Exil schicken
-
+
Set power/toughness
Kampfwerte setzen
-
+
Please enter the new PT:
Bitte die neuen Kampfwerte eingeben:
-
+
Set annotation
Hinweis setzen
-
+
Please enter the new annotation:
Bitte den Hinweis eingeben:
-
+
Set counters
Setze Zählmarken
@@ -3017,12 +3097,12 @@
Neue Lebenspunkte insgesamt:
-
+
Roll die
Würfeln
-
+
Number of sides:
Anzahl der Seiten:
@@ -3100,17 +3180,17 @@
Sideboard
-
+
Cockatrice decks (*.cod)
Cockatrice Decks (*.cod)
-
+
Plain text decks (*.dec *.mwDeck)
Text Decks (*.dec *.mwDeck)
-
+
All files (*.*)
Alle Dateien (*.*)
@@ -3133,12 +3213,44 @@
Änderungsdatum
+
+ RoomSelector
+
+
+ Rooms
+ Räume
+
+
+
+ Joi&n
+ Teil&nehmen
+
+
+
+ Room
+ Raum
+
+
+
+ Description
+ Beschreibung
+
+
+
+ Players
+ Spieler
+
+
+
+ Games
+ Spiele
+
+
ServerMessageLog
-
Server messages
- Servernachrichten
+ Servernachrichten
@@ -3154,27 +3266,61 @@
Langer Name
+
+ TabAdmin
+
+
+ Update server &message
+ Server&nachricht aktualisieren
+
+
+
+ Server administration functions
+ Funktionen zur Serverwartung
+
+
+
+ &Unlock functions
+ &Sperre aufheben
+
+
+
+ &Lock functions
+ Funktionen s&perren
+
+
+
+ Unlock administration functions
+ Wartungsfunktionen entsperren
+
+
+
+ Do you really want to unlock the administration functions?
+ Möchten Sie wirklich die Sperre der Wartungsfunktionen aufheben?
+
+
+
+ Administration
+ Wartung
+
+
TabChatChannel
-
C&hat channel
- C&hatraum
+ C&hatraum
-
&Leave channel
- Raum ver&lassen
+ Raum ver&lassen
-
%1 has joined the channel.
- %1 hat den Raum betreten.
+ %1 hat den Raum betreten.
-
%1 has left the channel.
- %1 hat den Raum verlassen.
+ %1 hat den Raum verlassen.
@@ -3248,57 +3394,57 @@ Bitte geben Sie einen Namen ein:
TabGame
-
+
&Game
Spi&el
-
+
Next &phase
Nächste &Phase
-
+
Ctrl+Space
Ctrl+Space
-
+
Next &turn
Nächster &Zug
-
+
Ctrl+Return
Ctrl+Return
-
+
Ctrl+Enter
Ctrl+Enter
-
+
&Remove all local arrows
&Lokale Pfeile entfernen
-
+
Ctrl+R
Ctrl+R
-
+
&Concede
-
+
F2
F2
-
+
&Leave game
Spiel ver&lassen
@@ -3319,7 +3465,7 @@ Bitte geben Sie einen Namen ein:
Spiel s&tarten
-
+
&Say:
&Sagen:
@@ -3332,22 +3478,22 @@ Bitte geben Sie einen Namen ein:
Esc
-
+
Concede
Aufgeben
-
+
Are you sure you want to concede this game?
Sind Sie sicher, dass Sie das Spiel aufgeben möchten?
-
+
Leave game
Spiel verlassen
-
+
Are you sure you want to leave this game?
Sind Sie sicher, dass Sie das Spiel verlassen möchten?
@@ -3356,7 +3502,7 @@ Bitte geben Sie einen Namen ein:
Deck laden
-
+
Game %1: %2
Spiel %1: %2
@@ -3384,10 +3530,43 @@ Bitte geben Sie einen Namen ein:
Gespräch mit %1
+
+ TabRoom
+
+
+ &Say:
+ &Sagen:
+
+
+
+ Chat
+ Unterhaltung
+
+
+
+ &Room
+ &Raum
+
+
+
+ &Leave room
+ Raum ver&lassen
+
+
+
+ %1 has joined the room.
+ %1 hat den Raum betreten.
+
+
+
+ %1 has left the room.
+ %1 hat den Raum verlassen.
+
+
TabServer
-
+
Server
Server
@@ -3410,35 +3589,65 @@ Bitte geben Sie einen Namen ein:
UserInfoBox
-
+
+ User information
+ Benutzerinformationen
+
+
+
+ Real name:
+ Richtiger Name:
+
+
+
Location:
Ort:
-
+
User level:
Nutzerstatus:
+
+
+ Administrator
+ Administrator
+
+
+
+ Judge
+ Schiedsrichter
+
+
+
+ Registered user
+ Registrierter Benutzer
+
+
+
+ Unregistered user
+ Unregistrierter Benutzer
+
UserInterfaceSettingsPage
-
+
General interface settings
Allgemeine Bedienung
-
+
&Double-click cards to play them (instead of single-click)
Karten durch &Doppelklick ausspielen (statt Einzelklick)
-
+
Animation settings
Animationseinstellungen
-
+
&Tap/untap animation
Animiertes &Tappen/Enttappen
@@ -3446,10 +3655,25 @@ Bitte geben Sie einen Namen ein:
UserList
-
+
Users online: %1
Benutzer online: %1
+
+
+ Users in this room: %1
+ Benutzer in diesem Raum: %1
+
+
+
+ User &details
+ Benutzer&details
+
+
+
+ Direct &chat
+ &Persönliches Gespräch
+
WndDeckEditor
@@ -3637,7 +3861,21 @@ Willst du die Änderungen speichern?
Deck laden
-
+
+
+ Error
+ Fehler
+
+
+
+
+ The deck could not be saved.
+Please check that the directory is writable and try again.
+ Das Deck konnte nicht gespeichert werden.
+Bitte überprüfen Sie, dass Sie Schreibrechte in dem Verzeichnis haben, und versuchen Sie es erneut.
+
+
+
Save deck
Deck speichern
diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts
index 60ebb47d..a47980be 100644
--- a/cockatrice/translations/cockatrice_en.ts
+++ b/cockatrice/translations/cockatrice_en.ts
@@ -1,84 +1,112 @@
+
+ AbstractCounter
+
+
+ &Set counter...
+
+
+
+
+ Ctrl+L
+
+
+
+
+ F11
+
+
+
+
+ F12
+
+
+
+
+ Set counter
+
+
+
+
+ New value for counter '%1':
+
+
+
AppearanceSettingsPage
-
+
Zone background pictures
-
+
Path to hand background:
-
+
Path to stack background:
-
+
Path to table background:
-
+
Path to player info background:
-
+
Path to picture of card back:
-
+
Hand layout
-
+
Display hand horizontally (wastes space)
-
+
Table grid layout
-
- Economical layout
-
-
-
-
+
Invert vertical coordinate
-
+
Zone view layout
-
+
Sort by name
-
+
Sort by type
-
-
-
-
-
+
+
+
+
+
Choose path
@@ -137,112 +165,122 @@
CardItem
-
+
+ &Play
+
+
+
+
+ &Hide
+
+
+
+
&Tap
-
+
&Untap
-
+
Toggle &normal untapping
-
+
&Flip
-
+
&Clone
-
+
&Attach to card...
-
+
Ctrl+A
-
+
Unattac&h
-
+
Set &P/T...
-
+
&Set annotation...
-
+
red
-
+
yellow
-
+
green
-
+
&Add counter (%1)
-
+
&Remove counter (%1)
-
+
&Set counters (%1)...
-
+
&top of library
-
+
&bottom of library
-
+
&graveyard
-
+
Ctrl+Del
-
+
&exile
-
+
&Move to
@@ -430,67 +468,6 @@
-
- ChatChannelSelector
-
-
- Chat channels
-
-
-
-
- Joi&n
-
-
-
-
- Channel
-
-
-
-
- Description
-
-
-
-
- Players
-
-
-
-
- Counter
-
-
- &Set counter...
-
-
-
-
- Ctrl+L
-
-
-
-
- F11
-
-
-
-
- F12
-
-
-
-
- Set counter
-
-
-
-
- New value for counter '%1':
-
-
-
DeckListModel
@@ -669,12 +646,12 @@
-
+
Error
-
+
Server error.
@@ -816,54 +793,54 @@
DlgSettings
-
-
-
+
+
+
Error
-
+
Your card database is invalid. Would you like to go back and set the correct path?
-
+
The path to your deck directory is invalid. Would you like to go back and set the correct path?
-
+
The path to your card pictures directory is invalid. Would you like to go back and set the correct path?
-
+
Settings
-
+
General
-
+
Appearance
-
+
User interface
-
+
Messages
-
+
&Close
@@ -871,65 +848,65 @@
GameSelector
-
+
C&reate
-
+
&Join
-
-
-
-
+
+
+
+
Error
-
+
Wrong password.
-
+
Spectators are not allowed in this game.
-
+
The game is already full.
-
+
The game does not exist any more.
-
+
Join game
-
+
Password:
-
+
Games
-
- &Show full games
+
+ Show &full games
-
+
J&oin as spectator
@@ -937,7 +914,7 @@
GameView
-
+
Esc
@@ -1044,136 +1021,171 @@
MainWindow
-
+
Number of players
-
+
Please enter the number of players.
-
-
+
+
Player %1
-
+
About Cockatrice
-
-
- <font size="8"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Authors:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Translators:</b><br>Spanish: Gocho<br>Portugese: Milton Gonçalves<br>
-
-
+ Version %1
+
+
+
+
+ Authors:
+
+
+
+
+ Translators:
+
+
+
+
+ Spanish:
+
+
+
+
+ Portugese (Portugal):
+
+
+
+
+ Portugese (Brazil):
+
+
+
+ French:
+
+
+
+
+ Japanese:
+
+
+
-
+
+
+
Error
-
+
Server timeout
-
+
Invalid login data.
-
+
Socket error: %1
-
+
Protocol version mismatch. Local version: %1, remote version: %2.
-
+
Connecting to %1...
-
+
Disconnected
-
+
Logged in at %1
-
+
&Connect...
-
+
&Disconnect
-
+
Start &local game...
-
+
&Deck editor
-
+
&Full screen
-
+
Ctrl+F
-
+
&Settings...
-
+
&Exit
-
+
&Cockatrice
-
+
&About Cockatrice
-
+
&Help
-
+
Are you sure?
-
+
There are still open games. Are you sure you want to quit?
@@ -1281,88 +1293,93 @@
-
+
+ %1 gives %2 control over %3.
+
+
+
+
%1 puts %2 into play%3.
-
+
%1 puts %2%3 into graveyard.
-
+
%1 exiles %2%3.
-
+
%1 moves %2%3 to hand.
-
+
%1 puts %2%3 into his library.
-
+
%1 puts %2%3 on bottom of his library.
-
+
%1 puts %2%3 on top of his library.
-
+
%1 puts %2%3 into his library at position %4.
-
+
%1 moves %2%3 to sideboard.
-
+
%1 plays %2%3.
-
-
+
+
a card
-
+
%1 flips %2 face-down.
-
+
%1 flips %2 face-up.
-
+
%1 attaches %2 to %3's %4.
-
+
%1 unattaches %2.
-
+
%1 points from %2's %3 to %4's %5.
-
+
%1 places %n counter(s) (%2) on %3 (now %4).
%1 places a counter (%2) on %3 (now %4).
@@ -1370,7 +1387,7 @@
-
+
%1 removes %n counter(s) (%2) from %3 (now %4).
%1 removes a counter (%2) from %3 (now %4).
@@ -1378,37 +1395,37 @@
-
+
red
-
+
yellow
-
+
green
-
+
%1 sets counter %2 to %3 (%4%5).
-
+
%1 sets PT of %2 to %3.
-
+
%1 sets annotation of %2 to %3.
-
+
%1 is looking at the top %2 cards %3.
@@ -1473,52 +1490,52 @@
-
+
%1 destroys %2.
-
+
%1 creates token: %2%3.
-
+
%1 points from %2's %3 to %4.
-
+
%1 %2 %3.
-
+
%1 is looking at %2.
-
+
%1 stops looking at %2.
-
+
%1 reveals %2 to %3.
-
+
%1 reveals %2.
-
+
ending phase
-
+
It is now %1's turn.
@@ -1528,102 +1545,102 @@
-
+
%1 randomly reveals %2%3 to %4.
-
+
%1 randomly reveals %2%3.
-
+
%1 reveals %2%3 to %4.
-
+
%1 reveals %2%3.
-
+
untap step
-
+
upkeep step
-
+
draw step
-
+
first main phase
-
+
beginning of combat step
-
+
declare attackers step
-
+
declare blockers step
-
+
combat damage step
-
+
end of combat step
-
+
second main phase
-
+
It is now the %1.
-
+
taps
-
+
untaps
-
+
%1 sets %2 to not untap normally.
-
+
%1 sets %2 to untap normally.
-
+
his permanents
@@ -1631,22 +1648,22 @@
MessagesSettingsPage
-
+
&Add
-
+
&Remove
-
+
Add message
-
+
Message:
@@ -1654,57 +1671,57 @@
PhasesToolbar
-
+
Untap step
-
+
Upkeep step
-
+
Draw step
-
+
First main phase
-
+
Beginning of combat step
-
+
Declare attackers step
-
+
Declare blockers step
-
+
Combat damage step
-
+
End of combat step
-
+
Second main phase
-
+
End of turn step
@@ -1712,302 +1729,307 @@
Player
-
-
-
- Move to &top of library
-
-
-
-
- Move to &bottom of library
-
-
-
-
-
- Move to &graveyard
-
-
-
-
- &View library
-
-
-
-
- Reveal &library to
-
-
-
-
- Reveal t&op card to
-
-
-
-
- Move top cards to &graveyard...
-
-
-
-
- F3
-
-
-
- View &top cards of library...
-
-
-
-
- &View graveyard
-
-
-
-
- F4
-
-
-
-
- &View sideboard
-
-
-
-
- Player "%1"
-
-
-
-
- &Hand
-
-
-
-
- &Library
-
-
-
-
- &Graveyard
-
-
-
-
- &Sideboard
-
-
-
-
- View top cards of library
-
-
-
-
- Number of cards:
-
-
-
-
- &Draw card
-
-
-
-
- &View exile
-
-
-
-
- &Exile
+ Move to &top of library
- Move to &hand
+
+ Move to &bottom of library
-
- Move to &exile
+
+ Move to &graveyard
-
- Ctrl+W
-
-
-
-
- Ctrl+D
-
-
-
-
- D&raw cards...
-
-
-
-
- Ctrl+E
+
+ &View library
- Take &mulligan
-
-
-
-
- Ctrl+M
+ Reveal &library to
- &Shuffle
-
-
-
-
- Ctrl+S
-
-
-
-
- &Counters
-
-
-
-
- &Untap all permanents
-
-
-
-
- Ctrl+U
-
-
-
-
- R&oll die...
-
-
-
-
- Ctrl+I
-
-
-
-
- &Create token...
-
-
-
-
- Ctrl+T
-
-
-
-
- C&reate another token
-
-
-
-
- Ctrl+G
-
-
-
-
- S&ay
-
-
-
-
- Move top cards to &exile...
-
-
-
-
- &Reveal to
+ Reveal t&op card to
- Reveal r&andom card to
+ Move top cards to &graveyard...
+
+
+
+
+ F3
+
+
+
+
+ View &top cards of library...
+
+
+
+
+ &View graveyard
+
+
+
+
+ F4
+
+
+
+
+ &View sideboard
+
+
+
+
+ Player "%1"
+
+
+
+
+ &Hand
+
+
+
+
+ &Library
+
+
+
+
+ &Graveyard
+
+
+
+
+ &Sideboard
+
+
+
+
+ View top cards of library
+
+
+
+
+ Number of cards:
+
+
+
+
+ &Draw card
+
+
+
+
+ &View exile
+
+
+
+
+ &Exile
+
+
+
+
+
+ Move to &hand
+
+
+
+
+
+ Move to &exile
+
+
+
+
+ Ctrl+W
+
+
+
+
+ Ctrl+D
+
+
+
+
+ D&raw cards...
+
+
+
+
+ Ctrl+E
+
+
+
+
+ Take &mulligan
+
+
+
+
+ Ctrl+M
+
+
+
+
+ &Shuffle
+
+
+
+
+ Ctrl+S
+
+
+
+
+ &Counters
+
+
+
+
+ &Untap all permanents
+
+
+
+
+ Ctrl+U
+
+
+
+
+ R&oll die...
+
+
+
+
+ Ctrl+I
+
+
+
+
+ &Create token...
+
+
+
+
+ Ctrl+T
+
+
+
+
+ C&reate another token
+
+
+
+
+ Ctrl+G
+ S&ay
+
+
+
+
+ Move top cards to &exile...
+
+
+
+
+ Put top card on &bottom
+
+
+
+
+ &Reveal to
+
+
+
+
+ Reveal r&andom card to
+
+
+
+
C&ard
-
+
&All players
-
+
Draw cards
-
-
-
-
+
+
+
+
Number:
-
+
Move top cards to grave
-
+
Move top cards to exile
-
+
Roll die
-
+
Number of sides:
-
+
Set power/toughness
-
+
Please enter the new PT:
-
+
Set annotation
-
+
Please enter the new annotation:
-
+
Set counters
@@ -2053,17 +2075,17 @@
-
+
Cockatrice decks (*.cod)
-
+
Plain text decks (*.dec *.mwDeck)
-
+
All files (*.*)
@@ -2087,10 +2109,35 @@
- ServerMessageLog
+ RoomSelector
-
- Server messages
+
+ Rooms
+
+
+
+
+ Joi&n
+
+
+
+
+ Room
+
+
+
+
+ Description
+
+
+
+
+ Players
+
+
+
+
+ Games
@@ -2108,25 +2155,40 @@
- TabChatChannel
+ TabAdmin
-
- C&hat channel
+
+ Update server &message
-
- &Leave channel
+
+ Server administration functions
-
- %1 has joined the channel.
+
+ &Unlock functions
-
- %1 has left the channel.
+
+ &Lock functions
+
+
+
+
+ Unlock administration functions
+
+
+
+
+ Do you really want to unlock the administration functions?
+
+
+
+
+ Administration
@@ -2200,87 +2262,87 @@ Please enter a name:
TabGame
-
+
&Game
-
+
Next &phase
-
+
Ctrl+Space
-
+
Next &turn
-
+
Ctrl+Return
-
+
Ctrl+Enter
-
+
&Remove all local arrows
-
+
Ctrl+R
-
+
&Concede
-
+
F2
-
+
&Leave game
-
+
&Say:
-
+
Concede
-
+
Are you sure you want to concede this game?
-
+
Leave game
-
+
Are you sure you want to leave this game?
-
+
Game %1: %2
@@ -2308,10 +2370,43 @@ Please enter a name:
+
+ TabRoom
+
+
+ &Say:
+
+
+
+
+ Chat
+
+
+
+
+ &Room
+
+
+
+
+ &Leave room
+
+
+
+
+ %1 has joined the room.
+
+
+
+
+ %1 has left the room.
+
+
+
TabServer
-
+
Server
@@ -2319,35 +2414,65 @@ Please enter a name:
UserInfoBox
-
+
+ User information
+
+
+
+
+ Real name:
+
+
+
+
Location:
-
+
User level:
+
+
+ Administrator
+
+
+
+
+ Judge
+
+
+
+
+ Registered user
+
+
+
+
+ Unregistered user
+
+
UserInterfaceSettingsPage
-
+
General interface settings
-
+
&Double-click cards to play them (instead of single-click)
-
+
Animation settings
-
+
&Tap/untap animation
@@ -2355,10 +2480,25 @@ Please enter a name:
UserList
-
+
Users online: %1
+
+
+ Users in this room: %1
+
+
+
+
+ User &details
+
+
+
+
+ Direct &chat
+
+
WndDeckEditor
@@ -2443,7 +2583,20 @@ Please enter a name:
-
+
+
+ Error
+
+
+
+
+
+ The deck could not be saved.
+Please check that the directory is writable and try again.
+
+
+
+
Save deck
diff --git a/cockatrice/translations/cockatrice_es.ts b/cockatrice/translations/cockatrice_es.ts
index 0457d2f2..44daecba 100644
--- a/cockatrice/translations/cockatrice_es.ts
+++ b/cockatrice/translations/cockatrice_es.ts
@@ -1,60 +1,92 @@
+
+ AbstractCounter
+
+
+ &Set counter...
+ E&stablecer contadores...
+
+
+
+ Ctrl+L
+ Ctrl+L
+
+
+
+ F11
+ F11
+
+
+
+ F12
+ F12
+
+
+
+ Set counter
+ Establecer contador
+
+
+
+ New value for counter '%1':
+ Nuevo valor para el contador '%1':
+
+
AppearanceSettingsPage
-
+
Zone background pictures
Imagenes de la zona de fondo
-
+
Path to hand background:
Ruta a la imagen de fondo de la mano:
-
+
Path to stack background:
Ruta a la imagen de fondo de la pila:
-
+
Path to table background:
Ruta a la imagen de fondo de la mesa:
-
+
Path to player info background:
Ruta a la imagen de fondo de la información del jugador:
-
+
Path to picture of card back:
Ruta al reverso de las cartas:
-
+
Hand layout
Disposición de la mano
-
+
Display hand horizontally (wastes space)
Mostrar la mano horizontalmente (desperdicia espacio)
-
+
Table grid layout
Disposición de la rejilla de la mesa
-
Economical layout
- Disposición Económica
+ Disposición Económica
-
+
Invert vertical coordinate
Invertir coordenada vertical
@@ -63,26 +95,26 @@
Disposición económica
-
+
Zone view layout
Distribución de la zona de visionado
-
+
Sort by name
Ordenar por nombre
-
+
Sort by type
Ordenar por tipo
-
-
-
-
-
+
+
+
+
+
Choose path
Elija ruta
@@ -141,112 +173,122 @@
CardItem
-
+
+ &Play
+
+
+
+
+ &Hide
+
+
+
+
&Tap
&Girar
-
+
&Untap
&Enderezar
-
+
Toggle &normal untapping
Alternar enderezamiento &normal
-
+
&Flip
&Voltear
-
+
&Clone
&Clonar
-
+
&Attach to card...
Ane&xar a una carta...
-
+
Ctrl+A
Ctrl+A
-
+
Unattac&h
Desane&xar
-
+
Set &P/T...
Establecer &F/R...
-
+
&Set annotation...
E&scribir anotación...
-
+
red
rojo
-
+
yellow
amarillo
-
+
green
verde
-
+
&Add counter (%1)
&Añadir contador (%1)
-
+
&Remove counter (%1)
&Quitar contador (%1)
-
+
&Set counters (%1)...
E&stablecer contadores (%1)...
-
+
&top of library
&parte superior de la biblioteca
-
+
&bottom of library
&fondo de la biblioteca
-
+
&graveyard
&cementerio
-
+
Ctrl+Del
Ctrl+Del
-
+
&exile
&exilio
-
+
&Move to
&Mover a
@@ -567,62 +609,51 @@
ChatChannelSelector
-
Chat channels
- Canales de Chat
+ Canales de Chat
-
Joi&n
- E&ntrar
+ E&ntrar
-
Channel
- Canal
+ Canal
-
Description
- Descripción
+ Descripción
-
Players
- Jugadores
+ Jugadores
Counter
-
&Set counter...
- E&stablecer contadores...
+ E&stablecer contadores...
-
Ctrl+L
- Ctrl+L
+ Ctrl+L
-
F11
- F11
+ F11
-
F12
- F12
+ F12
-
Set counter
- Establecer contador
+ Establecer contador
-
New value for counter '%1':
- Nuevo valor para el contador '%1':
+ Nuevo valor para el contador '%1':
@@ -803,12 +834,12 @@
Crear partida
-
+
Error
Error
-
+
Server error.
Error del servidor.
@@ -950,9 +981,9 @@
DlgSettings
-
-
-
+
+
+
Error
Error
@@ -969,47 +1000,47 @@
La ruta a tu directorio de imagenes de las cartas es invalida.
-
+
Your card database is invalid. Would you like to go back and set the correct path?
Tu base de datos de cartas es invalida. ¿Deseas volver y seleccionar la ruta correcta?
-
+
The path to your deck directory is invalid. Would you like to go back and set the correct path?
La ruta a tu directorio de mazos es invalida. ¿Deseas volver y seleccionar la ruta correcta?
-
+
The path to your card pictures directory is invalid. Would you like to go back and set the correct path?
La ruta a tu directorio de imagenes de las cartas es invalida.¿Deseas volver y seleccionar la ruta correcta?
-
+
Settings
Preferencias
-
+
General
General
-
+
Appearance
Apariencia
-
+
User interface
Interfaz de usuario
-
+
Messages
Mensajes
-
+
&Close
&Cerrar
@@ -1017,65 +1048,69 @@
GameSelector
-
+
C&reate
C&rear
-
+
&Join
E&ntrar
-
-
-
-
+
+
+
+
Error
Error
-
+
Wrong password.
Contraseña incorrecta.
-
+
Spectators are not allowed in this game.
No se permiten espectadores en esta partida.
-
+
The game is already full.
La partida no tiene plazas libres.
-
+
The game does not exist any more.
La partida ya no existe.
-
+
Join game
Entrar en la partida
-
+
Password:
Contraseña:
-
+
Games
Partidas
-
- &Show full games
- &Ver partidas sin plazas libres
+
+ Show &full games
+
-
+ &Show full games
+ &Ver partidas sin plazas libres
+
+
+
J&oin as spectator
Entrar como e&spectador
@@ -1083,7 +1118,7 @@
GameView
-
+
Esc
Esc
@@ -1190,136 +1225,171 @@
MainWindow
-
+
Number of players
Número de jugadores
-
+
Please enter the number of players.
Por favor, introduzca el número de jugadores.
-
-
+
+
Player %1
Jugador %1
-
+
About Cockatrice
Acerca de Cockatrice
-
-
- <font size="8"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Authors:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Translators:</b><br>Spanish: Gocho<br>Portugese: Milton Gonçalves<br>
-
-
+ Version %1
+
+
+
+
+ Authors:
+
+
+
+
+ Translators:
+
+
+
+
+ Spanish:
+
+
+
+
+ Portugese (Portugal):
+
+
+
+
+ Portugese (Brazil):
+
+
+
+ French:
+
+
+
+
+ Japanese:
+
+
+
-
+
+
+
Error
Error
-
+
Server timeout
Tiempo de espera del servidor agotado
-
+
Invalid login data.
Datos de conexión invalidos.
-
+
Socket error: %1
Error del Socket: %1
-
+
Protocol version mismatch. Local version: %1, remote version: %2.
La versión del protocolo es diferente. Version local: %1, version remota: %2.
-
+
Connecting to %1...
Conectando a %1...
-
+
Disconnected
Desconectado
-
+
Logged in at %1
Conectado en %1
-
+
&Connect...
&Conectar...
-
+
&Disconnect
&Desconectar
-
+
Start &local game...
Empezar partida &local...
-
+
&Deck editor
Editor de &mazos
-
+
&Full screen
&Pantalla completa
-
+
Ctrl+F
CTRL+F
-
+
&Settings...
&Preferencias...
-
+
&Exit
&Salir
-
+
&Cockatrice
&Cockatrice
-
+
&About Cockatrice
&Acerca de Cockatrice
-
+
&Help
A&yuda
-
+
Are you sure?
¿Estás seguro?
-
+
There are still open games. Are you sure you want to quit?
TodavÃa hay partidas abiertas. ¿Estás seguro que quieres salir?
@@ -1427,88 +1497,93 @@
de la pila
-
+
+ %1 gives %2 control over %3.
+
+
+
+
%1 puts %2 into play%3.
%1 pone %2 en juego%3.
-
+
%1 puts %2%3 into graveyard.
%1 pone %2%3 en el cementerio.
-
+
%1 exiles %2%3.
%1 exilia %2%3.
-
+
%1 moves %2%3 to hand.
%1 mueve %2%3 a la mano.
-
+
%1 puts %2%3 into his library.
%1 pone %2%3 en la biblioteca.
-
+
%1 puts %2%3 on bottom of his library.
%1 pone %2%3 en la parte inferior de su biblioteca.
-
+
%1 puts %2%3 on top of his library.
%1 pone %2%3 en la parte superior de su biblioteca.
-
+
%1 puts %2%3 into his library at position %4.
%1 pone %2%3 en su biblioteca en la posición %4.
-
+
%1 moves %2%3 to sideboard.
%1 mueve %2%3 a la reserva.
-
+
%1 plays %2%3.
%1 juega %2%3.
-
-
+
+
a card
una carta
-
+
%1 flips %2 face-down.
%1 voltea %2 boca abajo.
-
+
%1 flips %2 face-up.
%1 voltea %2 boca arriba.
-
+
%1 attaches %2 to %3's %4.
%1 anexa %2 a el %4 de %3.
-
+
%1 unattaches %2.
%1 desanexa %2.
-
+
%1 points from %2's %3 to %4's %5.
%1 apunta desde el %3 de %2 al %5 de %4.
-
+
%1 places %n counter(s) (%2) on %3 (now %4).