diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro
index 4a0203f26..5902e4184 100644
--- a/cockatrice/cockatrice.pro
+++ b/cockatrice/cockatrice.pro
@@ -5,7 +5,7 @@ INCLUDEPATH += . src ../common
MOC_DIR = build
OBJECTS_DIR = build
RESOURCES = cockatrice.qrc
-QT += network svg
+QT += network script svg multimedia
HEADERS += src/abstractcounter.h \
src/counter_general.h \
@@ -28,6 +28,8 @@ HEADERS += src/abstractcounter.h \
src/handcounter.h \
src/carddatabase.h \
src/gameview.h \
+ src/gameselector.h \
+ src/gametypemap.h \
src/decklistmodel.h \
src/dlg_load_deck_from_clipboard.h \
src/dlg_load_remote_deck.h \
@@ -71,6 +73,8 @@ HEADERS += src/abstractcounter.h \
src/localserverinterface.h \
src/localclient.h \
src/translation.h \
+ src/priceupdater.h \
+ src/soundengine.h \
../common/color.h \
../common/serializable_item.h \
../common/decklist.h \
@@ -112,6 +116,7 @@ SOURCES += src/abstractcounter.cpp \
src/handcounter.cpp \
src/carddatabase.cpp \
src/gameview.cpp \
+ src/gameselector.cpp \
src/decklistmodel.cpp \
src/dlg_load_deck_from_clipboard.cpp \
src/dlg_load_remote_deck.cpp \
@@ -134,6 +139,7 @@ SOURCES += src/abstractcounter.cpp \
src/gamescene.cpp \
src/arrowitem.cpp \
src/arrowtarget.cpp \
+ src/tab.cpp \
src/tab_server.cpp \
src/tab_room.cpp \
src/tab_message.cpp \
@@ -153,6 +159,8 @@ SOURCES += src/abstractcounter.cpp \
src/localserver.cpp \
src/localserverinterface.cpp \
src/localclient.cpp \
+ src/priceupdater.cpp \
+ src/soundengine.cpp \
../common/serializable_item.cpp \
../common/decklist.cpp \
../common/protocol.cpp \
@@ -177,7 +185,11 @@ TRANSLATIONS += \
translations/cockatrice_pt-br.ts \
translations/cockatrice_fr.ts \
translations/cockatrice_ja.ts \
- translations/cockatrice_ru.ts
+ translations/cockatrice_ru.ts \
+ translations/cockatrice_cs.ts \
+ translations/cockatrice_pl.ts \
+ translations/cockatrice_sk.ts
+
win32 {
RC_FILE = cockatrice.rc
}
diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index a71ed41e6..3a75a53d8 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -7,6 +7,7 @@
resources/icon_config_appearance.svg
resources/icon_config_interface.svg
resources/icon_config_messages.svg
+ resources/icon_config_deckeditor.svg
resources/phases/icon_phase_untap.svg
resources/phases/icon_phase_upkeep.svg
resources/phases/icon_phase_draw.svg
@@ -23,6 +24,7 @@
resources/pencil.svg
resources/icon_search.svg
resources/icon_clearsearch.svg
+ resources/icon_update.png
resources/hr.jpg
resources/appicon.svg
resources/add_to_sideboard.svg
@@ -37,6 +39,10 @@
resources/icon_player.svg
resources/icon_spectator.svg
+ resources/genders/male.svg
+ resources/genders/female.svg
+ resources/genders/unknown.svg
+
translations/cockatrice_de.qm
translations/cockatrice_en.qm
translations/cockatrice_es.qm
@@ -45,12 +51,18 @@
translations/cockatrice_fr.qm
translations/cockatrice_ja.qm
translations/cockatrice_ru.qm
+ translations/cockatrice_cs.qm
+ translations/cockatrice_pl.qm
+ translations/cockatrice_sk.qm
+ resources/countries/ar.svg
resources/countries/at.svg
resources/countries/au.svg
resources/countries/be.svg
resources/countries/br.svg
+ resources/countries/by.svg
resources/countries/ca.svg
+ resources/countries/cz.svg
resources/countries/ch.svg
resources/countries/cn.svg
resources/countries/de.svg
@@ -65,16 +77,22 @@
resources/countries/it.svg
resources/countries/jp.svg
resources/countries/mx.svg
+ resources/countries/my.svg
resources/countries/nl.svg
resources/countries/no.svg
resources/countries/ph.svg
resources/countries/pl.svg
resources/countries/pt.svg
+ resources/countries/ro.svg
resources/countries/ru.svg
resources/countries/se.svg
+ resources/countries/sg.svg
+ resources/countries/sk.svg
resources/countries/tr.svg
+ resources/countries/ua.svg
resources/countries/uk.svg
resources/countries/us.svg
+ resources/countries/za.svg
resources/counters/w.svg
resources/counters/w_highlight.svg
@@ -91,7 +109,7 @@
resources/userlevels/normal.svg
resources/userlevels/registered.svg
- resources/userlevels/judge.svg
+ resources/userlevels/moderator.svg
resources/userlevels/admin.svg
resources/news/exclamation_mark.svg
diff --git a/cockatrice/resources/countries/ar.svg b/cockatrice/resources/countries/ar.svg
new file mode 100644
index 000000000..543196fc3
--- /dev/null
+++ b/cockatrice/resources/countries/ar.svg
@@ -0,0 +1,109 @@
+
+
+
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/by.svg b/cockatrice/resources/countries/by.svg
new file mode 100644
index 000000000..bb1dfa789
--- /dev/null
+++ b/cockatrice/resources/countries/by.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/cz.svg b/cockatrice/resources/countries/cz.svg
new file mode 100644
index 000000000..51bf4fb7e
--- /dev/null
+++ b/cockatrice/resources/countries/cz.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/cockatrice/resources/countries/my.svg b/cockatrice/resources/countries/my.svg
new file mode 100644
index 000000000..988b507b7
--- /dev/null
+++ b/cockatrice/resources/countries/my.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/cockatrice/resources/countries/ro.svg b/cockatrice/resources/countries/ro.svg
new file mode 100644
index 000000000..c9b6da860
--- /dev/null
+++ b/cockatrice/resources/countries/ro.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/sg.svg b/cockatrice/resources/countries/sg.svg
new file mode 100644
index 000000000..572cb3b1b
--- /dev/null
+++ b/cockatrice/resources/countries/sg.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/cockatrice/resources/countries/sk.svg b/cockatrice/resources/countries/sk.svg
new file mode 100644
index 000000000..3b4e666a3
--- /dev/null
+++ b/cockatrice/resources/countries/sk.svg
@@ -0,0 +1,12 @@
+
+
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/ua.svg b/cockatrice/resources/countries/ua.svg
new file mode 100644
index 000000000..8f4b0a436
--- /dev/null
+++ b/cockatrice/resources/countries/ua.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/cockatrice/resources/countries/za.svg b/cockatrice/resources/countries/za.svg
new file mode 100644
index 000000000..ccfe132f5
--- /dev/null
+++ b/cockatrice/resources/countries/za.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/cockatrice/resources/genders/female.svg b/cockatrice/resources/genders/female.svg
new file mode 100644
index 000000000..b0fbb1306
--- /dev/null
+++ b/cockatrice/resources/genders/female.svg
@@ -0,0 +1,33 @@
+
+
+
diff --git a/cockatrice/resources/genders/male.svg b/cockatrice/resources/genders/male.svg
new file mode 100644
index 000000000..8c58a40fc
--- /dev/null
+++ b/cockatrice/resources/genders/male.svg
@@ -0,0 +1,12 @@
+
+
+
\ No newline at end of file
diff --git a/cockatrice/resources/genders/unknown.svg b/cockatrice/resources/genders/unknown.svg
new file mode 100644
index 000000000..99f681f9c
--- /dev/null
+++ b/cockatrice/resources/genders/unknown.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/cockatrice/resources/icon_config_deckeditor.svg b/cockatrice/resources/icon_config_deckeditor.svg
new file mode 100644
index 000000000..9e167516c
--- /dev/null
+++ b/cockatrice/resources/icon_config_deckeditor.svg
@@ -0,0 +1,268 @@
+
+
+
+
diff --git a/cockatrice/resources/icon_update.png b/cockatrice/resources/icon_update.png
new file mode 100644
index 000000000..825c0aee7
Binary files /dev/null and b/cockatrice/resources/icon_update.png differ
diff --git a/cockatrice/resources/phases/icon_phase_cleanup.svg b/cockatrice/resources/phases/icon_phase_cleanup.svg
index a675d66f5..9786daca9 100644
--- a/cockatrice/resources/phases/icon_phase_cleanup.svg
+++ b/cockatrice/resources/phases/icon_phase_cleanup.svg
@@ -1,749 +1,186 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_combat_attackers.svg b/cockatrice/resources/phases/icon_phase_combat_attackers.svg
index 540107ac2..d74832536 100644
--- a/cockatrice/resources/phases/icon_phase_combat_attackers.svg
+++ b/cockatrice/resources/phases/icon_phase_combat_attackers.svg
@@ -1,162 +1,103 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_combat_blockers.svg b/cockatrice/resources/phases/icon_phase_combat_blockers.svg
index 6344ef6b3..6602eaef0 100644
--- a/cockatrice/resources/phases/icon_phase_combat_blockers.svg
+++ b/cockatrice/resources/phases/icon_phase_combat_blockers.svg
@@ -1,181 +1,1930 @@
-
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_combat_damage.svg b/cockatrice/resources/phases/icon_phase_combat_damage.svg
index 8536764e8..aa356e2a9 100644
--- a/cockatrice/resources/phases/icon_phase_combat_damage.svg
+++ b/cockatrice/resources/phases/icon_phase_combat_damage.svg
@@ -1,169 +1,108 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_combat_end.svg b/cockatrice/resources/phases/icon_phase_combat_end.svg
index 9e7b8950b..bbbbf9bff 100644
--- a/cockatrice/resources/phases/icon_phase_combat_end.svg
+++ b/cockatrice/resources/phases/icon_phase_combat_end.svg
@@ -1,253 +1,319 @@
-
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_combat_start.svg b/cockatrice/resources/phases/icon_phase_combat_start.svg
index 996571d71..b80b571dc 100644
--- a/cockatrice/resources/phases/icon_phase_combat_start.svg
+++ b/cockatrice/resources/phases/icon_phase_combat_start.svg
@@ -1,253 +1,348 @@
-
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_draw.svg b/cockatrice/resources/phases/icon_phase_draw.svg
index 51918274c..4d1062199 100644
--- a/cockatrice/resources/phases/icon_phase_draw.svg
+++ b/cockatrice/resources/phases/icon_phase_draw.svg
@@ -1,192 +1,190 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_main1.svg b/cockatrice/resources/phases/icon_phase_main1.svg
index 264cef395..48fce651b 100644
--- a/cockatrice/resources/phases/icon_phase_main1.svg
+++ b/cockatrice/resources/phases/icon_phase_main1.svg
@@ -1,135 +1,79 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_main2.svg b/cockatrice/resources/phases/icon_phase_main2.svg
index 50f77fa70..61be736ef 100644
--- a/cockatrice/resources/phases/icon_phase_main2.svg
+++ b/cockatrice/resources/phases/icon_phase_main2.svg
@@ -1,135 +1,235 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_nextturn.svg b/cockatrice/resources/phases/icon_phase_nextturn.svg
index 3cfd19ab0..302a57d67 100644
--- a/cockatrice/resources/phases/icon_phase_nextturn.svg
+++ b/cockatrice/resources/phases/icon_phase_nextturn.svg
@@ -1,89 +1,102 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_untap.svg b/cockatrice/resources/phases/icon_phase_untap.svg
index 2f4d81732..3d316ab04 100644
--- a/cockatrice/resources/phases/icon_phase_untap.svg
+++ b/cockatrice/resources/phases/icon_phase_untap.svg
@@ -1,198 +1,120 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases/icon_phase_upkeep.svg b/cockatrice/resources/phases/icon_phase_upkeep.svg
index 5a06aae9c..2317a9379 100644
--- a/cockatrice/resources/phases/icon_phase_upkeep.svg
+++ b/cockatrice/resources/phases/icon_phase_upkeep.svg
@@ -1,159 +1,162 @@
-
-
-
+
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_cleanup.svg b/cockatrice/resources/phases_old/icon_phase_cleanup.svg
new file mode 100644
index 000000000..a675d66f5
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_cleanup.svg
@@ -0,0 +1,749 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg b/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg
new file mode 100644
index 000000000..540107ac2
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg
@@ -0,0 +1,162 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg b/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg
new file mode 100644
index 000000000..6344ef6b3
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg
@@ -0,0 +1,181 @@
+
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_combat_damage.svg b/cockatrice/resources/phases_old/icon_phase_combat_damage.svg
new file mode 100644
index 000000000..8536764e8
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_combat_damage.svg
@@ -0,0 +1,169 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_combat_end.svg b/cockatrice/resources/phases_old/icon_phase_combat_end.svg
new file mode 100644
index 000000000..9e7b8950b
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_combat_end.svg
@@ -0,0 +1,253 @@
+
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_combat_start.svg b/cockatrice/resources/phases_old/icon_phase_combat_start.svg
new file mode 100644
index 000000000..996571d71
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_combat_start.svg
@@ -0,0 +1,253 @@
+
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_draw.svg b/cockatrice/resources/phases_old/icon_phase_draw.svg
new file mode 100644
index 000000000..51918274c
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_draw.svg
@@ -0,0 +1,192 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_main1.svg b/cockatrice/resources/phases_old/icon_phase_main1.svg
new file mode 100644
index 000000000..264cef395
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_main1.svg
@@ -0,0 +1,135 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_main2.svg b/cockatrice/resources/phases_old/icon_phase_main2.svg
new file mode 100644
index 000000000..50f77fa70
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_main2.svg
@@ -0,0 +1,135 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_nextturn.svg b/cockatrice/resources/phases_old/icon_phase_nextturn.svg
new file mode 100644
index 000000000..3cfd19ab0
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_nextturn.svg
@@ -0,0 +1,89 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_untap.svg b/cockatrice/resources/phases_old/icon_phase_untap.svg
new file mode 100644
index 000000000..2f4d81732
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_untap.svg
@@ -0,0 +1,198 @@
+
+
+
diff --git a/cockatrice/resources/phases_old/icon_phase_upkeep.svg b/cockatrice/resources/phases_old/icon_phase_upkeep.svg
new file mode 100644
index 000000000..5a06aae9c
--- /dev/null
+++ b/cockatrice/resources/phases_old/icon_phase_upkeep.svg
@@ -0,0 +1,159 @@
+
+
+
diff --git a/cockatrice/resources/userlevels/judge.svg b/cockatrice/resources/userlevels/moderator.svg
similarity index 100%
rename from cockatrice/resources/userlevels/judge.svg
rename to cockatrice/resources/userlevels/moderator.svg
diff --git a/cockatrice/src/abstractcarditem.cpp b/cockatrice/src/abstractcarditem.cpp
index 0deed4ea3..20e7c8e9e 100644
--- a/cockatrice/src/abstractcarditem.cpp
+++ b/cockatrice/src/abstractcarditem.cpp
@@ -26,6 +26,7 @@ AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, QGraphi
AbstractCardItem::~AbstractCardItem()
{
qDebug() << "AbstractCardItem destructor:" << name;
+ emit deleteCardInfoPopup(name);
}
QRectF AbstractCardItem::boundingRect() const
@@ -157,6 +158,10 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
void AbstractCardItem::setName(const QString &_name)
{
+ if (name == _name)
+ return;
+
+ emit deleteCardInfoPopup(name);
disconnect(info, 0, this, 0);
name = _name;
info = db->getCard(name);
@@ -212,6 +217,9 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
+ if (event->button() == Qt::MidButton)
+ emit deleteCardInfoPopup(name);
+
// This function ensures the parent function doesn't mess around with our selection.
event->accept();
}
diff --git a/cockatrice/src/abstractcarditem.h b/cockatrice/src/abstractcarditem.h
index c1345564f..e11bdf852 100644
--- a/cockatrice/src/abstractcarditem.h
+++ b/cockatrice/src/abstractcarditem.h
@@ -30,7 +30,7 @@ private slots:
signals:
void hovered(AbstractCardItem *card);
void showCardInfoPopup(QPoint pos, QString cardName);
- void deleteCardInfoPopup();
+ void deleteCardInfoPopup(QString cardName);
public:
enum { Type = typeCard };
int type() const { return Type; }
@@ -50,6 +50,7 @@ public:
bool getTapped() const { return tapped; }
void setTapped(bool _tapped, bool canAnimate = false);
void processHoverEvent();
+ void deleteCardInfoPopup() { emit deleteCardInfoPopup(name); }
protected:
QSizeF getTranslatedSize(QPainter *painter) const;
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
diff --git a/cockatrice/src/abstractclient.cpp b/cockatrice/src/abstractclient.cpp
index 5fb9b433a..7edb7a2ea 100644
--- a/cockatrice/src/abstractclient.cpp
+++ b/cockatrice/src/abstractclient.cpp
@@ -32,15 +32,16 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
GenericEvent *genericEvent = qobject_cast(item);
if (genericEvent) {
switch (genericEvent->getItemId()) {
- case ItemId_Event_ConnectionClosed: emit connectionClosedEventReceived(qobject_cast(item)); break;
- case ItemId_Event_AddToList: emit addToListEventReceived(qobject_cast(item)); break;
- case ItemId_Event_RemoveFromList: emit removeFromListEventReceived(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_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;
+ case ItemId_Event_ConnectionClosed: emit connectionClosedEventReceived(static_cast(item)); break;
+ case ItemId_Event_ServerShutdown: emit serverShutdownEventReceived(static_cast(item)); break;
+ case ItemId_Event_AddToList: emit addToListEventReceived(static_cast(item)); break;
+ case ItemId_Event_RemoveFromList: emit removeFromListEventReceived(static_cast(item)); break;
+ case ItemId_Event_UserJoined: emit userJoinedEventReceived(static_cast(item)); break;
+ case ItemId_Event_UserLeft: emit userLeftEventReceived(static_cast(item)); break;
+ case ItemId_Event_ServerMessage: emit serverMessageEventReceived(static_cast(item)); break;
+ case ItemId_Event_ListRooms: emit listRoomsEventReceived(static_cast(item)); break;
+ case ItemId_Event_GameJoined: emit gameJoinedEventReceived(static_cast(item)); break;
+ case ItemId_Event_Message: emit messageEventReceived(static_cast(item)); break;
}
if (genericEvent->getReceiverMayDelete())
delete genericEvent;
diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h
index f43131b56..d896a89dc 100644
--- a/cockatrice/src/abstractclient.h
+++ b/cockatrice/src/abstractclient.h
@@ -21,6 +21,7 @@ class Event_ListRooms;
class Event_GameJoined;
class Event_Message;
class Event_ConnectionClosed;
+class Event_ServerShutdown;
enum ClientStatus {
StatusDisconnected,
@@ -43,6 +44,7 @@ signals:
void gameEventContainerReceived(GameEventContainer *event);
// Generic events
void connectionClosedEventReceived(Event_ConnectionClosed *event);
+ void serverShutdownEventReceived(Event_ServerShutdown *event);
void addToListEventReceived(Event_AddToList *event);
void removeFromListEventReceived(Event_RemoveFromList *event);
void userJoinedEventReceived(Event_UserJoined *event);
diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp
index ff8e44742..1ba308b6d 100644
--- a/cockatrice/src/carddatabase.cpp
+++ b/cockatrice/src/carddatabase.cpp
@@ -298,8 +298,8 @@ QString CardInfo::getMainCardType() const
QString CardInfo::getCorrectedName() const
{
QString result = name;
- // Fire // Ice, Circle of Protection: Red
- return result.remove(" // ").remove(":");
+ // Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
+ return result.remove(" // ").remove(':').remove('"').remove('?').replace('/', ' ');
}
void CardInfo::addToSet(CardSet *set)
diff --git a/cockatrice/src/carddatabasemodel.h b/cockatrice/src/carddatabasemodel.h
index 453782579..d6404b422 100644
--- a/cockatrice/src/carddatabasemodel.h
+++ b/cockatrice/src/carddatabasemodel.h
@@ -31,11 +31,11 @@ private:
QSet cardTypes, cardColors;
public:
CardDatabaseDisplayModel(QObject *parent = 0);
- void setCardNameBeginning(const QString &_beginning) { cardNameBeginning = _beginning; invalidateFilter(); }
- void setCardName(const QString &_cardName) { cardName = _cardName; invalidateFilter(); }
- void setCardText(const QString &_cardText) { cardText = _cardText; invalidateFilter(); }
- void setCardTypes(const QSet &_cardTypes) { cardTypes = _cardTypes; invalidateFilter(); }
- void setCardColors(const QSet &_cardColors) { cardColors = _cardColors; invalidateFilter(); }
+ void setCardNameBeginning(const QString &_beginning) { cardNameBeginning = _beginning; invalidate(); }
+ void setCardName(const QString &_cardName) { cardName = _cardName; invalidate(); }
+ void setCardText(const QString &_cardText) { cardText = _cardText; invalidate(); }
+ void setCardTypes(const QSet &_cardTypes) { cardTypes = _cardTypes; invalidate(); }
+ void setCardColors(const QSet &_cardColors) { cardColors = _cardColors; invalidate(); }
void clearSearch();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
diff --git a/cockatrice/src/cardinfowidget.cpp b/cockatrice/src/cardinfowidget.cpp
index 3e7268bf3..1ce584b2f 100644
--- a/cockatrice/src/cardinfowidget.cpp
+++ b/cockatrice/src/cardinfowidget.cpp
@@ -11,13 +11,24 @@
#include "settingscache.h"
CardInfoWidget::CardInfoWidget(ResizeMode _mode, QWidget *parent, Qt::WindowFlags flags)
- : QFrame(parent, flags), pixmapWidth(160), aspectRatio((qreal) CARD_HEIGHT / (qreal) CARD_WIDTH), minimized(false), mode(_mode), minimizeButton(0), info(0)
+ : QFrame(parent, flags)
+ , pixmapWidth(160)
+ , aspectRatio((qreal) CARD_HEIGHT / (qreal) CARD_WIDTH)
+ , minimized(settingsCache->getCardInfoMinimized()) // Initialize the cardinfo view status from cache.
+ , mode(_mode)
+ , info(0)
{
if (mode == ModeGameTab) {
- minimizeButton = new QPushButton(QIcon(style()->standardIcon(QStyle::SP_ArrowUp)), QString());
- connect(minimizeButton, SIGNAL(clicked()), this, SLOT(minimizeClicked()));
+ // Create indexed list of status views for card.
+ const QStringList cardInfoStatus = QStringList() << tr("Hide card info") << tr("Show card only") << tr("Show text only") << tr("Show full info");
+
+ // Create droplist for cardinfo view selection, and set right current index.
+ dropList = new QComboBox();
+ dropList->addItems(cardInfoStatus);
+ dropList->setCurrentIndex(minimized);
+ connect(dropList, SIGNAL(currentIndexChanged(int)), this, SLOT(minimizeClicked(int)));
}
-
+
cardPicture = new QLabel;
cardPicture->setAlignment(Qt::AlignCenter);
@@ -39,7 +50,7 @@ CardInfoWidget::CardInfoWidget(ResizeMode _mode, QWidget *parent, Qt::WindowFlag
QGridLayout *grid = new QGridLayout(this);
int row = 0;
if (mode == ModeGameTab)
- grid->addWidget(minimizeButton, row++, 1, 1, 1, Qt::AlignRight);
+ grid->addWidget(dropList, row++, 1, 1, 1, Qt::AlignRight);
grid->addWidget(cardPicture, row++, 0, 1, 2);
grid->addWidget(nameLabel1, row, 0);
grid->addWidget(nameLabel2, row++, 1);
@@ -70,30 +81,38 @@ CardInfoWidget::CardInfoWidget(ResizeMode _mode, QWidget *parent, Qt::WindowFlag
setFixedHeight(sizeHint().height());
}
-void CardInfoWidget::minimizeClicked()
+void CardInfoWidget::minimizeClicked(int newMinimized)
{
- setMinimized(!minimized);
- settingsCache->setCardInfoMinimized(minimized);
+ // Set new status, and store it in the settings cache.
+ setMinimized(newMinimized);
+ settingsCache->setCardInfoMinimized(newMinimized);
}
-void CardInfoWidget::setMinimized(bool _minimized)
+void CardInfoWidget::setMinimized(int _minimized)
{
minimized = _minimized;
-
- cardPicture->setVisible(!minimized);
- nameLabel2->setVisible(!minimized);
- nameLabel1->setVisible(!minimized);
- manacostLabel1->setVisible(!minimized);
- manacostLabel2->setVisible(!minimized);
- cardtypeLabel1->setVisible(!minimized);
- cardtypeLabel2->setVisible(!minimized);
- powtoughLabel1->setVisible(!minimized);
- powtoughLabel2->setVisible(!minimized);
- textLabel->setVisible(!minimized);
-
- if (minimizeButton)
- minimizeButton->setIcon(style()->standardIcon(minimized ? QStyle::SP_ArrowDown : QStyle::SP_ArrowUp));
-
+
+ // Set the picture to be shown only at "card only" (1) and "full info" (3)
+ if (minimized == 1 || minimized == 3) {
+ cardPicture->setVisible(true);
+ } else {
+ cardPicture->setVisible(false);
+ }
+
+ // Set the rest of the fields to be shown only at "full info" (3) and "oracle only" (2)
+ bool showAll = (minimized == 2 || minimized == 3) ? true : false;
+
+ // Toggle oracle fields as according to selected view.
+ nameLabel2->setVisible(showAll);
+ nameLabel1->setVisible(showAll);
+ manacostLabel1->setVisible(showAll);
+ manacostLabel2->setVisible(showAll);
+ cardtypeLabel1->setVisible(showAll);
+ cardtypeLabel2->setVisible(showAll);
+ powtoughLabel1->setVisible(showAll);
+ powtoughLabel2->setVisible(showAll);
+ textLabel->setVisible(showAll);
+
setFixedHeight(sizeHint().height());
}
@@ -153,8 +172,7 @@ void CardInfoWidget::resizeEvent(QResizeEvent * /*event*/)
}
}
-void CardInfoWidget::mouseReleaseEvent(QMouseEvent *event)
+QString CardInfoWidget::getCardName() const
{
- if ((event->button() == Qt::MidButton) && (mode == ModePopUp))
- emit mouseReleased();
-}
+ return nameLabel2->text();
+}
\ No newline at end of file
diff --git a/cockatrice/src/cardinfowidget.h b/cockatrice/src/cardinfowidget.h
index d140009e4..21ee7ccd6 100644
--- a/cockatrice/src/cardinfowidget.h
+++ b/cockatrice/src/cardinfowidget.h
@@ -2,6 +2,8 @@
#define CARDINFOWIDGET_H
#include
+#include
+#include
class QLabel;
class QTextEdit;
@@ -13,40 +15,44 @@ class QMouseEvent;
class CardInfoWidget : public QFrame {
Q_OBJECT
+
public:
enum ResizeMode { ModeDeckEditor, ModeGameTab, ModePopUp };
+
private:
int pixmapWidth;
qreal aspectRatio;
- bool minimized;
+ int minimized; // 0 - minimized, 1 - card, 2 - oracle only, 3 - full
ResizeMode mode;
- QPushButton *minimizeButton;
+ QComboBox *dropList;
QLabel *cardPicture;
QLabel *nameLabel1, *nameLabel2;
QLabel *manacostLabel1, *manacostLabel2;
QLabel *cardtypeLabel1, *cardtypeLabel2;
QLabel *powtoughLabel1, *powtoughLabel2;
QTextEdit *textLabel;
-
+
CardInfo *info;
- void setMinimized(bool _minimized);
+ void setMinimized(int _minimized);
+
public:
CardInfoWidget(ResizeMode _mode, QWidget *parent = 0, Qt::WindowFlags f = 0);
void retranslateUi();
+ QString getCardName() const;
+
public slots:
void setCard(CardInfo *card);
void setCard(const QString &cardName);
void setCard(AbstractCardItem *card);
+
private slots:
void clear();
void updatePixmap();
- void minimizeClicked();
-signals:
- void mouseReleased();
+ void minimizeClicked(int newMinimized);
+
protected:
void resizeEvent(QResizeEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
};
#endif
diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp
index 21ae3bb68..afc15e8c0 100644
--- a/cockatrice/src/carditem.cpp
+++ b/cockatrice/src/carditem.cpp
@@ -34,6 +34,8 @@ CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, bool _reve
connect(aAttach, SIGNAL(triggered()), this, SLOT(actAttach()));
aUnattach = new QAction(this);
connect(aUnattach, SIGNAL(triggered()), this, SLOT(actUnattach()));
+ aDrawArrow = new QAction(this);
+ connect(aDrawArrow, SIGNAL(triggered()), this, SLOT(actDrawArrow()));
aIncP = new QAction(this);
connect(aIncP, SIGNAL(triggered()), this, SLOT(actIncP()));
aDecP = new QAction(this);
@@ -172,6 +174,7 @@ void CardItem::updateCardMenu()
cardMenu->addAction(aAttach);
if (attachedTo)
cardMenu->addAction(aUnattach);
+ cardMenu->addAction(aDrawArrow);
cardMenu->addSeparator();
cardMenu->addMenu(ptMenu);
cardMenu->addAction(aSetAnnotation);
@@ -186,6 +189,9 @@ void CardItem::updateCardMenu()
cardMenu->addAction(aSetCounter[i]);
}
cardMenu->addSeparator();
+ } else if (zone->getName() == "stack") {
+ cardMenu->addAction(aDrawArrow);
+ cardMenu->addMenu(moveMenu);
} else {
cardMenu->addAction(aPlay);
cardMenu->addMenu(moveMenu);
@@ -209,6 +215,7 @@ void CardItem::retranslateUi()
aAttach->setText(tr("&Attach to card..."));
aAttach->setShortcut(tr("Ctrl+A"));
aUnattach->setText(tr("Unattac&h"));
+ aDrawArrow->setText(tr("&Draw arrow..."));
ptMenu->setTitle(tr("&Power / toughness"));
aIncP->setText(tr("&Increase power"));
aIncP->setShortcut(tr("Ctrl++"));
@@ -360,7 +367,7 @@ void CardItem::resetState()
annotation.clear();
attachedTo = 0;
attachedCards.clear();
- setTapped(false);
+ setTapped(false, false);
setDoesntUntap(false);
update();
}
@@ -380,6 +387,7 @@ void CardItem::processCardInfo(ServerInfo_Card *info)
setColor(info->getColor());
setTapped(info->getTapped());
setDestroyOnZoneChange(info->getDestroyOnZoneChange());
+ setDoesntUntap(info->getDoesntUntap());
}
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
@@ -398,13 +406,35 @@ void CardItem::deleteDragItem()
dragItem = NULL;
}
+void CardItem::drawArrow(const QColor &arrowColor)
+{
+ if (static_cast(owner->parent())->getSpectator())
+ return;
+
+ Player *arrowOwner = static_cast(owner->parent())->getActiveLocalPlayer();
+ ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor);
+ scene()->addItem(arrow);
+ arrow->grabMouse();
+
+ QListIterator itemIterator(scene()->selectedItems());
+ while (itemIterator.hasNext()) {
+ CardItem *c = qgraphicsitem_cast(itemIterator.next());
+ if (!c || (c == this))
+ continue;
+ if (c->getZone() != zone)
+ continue;
+
+ ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
+ scene()->addItem(childArrow);
+ arrow->addChildArrow(childArrow);
+ }
+}
+
void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons().testFlag(Qt::RightButton)) {
if ((event->screenPos() - event->buttonDownScreenPos(Qt::RightButton)).manhattanLength() < 2 * QApplication::startDragDistance())
return;
- if (static_cast(owner->parent())->getSpectator())
- return;
QColor arrowColor = Qt::red;
if (event->modifiers().testFlag(Qt::ControlModifier))
@@ -414,23 +444,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
else if (event->modifiers().testFlag(Qt::ShiftModifier))
arrowColor = Qt::green;
- Player *arrowOwner = static_cast(owner->parent())->getActiveLocalPlayer();
- ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor);
- scene()->addItem(arrow);
- arrow->grabMouse();
-
- QListIterator itemIterator(scene()->selectedItems());
- while (itemIterator.hasNext()) {
- CardItem *c = qgraphicsitem_cast(itemIterator.next());
- if (!c || (c == this))
- continue;
- if (c->getZone() != zone)
- continue;
-
- ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
- scene()->addItem(childArrow);
- arrow->addChildArrow(childArrow);
- }
+ drawArrow(arrowColor);
} else if (event->buttons().testFlag(Qt::LeftButton)) {
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < 2 * QApplication::startDragDistance())
return;
@@ -546,6 +560,11 @@ void CardItem::actUnattach()
owner->actUnattach(static_cast(sender()));
}
+void CardItem::actDrawArrow()
+{
+ drawArrow(Qt::red);
+}
+
void CardItem::actIncP()
{
owner->actIncPT(1, 0);
diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h
index 88b19d6f3..6c02a4bbe 100644
--- a/cockatrice/src/carditem.h
+++ b/cockatrice/src/carditem.h
@@ -9,6 +9,7 @@ class CardZone;
class ServerInfo_Card;
class Player;
class QAction;
+class QColor;
const int MAX_COUNTERS_ON_CARD = 999;
@@ -33,17 +34,19 @@ private:
QList aAddCounter, aSetCounter, aRemoveCounter;
QAction *aPlay,
*aHide,
- *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aIncP, *aDecP, *aIncT, *aDecT, *aIncPT, *aDecPT, *aSetAnnotation, *aFlip, *aClone,
+ *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aDrawArrow, *aSetPT, *aIncP, *aDecP, *aIncT, *aDecT, *aIncPT, *aDecPT, *aSetAnnotation, *aFlip, *aClone,
*aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile;
QMenu *cardMenu, *ptMenu, *moveMenu;
void playCard(bool faceDown);
+ void drawArrow(const QColor &arrowColor);
void prepareDelete();
private slots:
void cardMenuAction();
void actCardCounterTrigger();
void actAttach();
void actUnattach();
+ void actDrawArrow();
void actSetPT();
void actIncP();
void actDecP();
diff --git a/cockatrice/src/cardzone.cpp b/cockatrice/src/cardzone.cpp
index 3c3606ee2..ceaf08523 100644
--- a/cockatrice/src/cardzone.cpp
+++ b/cockatrice/src/cardzone.cpp
@@ -46,35 +46,36 @@ void CardZone::clearContents()
QString CardZone::getTranslatedName(bool hisOwn, GrammaticalCase gc) const
{
QString ownerName = player->getName();
+ bool female = player->getUserInfo()->getGender() == ServerInfo_User::Female;
if (name == "hand")
switch (gc) {
- case CaseNominative: return hisOwn ? tr("his hand", "nominative") : tr("%1's hand", "nominative").arg(ownerName);
- case CaseGenitive: return hisOwn ? tr("of his hand", "genitive") : tr("of %1's hand", "genitive").arg(ownerName);
- case CaseAccusative: return hisOwn ? tr("his hand", "accusative") : tr("%1's hand", "accusative").arg(ownerName);
+ case CaseNominative: return female ? (hisOwn ? tr("her hand", "nominative, female owner") : tr("%1's hand", "nominative, female owner").arg(ownerName)) : (hisOwn ? tr("his hand", "nominative, male owner") : tr("%1's hand", "nominative, male owner").arg(ownerName));
+ case CaseGenitive: return female ? (hisOwn ? tr("of her hand", "genitive, female owner") : tr("of %1's hand", "genitive, female owner").arg(ownerName)) : (hisOwn ? tr("of his hand", "genitive, male owner") : tr("of %1's hand", "genitive, male owner").arg(ownerName));
+ case CaseAccusative: return female ? (hisOwn ? tr("her hand", "accusative, female owner") : tr("%1's hand", "accusative, female owner").arg(ownerName)) : (hisOwn ? tr("his hand", "accusative, male owner") : tr("%1's hand", "accusative, male owner").arg(ownerName));
}
else if (name == "deck")
switch (gc) {
- case CaseNominative: return hisOwn ? tr("his library", "nominative") : tr("%1's library", "nominative").arg(ownerName);
- case CaseGenitive: return hisOwn ? tr("of his library", "genitive") : tr("of %1's library", "genitive").arg(ownerName);
- case CaseAccusative: return hisOwn ? tr("his library", "accusative") : tr("%1's library", "accusative").arg(ownerName);
+ case CaseNominative: return female ? (hisOwn ? tr("her library", "nominative, female owner") : tr("%1's library", "nominative, female owner").arg(ownerName)) : (hisOwn ? tr("his library", "nominative, male owner") : tr("%1's library", "nominative, male owner").arg(ownerName));
+ case CaseGenitive: return female ? (hisOwn ? tr("of her library", "genitive, female owner") : tr("of %1's library", "genitive, female owner").arg(ownerName)) : (hisOwn ? tr("of his library", "genitive, male owner") : tr("of %1's library", "genitive, male owner").arg(ownerName));
+ case CaseAccusative: return female ? (hisOwn ? tr("her library", "accusative, female owner") : tr("%1's library", "accusative, female owner").arg(ownerName)) : (hisOwn ? tr("his library", "accusative, male owner") : tr("%1's library", "accusative, male owner").arg(ownerName));
}
else if (name == "grave")
switch (gc) {
- case CaseNominative: return hisOwn ? tr("his graveyard", "nominative") : tr("%1's graveyard", "nominative").arg(ownerName);
- case CaseGenitive: return hisOwn ? tr("of his graveyard", "genitive") : tr("of %1's graveyard", "genitive").arg(ownerName);
- case CaseAccusative: return hisOwn ? tr("his graveyard", "accusative") : tr("%1's graveyard", "accusative").arg(ownerName);
+ case CaseNominative: return female ? (hisOwn ? tr("her graveyard", "nominative, female owner") : tr("%1's graveyard", "nominative, female owner").arg(ownerName)) : (hisOwn ? tr("his graveyard", "nominative, male owner") : tr("%1's graveyard", "nominative, male owner").arg(ownerName));
+ case CaseGenitive: return female ? (hisOwn ? tr("of her graveyard", "genitive, female owner") : tr("of %1's graveyard", "genitive, female owner").arg(ownerName)) : (hisOwn ? tr("of his graveyard", "genitive, male owner") : tr("of %1's graveyard", "genitive, male owner").arg(ownerName));
+ case CaseAccusative: return female ? (hisOwn ? tr("her graveyard", "accusative, female owner") : tr("%1's graveyard", "accusative, female owner").arg(ownerName)) : (hisOwn ? tr("his graveyard", "accusative, male owner") : tr("%1's graveyard", "accusative, male owner").arg(ownerName));
}
else if (name == "rfg")
switch (gc) {
- case CaseNominative: return hisOwn ? tr("his exile", "nominative") : tr("%1's exile", "nominative").arg(ownerName);
- case CaseGenitive: return hisOwn ? tr("of his exile", "genitive") : tr("of %1's exile", "genitive").arg(ownerName);
- case CaseAccusative: return hisOwn ? tr("his exile", "accusative") : tr("%1's exile", "accusative").arg(ownerName);
+ case CaseNominative: return female ? (hisOwn ? tr("her exile", "nominative, female owner") : tr("%1's exile", "nominative, female owner").arg(ownerName)) : (hisOwn ? tr("his exile", "nominative, male owner") : tr("%1's exile", "nominative, male owner").arg(ownerName));
+ case CaseGenitive: return female ? (hisOwn ? tr("of her exile", "genitive, female owner") : tr("of %1's exile", "genitive, female owner").arg(ownerName)) : (hisOwn ? tr("of his exile", "genitive, male owner") : tr("of %1's exile", "genitive, male owner").arg(ownerName));
+ case CaseAccusative: return female ? (hisOwn ? tr("her exile", "accusative, female owner") : tr("%1's exile", "accusative, female owner").arg(ownerName)) : (hisOwn ? tr("his exile", "accusative, male owner") : tr("%1's exile", "accusative, male owner").arg(ownerName));
}
else if (name == "sb")
switch (gc) {
- case CaseNominative: return hisOwn ? tr("his sideboard", "nominative") : tr("%1's sideboard", "nominative").arg(ownerName);
- case CaseGenitive: return hisOwn ? tr("of his sideboard", "genitive") : tr("of %1's sideboard", "genitive").arg(ownerName);
- case CaseAccusative: return hisOwn ? tr("his sideboard", "accusative") : tr("%1's sideboard", "accusative").arg(ownerName);
+ case CaseNominative: return female ? (hisOwn ? tr("her sideboard", "nominative, female owner") : tr("%1's sideboard", "nominative, female owner").arg(ownerName)) : (hisOwn ? tr("his sideboard", "nominative, male owner") : tr("%1's sideboard", "nominative, male owner").arg(ownerName));
+ case CaseGenitive: return female ? (hisOwn ? tr("of her sideboard", "genitive, female owner") : tr("of %1's sideboard", "genitive, female owner").arg(ownerName)) : (hisOwn ? tr("of his sideboard", "genitive, male owner") : tr("of %1's sideboard", "genitive, male owner").arg(ownerName));
+ case CaseAccusative: return female ? (hisOwn ? tr("her sideboard", "accusative, female owner") : tr("%1's sideboard", "accusative, female owner").arg(ownerName)) : (hisOwn ? tr("his sideboard", "accusative, male owner") : tr("%1's sideboard", "accusative, male owner").arg(ownerName));
}
return QString();
}
diff --git a/cockatrice/src/chatview.cpp b/cockatrice/src/chatview.cpp
index 92696cf01..9aecfd1ee 100644
--- a/cockatrice/src/chatview.cpp
+++ b/cockatrice/src/chatview.cpp
@@ -1,45 +1,198 @@
#include
#include
-#include
#include
+#include
+#include
#include "chatview.h"
-ChatView::ChatView(const QString &_ownName, QWidget *parent)
- : QTextEdit(parent), ownName(_ownName)
+ChatView::ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent)
+ : QTextBrowser(parent), evenNumber(true), ownName(_ownName), showTimestamps(_showTimestamps)
{
- setTextInteractionFlags(Qt::TextSelectableByMouse);
+ setReadOnly(true);
+ setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
+ setOpenLinks(false);
+ connect(this, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(openLink(const QUrl &)));
}
-void ChatView::appendMessage(QString sender, const QString &message)
+QTextCursor ChatView::prepareBlock(bool same)
{
+ lastSender.clear();
+
QTextCursor cursor(document()->lastBlock());
cursor.movePosition(QTextCursor::End);
+ if (!same) {
+ QTextBlockFormat blockFormat;
+ if ((evenNumber = !evenNumber))
+ blockFormat.setBackground(palette().alternateBase());
+ blockFormat.setBottomMargin(2);
+ cursor.insertBlock(blockFormat);
+ } else
+ cursor.insertHtml("
");
- QTextBlockFormat blockFormat;
- blockFormat.setBottomMargin(3);
- cursor.insertBlock(blockFormat);
+ return cursor;
+}
+
+void ChatView::appendHtml(const QString &html)
+{
+ prepareBlock().insertHtml(html);
+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+}
+
+void ChatView::appendMessage(QString sender, QString message, QColor playerColor, bool playerBold)
+{
+ bool sameSender = (sender == lastSender) && !lastSender.isEmpty();
+ QTextCursor cursor = prepareBlock(sameSender);
+ lastSender = sender;
- QTextCharFormat timeFormat;
- timeFormat.setForeground(Qt::black);
- cursor.setCharFormat(timeFormat);
- cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] "));
+ if (showTimestamps) {
+ QTextCharFormat timeFormat;
+ if (sameSender)
+ timeFormat.setForeground(Qt::transparent);
+ else
+ timeFormat.setForeground(Qt::black);
+ cursor.setCharFormat(timeFormat);
+ cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] "));
+ }
QTextCharFormat senderFormat;
if (sender == ownName) {
senderFormat.setFontWeight(QFont::Bold);
senderFormat.setForeground(Qt::red);
- } else
- senderFormat.setForeground(Qt::blue);
+ } else {
+ if (playerColor == QColor())
+ senderFormat.setForeground(QColor(0, 0, 254));
+ else
+ senderFormat.setForeground(playerColor);
+ if (playerBold)
+ senderFormat.setFontWeight(QFont::Bold);
+ }
+ if (sameSender)
+ senderFormat.setForeground(Qt::transparent);
cursor.setCharFormat(senderFormat);
if (!sender.isEmpty())
- sender.append(" ");
+ sender.append(": ");
cursor.insertText(sender);
QTextCharFormat messageFormat;
if (sender.isEmpty())
messageFormat.setForeground(Qt::darkGreen);
cursor.setCharFormat(messageFormat);
- cursor.insertText(message);
+
+ int from = 0, index = 0;
+ while ((index = message.indexOf('[', from)) != -1) {
+ cursor.insertText(message.left(index));
+ message = message.mid(index);
+ if (message.isEmpty())
+ break;
+
+ if (message.startsWith("[card]")) {
+ message = message.mid(6);
+ QTextCharFormat tempFormat = messageFormat;
+ tempFormat.setForeground(Qt::blue);
+ cursor.setCharFormat(tempFormat);
+ int closeTagIndex = message.indexOf("[/card]");
+ cursor.insertText(message.left(closeTagIndex));
+ cursor.setCharFormat(messageFormat);
+ if (closeTagIndex == -1)
+ message.clear();
+ else
+ message = message.mid(closeTagIndex + 7);
+ } else if (message.startsWith("[url]")) {
+ message = message.mid(5);
+ int closeTagIndex = message.indexOf("[/url]");
+ QString url = message.left(closeTagIndex);
+ if (!url.startsWith("http://"))
+ url.prepend("http://");
+ QTextCharFormat tempFormat = messageFormat;
+ tempFormat.setForeground(QColor(0, 0, 254));
+ tempFormat.setAnchor(true);
+ tempFormat.setAnchorHref(url);
+ cursor.setCharFormat(tempFormat);
+ cursor.insertText(url);
+ cursor.setCharFormat(messageFormat);
+ if (closeTagIndex == -1)
+ message.clear();
+ else
+ message = message.mid(closeTagIndex + 6);
+ } else
+ from = 1;
+ }
+ if (!message.isEmpty())
+ cursor.insertText(message);
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
+
+void ChatView::enterEvent(QEvent * /*event*/)
+{
+ setMouseTracking(true);
+}
+
+void ChatView::leaveEvent(QEvent * /*event*/)
+{
+ setMouseTracking(false);
+}
+
+QTextFragment ChatView::getFragmentUnderMouse(const QPoint &pos) const
+{
+ QTextCursor cursor(cursorForPosition(pos));
+ QTextBlock block(cursor.block());
+ QTextBlock::iterator it;
+ for (it = block.begin(); !(it.atEnd()); ++it) {
+ QTextFragment frag = it.fragment();
+ if (frag.contains(cursor.position()))
+ return frag;
+ }
+ return QTextFragment();
+}
+
+QString ChatView::getCardNameUnderMouse(QTextFragment frag) const
+{
+ if (frag.charFormat().foreground().color() == Qt::blue)
+ return frag.text();
+ return QString();
+}
+
+QString ChatView::getCardNameUnderMouse(const QPoint &pos) const
+{
+ return getCardNameUnderMouse(getFragmentUnderMouse(pos));
+}
+
+void ChatView::mouseMoveEvent(QMouseEvent *event)
+{
+ QTextFragment frag = getFragmentUnderMouse(event->pos());
+ QString cardName = getCardNameUnderMouse(frag);
+ if (!cardName.isEmpty()) {
+ viewport()->setCursor(Qt::PointingHandCursor);
+ emit cardNameHovered(cardName);
+ } else if (frag.charFormat().isAnchor())
+ viewport()->setCursor(Qt::PointingHandCursor);
+ else
+ viewport()->setCursor(Qt::IBeamCursor);
+
+ QTextBrowser::mouseMoveEvent(event);
+}
+
+void ChatView::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::MidButton) {
+ QString cardName = getCardNameUnderMouse(event->pos());
+ if (!cardName.isEmpty())
+ emit showCardInfoPopup(event->globalPos(), cardName);
+ }
+
+ QTextBrowser::mousePressEvent(event);
+}
+
+void ChatView::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::MidButton)
+ emit deleteCardInfoPopup(QString("_"));
+
+ QTextBrowser::mouseReleaseEvent(event);
+}
+
+void ChatView::openLink(const QUrl &link)
+{
+ QDesktopServices::openUrl(link);
+}
diff --git a/cockatrice/src/chatview.h b/cockatrice/src/chatview.h
index bd7e763aa..33c583c68 100644
--- a/cockatrice/src/chatview.h
+++ b/cockatrice/src/chatview.h
@@ -1,18 +1,41 @@
#ifndef CHATVIEW_H
#define CHATVIEW_H
-#include
+#include
+#include
+#include
+#include
class QTextTable;
+class QMouseEvent;
-class ChatView : public QTextEdit {
+class ChatView : public QTextBrowser {
Q_OBJECT;
private:
- QTextTable *table;
+ QString lastSender;
+ bool evenNumber;
QString ownName;
+ bool showTimestamps;
+ QTextFragment getFragmentUnderMouse(const QPoint &pos) const;
+ QString getCardNameUnderMouse(QTextFragment frag) const;
+ QString getCardNameUnderMouse(const QPoint &pos) const;
+ QTextCursor prepareBlock(bool same = false);
+private slots:
+ void openLink(const QUrl &link);
public:
- ChatView(const QString &_ownName, QWidget *parent = 0);
- void appendMessage(QString sender, const QString &message);
+ ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent = 0);
+ void appendHtml(const QString &html);
+ void appendMessage(QString sender, QString message, QColor playerColor = QColor(), bool playerBold = false);
+protected:
+ void enterEvent(QEvent *event);
+ void leaveEvent(QEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+signals:
+ void cardNameHovered(QString cardName);
+ void showCardInfoPopup(QPoint pos, QString cardName);
+ void deleteCardInfoPopup(QString cardName);
};
#endif
\ No newline at end of file
diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp
index 1084f3457..82a443264 100644
--- a/cockatrice/src/decklistmodel.cpp
+++ b/cockatrice/src/decklistmodel.cpp
@@ -10,6 +10,7 @@
#include "main.h"
#include "decklistmodel.h"
#include "carddatabase.h"
+#include "settingscache.h"
DeckListModel::DeckListModel(QObject *parent)
: QAbstractItemModel(parent)
@@ -65,12 +66,20 @@ int DeckListModel::rowCount(const QModelIndex &parent) const
return 0;
}
+int DeckListModel::columnCount(const QModelIndex &/*parent*/) const
+{
+ if (settingsCache->getPriceTagFeature())
+ return 3;
+ else
+ return 2;
+}
+
QVariant DeckListModel::data(const QModelIndex &index, int role) const
{
// debugIndexInfo("data", index);
if (!index.isValid())
return QVariant();
- if (index.column() >= 2)
+ if (index.column() >= columnCount())
return QVariant();
AbstractDecklistNode *temp = static_cast(index.internalPointer());
@@ -86,8 +95,9 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
case Qt::EditRole:
switch (index.column()) {
- case 0: return node->recursiveCount(true);
- case 1: return node->getVisibleName();
+ case 0: return node->recursiveCount(true);
+ case 1: return node->getVisibleName();
+ case 2: return QString().sprintf("$%.2f", node->recursivePrice(true));
default: return QVariant();
}
case Qt::BackgroundRole: {
@@ -101,8 +111,9 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
case Qt::EditRole: {
switch (index.column()) {
- case 0: return card->getNumber();
- case 1: return card->getName();
+ case 0: return card->getNumber();
+ case 1: return card->getName();
+ case 2: return QString().sprintf("$%.2f", card->getTotalPrice());
default: return QVariant();
}
}
@@ -119,9 +130,12 @@ QVariant DeckListModel::headerData(int section, Qt::Orientation orientation, int
{
if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal))
return QVariant();
+ if (section >= columnCount())
+ return QVariant();
switch (section) {
- case 0: return tr("Number");
- case 1: return tr("Card");
+ case 0: return tr("Number");
+ case 1: return tr("Card");
+ case 2: return tr("Price");
default: return QVariant();
}
}
@@ -174,8 +188,9 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, int
return false;
switch (index.column()) {
- case 0: node->setNumber(value.toInt()); break;
- case 1: node->setName(value.toString()); break;
+ case 0: node->setNumber(value.toInt()); break;
+ case 1: node->setName(value.toString()); break;
+ case 2: node->setPrice(value.toFloat()); break;
default: return false;
}
emitRecursiveUpdates(index);
@@ -300,7 +315,7 @@ void DeckListModel::setDeckList(DeckList *_deck)
void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node)
{
- static const int totalColumns = 3;
+ const int totalColumns = settingsCache->getPriceTagFeature() ? 3 : 2;
if (node->height() == 1) {
QTextBlockFormat blockFormat;
@@ -308,13 +323,16 @@ void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *no
charFormat.setFontPointSize(11);
charFormat.setFontWeight(QFont::Bold);
cursor->insertBlock(blockFormat, charFormat);
- cursor->insertText(QString("%1: %2").arg(node->getVisibleName()).arg(node->recursiveCount(true)));
+ QString priceStr;
+ if (settingsCache->getPriceTagFeature())
+ priceStr = QString().sprintf(": $%.2f", node->recursivePrice(true));
+ cursor->insertText(QString("%1: %2").arg(node->getVisibleName()).arg(node->recursiveCount(true)).append(priceStr));
QTextTableFormat tableFormat;
tableFormat.setCellPadding(0);
tableFormat.setCellSpacing(0);
tableFormat.setBorder(0);
- QTextTable *table = cursor->insertTable(node->size() + 1, 2, tableFormat);
+ QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat);
for (int i = 0; i < node->size(); i++) {
AbstractDecklistCardNode *card = dynamic_cast(node->at(i));
@@ -330,6 +348,13 @@ void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *no
cell.setFormat(cellCharFormat);
cellCursor = cell.firstCursorPosition();
cellCursor.insertText(card->getName());
+
+ if (settingsCache->getPriceTagFeature()) {
+ cell = table->cellAt(i, 2);
+ cell.setFormat(cellCharFormat);
+ cellCursor = cell.firstCursorPosition();
+ cellCursor.insertText(QString().sprintf("$%.2f ", card->getTotalPrice()));
+ }
}
} else if (node->height() == 2) {
QTextBlockFormat blockFormat;
@@ -338,7 +363,10 @@ void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *no
charFormat.setFontWeight(QFont::Bold);
cursor->insertBlock(blockFormat, charFormat);
- cursor->insertText(QString("%1: %2").arg(node->getVisibleName()).arg(node->recursiveCount(true)));
+ QString priceStr;
+ if (settingsCache->getPriceTagFeature())
+ priceStr = QString().sprintf(": $%.2f", node->recursivePrice(true));
+ cursor->insertText(QString("%1: %2").arg(node->getVisibleName()).arg(node->recursiveCount(true)).append(priceStr));
QTextTableFormat tableFormat;
tableFormat.setCellPadding(10);
@@ -391,3 +419,14 @@ void DeckListModel::printDeckList(QPrinter *printer)
doc.print(printer);
}
+
+void DeckListModel::pricesUpdated(InnerDecklistNode *node)
+{
+ if (!node)
+ node = root;
+
+ if (node->isEmpty())
+ return;
+
+ emit dataChanged(createIndex(0, 2, node->at(0)), createIndex(node->size() - 1, 2, node->last()));
+}
diff --git a/cockatrice/src/decklistmodel.h b/cockatrice/src/decklistmodel.h
index f66f509de..a8a22c78b 100644
--- a/cockatrice/src/decklistmodel.h
+++ b/cockatrice/src/decklistmodel.h
@@ -17,6 +17,8 @@ public:
DecklistModelCardNode(DecklistCardNode *_dataNode, InnerDecklistNode *_parent) : AbstractDecklistCardNode(_parent), dataNode(_dataNode) { }
int getNumber() const { return dataNode->getNumber(); }
void setNumber(int _number) { dataNode->setNumber(_number); }
+ float getPrice() const { return dataNode->getPrice(); }
+ void setPrice(float _price) { dataNode->setPrice(_price); }
QString getName() const { return dataNode->getName(); }
void setName(const QString &_name) { dataNode->setName(_name); }
DecklistCardNode *getDataNode() const { return dataNode; }
@@ -32,7 +34,7 @@ public:
DeckListModel(QObject *parent = 0);
~DeckListModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 2; }
+ int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
@@ -45,6 +47,7 @@ public:
void cleanList();
DeckList *getDeckList() const { return deckList; }
void setDeckList(DeckList *_deck);
+ void pricesUpdated(InnerDecklistNode *node = 0);
private:
DeckList *deckList;
InnerDecklistNode *root;
diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp
index b96c93a16..0d5b69f43 100644
--- a/cockatrice/src/dlg_creategame.cpp
+++ b/cockatrice/src/dlg_creategame.cpp
@@ -17,6 +17,7 @@ DlgCreateGame::DlgCreateGame(AbstractClient *_client, int _roomId, const QMapsetBuddy(descriptionEdit);
+ descriptionEdit->setMaxLength(60);
maxPlayersLabel = new QLabel(tr("P&layers:"));
maxPlayersEdit = new QSpinBox();
diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp
index 88bdfd989..01d4445a5 100644
--- a/cockatrice/src/dlg_settings.cpp
+++ b/cockatrice/src/dlg_settings.cpp
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include "carddatabase.h"
#include "dlg_settings.h"
#include "main.h"
@@ -242,8 +243,17 @@ AppearanceSettingsPage::AppearanceSettingsPage()
invertVerticalCoordinateCheckBox->setChecked(settingsCache->getInvertVerticalCoordinate());
connect(invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setInvertVerticalCoordinate(int)));
+ minPlayersForMultiColumnLayoutLabel = new QLabel;
+ minPlayersForMultiColumnLayoutEdit = new QSpinBox;
+ minPlayersForMultiColumnLayoutEdit->setMinimum(2);
+ minPlayersForMultiColumnLayoutEdit->setValue(settingsCache->getMinPlayersForMultiColumnLayout());
+ connect(minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMinPlayersForMultiColumnLayout(int)));
+ minPlayersForMultiColumnLayoutLabel->setBuddy(minPlayersForMultiColumnLayoutEdit);
+
QGridLayout *tableGrid = new QGridLayout;
tableGrid->addWidget(invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
+ tableGrid->addWidget(minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1);
+ tableGrid->addWidget(minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1);
tableGroupBox = new QGroupBox;
tableGroupBox->setLayout(tableGrid);
@@ -289,6 +299,7 @@ void AppearanceSettingsPage::retranslateUi()
tableGroupBox->setTitle(tr("Table grid layout"));
invertVerticalCoordinateCheckBox->setText(tr("Invert vertical coordinate"));
+ minPlayersForMultiColumnLayoutLabel->setText(tr("Minimum player count for multi-column layout:"));
zoneViewGroupBox->setTitle(tr("Zone view layout"));
zoneViewSortByNameCheckBox->setText(tr("Sort by name"));
@@ -377,6 +388,8 @@ void AppearanceSettingsPage::cardBackPicturePathButtonClicked()
UserInterfaceSettingsPage::UserInterfaceSettingsPage()
{
+ QIcon deleteIcon(":/resources/icon_delete.svg");
+
doubleClickToPlayCheckBox = new QCheckBox;
doubleClickToPlayCheckBox->setChecked(settingsCache->getDoubleClickToPlay());
connect(doubleClickToPlayCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setDoubleClickToPlay(int)));
@@ -391,6 +404,28 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
tapAnimationCheckBox->setChecked(settingsCache->getTapAnimation());
connect(tapAnimationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setTapAnimation(int)));
+ soundEnabledCheckBox = new QCheckBox;
+ soundEnabledCheckBox->setChecked(settingsCache->getSoundEnabled());
+ connect(soundEnabledCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setSoundEnabled(int)));
+
+ soundPathLabel = new QLabel;
+ soundPathEdit = new QLineEdit(settingsCache->getSoundPath());
+ soundPathEdit->setReadOnly(true);
+ QPushButton *soundPathClearButton = new QPushButton(deleteIcon, QString());
+ connect(soundPathClearButton, SIGNAL(clicked()), this, SLOT(soundPathClearButtonClicked()));
+ QPushButton *soundPathButton = new QPushButton("...");
+ connect(soundPathButton, SIGNAL(clicked()), this, SLOT(soundPathButtonClicked()));
+
+ QGridLayout *soundGrid = new QGridLayout;
+ soundGrid->addWidget(soundEnabledCheckBox, 0, 0, 1, 4);
+ soundGrid->addWidget(soundPathLabel, 1, 0);
+ soundGrid->addWidget(soundPathEdit, 1, 1);
+ soundGrid->addWidget(soundPathClearButton, 1, 2);
+ soundGrid->addWidget(soundPathButton, 1, 3);
+
+ soundGroupBox = new QGroupBox;
+ soundGroupBox->setLayout(soundGrid);
+
QGridLayout *animationGrid = new QGridLayout;
animationGrid->addWidget(tapAnimationCheckBox, 0, 0);
@@ -400,6 +435,7 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(generalGroupBox);
mainLayout->addWidget(animationGroupBox);
+ mainLayout->addWidget(soundGroupBox);
setLayout(mainLayout);
}
@@ -410,6 +446,48 @@ void UserInterfaceSettingsPage::retranslateUi()
doubleClickToPlayCheckBox->setText(tr("&Double-click cards to play them (instead of single-click)"));
animationGroupBox->setTitle(tr("Animation settings"));
tapAnimationCheckBox->setText(tr("&Tap/untap animation"));
+ soundEnabledCheckBox->setText(tr("Enable &sounds"));
+ soundPathLabel->setText(tr("Path to sounds directory:"));
+}
+
+void UserInterfaceSettingsPage::soundPathClearButtonClicked()
+{
+ soundPathEdit->setText(QString());
+ settingsCache->setSoundPath(QString());
+}
+
+void UserInterfaceSettingsPage::soundPathButtonClicked()
+{
+ QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
+ if (path.isEmpty())
+ return;
+
+ soundPathEdit->setText(path);
+ settingsCache->setSoundPath(path);
+}
+
+DeckEditorSettingsPage::DeckEditorSettingsPage()
+{
+ priceTagsCheckBox = new QCheckBox;
+ priceTagsCheckBox->setChecked(settingsCache->getPriceTagFeature());
+ connect(priceTagsCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPriceTagFeature(int)));
+
+ QGridLayout *generalGrid = new QGridLayout;
+ generalGrid->addWidget(priceTagsCheckBox, 0, 0);
+
+ generalGroupBox = new QGroupBox;
+ generalGroupBox->setLayout(generalGrid);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(generalGroupBox);
+
+ setLayout(mainLayout);
+}
+
+void DeckEditorSettingsPage::retranslateUi()
+{
+ priceTagsCheckBox->setText(tr("Enable &price tag feature (using data from blacklotusproject.com)"));
+ generalGroupBox->setTitle(tr("General"));
}
MessagesSettingsPage::MessagesSettingsPage()
@@ -490,6 +568,7 @@ DlgSettings::DlgSettings(QWidget *parent)
pagesWidget->addWidget(new GeneralSettingsPage);
pagesWidget->addWidget(new AppearanceSettingsPage);
pagesWidget->addWidget(new UserInterfaceSettingsPage);
+ pagesWidget->addWidget(new DeckEditorSettingsPage);
pagesWidget->addWidget(new MessagesSettingsPage);
closeButton = new QPushButton;
@@ -534,6 +613,11 @@ void DlgSettings::createIcons()
userInterfaceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
userInterfaceButton->setIcon(QIcon(":/resources/icon_config_interface.svg"));
+ deckEditorButton = new QListWidgetItem(contentsWidget);
+ deckEditorButton->setTextAlignment(Qt::AlignHCenter);
+ deckEditorButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ deckEditorButton->setIcon(QIcon(":/resources/icon_config_deckeditor.svg"));
+
messagesButton = new QListWidgetItem(contentsWidget);
messagesButton->setTextAlignment(Qt::AlignHCenter);
messagesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
@@ -590,6 +674,7 @@ void DlgSettings::retranslateUi()
generalButton->setText(tr("General"));
appearanceButton->setText(tr("Appearance"));
userInterfaceButton->setText(tr("User interface"));
+ deckEditorButton->setText(tr("Deck editor"));
messagesButton->setText(tr("Messages"));
closeButton->setText(tr("&Close"));
diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h
index 70e231f20..f7bd1a522 100644
--- a/cockatrice/src/dlg_settings.h
+++ b/cockatrice/src/dlg_settings.h
@@ -14,6 +14,7 @@ class QGroupBox;
class QCheckBox;
class QLabel;
class QCloseEvent;
+class QSpinBox;
class AbstractSettingsPage : public QWidget {
public:
@@ -65,10 +66,11 @@ signals:
void playerAreaBgChanged(const QString &path);
void cardBackPicturePathChanged(const QString &path);
private:
- QLabel *handBgLabel, *stackBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel;
+ QLabel *handBgLabel, *stackBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel, *minPlayersForMultiColumnLayoutLabel;
QLineEdit *handBgEdit, *stackBgEdit, *tableBgEdit, *playerAreaBgEdit, *cardBackPicturePathEdit;
QCheckBox *displayCardNamesCheckBox, *horizontalHandCheckBox, *invertVerticalCoordinateCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox;
QGroupBox *zoneBgGroupBox, *cardsGroupBox, *handGroupBox, *tableGroupBox, *zoneViewGroupBox;
+ QSpinBox *minPlayersForMultiColumnLayoutEdit;
public:
AppearanceSettingsPage();
void retranslateUi();
@@ -76,15 +78,33 @@ public:
class UserInterfaceSettingsPage : public AbstractSettingsPage {
Q_OBJECT
+private slots:
+ void soundPathClearButtonClicked();
+ void soundPathButtonClicked();
+signals:
+ void soundPathChanged();
private:
QCheckBox *doubleClickToPlayCheckBox;
QCheckBox *tapAnimationCheckBox;
- QGroupBox *generalGroupBox, *animationGroupBox;
+ QCheckBox *soundEnabledCheckBox;
+ QLabel *soundPathLabel;
+ QLineEdit *soundPathEdit;
+ QGroupBox *generalGroupBox, *animationGroupBox, *soundGroupBox;
public:
UserInterfaceSettingsPage();
void retranslateUi();
};
+class DeckEditorSettingsPage : public AbstractSettingsPage {
+ Q_OBJECT
+public:
+ DeckEditorSettingsPage();
+ void retranslateUi();
+private:
+ QCheckBox *priceTagsCheckBox;
+ QGroupBox *generalGroupBox;
+};
+
class MessagesSettingsPage : public AbstractSettingsPage {
Q_OBJECT
public:
@@ -110,7 +130,7 @@ private slots:
private:
QListWidget *contentsWidget;
QStackedWidget *pagesWidget;
- QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *messagesButton;
+ QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *messagesButton;
QPushButton *closeButton;
void createIcons();
void retranslateUi();
diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp
index 7b62db5d6..8a8dd17c5 100644
--- a/cockatrice/src/gamescene.cpp
+++ b/cockatrice/src/gamescene.cpp
@@ -3,6 +3,8 @@
#include "zoneviewwidget.h"
#include "zoneviewzone.h"
#include "phasestoolbar.h"
+#include "settingscache.h"
+#include
#include
#include
#include
@@ -13,6 +15,7 @@ GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
{
animationTimer = new QBasicTimer;
addItem(phasesToolbar);
+ connect(settingsCache, SIGNAL(minPlayersForMultiColumnLayoutChanged()), this, SLOT(rearrange()));
}
GameScene::~GameScene()
@@ -31,7 +34,6 @@ void GameScene::addPlayer(Player *player)
qDebug("GameScene::addPlayer");
players << player;
addItem(player);
- rearrange();
connect(player, SIGNAL(sizeChanged()), this, SLOT(rearrange()));
connect(player, SIGNAL(gameConceded()), this, SLOT(rearrange()));
}
@@ -46,44 +48,63 @@ void GameScene::removePlayer(Player *player)
void GameScene::rearrange()
{
- struct PlayerProcessor {
- static void processPlayer(Player *p, qreal &w, QPointF &b, bool singlePlayer)
- {
- if (p->getConceded())
- return;
-
- const QRectF br = p->boundingRect();
- if (br.width() > w)
- w = br.width();
- p->setPos(b);
- p->setMirrored((b.y() < playerAreaSpacing) && !singlePlayer);
- b += QPointF(0, br.height() + playerAreaSpacing);
- }
- };
-
- qreal sceneHeight = -playerAreaSpacing;
+ playersByColumn.clear();
+
+ QList playersPlaying;
+ int firstPlayer = -1;
for (int i = 0; i < players.size(); ++i)
- if (!players[i]->getConceded())
- sceneHeight += players[i]->boundingRect().height() + playerAreaSpacing;
+ if (!players[i]->getConceded()) {
+ playersPlaying.append(players[i]);
+ if ((firstPlayer == -1) && (players[i]->getLocal()))
+ firstPlayer = playersPlaying.size() - 1;
+ }
+ if (firstPlayer == -1)
+ firstPlayer = 0;
+ const int playersCount = playersPlaying.size();
+ const int columns = playersCount < settingsCache->getMinPlayersForMultiColumnLayout() ? 1 : 2;
+ const int rows = ceil((qreal) playersCount / columns);
+
+ qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing;
+ QList columnWidth;
+ int firstPlayerOfColumn = firstPlayer;
+ for (int col = 0; col < columns; ++col) {
+ playersByColumn.append(QList());
+ columnWidth.append(0);
+ qreal thisColumnHeight = -playerAreaSpacing;
+ const int rowsInColumn = rows - (playersCount % columns);
+ for (int j = 0; j < rowsInColumn; ++j) {
+ Player *player = playersPlaying[(firstPlayerOfColumn + j) % playersCount];
+ if (col == 0)
+ playersByColumn[col].prepend(player);
+ else
+ playersByColumn[col].append(player);
+ thisColumnHeight += player->boundingRect().height() + playerAreaSpacing;
+ if (player->boundingRect().width() > columnWidth[col])
+ columnWidth[col] = player->boundingRect().width();
+ }
+ if (thisColumnHeight > sceneHeight)
+ sceneHeight = thisColumnHeight;
+ sceneWidth += columnWidth[col] + playerAreaSpacing;
+
+ firstPlayerOfColumn += rowsInColumn;
+ }
+
phasesToolbar->setHeight(sceneHeight);
qreal phasesWidth = phasesToolbar->getWidth();
-
- QPointF base(phasesWidth, 0);
- qreal sceneWidth;
- QList localPlayers;
-
- for (int i = 0; i < players.size(); ++i)
- if (!players[i]->getLocal())
- PlayerProcessor::processPlayer(players[i], sceneWidth, base, players.size() == 1);
- else
- localPlayers.append(players[i]);
-
- for (int i = 0; i < localPlayers.size(); ++i)
- PlayerProcessor::processPlayer(localPlayers[i], sceneWidth, base, players.size() == 1);
-
sceneWidth += phasesWidth;
- playersRect = QRectF(0, 0, sceneWidth, sceneHeight);
-
+
+ qreal x = phasesWidth;
+ for (int col = 0; col < columns; ++col) {
+ qreal y = 0;
+ for (int row = 0; row < playersByColumn[col].size(); ++row) {
+ Player *player = playersByColumn[col][row];
+ player->setPos(x, y);
+ player->setMirrored(row != rows - 1);
+ y += player->boundingRect().height() + playerAreaSpacing;
+ }
+ x += columnWidth[col] + playerAreaSpacing;
+ }
+
setSceneRect(sceneRect().x(), sceneRect().y(), sceneWidth, sceneHeight);
processViewSizeChange(viewSize);
}
@@ -139,24 +160,33 @@ void GameScene::processViewSizeChange(const QSize &newSize)
qreal newRatio = ((qreal) newSize.width()) / newSize.height();
qreal minWidth = 0;
- for (int i = 0; i < players.size(); ++i) {
- qreal w = players[i]->getMinimumWidth();
- if (w > minWidth)
- minWidth = w;
+ QList minWidthByColumn;
+ for (int col = 0; col < playersByColumn.size(); ++col) {
+ minWidthByColumn.append(0);
+ for (int row = 0; row < playersByColumn[col].size(); ++row) {
+ qreal w = playersByColumn[col][row]->getMinimumWidth();
+ if (w > minWidthByColumn[col])
+ minWidthByColumn[col] = w;
+ }
+ minWidth += minWidthByColumn[col];
}
minWidth += phasesToolbar->getWidth();
qreal minRatio = minWidth / sceneRect().height();
+ qreal newWidth;
if (minRatio > newRatio) {
// Aspect ratio is dominated by table width.
- setSceneRect(0, 0, minWidth, sceneRect().height());
+ newWidth = minWidth;
} else {
// Aspect ratio is dominated by window dimensions.
- setSceneRect(0, 0, newRatio * sceneRect().height(), sceneRect().height());
+ newWidth = newRatio * sceneRect().height();
}
-
- for (int i = 0; i < players.size(); ++i)
- players[i]->processSceneSizeChange(sceneRect().size() - QSizeF(phasesToolbar->getWidth(), 0));
+ setSceneRect(0, 0, newWidth, sceneRect().height());
+
+ qreal extraWidthPerColumn = (newWidth - minWidth) / playersByColumn.size();
+ for (int col = 0; col < playersByColumn.size(); ++col)
+ for (int row = 0; row < playersByColumn[col].size(); ++row)
+ playersByColumn[col][row]->processSceneSizeChange(minWidthByColumn[col] + extraWidthPerColumn);
}
void GameScene::updateHover(const QPointF &scenePos)
diff --git a/cockatrice/src/gamescene.h b/cockatrice/src/gamescene.h
index eee167be5..7b93a35f7 100644
--- a/cockatrice/src/gamescene.h
+++ b/cockatrice/src/gamescene.h
@@ -22,7 +22,7 @@ private:
PhasesToolbar *phasesToolbar;
QList players;
- QRectF playersRect;
+ QList > playersByColumn;
QList views;
QSize viewSize;
QPointer hoveredCard;
@@ -33,7 +33,6 @@ public:
GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = 0);
~GameScene();
void retranslateUi();
- const QRectF &getPlayersRect() const { return playersRect; }
void processViewSizeChange(const QSize &newSize);
void startRubberBand(const QPointF &selectionOrigin);
diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp
new file mode 100644
index 000000000..1feb63d07
--- /dev/null
+++ b/cockatrice/src/gameselector.cpp
@@ -0,0 +1,150 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dlg_creategame.h"
+#include "abstractclient.h"
+#include "protocol_items.h"
+#include "gameselector.h"
+#include "gamesmodel.h"
+
+GameSelector::GameSelector(AbstractClient *_client, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent)
+ : QGroupBox(parent), client(_client), room(_room)
+{
+ gameListView = new QTreeView;
+ gameListModel = new GamesModel(_rooms, _gameTypes, this);
+ gameListProxyModel = new GamesProxyModel(this);
+ gameListProxyModel->setSourceModel(gameListModel);
+ gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ gameListView->setModel(gameListProxyModel);
+ gameListView->setSortingEnabled(true);
+ gameListView->setAlternatingRowColors(true);
+ if (_room)
+ gameListView->header()->hideSection(0);
+ gameListView->header()->setResizeMode(1, QHeaderView::ResizeToContents);
+
+ showFullGamesCheckBox = new QCheckBox;
+ showRunningGamesCheckBox = new QCheckBox;
+
+ QVBoxLayout *filterLayout = new QVBoxLayout;
+ filterLayout->addWidget(showFullGamesCheckBox);
+ filterLayout->addWidget(showRunningGamesCheckBox);
+
+ if (room)
+ createButton = new QPushButton;
+ else
+ createButton = 0;
+ joinButton = new QPushButton;
+ spectateButton = new QPushButton;
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ if (room)
+ buttonLayout->addWidget(createButton);
+ buttonLayout->addWidget(joinButton);
+ buttonLayout->addWidget(spectateButton);
+ buttonLayout->setAlignment(Qt::AlignTop);
+
+ QHBoxLayout *hbox = new QHBoxLayout;
+ hbox->addLayout(filterLayout);
+ hbox->addStretch();
+ hbox->addLayout(buttonLayout);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(gameListView);
+ mainLayout->addLayout(hbox);
+
+ retranslateUi();
+ setLayout(mainLayout);
+
+ setMinimumWidth((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5);
+ setMinimumHeight(200);
+
+ connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
+ connect(showRunningGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showRunningGamesChanged(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::showRunningGamesChanged(int state)
+{
+ gameListProxyModel->setRunningGamesVisible(state);
+}
+
+void GameSelector::actCreate()
+{
+ DlgCreateGame dlg(client, room->getRoomId(), room->getGameTypes(), this);
+ dlg.exec();
+}
+
+void GameSelector::checkResponse(ResponseCode response)
+{
+ if (createButton)
+ createButton->setEnabled(true);
+ joinButton->setEnabled(true);
+ spectateButton->setEnabled(true);
+
+ switch (response) {
+ case RespNotInRoom: QMessageBox::critical(this, tr("Error"), tr("Please join the appropriate room first.")); break;
+ 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;
+ case RespUserLevelTooLow: QMessageBox::critical(this, tr("Error"), tr("This game is only open to registered users.")); break;
+ case RespOnlyBuddies: QMessageBox::critical(this, tr("Error"), tr("This game is only open to its creator's buddies.")); break;
+ case RespInIgnoreList: QMessageBox::critical(this, tr("Error"), tr("You are being ignored by the creator of this game.")); 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->getRoomId(), game->getGameId(), password, spectator);
+ connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
+ client->sendCommand(commandJoinGame);
+
+ if (createButton)
+ createButton->setEnabled(false);
+ joinButton->setEnabled(false);
+ spectateButton->setEnabled(false);
+}
+
+void GameSelector::retranslateUi()
+{
+ setTitle(tr("Games"));
+ showFullGamesCheckBox->setText(tr("Show &full games"));
+ showRunningGamesCheckBox->setText(tr("Show &running games"));
+ if (createButton)
+ 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);
+}
+
diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h
new file mode 100644
index 000000000..cf603b336
--- /dev/null
+++ b/cockatrice/src/gameselector.h
@@ -0,0 +1,42 @@
+#ifndef GAMESELECTOR_H
+#define GAMESELECTOR_H
+
+#include
+#include "protocol_datastructures.h"
+#include "tab_room.h"
+#include "gametypemap.h"
+
+class QTreeView;
+class GamesModel;
+class GamesProxyModel;
+class QPushButton;
+class QCheckBox;
+class AbstractClient;
+class TabRoom;
+
+class GameSelector : public QGroupBox {
+ Q_OBJECT
+private slots:
+ void showFullGamesChanged(int state);
+ void showRunningGamesChanged(int state);
+ void actCreate();
+ void actJoin();
+ void checkResponse(ResponseCode response);
+signals:
+ void gameJoined(int gameId);
+private:
+ AbstractClient *client;
+ TabRoom *room;
+
+ QTreeView *gameListView;
+ GamesModel *gameListModel;
+ GamesProxyModel *gameListProxyModel;
+ QPushButton *createButton, *joinButton, *spectateButton;
+ QCheckBox *showFullGamesCheckBox, *showRunningGamesCheckBox;
+public:
+ GameSelector(AbstractClient *_client, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent = 0);
+ void retranslateUi();
+ void processGameInfo(ServerInfo_Game *info);
+};
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp
index 700877f2f..fc8e7d555 100644
--- a/cockatrice/src/gamesmodel.cpp
+++ b/cockatrice/src/gamesmodel.cpp
@@ -1,8 +1,8 @@
#include "gamesmodel.h"
#include "protocol_datastructures.h"
-GamesModel::GamesModel(const QMap &_gameTypes, QObject *parent)
- : QAbstractTableModel(parent), gameTypes(_gameTypes)
+GamesModel::GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent)
+ : QAbstractTableModel(parent), rooms(_rooms), gameTypes(_gameTypes)
{
}
@@ -30,17 +30,19 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
ServerInfo_Game *g = gameList[index.row()];
switch (index.column()) {
- case 0: return g->getDescription();
- case 1: return g->getCreatorInfo()->getName();
- case 2: {
+ case 0: return rooms.value(g->getRoomId());
+ case 1: return g->getDescription();
+ case 2: return g->getCreatorInfo()->getName();
+ case 3: {
QStringList result;
QList gameTypeList = g->getGameTypes();
+ GameTypeMap gameTypeMap = gameTypes.value(g->getRoomId());
for (int i = 0; i < gameTypeList.size(); ++i)
- result.append(gameTypes.value(gameTypeList[i]->getData()));
+ result.append(gameTypeMap.value(gameTypeList[i]->getData()));
return result.join(", ");
}
- case 3: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no");
- case 4: {
+ case 4: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no");
+ case 5: {
QStringList result;
if (g->getOnlyBuddies())
result.append(tr("buddies only"));
@@ -48,8 +50,8 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
result.append(tr("reg. users only"));
return result.join(", ");
}
- case 5: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
- case 6: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed"));
+ case 6: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
+ case 7: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed"));
default: return QVariant();
}
}
@@ -59,13 +61,14 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro
if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal))
return QVariant();
switch (section) {
- case 0: return tr("Description");
- case 1: return tr("Creator");
- case 2: return tr("Game type");
- case 3: return tr("Password");
- case 4: return tr("Restrictions");
- case 5: return tr("Players");
- case 6: return tr("Spectators");
+ case 0: return tr("Room");
+ case 1: return tr("Description");
+ case 2: return tr("Creator");
+ case 3: return tr("Game type");
+ case 4: return tr("Password");
+ case 5: return tr("Restrictions");
+ case 6: return tr("Players");
+ case 7: return tr("Spectators");
default: return QVariant();
}
}
@@ -82,7 +85,7 @@ void GamesModel::updateGameList(ServerInfo_Game *_game)
for (int i = 0; i < oldGameTypeList.size(); ++i)
gameTypeList.append(new GameTypeId(oldGameTypeList[i]->getData()));
- ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), gameTypeList, new ServerInfo_User(_game->getCreatorInfo()), _game->getOnlyBuddies(), _game->getOnlyRegistered(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount());
+ ServerInfo_Game *game = new ServerInfo_Game(_game->getRoomId(), _game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getStarted(), gameTypeList, new ServerInfo_User(_game->getCreatorInfo()), _game->getOnlyBuddies(), _game->getOnlyRegistered(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount());
for (int i = 0; i < gameList.size(); i++)
if (gameList[i]->getGameId() == game->getGameId()) {
if (game->getPlayerCount() == 0) {
@@ -92,7 +95,7 @@ void GamesModel::updateGameList(ServerInfo_Game *_game)
} else {
delete gameList[i];
gameList[i] = game;
- emit dataChanged(index(i, 0), index(i, 4));
+ emit dataChanged(index(i, 0), index(i, 7));
}
return;
}
@@ -115,17 +118,22 @@ void GamesProxyModel::setFullGamesVisible(bool _fullGamesVisible)
invalidateFilter();
}
+void GamesProxyModel::setRunningGamesVisible(bool _runningGamesVisible)
+{
+ runningGamesVisible = _runningGamesVisible;
+ invalidateFilter();
+}
+
bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourceParent*/) const
{
- if (fullGamesVisible)
- return true;
-
GamesModel *model = qobject_cast(sourceModel());
if (!model)
return false;
ServerInfo_Game *game = model->getGame(sourceRow);
- if (game->getPlayerCount() == game->getMaxPlayers())
+ if ((game->getPlayerCount() == game->getMaxPlayers()) && !fullGamesVisible)
+ return false;
+ if (game->getStarted() && !runningGamesVisible)
return false;
return true;
diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h
index a7f4fe68d..8461faf66 100644
--- a/cockatrice/src/gamesmodel.h
+++ b/cockatrice/src/gamesmodel.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include "gametypemap.h"
class ServerInfo_Game;
@@ -11,12 +12,13 @@ class GamesModel : public QAbstractTableModel {
Q_OBJECT
private:
QList gameList;
- QMap gameTypes;
+ QMap rooms;
+ QMap gameTypes;
public:
- GamesModel(const QMap &_gameTypes, QObject *parent = 0);
+ GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent = 0);
~GamesModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : gameList.size(); }
- int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 7; }
+ int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 8; }
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
@@ -28,9 +30,11 @@ class GamesProxyModel : public QSortFilterProxyModel {
Q_OBJECT
private:
bool fullGamesVisible;
+ bool runningGamesVisible;
public:
GamesProxyModel(QObject *parent = 0);
void setFullGamesVisible(bool _fullGamesVisible);
+ void setRunningGamesVisible(bool _runningGamesVisible);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
diff --git a/cockatrice/src/gametypemap.h b/cockatrice/src/gametypemap.h
new file mode 100644
index 000000000..fce161752
--- /dev/null
+++ b/cockatrice/src/gametypemap.h
@@ -0,0 +1,8 @@
+#ifndef GAMETYPEMAP_H
+#define GAMETYPEMAP_H
+
+#include
+
+typedef QMap GameTypeMap;
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/localserver.cpp b/cockatrice/src/localserver.cpp
index 4cadbdf31..2793a28e2 100644
--- a/cockatrice/src/localserver.cpp
+++ b/cockatrice/src/localserver.cpp
@@ -10,6 +10,7 @@ LocalServer::LocalServer(QObject *parent)
LocalServer::~LocalServer()
{
+ prepareDestroy();
}
LocalServerInterface *LocalServer::newConnection()
diff --git a/cockatrice/src/localserver.h b/cockatrice/src/localserver.h
index b68e4f25a..cf24b4385 100644
--- a/cockatrice/src/localserver.h
+++ b/cockatrice/src/localserver.h
@@ -11,11 +11,12 @@ class LocalServer : public Server
public:
LocalServer(QObject *parent = 0);
~LocalServer();
- AuthenticationResult checkUserPassword(const QString & /*user*/, const QString & /*password*/) { return UnknownUser; }
+ AuthenticationResult checkUserPassword(Server_ProtocolHandler * /*handler*/, const QString & /*user*/, const QString & /*password*/) { return UnknownUser; }
QString getLoginMessage() const { return QString(); }
bool getGameShouldPing() const { return false; }
int getMaxGameInactivityTime() const { return 9999999; }
int getMaxPlayerInactivityTime() const { return 9999999; }
+ bool getThreaded() const { return false; }
LocalServerInterface *newConnection();
protected:
diff --git a/cockatrice/src/localserverinterface.cpp b/cockatrice/src/localserverinterface.cpp
index b4e0918d6..79734c40c 100644
--- a/cockatrice/src/localserverinterface.cpp
+++ b/cockatrice/src/localserverinterface.cpp
@@ -9,6 +9,7 @@ LocalServerInterface::LocalServerInterface(LocalServer *_server)
LocalServerInterface::~LocalServerInterface()
{
+ prepareDestroy();
}
void LocalServerInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem)
diff --git a/cockatrice/src/localserverinterface.h b/cockatrice/src/localserverinterface.h
index fc23b1b57..1db974129 100644
--- a/cockatrice/src/localserverinterface.h
+++ b/cockatrice/src/localserverinterface.h
@@ -18,14 +18,16 @@ 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; }
ResponseCode cmdBanFromServer(Command_BanFromServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
+ ResponseCode cmdShutdownServer(Command_ShutdownServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
+ ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
+protected:
+ bool getCompressionSupport() const { return false; }
public:
LocalServerInterface(LocalServer *_server);
~LocalServerInterface();
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
-
signals:
void itemToClient(ProtocolItem *item);
public slots:
diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp
index 5b872b69e..8ce2581b7 100644
--- a/cockatrice/src/main.cpp
+++ b/cockatrice/src/main.cpp
@@ -36,6 +36,7 @@
#include "settingscache.h"
#include "pixmapgenerator.h"
#include "rng_sfmt.h"
+#include "soundengine.h"
//Q_IMPORT_PLUGIN(qjpeg)
@@ -43,6 +44,7 @@ CardDatabase *db;
QTranslator *translator, *qtTranslator;
SettingsCache *settingsCache;
RNG_Abstract *rng;
+SoundEngine *soundEngine;
void myMessageOutput(QtMsgType /*type*/, const char *msg)
{
@@ -114,6 +116,8 @@ int main(int argc, char *argv[])
}
if (startMainProgram) {
+ soundEngine = new SoundEngine;
+
MainWindow ui;
qDebug("main(): MainWindow constructor finished");
diff --git a/cockatrice/src/main.h b/cockatrice/src/main.h
index b1f30bdb8..3e7ad1ead 100644
--- a/cockatrice/src/main.h
+++ b/cockatrice/src/main.h
@@ -3,12 +3,13 @@
class CardDatabase;
class QTranslator;
+class SoundEngine;
extern CardDatabase *db;
extern QTranslator *translator;
const QString translationPrefix = "cockatrice";
-const QString versionString = "0.20110303";
+const QString versionString = "0.20110625";
void installNewTranslator();
diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp
index b2907e8c5..98b61c907 100644
--- a/cockatrice/src/messagelogwidget.cpp
+++ b/cockatrice/src/messagelogwidget.cpp
@@ -1,11 +1,9 @@
#include "messagelogwidget.h"
#include "player.h"
#include "cardzone.h"
-#include "cardinfowidget.h"
#include "protocol_items.h"
-#include
-#include
-#include
+#include "soundengine.h"
+#include
QString MessageLogWidget::sanitizeHtml(QString dirty) const
{
@@ -15,133 +13,158 @@ QString MessageLogWidget::sanitizeHtml(QString dirty) const
.replace(">", ">");
}
-void MessageLogWidget::logConnecting(QString hostname)
+bool MessageLogWidget::isFemale(Player *player) const
{
- append(tr("Connecting to %1...").arg(sanitizeHtml(hostname)));
-}
-
-void MessageLogWidget::logConnected()
-{
- append(tr("Connected."));
-}
-
-void MessageLogWidget::logDisconnected()
-{
- append(tr("Disconnected from server."));
-}
-
-void MessageLogWidget::logSocketError(const QString &errorString)
-{
- append(sanitizeHtml(errorString));
-}
-
-void MessageLogWidget::logServerError(ResponseCode response)
-{
- switch (response) {
- case RespWrongPassword: append(tr("Invalid password.")); break;
- default: ;
- }
-}
-
-void MessageLogWidget::logProtocolVersionMismatch(int clientVersion, int serverVersion)
-{
- append(tr("Protocol version mismatch. Client: %1, Server: %2").arg(clientVersion).arg(serverVersion));
-}
-
-void MessageLogWidget::logProtocolError()
-{
- append(tr("Protocol error."));
+ return player->getUserInfo()->getGender() == ServerInfo_User::Female;
}
void MessageLogWidget::logGameJoined(int gameId)
{
- append(tr("You have joined game #%1.").arg(gameId));
+ if (female)
+ appendHtml(tr("You have joined game #%1.", "female").arg(gameId));
+ else
+ appendHtml(tr("You have joined game #%1.", "male").arg(gameId));
}
void MessageLogWidget::logJoin(Player *player)
{
- append(tr("%1 has joined the game.").arg(sanitizeHtml(player->getName())));
+ soundEngine->cuckoo();
+ if (isFemale(player))
+ appendHtml(tr("%1 has joined the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has joined the game.", "male").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logLeave(Player *player)
{
- append(tr("%1 has left the game.").arg(sanitizeHtml(player->getName())));
+ if (isFemale(player))
+ appendHtml(tr("%1 has left the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has left the game.", "male").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logGameClosed()
{
- append(tr("The game has been closed."));
+ appendHtml(tr("The game has been closed."));
}
void MessageLogWidget::logJoinSpectator(QString name)
{
- append(tr("%1 is now watching the game.").arg(sanitizeHtml(name)));
+ appendHtml(tr("%1 is now watching the game.").arg(sanitizeHtml(name)));
}
void MessageLogWidget::logLeaveSpectator(QString name)
{
- append(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name)));
+ appendHtml(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name)));
}
void MessageLogWidget::logDeckSelect(Player *player, int deckId)
{
- if (deckId == -1)
- append(tr("%1 has loaded a local deck.").arg(sanitizeHtml(player->getName())));
- else
- append(tr("%1 has loaded deck #%2.").arg(sanitizeHtml(player->getName())).arg(deckId));
+ if (deckId == -1) {
+ if (isFemale(player))
+ appendHtml(tr("%1 has loaded a local deck.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has loaded a local deck.", "male").arg(sanitizeHtml(player->getName())));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 has loaded deck #%2.", "female").arg(sanitizeHtml(player->getName())).arg(deckId));
+ else
+ appendHtml(tr("%1 has loaded deck #%2.", "male").arg(sanitizeHtml(player->getName())).arg(deckId));
+ }
}
void MessageLogWidget::logReadyStart(Player *player)
{
- append(tr("%1 is ready to start the game.").arg(sanitizeHtml(player->getName())));
+ if (isFemale(player))
+ appendHtml(tr("%1 is ready to start the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 is ready to start the game.", "male").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logNotReadyStart(Player *player)
{
- append(tr("%1 is not ready to start the game any more.").arg(sanitizeHtml(player->getName())));
+ if (isFemale(player))
+ appendHtml(tr("%1 is not ready to start the game any more.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 is not ready to start the game any more.", "male").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logConcede(Player *player)
{
- append(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getName())));
+ if (isFemale(player))
+ appendHtml(tr("%1 has conceded the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has conceded the game.", "male").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logGameStart()
{
- append(tr("The game has started."));
+ appendHtml(tr("The game has started."));
+}
+
+void MessageLogWidget::logConnectionStateChanged(Player *player, bool connectionState)
+{
+ if (connectionState) {
+ if (isFemale(player))
+ appendHtml(tr("%1 has restored connection to the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has restored connection to the game.", "male").arg(sanitizeHtml(player->getName())));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 has lost connection to the game.", "female").arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 has lost connection to the game.", "male").arg(sanitizeHtml(player->getName())));
+ }
}
void MessageLogWidget::logSay(Player *player, QString message)
{
- append(QString("getLocal() ? "red" : "#0000fe") + QString("\">%1: %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message)));
+ appendMessage(player->getName(), message, QColor(), true);
}
void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message)
{
- append(QString("%1: %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message)));
+ appendMessage(spectatorName, message, QColor(), false);
}
-void MessageLogWidget::logShuffle(Player *player)
+void MessageLogWidget::logShuffle(Player *player, CardZone *zone)
{
- append(tr("%1 shuffles his library.").arg(sanitizeHtml(player->getName())));
+ soundEngine->shuffle();
+ if (currentContext != MessageContext_Mulligan) {
+ if (isFemale(player))
+ appendHtml(tr("%1 shuffles %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ else
+ appendHtml(tr("%1 shuffles %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ }
}
void MessageLogWidget::logRollDie(Player *player, int sides, int roll)
{
- append(tr("%1 rolls a %2 with a %3-sided die.").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides));
+ if (isFemale(player))
+ appendHtml(tr("%1 rolls a %2 with a %3-sided die.", "female").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides));
+ else
+ appendHtml(tr("%1 rolls a %2 with a %3-sided die.", "male").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides));
}
void MessageLogWidget::logDrawCards(Player *player, int number)
{
- append(tr("%1 draws %n card(s).", "", number).arg(sanitizeHtml(player->getName())));
+ if (currentContext == MessageContext_Mulligan)
+ mulliganPlayer = player;
+ else {
+ soundEngine->draw();
+ if (isFemale(player))
+ appendHtml(tr("%1 draws %n card(s).", "female", number).arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 draws %n card(s).", "male", number).arg(sanitizeHtml(player->getName())));
+ }
}
void MessageLogWidget::logUndoDraw(Player *player, QString cardName)
{
if (cardName.isEmpty())
- append(tr("%1 undoes his last draw.").arg(sanitizeHtml(player->getName())));
+ appendHtml((isFemale(player) ? tr("%1 undoes her last draw.") : tr("%1 undoes his last draw.")).arg(sanitizeHtml(player->getName())));
else
- append(tr("%1 undoes his last draw (%2).").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
+ appendHtml((isFemale(player) ? tr("%1 undoes her last draw (%2).") : tr("%1 undoes his last draw (%2).")).arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
}
QPair MessageLogWidget::getFromStr(CardZone *zone, QString cardName, int position) const
@@ -161,16 +184,16 @@ QPair MessageLogWidget::getFromStr(CardZone *zone, QString car
else if (startName == "deck") {
if (position == zone->getCards().size() - 1) {
if (cardName.isEmpty()) {
- cardName = tr("the bottom card of his library");
+ cardName = isFemale(zone->getPlayer()) ? tr("the bottom card of her library") : tr("the bottom card of his library");
cardNameContainsStartZone = true;
} else
- fromStr = tr(" from the bottom of his library");
+ fromStr = isFemale(zone->getPlayer()) ? tr(" from the bottom of her library") : tr(" from the bottom of his library");
} else if (position == 0) {
if (cardName.isEmpty()) {
- cardName = tr("the top card of his library");
+ cardName = isFemale(zone->getPlayer()) ? tr("the top card of her library") : tr("the top card of his library");
cardNameContainsStartZone = true;
} else
- fromStr = tr(" from the top of his library");
+ fromStr = isFemale(zone->getPlayer()) ? tr(" from the top of her library") : tr(" from the top of his library");
} else
fromStr = tr(" from library");
} else if (startName == "sb")
@@ -206,12 +229,13 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes)
cardStr = QString("%1").arg(sanitizeHtml(cardName));
if (attributes.startZone->getPlayer() != attributes.targetZone->getPlayer()) {
- append(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr));
+ appendHtml(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr));
return;
}
QString finalStr;
if (targetName == "table") {
+ soundEngine->playCard();
if (moveCardTapped.value(attributes.card))
finalStr = tr("%1 puts %2 into play tapped%3.");
else
@@ -224,19 +248,21 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes)
finalStr = tr("%1 moves %2%3 to hand.");
else if (targetName == "deck") {
if (attributes.newX == -1)
- finalStr = tr("%1 puts %2%3 into his library.");
+ finalStr = isFemale(attributes.targetZone->getPlayer()) ? tr("%1 puts %2%3 into her library.") : tr("%1 puts %2%3 into his library.");
else if (attributes.newX == attributes.targetZone->getCards().size() - 1)
- finalStr = tr("%1 puts %2%3 on bottom of his library.");
+ finalStr = isFemale(attributes.targetZone->getPlayer()) ? tr("%1 puts %2%3 on bottom of her library.") : tr("%1 puts %2%3 on bottom of his library.");
else if (attributes.newX == 0)
- finalStr = tr("%1 puts %2%3 on top of his library.");
+ finalStr = isFemale(attributes.targetZone->getPlayer()) ? tr("%1 puts %2%3 on top of her library.") : tr("%1 puts %2%3 on top of his library.");
else
- finalStr = tr("%1 puts %2%3 into his library at position %4.");
+ finalStr = isFemale(attributes.targetZone->getPlayer()) ? tr("%1 puts %2%3 into her library at position %4.") : tr("%1 puts %2%3 into his library at position %4.");
} else if (targetName == "sb")
finalStr = tr("%1 moves %2%3 to sideboard.");
- else if (targetName == "stack")
+ else if (targetName == "stack") {
+ soundEngine->playCard();
finalStr = tr("%1 plays %2%3.");
+ }
- append(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX));
+ appendHtml(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX));
}
void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *startZone, int oldX, CardZone *targetZone, int newX)
@@ -244,55 +270,211 @@ void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *sta
LogMoveCard attributes = {player, card, card->getName(), startZone, oldX, targetZone, newX};
if (currentContext == MessageContext_MoveCard)
moveCardQueue.append(attributes);
+ else if (currentContext == MessageContext_Mulligan)
+ mulliganPlayer = player;
else
doMoveCard(attributes);
}
+void MessageLogWidget::logMulligan(Player *player, int number)
+{
+ if (!player)
+ return;
+
+ if (number > -1) {
+ if (isFemale(player))
+ appendHtml(tr("%1 takes a mulligan to %n.", "female", number).arg(sanitizeHtml(player->getName())));
+ else
+ appendHtml(tr("%1 takes a mulligan to %n.", "male", number).arg(sanitizeHtml(player->getName())));
+ } else
+ appendHtml((isFemale(player) ? tr("%1 draws her initial hand.") : tr("%1 draws his initial hand.")).arg(sanitizeHtml(player->getName())));
+}
+
void MessageLogWidget::logFlipCard(Player *player, QString cardName, bool faceDown)
{
- if (faceDown)
- append(tr("%1 flips %2 face-down.").arg(sanitizeHtml(player->getName())).arg(cardName));
- else
- append(tr("%1 flips %2 face-up.").arg(sanitizeHtml(player->getName())).arg(cardName));
+ if (faceDown) {
+ if (isFemale(player))
+ appendHtml(tr("%1 flips %2 face-down.", "female").arg(sanitizeHtml(player->getName())).arg(cardName));
+ else
+ appendHtml(tr("%1 flips %2 face-down.", "male").arg(sanitizeHtml(player->getName())).arg(cardName));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 flips %2 face-up.", "female").arg(sanitizeHtml(player->getName())).arg(cardName));
+ else
+ appendHtml(tr("%1 flips %2 face-up.", "male").arg(sanitizeHtml(player->getName())).arg(cardName));
+ }
}
void MessageLogWidget::logDestroyCard(Player *player, QString cardName)
{
- append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
+ if (isFemale(player))
+ appendHtml(tr("%1 destroys %2.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
+ else
+ appendHtml(tr("%1 destroys %2.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
}
void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName)
{
- append(tr("%1 attaches %2 to %3's %4.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("%1").arg(sanitizeHtml(targetCardName))));
+ QString str;
+ if (isFemale(player)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 attaches %2 to %3's %4.", "p1 female, p2 female");
+ else
+ str = tr("%1 attaches %2 to %3's %4.", "p1 female, p2 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 attaches %2 to %3's %4.", "p1 male, p2 female");
+ else
+ str = tr("%1 attaches %2 to %3's %4.", "p1 male, p2 male");
+ }
+
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("%1").arg(sanitizeHtml(targetCardName))));
}
void MessageLogWidget::logUnattachCard(Player *player, QString cardName)
{
- append(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
+ if (isFemale(player))
+ appendHtml(tr("%1 unattaches %2.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
+ else
+ appendHtml(tr("%1 unattaches %2.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))));
}
void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt)
{
- append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
+ if (isFemale(player))
+ appendHtml(tr("%1 creates token: %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
+ else
+ appendHtml(tr("%1 creates token: %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
}
void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget)
{
- if (playerTarget)
- append(tr("%1 points from %2's %3 to %4.")
- .arg(sanitizeHtml(player->getName()))
- .arg(sanitizeHtml(startPlayer->getName()))
- .arg(sanitizeHtml(startCard))
- .arg(sanitizeHtml(targetPlayer->getName()))
- );
- else
- append(tr("%1 points from %2's %3 to %4's %5.")
- .arg(sanitizeHtml(player->getName()))
- .arg(sanitizeHtml(startPlayer->getName()))
- .arg(sanitizeHtml(startCard))
- .arg(sanitizeHtml(targetPlayer->getName()))
- .arg(sanitizeHtml(targetCard))
- );
+ startCard = QString("%1").arg(sanitizeHtml(startCard));
+ targetCard = QString("%1").arg(sanitizeHtml(targetCard));
+ QString str;
+ if (playerTarget) {
+ if ((player == startPlayer) && (player == targetPlayer)) {
+ if (isFemale(player))
+ str = tr("%1 points from her %2 to herself.", "female");
+ else
+ str = tr("%1 points from his %2 to himself.", "male");
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard));
+ } else if (player == startPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from her %2 to %3.", "p1 female, p2 female");
+ else
+ str = tr("%1 points from her %2 to %3.", "p1 female, p2 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from his %2 to %3.", "p1 male, p2 female");
+ else
+ str = tr("%1 points from his %2 to %3.", "p1 male, p2 male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())));
+ } else if (player == targetPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(startPlayer))
+ str = tr("%1 points from %2's %3 to herself.", "card owner female, target female");
+ else
+ str = tr("%1 points from %2's %3 to herself.", "card owner male, target female");
+ } else {
+ if (isFemale(startPlayer))
+ str = tr("%1 points from %2's %3 to himself.", "card owner female, target male");
+ else
+ str = tr("%1 points from %2's %3 to himself.", "card owner male, target male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard));
+ } else {
+ if (isFemale(player)) {
+ if (isFemale(startPlayer)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 female, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 female, p3 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 male, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 male, p3 male");
+ }
+ } else {
+ if (isFemale(startPlayer)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 female, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 female, p3 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 male, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 male, p3 male");
+ }
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())));
+ }
+ } else {
+ if ((player == startPlayer) && (player == targetPlayer)) {
+ if (isFemale(player))
+ str = tr("%1 points from her %2 to her %3.", "female");
+ else
+ str = tr("%1 points from his %2 to his %3.", "male");
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(targetCard));
+ } else if (player == startPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from her %2 to %3's %4.", "p1 female, p2 female");
+ else
+ str = tr("%1 points from her %2 to %3's %4.", "p1 female, p2 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from his %2 to %3's %4.", "p1 male, p2 female");
+ else
+ str = tr("%1 points from his %2 to %3's %4.", "p1 male, p2 male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())).arg(targetCard));
+ } else if (player == targetPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(startPlayer))
+ str = tr("%1 points from %2's %3 to her own %4.", "card owner female, target female");
+ else
+ str = tr("%1 points from %2's %3 to her own %4.", "card owner male, target female");
+ } else {
+ if (isFemale(startPlayer))
+ str = tr("%1 points from %2's %3 to his own %4.", "card owner female, target male");
+ else
+ str = tr("%1 points from %2's %3 to his own %4.", "card owner male, target male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(targetCard));
+ } else {
+ if (isFemale(player)) {
+ if (isFemale(startPlayer)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 female, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 female, p3 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 male, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 male, p3 male");
+ }
+ } else {
+ if (isFemale(startPlayer)) {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 female, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 female, p3 male");
+ } else {
+ if (isFemale(targetPlayer))
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 male, p3 female");
+ else
+ str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 male, p3 male");
+ }
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())).arg(targetCard));
+ }
+ }
}
void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue)
@@ -300,10 +482,17 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c
QString finalStr, colorStr;
int delta = abs(oldValue - value);
- if (value > oldValue)
- finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "", delta);
- else
- finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "", delta);
+ if (value > oldValue) {
+ if (isFemale(player))
+ finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "female", delta);
+ else
+ finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "male", delta);
+ } else {
+ if (isFemale(player))
+ finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "female", delta);
+ else
+ finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "male", delta);
+ }
switch (counterId) {
case 0: colorStr = tr("red", "", delta); break;
@@ -312,63 +501,124 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c
default: ;
}
- append(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value));
+ appendHtml(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value));
}
void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped)
{
+ if (tapped)
+ soundEngine->tap();
+ else
+ soundEngine->untap();
+
if (currentContext == MessageContext_MoveCard)
moveCardTapped.insert(card, tapped);
else {
- QString cardStr;
- if (!card)
- cardStr = tr("his permanents");
- else
- cardStr = QString("%1").arg(sanitizeHtml(card->getName()));
- append(tr("%1 %2 %3.").arg(sanitizeHtml(player->getName())).arg(tapped ? tr("taps") : tr("untaps")).arg(cardStr));
+ QString str;
+ if (!card) {
+ if (isFemale(player)) {
+ if (tapped)
+ str = tr("%1 taps her permanents.", "female");
+ else
+ str = tr("%1 untaps her permanents.", "female");
+ } else {
+ if (tapped)
+ str = tr("%1 taps his permanents.", "male");
+ else
+ str = tr("%1 untaps his permanents.", "male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())));
+ } else {
+ if (isFemale(player)) {
+ if (tapped)
+ str = tr("%1 taps %2.", "female");
+ else
+ str = tr("%1 untaps %2.", "female");
+ } else {
+ if (tapped)
+ str = tr("%1 taps %2.", "male");
+ else
+ str = tr("%1 untaps %2.", "male");
+ }
+ QString cardStr = QString("%1").arg(sanitizeHtml(card->getName()));
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr));
+ }
}
}
void MessageLogWidget::logSetCounter(Player *player, QString counterName, int value, int oldValue)
{
- append(tr("%1 sets counter %2 to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(counterName))).arg(QString("%1").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue));
+ QString str;
+ if (isFemale(player))
+ str = tr("%1 sets counter %2 to %3 (%4%5).", "female");
+ else
+ str = tr("%1 sets counter %2 to %3 (%4%5).", "male");
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(counterName))).arg(QString("%1").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue));
}
void MessageLogWidget::logSetDoesntUntap(Player *player, CardItem *card, bool doesntUntap)
{
- QString finalStr;
- if (doesntUntap)
- finalStr = tr("%1 sets %2 to not untap normally.");
- else
- finalStr = tr("%1 sets %2 to untap normally.");
- append(finalStr.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))));
+ QString str;
+ if (doesntUntap) {
+ if (isFemale(player))
+ str = tr("%1 sets %2 to not untap normally.", "female");
+ else
+ str = tr("%1 sets %2 to not untap normally.", "male");
+ } else {
+ if (isFemale(player))
+ str = tr("%1 sets %2 to untap normally.", "female");
+ else
+ str = tr("%1 sets %2 to untap normally.", "male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))));
}
void MessageLogWidget::logSetPT(Player *player, CardItem *card, QString newPT)
{
if (currentContext == MessageContext_MoveCard)
moveCardPT.insert(card, newPT);
- else
- append(tr("%1 sets PT of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newPT))));
+ else {
+ QString str;
+ if (isFemale(player))
+ str = tr("%1 sets PT of %2 to %3.", "female");
+ else
+ str = tr("%1 sets PT of %2 to %3.", "male");
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newPT))));
+ }
}
void MessageLogWidget::logSetAnnotation(Player *player, CardItem *card, QString newAnnotation)
{
- append(tr("%1 sets annotation of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newAnnotation))));
+ QString str;
+ if (isFemale(player))
+ str = tr("%1 sets annotation of %2 to %3.", "female");
+ else
+ str = tr("%1 sets annotation of %2 to %3.", "male");
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newAnnotation))));
}
void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards)
{
- if (numberCards != -1)
- append(tr("%1 is looking at the top %2 cards %3.").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive)));
- else
- append(tr("%1 is looking at %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative)));
+ if (numberCards != -1) {
+ if (isFemale(player))
+ appendHtml(tr("%1 is looking at the top %2 cards %3.", "female").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive)));
+ else
+ appendHtml(tr("%1 is looking at the top %2 cards %3.", "male").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive)));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 is looking at %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative)));
+ else
+ appendHtml(tr("%1 is looking at %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative)));
+ }
}
void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone)
{
QString zoneName = zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative);
- append(tr("%1 stops looking at %2.").arg(sanitizeHtml(player->getName())).arg(zoneName));
+ if (isFemale(player))
+ appendHtml(tr("%1 stops looking at %2.", "female").arg(sanitizeHtml(player->getName())).arg(zoneName));
+ else
+ appendHtml(tr("%1 stops looking at %2.", "male").arg(sanitizeHtml(player->getName())).arg(zoneName));
}
void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId, QString cardName, Player *otherPlayer)
@@ -389,33 +639,85 @@ void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId
else
cardStr = QString("%1").arg(sanitizeHtml(cardName));
+ QString str;
if (cardId == -1) {
- if (otherPlayer)
- append(tr("%1 reveals %2 to %3.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName())));
- else
- append(tr("%1 reveals %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ if (otherPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(otherPlayer))
+ str = tr("%1 reveals %2 to %3.", "p1 female, p2 female");
+ else
+ str = tr("%1 reveals %2 to %3.", "p1 female, p2 male");
+ } else {
+ if (isFemale(otherPlayer))
+ str = tr("%1 reveals %2 to %3.", "p1 male, p2 female");
+ else
+ str = tr("%1 reveals %2 to %3.", "p1 male, p2 male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName())));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 reveals %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ else
+ appendHtml(tr("%1 reveals %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ }
} else if (cardId == -2) {
- if (otherPlayer)
- append(tr("%1 randomly reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
- else
- append(tr("%1 randomly reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
+ if (otherPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(otherPlayer))
+ str = tr("%1 randomly reveals %2%3 to %4.", "p1 female, p2 female");
+ else
+ str = tr("%1 randomly reveals %2%3 to %4.", "p1 female, p2 male");
+ } else {
+ if (isFemale(otherPlayer))
+ str = tr("%1 randomly reveals %2%3 to %4.", "p1 male, p2 female");
+ else
+ str = tr("%1 randomly reveals %2%3 to %4.", "p1 male, p2 male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 randomly reveals %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ else
+ appendHtml(tr("%1 randomly reveals %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
+ }
} else {
- if (otherPlayer)
- append(tr("%1 reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
- else
- append(tr("%1 reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
+ if (otherPlayer) {
+ if (isFemale(player)) {
+ if (isFemale(otherPlayer))
+ str = tr("%1 reveals %2%3 to %4.", "p1 female, p2 female");
+ else
+ str = tr("%1 reveals %2%3 to %4.", "p1 female, p2 male");
+ } else {
+ if (isFemale(otherPlayer))
+ str = tr("%1 reveals %2%3 to %4.", "p1 male, p2 female");
+ else
+ str = tr("%1 reveals %2%3 to %4.", "p1 male, p2 male");
+ }
+ appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
+ } else {
+ if (isFemale(player))
+ appendHtml(tr("%1 reveals %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
+ else
+ appendHtml(tr("%1 reveals %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
+ }
}
}
void MessageLogWidget::logSetActivePlayer(Player *player)
{
- append(QString());
- append("" + tr("It is now %1's turn.").arg(player->getName()) + "");
- append(QString());
+ soundEngine->notification();
+
+ QString str;
+ if (isFemale(player))
+ str = tr("It is now %1's turn.", "female");
+ else
+ str = tr("It is now %1's turn.", "male");
+ appendHtml("
" + str.arg(player->getName()) + "
");
}
void MessageLogWidget::logSetActivePhase(int phase)
{
+ soundEngine->notification();
QString phaseName;
switch (phase) {
case 0: phaseName = tr("untap step"); break;
@@ -430,13 +732,18 @@ void MessageLogWidget::logSetActivePhase(int phase)
case 9: phaseName = tr("second main phase"); break;
case 10: phaseName = tr("ending phase"); break;
}
- append("" + tr("It is now the %1.").arg(phaseName) + "");
+ appendHtml("" + tr("It is now the %1.").arg(phaseName) + "");
}
void MessageLogWidget::containerProcessingStarted(GameEventContext *_context)
{
if (qobject_cast(_context))
currentContext = MessageContext_MoveCard;
+ else if (qobject_cast(_context)) {
+ currentContext = MessageContext_Mulligan;
+ mulliganPlayer = 0;
+ mulliganNumber = static_cast(_context)->getNumber();
+ }
}
void MessageLogWidget::containerProcessingDone()
@@ -447,6 +754,10 @@ void MessageLogWidget::containerProcessingDone()
moveCardQueue.clear();
moveCardPT.clear();
moveCardTapped.clear();
+ } else if (currentContext == MessageContext_Mulligan) {
+ logMulligan(mulliganPlayer, mulliganNumber);
+ mulliganPlayer = 0;
+ mulliganNumber = 0;
}
currentContext = MessageContext_None;
@@ -454,8 +765,9 @@ void MessageLogWidget::containerProcessingDone()
void MessageLogWidget::connectToPlayer(Player *player)
{
+ connect(player, SIGNAL(logConnectionStateChanged(Player *, bool)), this, SLOT(logConnectionStateChanged(Player *, bool)));
connect(player, SIGNAL(logSay(Player *, QString)), this, SLOT(logSay(Player *, QString)));
- connect(player, SIGNAL(logShuffle(Player *)), this, SLOT(logShuffle(Player *)));
+ connect(player, SIGNAL(logShuffle(Player *, CardZone *)), this, SLOT(logShuffle(Player *, CardZone *)));
connect(player, SIGNAL(logRollDie(Player *, int, int)), this, SLOT(logRollDie(Player *, int, int)));
connect(player, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString, bool)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString, bool)));
connect(player, SIGNAL(logCreateToken(Player *, QString, QString)), this, SLOT(logCreateToken(Player *, QString, QString)));
@@ -477,66 +789,7 @@ void MessageLogWidget::connectToPlayer(Player *player)
connect(player, SIGNAL(logRevealCards(Player *, CardZone *, int, QString, Player *)), this, SLOT(logRevealCards(Player *, CardZone *, int, QString, Player *)));
}
-MessageLogWidget::MessageLogWidget(QWidget *parent)
- : QTextEdit(parent)
+MessageLogWidget::MessageLogWidget(const QString &_ownName, bool _female, QWidget *parent)
+ : ChatView(_ownName, false, parent), female(_female)
{
- setReadOnly(true);
-}
-
-void MessageLogWidget::enterEvent(QEvent * /*event*/)
-{
- setMouseTracking(true);
-}
-
-void MessageLogWidget::leaveEvent(QEvent * /*event*/)
-{
- setMouseTracking(false);
-}
-
-QString MessageLogWidget::getCardNameUnderMouse(const QPoint &pos) const
-{
- QTextCursor cursor(cursorForPosition(pos));
- QTextBlock block(cursor.block());
- QTextBlock::iterator it;
- for (it = block.begin(); !(it.atEnd()); ++it) {
- QTextFragment frag = it.fragment();
- if (!frag.contains(cursor.position()))
- continue;
-
- if (frag.charFormat().foreground().color() == Qt::blue)
- return frag.text();
-
- break;
- }
- return QString();
-}
-
-void MessageLogWidget::mouseMoveEvent(QMouseEvent *event)
-{
- QString cardName = getCardNameUnderMouse(event->pos());
- if (!cardName.isEmpty()) {
- viewport()->setCursor(Qt::PointingHandCursor);
- emit cardNameHovered(cardName);
- } else
- viewport()->setCursor(Qt::IBeamCursor);
-
- QTextEdit::mouseMoveEvent(event);
-}
-
-void MessageLogWidget::mousePressEvent(QMouseEvent *event)
-{
- if (event->button() == Qt::MidButton) {
- QString cardName = getCardNameUnderMouse(event->pos());
- if (!cardName.isEmpty())
- emit showCardInfoPopup(event->globalPos(), cardName);
- }
-
- QTextEdit::mousePressEvent(event);
-}
-
-void MessageLogWidget::mouseReleaseEvent(QMouseEvent *event)
-{
- emit deleteCardInfoPopup();
-
- QTextEdit::mouseReleaseEvent(event);
}
diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h
index b5295c35a..37d4a2422 100644
--- a/cockatrice/src/messagelogwidget.h
+++ b/cockatrice/src/messagelogwidget.h
@@ -1,15 +1,13 @@
#ifndef MESSAGELOGWIDGET_H
#define MESSAGELOGWIDGET_H
-#include
+#include "chatview.h"
#include
#include "translation.h"
#include "protocol_datastructures.h"
class Player;
class CardZone;
-class QMouseEvent;
-class QEvent;
class CardInfoWidget;
class GameEventContext;
class CardItem;
@@ -24,31 +22,24 @@ struct LogMoveCard {
int newX;
};
-class MessageLogWidget : public QTextEdit {
+class MessageLogWidget : public ChatView {
Q_OBJECT
private:
- enum MessageContext { MessageContext_None, MessageContext_MoveCard };
+ enum MessageContext { MessageContext_None, MessageContext_MoveCard, MessageContext_Mulligan };
- CardInfoWidget *infoWidget;
QString sanitizeHtml(QString dirty) const;
+ bool isFemale(Player *player) const;
QPair getFromStr(CardZone *zone, QString cardName, int position) const;
- QString getCardNameUnderMouse(const QPoint &pos) const;
MessageContext currentContext;
+ bool female;
+
QList moveCardQueue;
QMap moveCardPT;
QMap moveCardTapped;
-signals:
- void cardNameHovered(QString cardName);
- void showCardInfoPopup(QPoint pos, QString cardName);
- void deleteCardInfoPopup();
+
+ Player *mulliganPlayer;
+ int mulliganNumber;
public slots:
- void logConnecting(QString hostname);
- void logConnected();
- void logDisconnected();
- void logSocketError(const QString &errorString);
- void logServerError(ResponseCode response);
- void logProtocolVersionMismatch(int clientVersion, int serverVersion);
- void logProtocolError();
void logGameJoined(int gameId);
void logJoin(Player *player);
void logLeave(Player *player);
@@ -60,14 +51,16 @@ public slots:
void logNotReadyStart(Player *player);
void logConcede(Player *player);
void logGameStart();
+ void logConnectionStateChanged(Player *player, bool connectionState);
void logSay(Player *player, QString message);
void logSpectatorSay(QString spectatorName, QString message);
- void logShuffle(Player *player);
+ void logShuffle(Player *player, CardZone *zone);
void logRollDie(Player *player, int sides, int roll);
void logDrawCards(Player *player, int number);
void logUndoDraw(Player *player, QString cardName);
void doMoveCard(LogMoveCard &attributes);
void logMoveCard(Player *player, CardItem *card, CardZone *startZone, int oldX, CardZone *targetZone, int newX);
+ void logMulligan(Player *player, int number);
void logFlipCard(Player *player, QString cardName, bool faceDown);
void logDestroyCard(Player *player, QString cardName);
void logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName);
@@ -89,13 +82,7 @@ public slots:
void containerProcessingDone();
public:
void connectToPlayer(Player *player);
- MessageLogWidget(QWidget *parent = 0);
-protected:
- void enterEvent(QEvent *event);
- void leaveEvent(QEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
+ MessageLogWidget(const QString &_ownName, bool _female, QWidget *parent = 0);
};
#endif
diff --git a/cockatrice/src/pixmapgenerator.cpp b/cockatrice/src/pixmapgenerator.cpp
index a27b081da..1c04e9226 100644
--- a/cockatrice/src/pixmapgenerator.cpp
+++ b/cockatrice/src/pixmapgenerator.cpp
@@ -78,6 +78,36 @@ QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max)
QMap PingPixmapGenerator::pmCache;
+QPixmap GenderPixmapGenerator::generatePixmap(int height, int _gender)
+{
+ ServerInfo_User::Gender gender = static_cast(_gender);
+ if ((gender != ServerInfo_User::Male) && (gender != ServerInfo_User::Female))
+ gender = ServerInfo_User::GenderUnknown;
+
+ int key = gender * 100000 + height;
+ if (pmCache.contains(key))
+ return pmCache.value(key);
+
+ QString genderStr;
+ switch (gender) {
+ case ServerInfo_User::Male: genderStr = "male"; break;
+ case ServerInfo_User::Female: genderStr = "female"; break;
+ default: genderStr = "unknown";
+ };
+
+ QSvgRenderer svg(QString(":/resources/genders/" + genderStr + ".svg"));
+ int width = (int) round(height * (double) svg.defaultSize().width() / (double) svg.defaultSize().height());
+ QPixmap pixmap(width, height);
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ svg.render(&painter, QRectF(0, 0, width, height));
+
+ pmCache.insert(key, pixmap);
+ return pixmap;
+}
+
+QMap GenderPixmapGenerator::pmCache;
+
QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countryCode)
{
if (countryCode.size() != 2)
@@ -110,8 +140,8 @@ QPixmap UserLevelPixmapGenerator::generatePixmap(int height, int userLevel)
QString levelString;
if (userLevel & ServerInfo_User::IsAdmin)
levelString = "admin";
- else if (userLevel & ServerInfo_User::IsJudge)
- levelString = "judge";
+ else if (userLevel & ServerInfo_User::IsModerator)
+ levelString = "moderator";
else if (userLevel &ServerInfo_User::IsRegistered)
levelString = "registered";
else
diff --git a/cockatrice/src/pixmapgenerator.h b/cockatrice/src/pixmapgenerator.h
index 7f69c26dd..25fa00c96 100644
--- a/cockatrice/src/pixmapgenerator.h
+++ b/cockatrice/src/pixmapgenerator.h
@@ -28,6 +28,14 @@ public:
static void clear() { pmCache.clear(); }
};
+class GenderPixmapGenerator {
+private:
+ static QMap pmCache;
+public:
+ static QPixmap generatePixmap(int height, int gender);
+ static void clear() { pmCache.clear(); }
+};
+
class CountryPixmapGenerator {
private:
static QMap pmCache;
diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp
index 96bad5031..fc794bd3f 100644
--- a/cockatrice/src/player.cpp
+++ b/cockatrice/src/player.cpp
@@ -706,6 +706,11 @@ void Player::setCardAttrHelper(GameEventContext *context, CardItem *card, const
}
}
+void Player::eventConnectionStateChanged(Event_ConnectionStateChanged *event)
+{
+ emit logConnectionStateChanged(this, event->getConnected());
+}
+
void Player::eventSay(Event_Say *event)
{
emit logSay(this, event->getMessage());
@@ -713,7 +718,7 @@ void Player::eventSay(Event_Say *event)
void Player::eventShuffle(Event_Shuffle * /*event*/)
{
- emit logShuffle(this);
+ emit logShuffle(this, zones.value("deck"));
}
void Player::eventRollDie(Event_RollDie *event)
@@ -862,6 +867,8 @@ void Player::eventMoveCard(Event_MoveCard *event, GameEventContext *context)
CardItem *card = startZone->takeCard(position, event->getCardId(), startZone != targetZone);
if (!card)
return;
+ if (startZone != targetZone)
+ card->deleteCardInfoPopup();
card->setName(event->getCardName());
if (card->getAttachedTo() && (startZone != targetZone)) {
@@ -891,8 +898,7 @@ void Player::eventMoveCard(Event_MoveCard *event, GameEventContext *context)
if (context)
switch (context->getItemId()) {
case ItemId_Context_UndoDraw: emit logUndoDraw(this, card->getName()); break;
- case ItemId_Context_MoveCard: emit logMoveCard(this, card, startZone, logPosition, targetZone, logX);
- default: ;
+ default: emit logMoveCard(this, card, startZone, logPosition, targetZone, logX);
}
else
emit logMoveCard(this, card, startZone, logPosition, targetZone, logX);
@@ -1008,7 +1014,6 @@ void Player::eventDrawCards(Event_DrawCards *event)
hand->reorganizeCards();
deck->reorganizeCards();
-
emit logDrawCards(this, event->getNumberCards());
}
@@ -1038,6 +1043,7 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context)
{
qDebug() << "player event: id=" << event->getItemId();
switch (event->getItemId()) {
+ case ItemId_Event_ConnectionStateChanged: eventConnectionStateChanged(static_cast(event)); break;
case ItemId_Event_Say: eventSay(static_cast(event)); break;
case ItemId_Event_Shuffle: eventShuffle(static_cast(event)); break;
case ItemId_Event_RollDie: eventRollDie(static_cast(event)); break;
@@ -1546,12 +1552,9 @@ void Player::setMirrored(bool _mirrored)
}
}
-void Player::processSceneSizeChange(const QSizeF &newSize)
+void Player::processSceneSizeChange(int newPlayerWidth)
{
- // 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 - 15 - counterAreaWidth - stack->boundingRect().width();
+ qreal tableWidth = newPlayerWidth - 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 c30fc3760..72f19c260 100644
--- a/cockatrice/src/player.h
+++ b/cockatrice/src/player.h
@@ -26,6 +26,7 @@ class CommandContainer;
class GameCommand;
class GameEvent;
class GameEventContext;
+class Event_ConnectionStateChanged;
class Event_Say;
class Event_Shuffle;
class Event_RollDie;
@@ -69,8 +70,9 @@ class Player : public QObject, public QGraphicsItem {
signals:
void newCardAdded(AbstractCardItem *card);
// Log events
+ void logConnectionStateChanged(Player *player, bool connectionState);
void logSay(Player *player, QString message);
- void logShuffle(Player *player);
+ void logShuffle(Player *player, CardZone *zone);
void logRollDie(Player *player, int sides, int roll);
void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool _playerTarget);
void logCreateToken(Player *player, QString cardName, QString pt);
@@ -176,6 +178,7 @@ private:
void initSayMenu();
+ void eventConnectionStateChanged(Event_ConnectionStateChanged *event);
void eventSay(Event_Say *event);
void eventShuffle(Event_Shuffle *event);
void eventRollDie(Event_RollDie *event);
@@ -245,7 +248,7 @@ public:
qreal getMinimumWidth() const;
void setMirrored(bool _mirrored);
- void processSceneSizeChange(const QSizeF &newSize);
+ void processSceneSizeChange(int newPlayerWidth);
void processPlayerInfo(ServerInfo_Player *info);
void processCardAttachment(ServerInfo_Player *info);
diff --git a/cockatrice/src/priceupdater.cpp b/cockatrice/src/priceupdater.cpp
new file mode 100644
index 000000000..e9f1a6953
--- /dev/null
+++ b/cockatrice/src/priceupdater.cpp
@@ -0,0 +1,81 @@
+/**
+ * @author Marcio Ribeiro
+ * @version 1.0
+ */
+#include
+#include
+
+#include
+#include
+#include "priceupdater.h"
+
+/**
+ * Constructor.
+ *
+ * @param _deck deck.
+ */
+PriceUpdater::PriceUpdater(const DeckList *_deck)
+{
+ nam = new QNetworkAccessManager(this);
+ deck = _deck;
+}
+
+/**
+ * Update the prices of the cards in deckList.
+ */
+void PriceUpdater::updatePrices()
+{
+ QString q = "http://blacklotusproject.com/json/?cards=";
+ QStringList cards = deck->getCardList();
+ for (int i = 0; i < cards.size(); ++i) {
+ q += cards[i] + "|";
+ }
+ QUrl url(q.replace(' ', '+'));
+
+ QNetworkReply *reply = nam->get(QNetworkRequest(url));
+ connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+}
+
+/**
+ * Called when the download of the json file with the prices is finished.
+ */
+void PriceUpdater::downloadFinished()
+{
+ QMap cmap;
+ InnerDecklistNode *listRoot = deck->getRoot();
+ for (int i = 0; i < listRoot->size(); i++) {
+ InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i));
+ for (int j = 0; j < currentZone->size(); j++) {
+ DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j));
+ if (!currentCard)
+ continue;
+ cmap.insert(currentCard->getName().toLower(), currentCard);
+ currentCard->setPrice(0);
+ }
+ }
+
+ QNetworkReply *reply = static_cast(sender());
+ QByteArray result = reply->readAll();
+ QScriptValue sc;
+ QScriptEngine engine;
+ sc = engine.evaluate("value = " + result);
+
+ if (sc.property("cards").isArray()) {
+ QScriptValueIterator it(sc.property("cards"));
+ while (it.hasNext()) {
+ it.next();
+ QString name = it.value().property("name").toString().toLower();
+ float price = it.value().property("average").toString().toFloat();
+ DecklistCardNode *c = cmap[name];
+ if (!c)
+ continue;
+ if (c->getPrice() == 0 || c->getPrice() > price) {
+ c->setPrice(price);
+ }
+ }
+ }
+
+ reply->deleteLater();
+ deleteLater();
+ emit finishedUpdate();
+}
diff --git a/cockatrice/src/priceupdater.h b/cockatrice/src/priceupdater.h
new file mode 100644
index 000000000..a95252eb8
--- /dev/null
+++ b/cockatrice/src/priceupdater.h
@@ -0,0 +1,28 @@
+#ifndef PRICEUPDATER_H
+#define PRICEUPDATER_H
+
+#include
+#include "decklist.h"
+
+class QNetworkAccessManager;
+
+/**
+ * Price Updater.
+ *
+ * @author Marcio Ribeiro
+ */
+class PriceUpdater : public QObject
+{
+ Q_OBJECT
+private:
+ const DeckList *deck;
+ QNetworkAccessManager *nam;
+signals:
+ void finishedUpdate();
+private slots:
+ void downloadFinished();
+public:
+ PriceUpdater(const DeckList *deck);
+ void updatePrices();
+};
+#endif
diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp
index 2bb43b999..8f0844870 100644
--- a/cockatrice/src/remoteclient.cpp
+++ b/cockatrice/src/remoteclient.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include "remoteclient.h"
#include "protocol.h"
#include "protocol_items.h"
@@ -82,12 +83,13 @@ void RemoteClient::readData()
xmlWriter->writeStartDocument();
xmlWriter->writeStartElement("cockatrice_client_stream");
xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion));
+ xmlWriter->writeAttribute("comp", "1");
topLevelItem = new TopLevelProtocolItem;
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
setStatus(StatusLoggingIn);
- Command_Login *cmdLogin = new Command_Login(userName, password);
+ Command_Login *cmdLogin = new Command_Login(userName, QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1).toBase64());
connect(cmdLogin, SIGNAL(finished(ProtocolResponse *)), this, SLOT(loginResponse(ProtocolResponse *)));
sendCommand(cmdLogin);
}
diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp
index de7cb7bf7..8c3cee479 100644
--- a/cockatrice/src/settingscache.cpp
+++ b/cockatrice/src/settingscache.cpp
@@ -19,14 +19,21 @@ SettingsCache::SettingsCache()
picDownload = settings->value("personal/picturedownload", true).toBool();
doubleClickToPlay = settings->value("interface/doubleclicktoplay", true).toBool();
- cardInfoMinimized = settings->value("interface/cardinfominimized", false).toBool();
+ cardInfoMinimized = settings->value("interface/cardinfominimized", 0).toInt();
+ tabGameSplitterSizes = settings->value("interface/tabgame_splittersizes").toByteArray();
displayCardNames = settings->value("cards/displaycardnames", true).toBool();
horizontalHand = settings->value("hand/horizontal", true).toBool();
invertVerticalCoordinate = settings->value("table/invert_vertical", false).toBool();
+ minPlayersForMultiColumnLayout = settings->value("interface/min_players_multicolumn", 5).toInt();
tapAnimation = settings->value("cards/tapanimation", true).toBool();
zoneViewSortByName = settings->value("zoneview/sortbyname", true).toBool();
zoneViewSortByType = settings->value("zoneview/sortbytype", true).toBool();
+
+ soundEnabled = settings->value("sound/enabled", false).toBool();
+ soundPath = settings->value("sound/path").toString();
+
+ priceTagFeature = settings->value("deckeditor/pricetags", false).toBool();
}
void SettingsCache::setLang(const QString &_lang)
@@ -104,12 +111,18 @@ void SettingsCache::setDoubleClickToPlay(int _doubleClickToPlay)
settings->setValue("interface/doubleclicktoplay", doubleClickToPlay);
}
-void SettingsCache::setCardInfoMinimized(bool _cardInfoMinimized)
+void SettingsCache::setCardInfoMinimized(int _cardInfoMinimized)
{
- cardInfoMinimized = _cardInfoMinimized;
+ cardInfoMinimized = _cardInfoMinimized;
settings->setValue("interface/cardinfominimized", cardInfoMinimized);
}
+void SettingsCache::setTabGameSplitterSizes(const QByteArray &_tabGameSplitterSizes)
+{
+ tabGameSplitterSizes = _tabGameSplitterSizes;
+ settings->setValue("interface/tabgame_splittersizes", tabGameSplitterSizes);
+}
+
void SettingsCache::setDisplayCardNames(int _displayCardNames)
{
displayCardNames = _displayCardNames;
@@ -131,6 +144,13 @@ void SettingsCache::setInvertVerticalCoordinate(int _invertVerticalCoordinate)
emit invertVerticalCoordinateChanged();
}
+void SettingsCache::setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout)
+{
+ minPlayersForMultiColumnLayout = _minPlayersForMultiColumnLayout;
+ settings->setValue("interface/min_players_multicolumn", minPlayersForMultiColumnLayout);
+ emit minPlayersForMultiColumnLayoutChanged();
+}
+
void SettingsCache::setTapAnimation(int _tapAnimation)
{
tapAnimation = _tapAnimation;
@@ -148,3 +168,22 @@ void SettingsCache::setZoneViewSortByType(int _zoneViewSortByType)
zoneViewSortByType = _zoneViewSortByType;
settings->setValue("zoneview/sortbytype", zoneViewSortByType);
}
+
+void SettingsCache::setSoundEnabled(int _soundEnabled)
+{
+ soundEnabled = _soundEnabled;
+ settings->setValue("sound/enabled", soundEnabled);
+}
+
+void SettingsCache::setSoundPath(const QString &_soundPath)
+{
+ soundPath = _soundPath;
+ settings->setValue("sound/path", soundPath);
+ emit soundPathChanged();
+}
+
+void SettingsCache::setPriceTagFeature(int _priceTagFeature)
+{
+ priceTagFeature = _priceTagFeature;
+ settings->setValue("deckeditor/pricetags", priceTagFeature);
+}
diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h
index 607d572d9..b3f1ae6c0 100644
--- a/cockatrice/src/settingscache.h
+++ b/cockatrice/src/settingscache.h
@@ -20,6 +20,8 @@ signals:
void displayCardNamesChanged();
void horizontalHandChanged();
void invertVerticalCoordinateChanged();
+ void minPlayersForMultiColumnLayoutChanged();
+ void soundPathChanged();
private:
QSettings *settings;
@@ -28,12 +30,17 @@ private:
QString handBgPath, stackBgPath, tableBgPath, playerBgPath, cardBackPicturePath;
bool picDownload;
bool doubleClickToPlay;
- bool cardInfoMinimized;
+ int cardInfoMinimized;
+ QByteArray tabGameSplitterSizes;
bool displayCardNames;
bool horizontalHand;
bool invertVerticalCoordinate;
+ int minPlayersForMultiColumnLayout;
bool tapAnimation;
bool zoneViewSortByName, zoneViewSortByType;
+ bool soundEnabled;
+ QString soundPath;
+ bool priceTagFeature;
public:
SettingsCache();
QString getLang() const { return lang; }
@@ -47,13 +54,18 @@ public:
QString getCardBackPicturePath() const { return cardBackPicturePath; }
bool getPicDownload() const { return picDownload; }
bool getDoubleClickToPlay() const { return doubleClickToPlay; }
- bool getCardInfoMinimized() const { return cardInfoMinimized; }
+ int getCardInfoMinimized() const { return cardInfoMinimized; }
+ QByteArray getTabGameSplitterSizes() const { return tabGameSplitterSizes; }
bool getDisplayCardNames() const { return displayCardNames; }
bool getHorizontalHand() const { return horizontalHand; }
bool getInvertVerticalCoordinate() const { return invertVerticalCoordinate; }
+ int getMinPlayersForMultiColumnLayout() const { return minPlayersForMultiColumnLayout; }
bool getTapAnimation() const { return tapAnimation; }
bool getZoneViewSortByName() const { return zoneViewSortByName; }
bool getZoneViewSortByType() const { return zoneViewSortByType; }
+ bool getSoundEnabled() const { return soundEnabled; }
+ QString getSoundPath() const { return soundPath; }
+ bool getPriceTagFeature() const { return priceTagFeature; }
public slots:
void setLang(const QString &_lang);
void setDeckPath(const QString &_deckPath);
@@ -66,13 +78,18 @@ public slots:
void setCardBackPicturePath(const QString &_cardBackPicturePath);
void setPicDownload(int _picDownload);
void setDoubleClickToPlay(int _doubleClickToPlay);
- void setCardInfoMinimized(bool _cardInfoMinimized);
+ void setCardInfoMinimized(int _cardInfoMinimized);
+ void setTabGameSplitterSizes(const QByteArray &_tabGameSplitterSizes);
void setDisplayCardNames(int _displayCardNames);
void setHorizontalHand(int _horizontalHand);
void setInvertVerticalCoordinate(int _invertVerticalCoordinate);
+ void setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout);
void setTapAnimation(int _tapAnimation);
void setZoneViewSortByName(int _zoneViewSortByName);
void setZoneViewSortByType(int _zoneViewSortByType);
+ void setSoundEnabled(int _soundEnabled);
+ void setSoundPath(const QString &_soundPath);
+ void setPriceTagFeature(int _priceTagFeature);
};
extern SettingsCache *settingsCache;
diff --git a/cockatrice/src/soundengine.cpp b/cockatrice/src/soundengine.cpp
new file mode 100644
index 000000000..247567ccc
--- /dev/null
+++ b/cockatrice/src/soundengine.cpp
@@ -0,0 +1,82 @@
+#include "soundengine.h"
+#include "settingscache.h"
+#include
+#include
+#include
+#include
+
+SoundEngine::SoundEngine(QObject *parent)
+ : QObject(parent)
+{
+ inputBuffer = new QBuffer;
+ QAudioFormat format;
+ format.setFrequency(44100);
+ format.setChannels(1);
+ format.setSampleSize(16);
+ format.setCodec("audio/pcm");
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setSampleType(QAudioFormat::SignedInt);
+ audio = new QAudioOutput(format, this);
+
+ connect(settingsCache, SIGNAL(soundPathChanged()), this, SLOT(cacheData()));
+ cacheData();
+}
+
+void SoundEngine::cacheData()
+{
+ static const QStringList fileNames = QStringList()
+ << "notification" << "draw" << "playcard" << "shuffle" << "tap" << "untap" << "cuckoo";
+ for (int i = 0; i < fileNames.size(); ++i) {
+ QFile file(settingsCache->getSoundPath() + "/" + fileNames[i] + ".raw");
+ file.open(QIODevice::ReadOnly);
+ audioData.insert(fileNames[i], file.readAll());
+ file.close();
+ }
+}
+
+void SoundEngine::playSound(const QString &fileName)
+{
+ if (!settingsCache->getSoundEnabled())
+ return;
+
+ audio->stop();
+ inputBuffer->close();
+ inputBuffer->setData(audioData[fileName]);
+ inputBuffer->open(QIODevice::ReadOnly);
+ audio->start(inputBuffer);
+}
+
+void SoundEngine::notification()
+{
+ playSound("notification");
+}
+
+void SoundEngine::draw()
+{
+ playSound("draw");
+}
+
+void SoundEngine::playCard()
+{
+ playSound("playcard");
+}
+
+void SoundEngine::shuffle()
+{
+ playSound("shuffle");
+}
+
+void SoundEngine::tap()
+{
+ playSound("tap");
+}
+
+void SoundEngine::untap()
+{
+ playSound("untap");
+}
+
+void SoundEngine::cuckoo()
+{
+ playSound("cuckoo");
+}
diff --git a/cockatrice/src/soundengine.h b/cockatrice/src/soundengine.h
new file mode 100644
index 000000000..d65b3f2dd
--- /dev/null
+++ b/cockatrice/src/soundengine.h
@@ -0,0 +1,33 @@
+#ifndef SOUNDENGINE_H
+#define SOUNDENGINE_H
+
+#include
+#include
+
+class QAudioOutput;
+class QBuffer;
+
+class SoundEngine : public QObject {
+ Q_OBJECT
+private:
+ void playSound(const QString &fileName);
+ QMap audioData;
+ QBuffer *inputBuffer;
+ QAudioOutput *audio;
+private slots:
+ void cacheData();
+public:
+ SoundEngine(QObject *parent = 0);
+public slots:
+ void notification();
+ void draw();
+ void playCard();
+ void shuffle();
+ void tap();
+ void untap();
+ void cuckoo();
+};
+
+extern SoundEngine *soundEngine;
+
+#endif
\ No newline at end of file
diff --git a/cockatrice/src/tab.cpp b/cockatrice/src/tab.cpp
new file mode 100644
index 000000000..2eed9b546
--- /dev/null
+++ b/cockatrice/src/tab.cpp
@@ -0,0 +1,32 @@
+#include "tab.h"
+#include "cardinfowidget.h"
+#include
+#include
+
+Tab::Tab(TabSupervisor *_tabSupervisor, QWidget *parent)
+ : QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0)
+{
+}
+
+void Tab::showCardInfoPopup(const QPoint &pos, const QString &cardName)
+{
+ infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint);
+ infoPopup->setAttribute(Qt::WA_TransparentForMouseEvents);
+ infoPopup->setCard(cardName);
+ QRect screenRect = qApp->desktop()->screenGeometry(this);
+ infoPopup->move(
+ qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())),
+ qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height()))
+ );
+ infoPopup->show();
+}
+
+void Tab::deleteCardInfoPopup(const QString &cardName)
+{
+ if (infoPopup) {
+ if ((infoPopup->getCardName() == cardName) || (cardName == "_")) {
+ infoPopup->deleteLater();
+ infoPopup = 0;
+ }
+ }
+}
diff --git a/cockatrice/src/tab.h b/cockatrice/src/tab.h
index ac83ec593..3fefde1a1 100644
--- a/cockatrice/src/tab.h
+++ b/cockatrice/src/tab.h
@@ -5,24 +5,29 @@
class QMenu;
class TabSupervisor;
+class CardInfoWidget;
class Tab : public QWidget {
Q_OBJECT
signals:
- void userEvent();
+ void userEvent(bool globalEvent = true);
protected:
QMenu *tabMenu;
TabSupervisor *tabSupervisor;
+protected slots:
+ void showCardInfoPopup(const QPoint &pos, const QString &cardName);
+ void deleteCardInfoPopup(const QString &cardName);
private:
bool contentsChanged;
+ CardInfoWidget *infoPopup;
public:
- Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0)
- : QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false) { }
+ Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0);
QMenu *getTabMenu() const { return tabMenu; }
bool getContentsChanged() const { return contentsChanged; }
void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; }
virtual QString getTabText() const = 0;
virtual void retranslateUi() = 0;
+ virtual void closeRequest() { }
};
#endif
diff --git a/cockatrice/src/tab_admin.cpp b/cockatrice/src/tab_admin.cpp
index 4ea3a6527..082321384 100644
--- a/cockatrice/src/tab_admin.cpp
+++ b/cockatrice/src/tab_admin.cpp
@@ -1,19 +1,72 @@
+#include
#include
+#include
#include
#include
#include
+#include
+#include
+#include
#include "tab_admin.h"
#include "abstractclient.h"
#include "protocol_items.h"
-TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent)
- : Tab(_tabSupervisor, parent), locked(true), client(_client)
+ShutdownDialog::ShutdownDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ QLabel *reasonLabel = new QLabel(tr("&Reason for shutdown:"));
+ reasonEdit = new QLineEdit;
+ reasonLabel->setBuddy(reasonEdit);
+ QLabel *minutesLabel = new QLabel(tr("&Time until shutdown (minutes):"));
+ minutesEdit = new QSpinBox;
+ minutesLabel->setBuddy(minutesEdit);
+ minutesEdit->setMinimum(0);
+ minutesEdit->setValue(5);
+
+ QPushButton *okButton = new QPushButton(tr("&OK"));
+ okButton->setAutoDefault(true);
+ okButton->setDefault(true);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
+ QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(okButton);
+ buttonLayout->addWidget(cancelButton);
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addWidget(reasonLabel, 0, 0);
+ mainLayout->addWidget(reasonEdit, 0, 1);
+ mainLayout->addWidget(minutesLabel, 1, 0);
+ mainLayout->addWidget(minutesEdit, 1, 1);
+ mainLayout->addLayout(buttonLayout, 2, 0, 1, 2);
+
+ setLayout(mainLayout);
+ setWindowTitle(tr("Shut down server"));
+}
+
+QString ShutdownDialog::getReason() const
+{
+ return reasonEdit->text();
+}
+
+int ShutdownDialog::getMinutes() const
+{
+ return minutesEdit->value();
+}
+
+TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool _fullAdmin, QWidget *parent)
+ : Tab(_tabSupervisor, parent), locked(true), client(_client), fullAdmin(_fullAdmin)
{
updateServerMessageButton = new QPushButton;
connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage()));
+ shutdownServerButton = new QPushButton;
+ connect(shutdownServerButton, SIGNAL(clicked()), this, SLOT(actShutdownServer()));
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(updateServerMessageButton);
+ vbox->addWidget(shutdownServerButton);
vbox->addStretch();
adminGroupBox = new QGroupBox;
@@ -38,6 +91,7 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidg
void TabAdmin::retranslateUi()
{
updateServerMessageButton->setText(tr("Update server &message"));
+ shutdownServerButton->setText(tr("&Shut down server"));
adminGroupBox->setTitle(tr("Server administration functions"));
unlockButton->setText(tr("&Unlock functions"));
@@ -49,10 +103,18 @@ void TabAdmin::actUpdateServerMessage()
client->sendCommand(new Command_UpdateServerMessage());
}
+void TabAdmin::actShutdownServer()
+{
+ ShutdownDialog dlg;
+ if (dlg.exec())
+ client->sendCommand(new Command_ShutdownServer(dlg.getReason(), dlg.getMinutes()));
+}
+
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);
+ if (fullAdmin)
+ adminGroupBox->setEnabled(true);
lockButton->setEnabled(true);
unlockButton->setEnabled(false);
locked = false;
@@ -61,7 +123,8 @@ void TabAdmin::actUnlock()
void TabAdmin::actLock()
{
- adminGroupBox->setEnabled(false);
+ if (fullAdmin)
+ adminGroupBox->setEnabled(false);
lockButton->setEnabled(false);
unlockButton->setEnabled(true);
locked = true;
diff --git a/cockatrice/src/tab_admin.h b/cockatrice/src/tab_admin.h
index 8450d473b..a4982bbae 100644
--- a/cockatrice/src/tab_admin.h
+++ b/cockatrice/src/tab_admin.h
@@ -2,27 +2,43 @@
#define TAB_ADMIN_H
#include "tab.h"
+#include
class AbstractClient;
class QGroupBox;
class QPushButton;
+class QSpinBox;
+class QLineEdit;
+
+class ShutdownDialog : public QDialog {
+ Q_OBJECT
+private:
+ QLineEdit *reasonEdit;
+ QSpinBox *minutesEdit;
+public:
+ ShutdownDialog(QWidget *parent = 0);
+ QString getReason() const;
+ int getMinutes() const;
+};
class TabAdmin : public Tab {
Q_OBJECT
private:
bool locked;
AbstractClient *client;
- QPushButton *updateServerMessageButton;
+ bool fullAdmin;
+ QPushButton *updateServerMessageButton, *shutdownServerButton;
QGroupBox *adminGroupBox;
QPushButton *unlockButton, *lockButton;
private slots:
void actUpdateServerMessage();
+ void actShutdownServer();
void actUnlock();
void actLock();
public:
- TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent = 0);
+ TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool _fullAdmin, QWidget *parent = 0);
void retranslateUi();
QString getTabText() const { return tr("Administration"); }
bool getLocked() const { return locked; }
diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp
index fa608c29d..9b15e0deb 100644
--- a/cockatrice/src/tab_game.cpp
+++ b/cockatrice/src/tab_game.cpp
@@ -1,11 +1,10 @@
#include
#include
+#include
#include
#include
#include
#include
-#include
-#include
#include "tab_game.h"
#include "cardinfowidget.h"
#include "playerlistwidget.h"
@@ -159,8 +158,8 @@ void DeckViewContainer::setDeck(DeckList *deck)
readyStartButton->setEnabled(true);
}
-TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
- : Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1), infoPopup(0)
+TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, ServerInfo_User *_userInfo, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
+ : Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1)
{
phasesToolbar = new PhasesToolbar;
phasesToolbar->hide();
@@ -177,10 +176,10 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_client
timeElapsedLabel = new QLabel;
timeElapsedLabel->setAlignment(Qt::AlignCenter);
- messageLog = new MessageLogWidget;
+ messageLog = new MessageLogWidget(_userInfo->getName(), _userInfo->getGender() == ServerInfo_User::Female);
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
- connect(messageLog, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
+ connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
sayLabel = new QLabel;
sayEdit = new QLineEdit;
sayLabel->setBuddy(sayEdit);
@@ -191,17 +190,23 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_client
deckViewContainerLayout = new QVBoxLayout;
- QVBoxLayout *verticalLayout = new QVBoxLayout;
- verticalLayout->addWidget(cardInfo);
- verticalLayout->addWidget(playerListWidget, 1);
- verticalLayout->addWidget(timeElapsedLabel);
- verticalLayout->addWidget(messageLog, 5);
- verticalLayout->addLayout(hLayout);
+ QVBoxLayout *messageLogLayout = new QVBoxLayout;
+ messageLogLayout->addWidget(timeElapsedLabel);
+ messageLogLayout->addWidget(messageLog);
+ messageLogLayout->addLayout(hLayout);
+
+ QWidget *messageLogLayoutWidget = new QWidget;
+ messageLogLayoutWidget->setLayout(messageLogLayout);
+
+ splitter = new QSplitter(Qt::Vertical);
+ splitter->addWidget(cardInfo);
+ splitter->addWidget(playerListWidget);
+ splitter->addWidget(messageLogLayoutWidget);
mainLayout = new QHBoxLayout;
mainLayout->addWidget(gameView, 10);
mainLayout->addLayout(deckViewContainerLayout, 10);
- mainLayout->addLayout(verticalLayout);
+ mainLayout->addWidget(splitter);
if (spectator && !spectatorsCanTalk) {
sayLabel->hide();
@@ -253,12 +258,16 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_client
retranslateUi();
setLayout(mainLayout);
+
+ splitter->restoreState(settingsCache->getTabGameSplitterSizes());
messageLog->logGameJoined(gameId);
}
TabGame::~TabGame()
{
+ settingsCache->setTabGameSplitterSizes(splitter->saveState());
+
QMapIterator i(players);
while (i.hasNext())
delete i.next().value();
@@ -285,6 +294,7 @@ void TabGame::retranslateUi()
aConcede->setText(tr("&Concede"));
aConcede->setShortcut(tr("F2"));
aLeaveGame->setText(tr("&Leave game"));
+ aLeaveGame->setShortcut(tr("Ctrl+Q"));
sayLabel->setText(tr("&Say:"));
cardInfo->retranslateUi();
@@ -299,6 +309,11 @@ void TabGame::retranslateUi()
scene->retranslateUi();
}
+void TabGame::closeRequest()
+{
+ actLeaveGame();
+}
+
void TabGame::actConcede()
{
if (QMessageBox::question(this, tr("Concede"), tr("Are you sure you want to concede this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
@@ -309,8 +324,9 @@ void TabGame::actConcede()
void TabGame::actLeaveGame()
{
- if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
- return;
+ if (!spectator)
+ if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
+ return;
sendGameCommand(new Command_LeaveGame);
deleteLater();
@@ -729,7 +745,7 @@ void TabGame::newCardAdded(AbstractCardItem *card)
{
connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfo, SLOT(setCard(AbstractCardItem *)));
connect(card, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
- connect(card, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
+ connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
}
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
@@ -761,25 +777,3 @@ Player *TabGame::getActiveLocalPlayer() const
return 0;
}
-
-void TabGame::showCardInfoPopup(const QPoint &pos, const QString &cardName)
-{
- infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint);
- connect(infoPopup, SIGNAL(mouseReleased()), this, SLOT(deleteCardInfoPopup()));
- infoPopup->setCard(cardName);
- QRect screenRect = qApp->desktop()->screenGeometry(this);
- infoPopup->move(
- qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())),
- qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height()))
- );
- infoPopup->show();
- infoPopup->grabMouse();
-}
-
-void TabGame::deleteCardInfoPopup()
-{
- if (infoPopup) {
- infoPopup->deleteLater();
- infoPopup = 0;
- }
-}
diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h
index b11f857c0..a5eb5db9f 100644
--- a/cockatrice/src/tab_game.h
+++ b/cockatrice/src/tab_game.h
@@ -12,6 +12,7 @@ class DeckView;
class GameScene;
class CardInfoWidget;
class MessageLogWidget;
+class QSplitter;
class QLabel;
class QLineEdit;
class QPushButton;
@@ -98,7 +99,7 @@ private:
int currentPhase;
int activePlayer;
- CardInfoWidget *infoPopup;
+ QSplitter *splitter;
CardInfoWidget *cardInfo;
PlayerListWidget *playerListWidget;
QLabel *timeElapsedLabel;
@@ -145,8 +146,6 @@ signals:
void openMessageDialog(const QString &userName, bool focus);
private slots:
void newCardAdded(AbstractCardItem *card);
- void showCardInfoPopup(const QPoint &pos, const QString &cardName);
- void deleteCardInfoPopup();
void actConcede();
void actLeaveGame();
@@ -156,9 +155,10 @@ private slots:
void actNextPhase();
void actNextTurn();
public:
- TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
+ TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, ServerInfo_User *_userInfo, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
~TabGame();
void retranslateUi();
+ void closeRequest();
const QMap &getPlayers() const { return players; }
CardItem *getCard(int playerId, const QString &zoneName, int cardId) const;
int getGameId() const { return gameId; }
diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp
index 4581ad140..f4efd7f57 100644
--- a/cockatrice/src/tab_message.cpp
+++ b/cockatrice/src/tab_message.cpp
@@ -11,7 +11,9 @@
TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName)
: Tab(_tabSupervisor), client(_client), userName(_userName), userOnline(true)
{
- chatView = new ChatView(_ownName);
+ chatView = new ChatView(_ownName, true);
+ connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
+ connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
sayEdit = new QLineEdit;
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
@@ -40,6 +42,11 @@ void TabMessage::retranslateUi()
aLeave->setText(tr("&Leave"));
}
+void TabMessage::closeRequest()
+{
+ actLeave();
+}
+
void TabMessage::sendMessage()
{
if (sayEdit->text().isEmpty() || !userOnline)
diff --git a/cockatrice/src/tab_message.h b/cockatrice/src/tab_message.h
index 17856aa53..b8543704c 100644
--- a/cockatrice/src/tab_message.h
+++ b/cockatrice/src/tab_message.h
@@ -30,6 +30,7 @@ public:
TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName);
~TabMessage();
void retranslateUi();
+ void closeRequest();
QString getUserName() const { return userName; }
QString getTabText() const { return tr("Talking to %1").arg(userName); }
diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp
index 4e7770aea..7fbce5a7a 100644
--- a/cockatrice/src/tab_room.cpp
+++ b/cockatrice/src/tab_room.cpp
@@ -4,126 +4,17 @@
#include
#include
#include
-#include
#include
#include
-#include
#include
-#include "dlg_creategame.h"
+#include
#include "tab_supervisor.h"
#include "tab_room.h"
#include "userlist.h"
#include "abstractclient.h"
#include "protocol_items.h"
-#include "gamesmodel.h"
#include "chatview.h"
-
-GameSelector::GameSelector(AbstractClient *_client, TabRoom *_room, QWidget *parent)
- : QGroupBox(parent), client(_client), room(_room)
-{
- gameListView = new QTreeView;
- gameListModel = new GamesModel(room->getGameTypes(), this);
- gameListProxyModel = new GamesProxyModel(this);
- gameListProxyModel->setSourceModel(gameListModel);
- gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- gameListView->setModel(gameListProxyModel);
- gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
- gameListView->setSortingEnabled(true);
-
- 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((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5);
- 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, room->getRoomId(), room->getGameTypes(), 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;
- case RespUserLevelTooLow: QMessageBox::critical(this, tr("Error"), tr("This game is only open to registered users.")); break;
- case RespOnlyBuddies: QMessageBox::critical(this, tr("Error"), tr("This game is only open to its creator's buddies.")); break;
- case RespInIgnoreList: QMessageBox::critical(this, tr("Error"), tr("You are being ignored by the creator of this game.")); 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(room->getRoomId(), 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);
-}
+#include "gameselector.h"
TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info)
: Tab(_tabSupervisor), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName)
@@ -132,11 +23,15 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const Q
for (int i = 0; i < gameTypeList.size(); ++i)
gameTypes.insert(gameTypeList[i]->getGameTypeId(), gameTypeList[i]->getDescription());
- gameSelector = new GameSelector(client, this);
+ QMap tempMap;
+ tempMap.insert(info->getRoomId(), gameTypes);
+ gameSelector = new GameSelector(client, this, QMap(), tempMap);
userList = new UserList(tabSupervisor, client, UserList::RoomList);
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
- chatView = new ChatView(ownName);
+ chatView = new ChatView(ownName, true);
+ connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
+ connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
sayLabel = new QLabel;
sayEdit = new QLineEdit;
sayLabel->setBuddy(sayEdit);
@@ -153,12 +48,12 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const Q
chatGroupBox = new QGroupBox;
chatGroupBox->setLayout(chatVbox);
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(gameSelector);
- vbox->addWidget(chatGroupBox);
+ QSplitter *splitter = new QSplitter(Qt::Vertical);
+ splitter->addWidget(gameSelector);
+ splitter->addWidget(chatGroupBox);
QHBoxLayout *hbox = new QHBoxLayout;
- hbox->addLayout(vbox, 3);
+ hbox->addWidget(splitter, 3);
hbox->addWidget(userList, 1);
aLeaveRoom = new QAction(this);
@@ -193,6 +88,11 @@ void TabRoom::retranslateUi()
aLeaveRoom->setText(tr("&Leave room"));
}
+void TabRoom::closeRequest()
+{
+ actLeaveRoom();
+}
+
QString TabRoom::sanitizeHtml(QString dirty) const
{
return dirty
@@ -256,5 +156,5 @@ void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event)
void TabRoom::processSayEvent(Event_RoomSay *event)
{
chatView->appendMessage(event->getPlayerName(), event->getMessage());
- emit userEvent();
+ emit userEvent(false);
}
diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h
index 1b0133067..37e6a3d14 100644
--- a/cockatrice/src/tab_room.h
+++ b/cockatrice/src/tab_room.h
@@ -2,20 +2,16 @@
#define TAB_ROOM_H
#include "tab.h"
-#include "protocol_datastructures.h"
#include
+#include
class AbstractClient;
class UserList;
class QLabel;
class ChatView;
class QLineEdit;
-class QTreeView;
class QPushButton;
class QTextTable;
-class QCheckBox;
-class GamesModel;
-class GamesProxyModel;
class RoomEvent;
class ServerInfo_Room;
class ServerInfo_Game;
@@ -24,31 +20,7 @@ class Event_JoinRoom;
class Event_LeaveRoom;
class Event_RoomSay;
class ProtocolResponse;
-class TabRoom;
-
-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;
- TabRoom *room;
-
- QTreeView *gameListView;
- GamesModel *gameListModel;
- GamesProxyModel *gameListProxyModel;
- QPushButton *createButton, *joinButton, *spectateButton;
- QCheckBox *showFullGamesCheckBox;
-public:
- GameSelector(AbstractClient *_client, TabRoom *_room, QWidget *parent = 0);
- void retranslateUi();
- void processGameInfo(ServerInfo_Game *info);
-};
+class GameSelector;
class TabRoom : public Tab {
Q_OBJECT
@@ -84,6 +56,7 @@ public:
TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info);
~TabRoom();
void retranslateUi();
+ void closeRequest();
void processRoomEvent(RoomEvent *event);
int getRoomId() const { return roomId; }
const QMap &getGameTypes() const { return gameTypes; }
diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp
index 2d09bb124..824d149d9 100644
--- a/cockatrice/src/tab_supervisor.cpp
+++ b/cockatrice/src/tab_supervisor.cpp
@@ -11,8 +11,60 @@
#include "protocol_items.h"
#include "pixmapgenerator.h"
#include
+#include
-TabSupervisor:: TabSupervisor(QWidget *parent)
+CloseButton::CloseButton(QWidget *parent)
+ : QAbstractButton(parent)
+{
+ setFocusPolicy(Qt::NoFocus);
+ setCursor(Qt::ArrowCursor);
+ resize(sizeHint());
+}
+
+QSize CloseButton::sizeHint() const
+{
+ ensurePolished();
+ int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this);
+ int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this);
+ return QSize(width, height);
+}
+
+void CloseButton::enterEvent(QEvent *event)
+{
+ update();
+ QAbstractButton::enterEvent(event);
+}
+
+void CloseButton::leaveEvent(QEvent *event)
+{
+ update();
+ QAbstractButton::leaveEvent(event);
+}
+
+void CloseButton::paintEvent(QPaintEvent * /*event*/)
+{
+ QPainter p(this);
+ QStyleOption opt;
+ opt.init(this);
+ opt.state |= QStyle::State_AutoRaise;
+ if (isEnabled() && underMouse() && !isChecked() && !isDown())
+ opt.state |= QStyle::State_Raised;
+ if (isChecked())
+ opt.state |= QStyle::State_On;
+ if (isDown())
+ opt.state |= QStyle::State_Sunken;
+
+ if (const QTabBar *tb = qobject_cast(parent())) {
+ int index = tb->currentIndex();
+ QTabBar::ButtonPosition position = (QTabBar::ButtonPosition) style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tb);
+ if (tb->tabButton(index, position) == this)
+ opt.state |= QStyle::State_Selected;
+ }
+
+ style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
+}
+
+TabSupervisor::TabSupervisor(QWidget *parent)
: QTabWidget(parent), client(0), tabServer(0), tabDeckStorage(0), tabAdmin(0)
{
tabChangedIcon = new QIcon(":/resources/icon_tab_changed.svg");
@@ -47,17 +99,16 @@ void TabSupervisor::retranslateUi()
}
}
-void TabSupervisor::myAddTab(Tab *tab)
+int TabSupervisor::myAddTab(Tab *tab)
{
- connect(tab, SIGNAL(userEvent()), this, SLOT(tabUserEvent()));
- addTab(tab, tab->getTabText());
+ connect(tab, SIGNAL(userEvent(bool)), this, SLOT(tabUserEvent(bool)));
+ return addTab(tab, tab->getTabText());
}
-void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo)
+void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *_userInfo)
{
client = _client;
- userName = userInfo->getName();
- userLevel = userInfo->getUserLevel();
+ userInfo = new ServerInfo_User(_userInfo);
connect(client, SIGNAL(roomEventReceived(RoomEvent *)), this, SLOT(processRoomEvent(RoomEvent *)));
connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
@@ -83,8 +134,8 @@ void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo)
} else
tabDeckStorage = 0;
- if (userInfo->getUserLevel() & ServerInfo_User::IsAdmin) {
- tabAdmin = new TabAdmin(this, client);
+ if (userInfo->getUserLevel() & ServerInfo_User::IsModerator) {
+ tabAdmin = new TabAdmin(this, client, (userInfo->getUserLevel() & ServerInfo_User::IsAdmin));
myAddTab(tabAdmin);
} else
tabAdmin = 0;
@@ -94,6 +145,7 @@ void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo)
void TabSupervisor::startLocal(const QList &_clients)
{
+ userInfo = new ServerInfo_User;
localClients = _clients;
for (int i = 0; i < localClients.size(); ++i)
connect(localClients[i], SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
@@ -140,6 +192,9 @@ void TabSupervisor::stop()
while (messageIterator.hasNext())
messageIterator.next().value()->deleteLater();
messageTabs.clear();
+
+ delete userInfo;
+ userInfo = 0;
}
void TabSupervisor::updatePingTime(int value, int max)
@@ -152,21 +207,38 @@ void TabSupervisor::updatePingTime(int value, int max)
setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max)));
}
+void TabSupervisor::closeButtonPressed()
+{
+ Tab *tab = static_cast(static_cast(sender())->property("tab").value());
+ tab->closeRequest();
+}
+
+void TabSupervisor::addCloseButtonToTab(Tab *tab, int tabIndex)
+{
+ QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition) tabBar()->style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tabBar());
+ CloseButton *closeButton = new CloseButton;
+ connect(closeButton, SIGNAL(clicked()), this, SLOT(closeButtonPressed()));
+ closeButton->setProperty("tab", qVariantFromValue((QObject *) tab));
+ tabBar()->setTabButton(tabIndex, closeSide, closeButton);
+}
+
void TabSupervisor::gameJoined(Event_GameJoined *event)
{
- TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
+ TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), userInfo, event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
- myAddTab(tab);
+ int tabIndex = myAddTab(tab);
+ addCloseButtonToTab(tab, tabIndex);
gameTabs.insert(event->getGameId(), tab);
setCurrentWidget(tab);
}
void TabSupervisor::localGameJoined(Event_GameJoined *event)
{
- TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
+ TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), userInfo, event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
- myAddTab(tab);
+ int tabIndex = myAddTab(tab);
+ addCloseButtonToTab(tab, tabIndex);
gameTabs.insert(event->getGameId(), tab);
setCurrentWidget(tab);
@@ -189,10 +261,11 @@ void TabSupervisor::gameLeft(TabGame *tab)
void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent)
{
- TabRoom *tab = new TabRoom(this, client, userName, info);
+ TabRoom *tab = new TabRoom(this, client, userInfo->getName(), info);
connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *)));
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
- myAddTab(tab);
+ int tabIndex = myAddTab(tab);
+ addCloseButtonToTab(tab, tabIndex);
roomTabs.insert(info->getRoomId(), tab);
if (setCurrent)
setCurrentWidget(tab);
@@ -208,12 +281,13 @@ void TabSupervisor::roomLeft(TabRoom *tab)
TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus)
{
- if (receiverName == userName)
+ if (receiverName == userInfo->getName())
return 0;
- TabMessage *tab = new TabMessage(this, client, userName, receiverName);
+ TabMessage *tab = new TabMessage(this, client, userInfo->getName(), receiverName);
connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *)));
- myAddTab(tab);
+ int tabIndex = myAddTab(tab);
+ addCloseButtonToTab(tab, tabIndex);
messageTabs.insert(receiverName, tab);
if (focus)
setCurrentWidget(tab);
@@ -228,14 +302,15 @@ void TabSupervisor::talkLeft(TabMessage *tab)
removeTab(indexOf(tab));
}
-void TabSupervisor::tabUserEvent()
+void TabSupervisor::tabUserEvent(bool globalEvent)
{
Tab *tab = static_cast(sender());
if (tab != currentWidget()) {
tab->setContentsChanged(true);
setTabIcon(indexOf(tab), *tabChangedIcon);
}
- QApplication::alert(this);
+ if (globalEvent)
+ QApplication::alert(this);
}
void TabSupervisor::processRoomEvent(RoomEvent *event)
@@ -300,3 +375,8 @@ bool TabSupervisor::getAdminLocked() const
return true;
return tabAdmin->getLocked();
}
+
+int TabSupervisor::getUserLevel() const
+{
+ return userInfo->getUserLevel();
+}
diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h
index 087d93270..0a38d5f83 100644
--- a/cockatrice/src/tab_supervisor.h
+++ b/cockatrice/src/tab_supervisor.h
@@ -3,6 +3,7 @@
#include
#include
+#include
class QMenu;
class AbstractClient;
@@ -21,11 +22,22 @@ class Event_Message;
class ServerInfo_Room;
class ServerInfo_User;
+class CloseButton : public QAbstractButton {
+ Q_OBJECT
+public:
+ CloseButton(QWidget *parent = 0);
+ QSize sizeHint() const;
+ inline QSize minimumSizeHint() const { return sizeHint(); }
+protected:
+ void enterEvent(QEvent *event);
+ void leaveEvent(QEvent *event);
+ void paintEvent(QPaintEvent *event);
+};
+
class TabSupervisor : public QTabWidget {
Q_OBJECT
private:
- QString userName;
- int userLevel;
+ ServerInfo_User *userInfo;
QIcon *tabChangedIcon;
AbstractClient *client;
QList localClients;
@@ -36,7 +48,8 @@ private:
QMap roomTabs;
QMap gameTabs;
QMap messageTabs;
- void myAddTab(Tab *tab);
+ int myAddTab(Tab *tab);
+ void addCloseButtonToTab(Tab *tab, int tabIndex);
public:
TabSupervisor(QWidget *parent = 0);
~TabSupervisor();
@@ -47,11 +60,12 @@ public:
int getGameCount() const { return gameTabs.size(); }
TabUserLists *getUserListsTab() const { return tabUserLists; }
bool getAdminLocked() const;
- int getUserLevel() const { return userLevel; }
+ int getUserLevel() const;
signals:
void setMenu(QMenu *menu);
void localGameEnded();
private slots:
+ void closeButtonPressed();
void updateCurrent(int index);
void updatePingTime(int value, int max);
void gameJoined(Event_GameJoined *event);
@@ -63,7 +77,7 @@ private slots:
void processUserLeft(const QString &userName);
void processUserJoined(const QString &userName);
void talkLeft(TabMessage *tab);
- void tabUserEvent();
+ void tabUserEvent(bool globalEvent);
void processRoomEvent(RoomEvent *event);
void processGameEventContainer(GameEventContainer *cont);
void processMessageEvent(Event_Message *event);
diff --git a/cockatrice/src/userinfobox.cpp b/cockatrice/src/userinfobox.cpp
index 40b4b0126..53b319c09 100644
--- a/cockatrice/src/userinfobox.cpp
+++ b/cockatrice/src/userinfobox.cpp
@@ -17,6 +17,8 @@ UserInfoBox::UserInfoBox(AbstractClient *_client, bool _fullInfo, QWidget *paren
nameLabel->setFont(nameFont);
realNameLabel1 = new QLabel;
realNameLabel2 = new QLabel;
+ genderLabel1 = new QLabel;
+ genderLabel2 = new QLabel;
countryLabel1 = new QLabel;
countryLabel2 = new QLabel;
userLevelLabel1 = new QLabel;
@@ -28,11 +30,13 @@ UserInfoBox::UserInfoBox(AbstractClient *_client, bool _fullInfo, QWidget *paren
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->addWidget(genderLabel1, 3, 0, 1, 1);
+ mainLayout->addWidget(genderLabel2, 3, 1, 1, 2);
+ mainLayout->addWidget(countryLabel1, 4, 0, 1, 1);
+ mainLayout->addWidget(countryLabel2, 4, 1, 1, 2);
+ mainLayout->addWidget(userLevelLabel1, 5, 0, 1, 1);
+ mainLayout->addWidget(userLevelLabel2, 5, 1, 1, 1);
+ mainLayout->addWidget(userLevelLabel3, 5, 2, 1, 1);
mainLayout->setColumnStretch(2, 10);
setWindowTitle(tr("User information"));
@@ -43,6 +47,7 @@ UserInfoBox::UserInfoBox(AbstractClient *_client, bool _fullInfo, QWidget *paren
void UserInfoBox::retranslateUi()
{
realNameLabel1->setText(tr("Real name:"));
+ genderLabel1->setText(tr("Gender:"));
countryLabel1->setText(tr("Location:"));
userLevelLabel1->setText(tr("User level:"));
}
@@ -58,13 +63,14 @@ void UserInfoBox::updateInfo(ServerInfo_User *user)
nameLabel->setText(user->getName());
realNameLabel2->setText(user->getRealName());
+ genderLabel2->setPixmap(GenderPixmapGenerator::generatePixmap(15, user->getGender()));
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::IsModerator)
+ userLevelText = tr("Moderator");
else if (userLevel & ServerInfo_User::IsRegistered)
userLevelText = tr("Registered user");
else
diff --git a/cockatrice/src/userinfobox.h b/cockatrice/src/userinfobox.h
index adf5f832c..ee4fd6043 100644
--- a/cockatrice/src/userinfobox.h
+++ b/cockatrice/src/userinfobox.h
@@ -13,7 +13,7 @@ class UserInfoBox : public QWidget {
private:
AbstractClient *client;
bool fullInfo;
- QLabel *avatarLabel, *nameLabel, *realNameLabel1, *realNameLabel2, *countryLabel1, *countryLabel2, *userLevelLabel1, *userLevelLabel2, *userLevelLabel3;
+ QLabel *avatarLabel, *nameLabel, *realNameLabel1, *realNameLabel2, *genderLabel1, *genderLabel2, *countryLabel1, *countryLabel2, *userLevelLabel1, *userLevelLabel2, *userLevelLabel3;
public:
UserInfoBox(AbstractClient *_client, bool fullInfo, QWidget *parent = 0, Qt::WindowFlags flags = 0);
void retranslateUi();
diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp
index b63c68054..71101f481 100644
--- a/cockatrice/src/userlist.cpp
+++ b/cockatrice/src/userlist.cpp
@@ -5,11 +5,59 @@
#include "pixmapgenerator.h"
#include "userinfobox.h"
#include "protocol_items.h"
+#include "gameselector.h"
#include
#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+
+BanDialog::BanDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ QLabel *durationLabel = new QLabel(tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."));
+ durationEdit = new QSpinBox;
+ durationEdit->setMinimum(0);
+ durationEdit->setValue(5);
+ QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person."));
+ reasonEdit = new QPlainTextEdit;
+
+ QPushButton *okButton = new QPushButton(tr("&OK"));
+ okButton->setAutoDefault(true);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
+ QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(okButton);
+ buttonLayout->addWidget(cancelButton);
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(durationLabel);
+ vbox->addWidget(durationEdit);
+ vbox->addWidget(reasonLabel);
+ vbox->addWidget(reasonEdit);
+ vbox->addLayout(buttonLayout);
+
+ setLayout(vbox);
+ setWindowTitle(tr("Ban user from server"));
+}
+
+int BanDialog::getMinutes() const
+{
+ return durationEdit->value();
+}
+
+QString BanDialog::getReason() const
+{
+ return reasonEdit->toPlainText();
+}
UserListItemDelegate::UserListItemDelegate(QObject *const parent)
: QStyledItemDelegate(parent)
@@ -59,6 +107,7 @@ UserList::UserList(TabSupervisor *_tabSupervisor, AbstractClient *_client, UserL
userTree->setRootIsDecorated(false);
userTree->setIconSize(QSize(20, 12));
userTree->setItemDelegate(itemDelegate);
+ userTree->setAlternatingRowColors(true);
connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
QVBoxLayout *vbox = new QVBoxLayout;
@@ -163,6 +212,35 @@ void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
}
+void UserList::gamesOfUserReceived(ProtocolResponse *resp)
+{
+ Command_GetGamesOfUser *command = static_cast(sender());
+ Response_GetGamesOfUser *response = qobject_cast(resp);
+ if (!response)
+ return;
+
+ QMap gameTypeMap;
+ QMap roomMap;
+ const QList roomList = response->getRoomList();
+ for (int i = 0; i < roomList.size(); ++i) {
+ roomMap.insert(roomList[i]->getRoomId(), roomList[i]->getName());
+ const QList gameTypeList = roomList[i]->getGameTypeList();
+ GameTypeMap tempMap;
+ for (int j = 0; j < gameTypeList.size(); ++j)
+ tempMap.insert(gameTypeList[j]->getGameTypeId(), gameTypeList[j]->getDescription());
+ gameTypeMap.insert(roomList[i]->getRoomId(), tempMap);
+ }
+
+ GameSelector *selector = new GameSelector(client, 0, roomMap, gameTypeMap);
+ const QList gameList = response->getGameList();
+ for (int i = 0; i < gameList.size(); ++i)
+ selector->processGameInfo(gameList[i]);
+
+ selector->setWindowTitle(tr("%1's games").arg(command->getUserName()));
+ selector->setAttribute(Qt::WA_DeleteOnClose);
+ selector->show();
+}
+
void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
{
const QString &userName = index.sibling(index.row(), 2).data(Qt::UserRole).toString();
@@ -172,6 +250,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
aUserName->setEnabled(false);
QAction *aDetails = new QAction(tr("User &details"), this);
QAction *aChat = new QAction(tr("Direct &chat"), this);
+ QAction *aShowGames = new QAction(tr("Show this user's &games"), this);
QAction *aAddToBuddyList = new QAction(tr("Add to &buddy list"), this);
QAction *aRemoveFromBuddyList = new QAction(tr("Remove from &buddy list"), this);
QAction *aAddToIgnoreList = new QAction(tr("Add to &ignore list"), this);
@@ -182,6 +261,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
menu->addAction(aUserName);
menu->addSeparator();
menu->addAction(aDetails);
+ menu->addAction(aShowGames);
menu->addAction(aChat);
if ((userLevel & ServerInfo_User::IsRegistered) && (tabSupervisor->getUserLevel() & ServerInfo_User::IsRegistered)) {
menu->addSeparator();
@@ -210,14 +290,18 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
client->sendCommand(new Command_AddToList("buddy", userName));
else if (actionClicked == aRemoveFromBuddyList)
client->sendCommand(new Command_RemoveFromList("buddy", userName));
- else if (actionClicked == aAddToIgnoreList)
+ else if (actionClicked == aShowGames) {
+ Command *cmd = new Command_GetGamesOfUser(userName);
+ connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(gamesOfUserReceived(ProtocolResponse *)));
+ client->sendCommand(cmd);
+ } else if (actionClicked == aAddToIgnoreList)
client->sendCommand(new Command_AddToList("ignore", userName));
else if (actionClicked == aRemoveFromIgnoreList)
client->sendCommand(new Command_RemoveFromList("ignore", userName));
else if (actionClicked == aBan) {
- bool ok;
- int minutes = QInputDialog::getInt(this, tr("Duration"), tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."), 0, 0, 2147483647, 10, &ok);
- client->sendCommand(new Command_BanFromServer(userName, minutes));
+ BanDialog dlg(this);
+ if (dlg.exec())
+ client->sendCommand(new Command_BanFromServer(userName, dlg.getMinutes(), dlg.getReason()));
}
delete menu;
diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h
index a611bf5de..c71ddc31e 100644
--- a/cockatrice/src/userlist.h
+++ b/cockatrice/src/userlist.h
@@ -1,6 +1,7 @@
#ifndef USERLIST_H
#define USERLIST_H
+#include
#include
#include
#include
@@ -9,6 +10,20 @@ class QTreeWidget;
class ServerInfo_User;
class AbstractClient;
class TabSupervisor;
+class QSpinBox;
+class QPlainTextEdit;
+class ProtocolResponse;
+
+class BanDialog : public QDialog {
+ Q_OBJECT
+private:
+ QSpinBox *durationEdit;
+ QPlainTextEdit *reasonEdit;
+public:
+ BanDialog(QWidget *parent = 0);
+ int getMinutes() const;
+ QString getReason() const;
+};
class UserListItemDelegate : public QStyledItemDelegate {
public:
@@ -38,6 +53,7 @@ private:
void setUserOnline(QTreeWidgetItem *user, bool online);
private slots:
void userClicked(QTreeWidgetItem *item, int column);
+ void gamesOfUserReceived(ProtocolResponse *resp);
signals:
void openMessageDialog(const QString &userName, bool focus);
void addBuddy(const QString &userName);
diff --git a/cockatrice/src/window_deckeditor.cpp b/cockatrice/src/window_deckeditor.cpp
index 2822df52d..acb3bf541 100644
--- a/cockatrice/src/window_deckeditor.cpp
+++ b/cockatrice/src/window_deckeditor.cpp
@@ -26,6 +26,7 @@
#include "dlg_load_deck_from_clipboard.h"
#include "main.h"
#include "settingscache.h"
+#include "priceupdater.h"
void SearchLineEdit::keyPressEvent(QKeyEvent *event)
{
@@ -68,6 +69,7 @@ WndDeckEditor::WndDeckEditor(QWidget *parent)
databaseView = new QTreeView();
databaseView->setModel(databaseDisplayModel);
databaseView->setUniformRowHeights(true);
+ databaseView->setRootIsDecorated(false);
databaseView->setAlternatingRowColors(true);
databaseView->setSortingEnabled(true);
databaseView->sortByColumn(0, Qt::AscendingOrder);
@@ -112,15 +114,37 @@ WndDeckEditor::WndDeckEditor(QWidget *parent)
commentsEdit->setMaximumHeight(70);
commentsLabel->setBuddy(commentsEdit);
connect(commentsEdit, SIGNAL(textChanged()), this, SLOT(updateComments()));
+
QGridLayout *grid = new QGridLayout;
grid->addWidget(nameLabel, 0, 0);
grid->addWidget(nameEdit, 0, 1);
+
grid->addWidget(commentsLabel, 1, 0);
grid->addWidget(commentsEdit, 1, 1);
+ // Update price
+ aUpdatePrices = new QAction(tr("&Update prices"), this);
+ aUpdatePrices->setShortcut(tr("Ctrl+U"));
+ aUpdatePrices->setIcon(QIcon(":/resources/icon_update.png"));
+ connect(aUpdatePrices, SIGNAL(triggered()), this, SLOT(actUpdatePrices()));
+ if (!settingsCache->getPriceTagFeature())
+ aUpdatePrices->setVisible(false);
+
+ QToolBar *deckToolBar = new QToolBar;
+ deckToolBar->setOrientation(Qt::Vertical);
+ deckToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ deckToolBar->setIconSize(QSize(24, 24));
+ deckToolBar->addAction(aUpdatePrices);
+ QHBoxLayout *deckToolbarLayout = new QHBoxLayout;
+ deckToolbarLayout->addStretch();
+ deckToolbarLayout->addWidget(deckToolBar);
+ deckToolbarLayout->addStretch();
+
+
QVBoxLayout *rightFrame = new QVBoxLayout;
rightFrame->addLayout(grid);
rightFrame->addWidget(deckView);
+ rightFrame->addLayout(deckToolbarLayout);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftFrame, 10);
@@ -456,6 +480,21 @@ void WndDeckEditor::actDecrement()
setWindowModified(true);
}
+void WndDeckEditor::actUpdatePrices()
+{
+ aUpdatePrices->setDisabled(true);
+ PriceUpdater *up = new PriceUpdater(deckModel->getDeckList());
+ connect(up, SIGNAL(finishedUpdate()), this, SLOT(finishedUpdatingPrices()));
+ up->updatePrices();
+}
+
+void WndDeckEditor::finishedUpdatingPrices()
+{
+ deckModel->pricesUpdated();
+ setWindowModified(true);
+ aUpdatePrices->setDisabled(false);
+}
+
void WndDeckEditor::setDeck(DeckList *_deck, const QString &_lastFileName, DeckList::FileFormat _lastFileFormat)
{
deckModel->setDeckList(_deck);
diff --git a/cockatrice/src/window_deckeditor.h b/cockatrice/src/window_deckeditor.h
index e14c16331..92a90bb99 100644
--- a/cockatrice/src/window_deckeditor.h
+++ b/cockatrice/src/window_deckeditor.h
@@ -52,6 +52,9 @@ private slots:
void actRemoveCard();
void actIncrement();
void actDecrement();
+ void actUpdatePrices();
+
+ void finishedUpdatingPrices();
private:
void addCardHelper(const QString &zoneName);
void recursiveExpand(const QModelIndex &index);
@@ -74,7 +77,7 @@ private:
QMenu *deckMenu, *dbMenu;
QAction *aNewDeck, *aLoadDeck, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, *aSaveDeckToClipboard, *aPrintDeck, *aClose;
QAction *aEditSets, *aSearch, *aClearSearch;
- QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement;
+ QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement, *aUpdatePrices;
public:
WndDeckEditor(QWidget *parent = 0);
~WndDeckEditor();
diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp
index df1fedbc4..7acbe5510 100644
--- a/cockatrice/src/window_main.cpp
+++ b/cockatrice/src/window_main.cpp
@@ -56,11 +56,18 @@ void MainWindow::processConnectionClosedEvent(Event_ConnectionClosed *event)
reasonStr = tr("There are too many concurrent connections from your address.");
else if (reason == "banned")
reasonStr = tr("Banned by moderator.");
+ else if (reason == "server_shutdown")
+ reasonStr = tr("Scheduled server shutdown.");
else
reasonStr = tr("Unknown reason.");
QMessageBox::critical(this, tr("Connection closed"), tr("The server has terminated your connection.\nReason: %1").arg(reasonStr));
}
+void MainWindow::processServerShutdownEvent(Event_ServerShutdown *event)
+{
+ QMessageBox::information(this, tr("Scheduled server shutdown"), tr("The server is going to be restarted in %n minute(s).\nAll running games will be lost.\nReason for shutdown: %1", "", event->getMinutes()).arg(event->getReason()));
+}
+
void MainWindow::statusChanged(ClientStatus _status)
{
setClientStatusTitle();
@@ -178,6 +185,8 @@ void MainWindow::actAbout()
+ tr("French:") + " Yannick Hammer, Arnaud Faes
"
+ tr("Japanese:") + " Nagase Task
"
+ tr("Russian:") + " Alexander Davidov
"
+ + tr("Czech:") + " Ondřej Trhoň
"
+ + tr("Slovak:") + " Ganjalf Rendy
"
));
}
@@ -288,6 +297,7 @@ MainWindow::MainWindow(QWidget *parent)
client = new RemoteClient(this);
connect(client, SIGNAL(connectionClosedEventReceived(Event_ConnectionClosed *)), this, SLOT(processConnectionClosedEvent(Event_ConnectionClosed *)));
+ connect(client, SIGNAL(serverShutdownEventReceived(Event_ServerShutdown *)), this, SLOT(processServerShutdownEvent(Event_ServerShutdown *)));
connect(client, SIGNAL(serverError(ResponseCode)), this, SLOT(serverError(ResponseCode)));
connect(client, SIGNAL(socketError(const QString &)), this, SLOT(socketError(const QString &)));
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h
index 9ca62ba84..4d8b45d60 100644
--- a/cockatrice/src/window_main.h
+++ b/cockatrice/src/window_main.h
@@ -36,6 +36,7 @@ private slots:
void updateTabMenu(QMenu *menu);
void statusChanged(ClientStatus _status);
void processConnectionClosedEvent(Event_ConnectionClosed *event);
+ void processServerShutdownEvent(Event_ServerShutdown *event);
void serverTimeout();
void serverError(ResponseCode r);
void socketError(const QString &errorStr);
diff --git a/cockatrice/translations/cockatrice_cs.ts b/cockatrice/translations/cockatrice_cs.ts
new file mode 100644
index 000000000..61567e4fb
--- /dev/null
+++ b/cockatrice/translations/cockatrice_cs.ts
@@ -0,0 +1,4423 @@
+
+
+
+
+ AbstractCounter
+
+
+ &Set counter...
+ &Nastavit žeton...
+
+
+
+ Ctrl+L
+ Ctrl+L
+
+
+
+ F11
+ F11
+
+
+
+ F12
+ F12
+
+
+
+ Set counter
+ Nastavit žeton
+
+
+
+ New value for counter '%1':
+ Nová hodnota pro žeton '%1':
+
+
+
+ AppearanceSettingsPage
+
+
+ Zone background pictures
+ Pozadí zón
+
+
+
+ Path to hand background:
+ Cesta k pozadí ruky:
+
+
+
+ Path to stack background:
+ Cesta k pozadí stacku:
+
+
+
+ Path to table background:
+ Cesta k pozadí stolu:
+
+
+
+ Path to player info background:
+ Cesta k pozadí informací o uživateli:
+
+
+
+ Path to picture of card back:
+ Cesta k rubu karet:
+
+
+
+ Card rendering
+ Vykreslování karet
+
+
+
+ Display card names on cards having a picture
+ Zobrazit jména karet na kartách s obrázky
+
+
+
+ Hand layout
+ Rozvržení ruky
+
+
+
+ Display hand horizontally (wastes space)
+ Zobrazit ruku horizontálně (zabírá více místa)
+
+
+
+ Table grid layout
+ Rozložení herní mřížky
+
+
+
+ Invert vertical coordinate
+ Převrátit vertikální souřadnice
+
+
+
+ Minimum player count for multi-column layout:
+
+
+
+
+ Zone view layout
+ Rozvržení zón
+
+
+
+ Sort by name
+ Seřadit dle jména
+
+
+
+ Sort by type
+ Seřadit dle typu
+
+
+
+
+
+
+
+ Choose path
+ Vyberte cestu
+
+
+
+ BanDialog
+
+
+ Please enter the duration of the ban (in minutes).
+Enter 0 for an indefinite ban.
+ Vložte dobu trvání banu (v minutách).
+Hodnota 0 je pro ban bez omezení.
+
+
+
+ Please enter the reason for the ban.
+This is only saved for moderators and cannot be seen by the banned person.
+
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+
+
+
+
+ Ban user from server
+
+
+
+
+ CardDatabaseModel
+
+
+ Name
+ Jméno
+
+
+
+ Sets
+ Sady
+
+
+
+ Mana cost
+ Sesílací cena
+
+
+
+ Card type
+ Typ karty
+
+
+
+ P/T
+ S/O
+
+
+
+ CardInfoWidget
+
+
+ Hide card info
+ Skrýt informace o kartě
+
+
+
+ Show card only
+ Zobrazit pouze kartu
+
+
+
+ Show text only
+ Zobrazit pouze text
+
+
+
+ Show full info
+ Zobrazit všechny informace
+
+
+
+ Name:
+ Jméno:
+
+
+
+ Mana cost:
+ Sesílací cena:
+
+
+
+ Card type:
+ Typ karty:
+
+
+
+ P / T:
+ S / O:
+
+
+
+ CardItem
+
+
+ &Play
+ &Zahrát
+
+
+
+ &Hide
+ &Skrýt
+
+
+
+ &Tap
+ &Tapnout
+
+
+
+ &Untap
+ &Odtapnout
+
+
+
+ Toggle &normal untapping
+ Přepnout &normální odtapnutí
+
+
+
+ &Flip
+ &Otočit
+
+
+
+ &Clone
+ &Zdvojit
+
+
+
+ Ctrl+H
+ Ctrl+H
+
+
+
+ &Attach to card...
+ Připojit ke k&artě...
+
+
+
+ Ctrl+A
+ Ctrl+A
+
+
+
+ Unattac&h
+ Od&pojit
+
+
+
+ &Draw arrow...
+
+
+
+
+ &Power / toughness
+ &Síla / odolnost
+
+
+
+ &Increase power
+ &Zvýšit sílu
+
+
+
+ Ctrl++
+ Ctrl++
+
+
+
+ &Decrease power
+ &Snížit sílu
+
+
+
+ Ctrl+-
+ Ctrl+-
+
+
+
+ I&ncrease toughness
+ &Zvýšit odolnost
+
+
+
+ Alt++
+ Alt++
+
+
+
+ D&ecrease toughness
+ &Snížit sílu
+
+
+
+ Alt+-
+ Alt+-
+
+
+
+ In&crease power and toughness
+ &Zvýšit sílu a odolnost
+
+
+
+ Ctrl+Alt++
+ Ctrl+Alt++
+
+
+
+ Dec&rease power and toughness
+ &Snížit sílu a odolnost
+
+
+
+ Ctrl+Alt+-
+ Ctrl+Alt+-
+
+
+
+ Set &power and toughness...
+ Nastavit &sílu a odolnost...
+
+
+
+ Ctrl+P
+ Ctrl+P
+
+
+
+ &Set annotation...
+ Na&stavit poznámku...
+
+
+
+ red
+ červená
+
+
+
+ yellow
+ žlutá
+
+
+
+ green
+ zelená
+
+
+
+ &Add counter (%1)
+ Přid&at žeton (%1)
+
+
+
+ &Remove counter (%1)
+ Odst&ranit žeton (%1)
+
+
+
+ &Set counters (%1)...
+ Na&stavit žetony (%1)...
+
+
+
+ &top of library
+ &vršek knihovny
+
+
+
+ &bottom of library
+ &spodek knihovny
+
+
+
+ &graveyard
+ &hřbitov
+
+
+
+ Ctrl+Del
+ Ctrl+Del
+
+
+
+ &exile
+ &exilnout
+
+
+
+ &Move to
+ &Přesunout
+
+
+
+ CardZone
+
+ his hand
+ nominative
+ jeho ruka
+
+
+ %1's hand
+ nominative
+ ruka hráče %1
+
+
+ of his hand
+ genitive
+ jeho ruky
+
+
+ of %1's hand
+ genitive
+ ruky hráče %1
+
+
+ his hand
+ accusative
+ jeho ruka
+
+
+ %1's hand
+ accusative
+ ruka hráče %1
+
+
+ his library
+ nominative
+ knihovna
+
+
+ %1's library
+ nominative
+ knihovna hráče %1
+
+
+ of his library
+ genitive
+ jeho knihovny
+
+
+ of %1's library
+ genitive
+ knihovny hráče %1
+
+
+ his library
+ accusative
+ knihovnu
+
+
+ %1's library
+ accusative
+ knihovna hráče %1
+
+
+ his graveyard
+ nominative
+ jeho hřbitov
+
+
+ %1's graveyard
+ nominative
+ hřbitov hráče %1
+
+
+ of his graveyard
+ genitive
+ jeho hřbitova
+
+
+ of %1's graveyard
+ genitive
+ hřbitova hráče %1
+
+
+ his graveyard
+ accusative
+ jeho hřbitov
+
+
+ %1's graveyard
+ accusative
+ hřbitov hráče %1
+
+
+ his exile
+ nominative
+ jeho exilnuté karty
+
+
+ %1's exile
+ nominative
+ exilnuté karty hráče %1
+
+
+ of his exile
+ genitive
+ exilnutých karet
+
+
+ of %1's exile
+ genitive
+ exilnutých karet hráče %1
+
+
+ his exile
+ accusative
+ jeho exilnuté karty
+
+
+ %1's exile
+ accusative
+ exilnuté karty hráče %1
+
+
+ his sideboard
+ nominative
+ jeho sideboard
+
+
+ %1's sideboard
+ nominative
+ sideboard hráče %1
+
+
+ of his sideboard
+ genitive
+ sideboardu hráče
+
+
+ of %1's sideboard
+ genitive
+ sideboardu hráče %1
+
+
+ his sideboard
+ accusative
+ jeho sideboard
+
+
+ %1's sideboard
+ accusative
+ sideboard hráče %1
+
+
+
+ her hand
+ nominative, female owner
+
+
+
+
+ %1's hand
+ nominative, female owner
+ ruka hráče %1
+
+
+
+ his hand
+ nominative, male owner
+ jeho ruka
+
+
+
+ %1's hand
+ nominative, male owner
+ ruka hráče %1
+
+
+
+ of her hand
+ genitive, female owner
+
+
+
+
+ of %1's hand
+ genitive, female owner
+ ruky hráče %1
+
+
+
+ of his hand
+ genitive, male owner
+ jeho ruky
+
+
+
+ of %1's hand
+ genitive, male owner
+ ruky hráče %1
+
+
+
+ her hand
+ accusative, female owner
+
+
+
+
+ %1's hand
+ accusative, female owner
+ ruka hráče %1
+
+
+
+ his hand
+ accusative, male owner
+ jeho ruka
+
+
+
+ %1's hand
+ accusative, male owner
+ ruka hráče %1
+
+
+
+ her library
+ nominative, female owner
+
+
+
+
+ %1's library
+ nominative, female owner
+ knihovna hráče %1
+
+
+
+ his library
+ nominative, male owner
+
+
+
+
+ %1's library
+ nominative, male owner
+ knihovna hráče %1
+
+
+
+ of her library
+ genitive, female owner
+
+
+
+
+ of %1's library
+ genitive, female owner
+ knihovny hráče %1
+
+
+
+ of his library
+ genitive, male owner
+ jeho knihovny
+
+
+
+ of %1's library
+ genitive, male owner
+ knihovny hráče %1
+
+
+
+ her library
+ accusative, female owner
+
+
+
+
+ %1's library
+ accusative, female owner
+ knihovna hráče %1
+
+
+
+ his library
+ accusative, male owner
+
+
+
+
+ %1's library
+ accusative, male owner
+ knihovna hráče %1
+
+
+
+ her graveyard
+ nominative, female owner
+
+
+
+
+ %1's graveyard
+ nominative, female owner
+ hřbitov hráče %1
+
+
+
+ his graveyard
+ nominative, male owner
+ jeho hřbitov
+
+
+
+ %1's graveyard
+ nominative, male owner
+ hřbitov hráče %1
+
+
+
+ of her graveyard
+ genitive, female owner
+
+
+
+
+ of %1's graveyard
+ genitive, female owner
+ hřbitova hráče %1
+
+
+
+ of his graveyard
+ genitive, male owner
+ jeho hřbitova
+
+
+
+ of %1's graveyard
+ genitive, male owner
+ hřbitova hráče %1
+
+
+
+ her graveyard
+ accusative, female owner
+
+
+
+
+ %1's graveyard
+ accusative, female owner
+ hřbitov hráče %1
+
+
+
+ his graveyard
+ accusative, male owner
+ jeho hřbitov
+
+
+
+ %1's graveyard
+ accusative, male owner
+ hřbitov hráče %1
+
+
+
+ her exile
+ nominative, female owner
+
+
+
+
+ %1's exile
+ nominative, female owner
+ exilnuté karty hráče %1
+
+
+
+ his exile
+ nominative, male owner
+ jeho exilnuté karty
+
+
+
+ %1's exile
+ nominative, male owner
+ exilnuté karty hráče %1
+
+
+
+ of her exile
+ genitive, female owner
+
+
+
+
+ of %1's exile
+ genitive, female owner
+ exilnutých karet hráče %1
+
+
+
+ of his exile
+ genitive, male owner
+ exilnutých karet
+
+
+
+ of %1's exile
+ genitive, male owner
+ exilnutých karet hráče %1
+
+
+
+ her exile
+ accusative, female owner
+
+
+
+
+ %1's exile
+ accusative, female owner
+ exilnuté karty hráče %1
+
+
+
+ his exile
+ accusative, male owner
+ jeho exilnuté karty
+
+
+
+ %1's exile
+ accusative, male owner
+ exilnuté karty hráče %1
+
+
+
+ her sideboard
+ nominative, female owner
+
+
+
+
+ %1's sideboard
+ nominative, female owner
+ sideboard hráče %1
+
+
+
+ his sideboard
+ nominative, male owner
+ jeho sideboard
+
+
+
+ %1's sideboard
+ nominative, male owner
+ sideboard hráče %1
+
+
+
+ of her sideboard
+ genitive, female owner
+
+
+
+
+ of %1's sideboard
+ genitive, female owner
+ sideboardu hráče %1
+
+
+
+ of his sideboard
+ genitive, male owner
+ sideboardu hráče
+
+
+
+ of %1's sideboard
+ genitive, male owner
+ sideboardu hráče %1
+
+
+
+ her sideboard
+ accusative, female owner
+
+
+
+
+ %1's sideboard
+ accusative, female owner
+ sideboard hráče %1
+
+
+
+ his sideboard
+ accusative, male owner
+ jeho sideboard
+
+
+
+ %1's sideboard
+ accusative, male owner
+ sideboard hráče %1
+
+
+
+ DeckEditorSettingsPage
+
+
+ Enable &price tag feature (using data from blacklotusproject.com)
+ &Povolit zobrazovaní cen (použijí se data z blacklotusproject.com)
+
+
+
+ General
+ Obecné
+
+
+
+ DeckListModel
+
+
+ Number
+ Počet
+
+
+
+ Card
+ Karta
+
+
+
+ Price
+ Cena
+
+
+
+ DeckViewContainer
+
+
+ Load &local deck
+ Nahrát &lokální balíček
+
+
+
+ Load d&eck from server
+ Nahrát &balíček ze serveru
+
+
+
+ Ready to s&tart
+ Připraven ke &hře
+
+
+
+ Load deck
+ Nahrát balíček
+
+
+
+ DlgCardSearch
+
+
+ Card name:
+ Jméno karty:
+
+
+
+ Card text:
+ Text karty:
+
+
+
+ Card type (OR):
+ Typ karty (NEBO):
+
+
+
+ Color (OR):
+ Barva (NEBO):
+
+
+
+ O&K
+ O&K
+
+
+
+ &Cancel
+ &Cancel
+
+
+
+ Card search
+ Hledat kartu
+
+
+
+ DlgConnect
+
+
+ &Host:
+ &Hostitel:
+
+
+
+ &Port:
+ &Port:
+
+
+
+ Player &name:
+ Jméno &hráče:
+
+
+
+ P&assword:
+ H&eslo:
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Zrušit
+
+
+
+ Connect to server
+ Připojit k serveru
+
+
+
+ DlgCreateGame
+
+
+ &Description:
+ &Popis:
+
+
+
+ P&layers:
+ H&ráči:
+
+
+
+ Game type
+ Formát
+
+
+
+ &Password:
+ &Heslo:
+
+
+
+ Only &buddies can join
+ Jen pro &přátele
+
+
+
+ Only ®istered users can join
+ Jen pro ®istrované
+
+
+
+ Joining restrictions
+ Omezení připojení
+
+
+
+ &Spectators allowed
+ &Diváci povoleni
+
+
+
+ Spectators &need a password to join
+ Diváci &musí znát heslo
+
+
+
+ Spectators can &chat
+ Diváci mohou &chatovat
+
+
+
+ Spectators see &everything
+ Diváci vidí &všechno
+
+
+
+ Spectators
+ Diváci
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Zrušit
+
+
+
+ Create game
+ Vytvořit hru
+
+
+
+ Error
+ Chyba
+
+
+
+ Server error.
+ Chyba serveru.
+
+
+
+ DlgCreateToken
+
+
+ &Name:
+ &Jméno:
+
+
+
+ Token
+ Token
+
+
+
+ C&olor:
+ B&arva:
+
+
+
+ white
+ bílá
+
+
+
+ blue
+ modrá
+
+
+
+ black
+ černá
+
+
+
+ red
+ červená
+
+
+
+ green
+ zelená
+
+
+
+ multicolor
+ multicolor
+
+
+
+ colorless
+ bezbarvý
+
+
+
+ &P/T:
+ &S/O:
+
+
+
+ &Annotation:
+ &Poznámka:
+
+
+
+ &Destroy token when it leaves the table
+ &Token se při odchodu z bojiště zničí
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Zrušit
+
+
+
+ Create token
+ Vytvořit token
+
+
+
+ DlgLoadDeckFromClipboard
+
+
+ &Refresh
+ &Obnovit
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Zrušit
+
+
+
+ Load deck from clipboard
+ Nahrát balíček ze schránky
+
+
+
+ Error
+ Chyba
+
+
+
+ Invalid deck list.
+ Neplatný formát balíčku.
+
+
+
+ DlgLoadRemoteDeck
+
+
+ O&K
+ O&K
+
+
+
+ &Cancel
+ &Zrušit
+
+
+
+ Load deck
+ Nahrát balíček
+
+
+
+ DlgSettings
+
+
+
+
+ Error
+ Chyba
+
+
+
+ Your card database is invalid. Would you like to go back and set the correct path?
+ Cesta k databázi je neplatná. Chcete se vrátit a nastavit správnou?
+
+
+
+ The path to your deck directory is invalid. Would you like to go back and set the correct path?
+ Cesta k adresáři s balíčky je neplatná. Chcete se vrátit a nastavit správnou?
+
+
+
+ The path to your card pictures directory is invalid. Would you like to go back and set the correct path?
+ Cesta k adresáři s obrázky je neplatná. Chcete se vrátit a nastavit správnou?
+
+
+
+ Settings
+ Nastavení
+
+
+
+ General
+ Obecné
+
+
+
+ Appearance
+ Vzhled
+
+
+
+ User interface
+ Uživatelské rozhraní
+
+
+
+ Deck editor
+ Editor balíčků
+
+
+
+ Messages
+ Zprávy
+
+
+
+ &Close
+ &Zavřít
+
+
+
+ GameSelector
+
+
+
+
+
+
+
+
+
+ Error
+ Chyba
+
+
+
+ Please join the appropriate room first.
+
+
+
+
+ Wrong password.
+ Špatné heslo.
+
+
+
+ Spectators are not allowed in this game.
+ Do této hry je divákům přístup zakázán.
+
+
+
+ The game is already full.
+ Hra je plná.
+
+
+
+ The game does not exist any more.
+ Hra již neexistuje.
+
+
+
+ This game is only open to registered users.
+ Hra je určena jen pro registrované.
+
+
+
+ This game is only open to its creator's buddies.
+ Hra je dostupná jen pro přátele zakládajícícho.
+
+
+
+ You are being ignored by the creator of this game.
+ Zakladatel hry vás ignoruje.
+
+
+
+ Join game
+ Připojit ke hře
+
+
+
+ Password:
+ Heslo:
+
+
+
+ Games
+ Hry
+
+
+
+ Show &full games
+ Ukázat &plné hry
+
+
+
+ Show &running games
+
+
+
+
+ C&reate
+ V&ytvořit
+
+
+
+ &Join
+ &Připojit
+
+
+
+ J&oin as spectator
+ P&řipojit se jako divák
+
+
+
+ GameView
+
+
+ Esc
+ Esc
+
+
+
+ GamesModel
+
+
+ yes
+ ano
+
+
+
+ yes, free for spectators
+ diváci povoleni
+
+
+
+ no
+ ne
+
+
+
+ buddies only
+ jen pro přátele
+
+
+
+ reg. users only
+ jen pro registrované
+
+
+
+ not allowed
+ nepovolené
+
+
+
+ Room
+ Místnost
+
+
+
+ Description
+ Popis
+
+
+
+ Creator
+ Zakladatel
+
+
+
+ Game type
+ Formát
+
+
+
+ Password
+ Heslo
+
+
+
+ Restrictions
+ Omezení
+
+
+
+ Players
+ Hráči
+
+
+
+ Spectators
+ Diváci
+
+
+
+ GeneralSettingsPage
+
+
+
+ English
+ Česky
+
+
+
+
+
+ Choose path
+ Vyberte cestu
+
+
+
+ Personal settings
+ Osobní nastavení
+
+
+
+ Language:
+ Jazyk:
+
+
+
+ Download card pictures on the fly
+ Stahovat obrázky karet za běhu
+
+
+
+ Paths
+ Cesty
+
+
+
+ Decks directory:
+ Adresář s balíčky:
+
+
+
+ Pictures directory:
+ Adresář s obrázky:
+
+
+
+ Path to card database:
+ Karetní databáze:
+
+
+
+ MainWindow
+
+
+ There are too many concurrent connections from your address.
+ Z vaší adresy jde mnoho současných připojení.
+
+
+
+ Banned by moderator.
+ Zabanován moderátorem.
+
+
+
+ Scheduled server shutdown.
+
+
+
+
+ Unknown reason.
+ Neznámý důvod.
+
+
+
+ Connection closed
+ Připojení uzavřeno
+
+
+
+ The server has terminated your connection.
+Reason: %1
+ Server přerušil spojení.
+Důvod: %1
+
+
+
+ Scheduled server shutdown
+
+
+
+
+ The server is going to be restarted in %n minute(s).
+All running games will be lost.
+Reason for shutdown: %1
+
+
+
+
+
+
+
+
+ Number of players
+ Počet hráčů
+
+
+
+ Please enter the number of players.
+ Vložte počet hráčů.
+
+
+
+
+ Player %1
+ Hráč %1
+
+
+
+ About Cockatrice
+ O Cockatrice
+
+
+
+ Version %1
+ Verze %1
+
+
+
+ Authors:
+ Autoři:
+
+
+
+ Translators:
+ Překlad:
+
+
+
+ Spanish:
+ Španělština:
+
+
+
+ Portugese (Portugal):
+ Portugalština (Portugalsko):
+
+
+
+ Portugese (Brazil):
+ Portugalština (Brazílie):
+
+
+
+ French:
+ Francouzština:
+
+
+
+ Japanese:
+ Japonština:
+
+
+
+ Russian:
+ Ruština:
+
+
+
+ Czech:
+ Čeština:
+
+
+
+ Slovak:
+ Slovenština:
+
+
+
+
+
+
+
+
+ Error
+ Chyba
+
+
+
+ Server timeout
+ Vypršel časový limit
+
+
+
+ Invalid login data.
+ Nesprávné údaje uživatele.
+
+
+
+ There is already an active session using this user name.
+Please close that session first and re-login.
+ S tímto uživatelským jménem jste již připojeni.
+Přerušte spojení a znovu se přihlašte.
+
+
+
+ Socket error: %1
+ Chyba socketu: %1
+
+
+
+ You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server.
+Local version is %1, remote version is %2.
+ Snažíte se připojit na zastaralý server. Prosíme, stáhněte si nižší verzi Cockatrice, nebo se připojte k odpovídajícímu serveru.
+Lokální verze je %1, verze serveru je %2.
+
+
+
+ Your Cockatrice client is obsolete. Please update your Cockatrice version.
+Local version is %1, remote version is %2.
+ Váš klient je zastaralý. Prosíme, aktualizujte Cockatrice na vyšší verzi.
+Lokální verze je %1, verze serveru je %2.
+
+
+
+ Connecting to %1...
+ Připojování k %1...
+
+
+
+ Disconnected
+ Odpojeno
+
+
+
+ Logged in at %1
+ Přihlášeno k %1
+
+
+
+ &Connect...
+ &Připojit...
+
+
+
+ &Disconnect
+ &Odpojit
+
+
+
+ Start &local game...
+ Spustit &lokální hru...
+
+
+
+ &Deck editor
+ &Editor balíčků
+
+
+
+ &Full screen
+ &Celá obrazovka
+
+
+
+ Ctrl+F
+ CTRL+F
+
+
+
+ &Settings...
+ &Nastavení...
+
+
+
+ &Exit
+ &Konec
+
+
+
+ &Cockatrice
+ &Cockatrice
+
+
+
+ &About Cockatrice
+ &O Cockatrice
+
+
+
+ &Help
+ &Nápověda
+
+
+
+ Are you sure?
+ Jste si jisti?
+
+
+
+ There are still open games. Are you sure you want to quit?
+ Některé hry jsou stále otevřené. Opravdu chcete odejít?
+
+
+
+ MessageLogWidget
+
+ Connecting to %1...
+ Připojování k %1...
+
+
+ Connected.
+ Připojeno.
+
+
+ Disconnected from server.
+ Odpojeno.
+
+
+ Invalid password.
+ Nesprávné heslo.
+
+
+ Protocol version mismatch. Client: %1, Server: %2
+ Neodpovídá verze protokolu. Klient: %1, Server: %2
+
+
+ Protocol error.
+ Chyba protokolu.
+
+
+ You have joined game #%1.
+ Připojili jste se ke hře #%1.
+
+
+ %1 has joined the game.
+ %1 se připojil ke hře.
+
+
+ %1 has left the game.
+ %1 opustil hru.
+
+
+
+ The game has been closed.
+ Hra byla ukončena.
+
+
+
+ %1 is now watching the game.
+ %1 nyní sleduje hru.
+
+
+
+ %1 is not watching the game any more.
+ %1 přestal sledovat hru.
+
+
+ %1 has loaded a local deck.
+ %1 nahrál lokální balíček.
+
+
+ %1 has loaded deck #%2.
+ %1 nahrál balíček #%2.
+
+
+ %1 is ready to start the game.
+ %1 je připraven ke hře.
+
+
+ %1 is not ready to start the game any more.
+ %1 již není připraven ke hře.
+
+
+ %1 has conceded the game.
+ %1 ukončil hru.
+
+
+
+ The game has started.
+ Hra začíná.
+
+
+ %1 shuffles his library.
+ %1 míchá knihovnu.
+
+
+ %1 rolls a %2 with a %3-sided die.
+ %1 hodil kostkou %2 (%3 stěn).
+
+
+ %1 draws %n card(s).
+
+ %1 si lízl %n kartu.
+ %1 si lízl %n karty.
+ %1 si lízl %n karet.
+
+
+
+
+ You have joined game #%1.
+ female
+ Připojili jste se ke hře #%1.
+
+
+
+ You have joined game #%1.
+ male
+ Připojili jste se ke hře #%1.
+
+
+
+ %1 has joined the game.
+ female
+ %1 se připojil ke hře.
+
+
+
+ %1 has joined the game.
+ male
+ %1 se připojil ke hře.
+
+
+
+ %1 has left the game.
+ female
+ %1 opustil hru.
+
+
+
+ %1 has left the game.
+ male
+ %1 opustil hru.
+
+
+
+ %1 has loaded a local deck.
+ female
+ %1 nahrál lokální balíček.
+
+
+
+ %1 has loaded a local deck.
+ male
+ %1 nahrál lokální balíček.
+
+
+
+ %1 has loaded deck #%2.
+ female
+ %1 nahrál balíček #%2.
+
+
+
+ %1 has loaded deck #%2.
+ male
+ %1 nahrál balíček #%2.
+
+
+
+ %1 is ready to start the game.
+ female
+ %1 je připraven ke hře.
+
+
+
+ %1 is ready to start the game.
+ male
+ %1 je připraven ke hře.
+
+
+
+ %1 is not ready to start the game any more.
+ female
+ %1 již není připraven ke hře.
+
+
+
+ %1 is not ready to start the game any more.
+ male
+ %1 již není připraven ke hře.
+
+
+
+ %1 has conceded the game.
+ female
+ %1 ukončil hru.
+
+
+
+ %1 has conceded the game.
+ male
+ %1 ukončil hru.
+
+
+
+ %1 has restored connection to the game.
+ female
+
+
+
+
+ %1 has restored connection to the game.
+ male
+
+
+
+
+ %1 has lost connection to the game.
+ female
+
+
+
+
+ %1 has lost connection to the game.
+ male
+
+
+
+
+ %1 shuffles %2.
+ female
+
+
+
+
+ %1 shuffles %2.
+ male
+
+
+
+
+ %1 rolls a %2 with a %3-sided die.
+ female
+ %1 hodil kostkou %2 (%3 stěn).
+
+
+
+ %1 rolls a %2 with a %3-sided die.
+ male
+ %1 hodil kostkou %2 (%3 stěn).
+
+
+
+ %1 draws %n card(s).
+ female
+
+ %1 si lízl %n kartu.
+ %1 si lízl %n karty.
+ %1 si lízl %n karet.
+
+
+
+
+ %1 draws %n card(s).
+ male
+
+ %1 si lízl %n kartu.
+ %1 si lízl %n karty.
+ %1 si lízl %n karet.
+
+
+
+
+ %1 undoes his last draw.
+ %1 vrátil zpět svoje poslední líznutí.
+
+
+
+ %1 undoes her last draw.
+
+
+
+
+ %1 undoes his last draw (%2).
+ %1 vrátil svoje poslední líznutí (%2).
+
+
+
+ %1 undoes her last draw (%2).
+
+
+
+
+ from table
+ z bojiště
+
+
+
+ from graveyard
+ ze hřbitova
+
+
+
+ from exile
+ z exilnutých karet
+
+
+
+ from hand
+ z ruky
+
+
+
+ the bottom card of his library
+ spodní kartu knihovny
+
+
+
+ the bottom card of her library
+
+
+
+
+ from the bottom of his library
+ ze spodku knihovny
+
+
+
+ from the bottom of her library
+
+
+
+
+ the top card of his library
+ vrchní kartu knihovny
+
+
+
+ the top card of her library
+
+
+
+
+ from the top of his library
+ z vršku knihovny
+
+
+
+ from the top of her library
+
+
+
+
+ from library
+ z knihovny
+
+
+
+ from sideboard
+ ze sideboardu
+
+
+
+ from the stack
+ ze stacku
+
+
+
+
+ a card
+ kartu
+
+
+
+ %1 gives %2 control over %3.
+ %1 předává kontrolu hráči %2 karty %3.
+
+
+
+ %1 puts %2 into play tapped%3.
+ %1 dává kartu %2 do hry %3 tapnutou.
+
+
+
+ %1 puts %2 into play%3.
+ %1 dává kartu %2 %3 do hry.
+
+
+
+ %1 puts %2%3 into graveyard.
+ %1 dává kartu %2%3 do hřbitova.
+
+
+
+ %1 exiles %2%3.
+ %1 exiluje %2%3.
+
+
+
+ %1 moves %2%3 to hand.
+ %1 přesouvá %2%3 do ruky.
+
+
+
+ %1 puts %2%3 into his library.
+ %1 dává %2%3 do knihovny.
+
+
+
+ %1 puts %2%3 into her library.
+
+
+
+
+ %1 puts %2%3 on bottom of his library.
+ %1 dává %2%3 na spodek knihovny.
+
+
+
+ %1 puts %2%3 on bottom of her library.
+
+
+
+
+ %1 puts %2%3 on top of his library.
+ %1 dává %2%3 na vršek knihovny.
+
+
+
+ %1 puts %2%3 on top of her library.
+
+
+
+
+ %1 puts %2%3 into his library at position %4.
+ %1 dává %2%3 knihovny na pozici %4.
+
+
+
+ %1 puts %2%3 into her library at position %4.
+
+
+
+
+ %1 moves %2%3 to sideboard.
+ %1 přesouvá %2%3 do sideboardu.
+
+
+
+ %1 plays %2%3.
+ %1 sesílá %2%3.
+
+
+
+ %1 takes a mulligan to %n.
+ female
+
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+
+
+
+
+ %1 takes a mulligan to %n.
+ male
+
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+
+
+
+
+ %1 draws her initial hand.
+
+
+
+
+ %1 flips %2 face-down.
+ female
+ %1 otáčí %2 lícem dolů.
+
+
+
+ %1 flips %2 face-down.
+ male
+ %1 otáčí %2 lícem dolů.
+
+
+
+ %1 flips %2 face-up.
+ female
+ %1 otáčí %2 lícem vzhůru.
+
+
+
+ %1 flips %2 face-up.
+ male
+ %1 otáčí %2 lícem vzhůru.
+
+
+
+ %1 destroys %2.
+ female
+ %1 ničí %2.
+
+
+
+ %1 destroys %2.
+ male
+ %1 ničí %2.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 female
+ %1 připojuje %2 k %3 %4.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 male
+ %1 připojuje %2 k %3 %4.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 female
+ %1 připojuje %2 k %3 %4.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 male
+ %1 připojuje %2 k %3 %4.
+
+
+
+ %1 unattaches %2.
+ female
+ %1 odpojuje %2.
+
+
+
+ %1 unattaches %2.
+ male
+ %1 odpojuje %2.
+
+
+
+ %1 creates token: %2%3.
+ female
+ %1 vykládá token %2%3.
+
+
+
+ %1 creates token: %2%3.
+ male
+ %1 vykládá token %2%3.
+
+
+
+ %1 points from her %2 to herself.
+ female
+
+
+
+
+ %1 points from his %2 to himself.
+ male
+
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 female
+
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 male
+
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 female
+
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 male
+
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner female, target female
+
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner male, target female
+
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner female, target male
+
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner male, target male
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+
+ %1 points from her %2 to her %3.
+ female
+
+
+
+
+ %1 points from his %2 to his %3.
+ male
+
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 female
+
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 male
+
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 female
+
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 male
+
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner female, target female
+
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner male, target female
+
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner female, target male
+
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner male, target male
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 female
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 male
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+ female
+
+ %1 pokládá %n %2 žeton na %3 (nyní %4).
+ %1 pokládá %n %2 žetony na %3 (nyní %4).
+ %1 pokládá %n %2 žetonů na %3 (nyní %4).
+
+
+
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+ male
+
+ %1 pokládá %n %2 žeton na %3 (nyní %4).
+ %1 pokládá %n %2 žetony na %3 (nyní %4).
+ %1 pokládá %n %2 žetonů na %3 (nyní %4).
+
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+ female
+
+ %1 odebírá %n %2 žeton z %3 (nyní %4).
+ %1 odebírá %n %2 žetony z %3 (nyní %4).
+ %1 odebírá %n %2 žetonů z %3 (nyní %4).
+
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+ male
+
+ %1 odebírá %n %2 žeton z %3 (nyní %4).
+ %1 odebírá %n %2 žetony z %3 (nyní %4).
+ %1 odebírá %n %2 žetonů z %3 (nyní %4).
+
+
+
+
+ %1 taps her permanents.
+ female
+
+
+
+
+ %1 untaps her permanents.
+ female
+
+
+
+
+ %1 taps his permanents.
+ male
+
+
+
+
+ %1 untaps his permanents.
+ male
+
+
+
+
+ %1 taps %2.
+ female
+
+
+
+
+ %1 untaps %2.
+ female
+
+
+
+
+ %1 taps %2.
+ male
+
+
+
+
+ %1 untaps %2.
+ male
+
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ female
+ %1 nastavuje počet %2 žetonů na %3 (%4%5).
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ male
+ %1 nastavuje počet %2 žetonů na %3 (%4%5).
+
+
+
+ %1 sets %2 to not untap normally.
+ female
+ %1 nastavuje %2 na neodtapování.
+
+
+
+ %1 sets %2 to not untap normally.
+ male
+ %1 nastavuje %2 na neodtapování.
+
+
+
+ %1 sets %2 to untap normally.
+ female
+ %1 nastavuje %2 na standardní odtapnutí.
+
+
+
+ %1 sets %2 to untap normally.
+ male
+ %1 nastavuje %2 na standardní odtapnutí.
+
+
+
+ %1 sets PT of %2 to %3.
+ female
+ %1 nastavuje sílu a odolnost pro %2 na %3.
+
+
+
+ %1 sets PT of %2 to %3.
+ male
+ %1 nastavuje sílu a odolnost pro %2 na %3.
+
+
+
+ %1 sets annotation of %2 to %3.
+ female
+ %1 nastavuje poznámku pro %2 na %3.
+
+
+
+ %1 sets annotation of %2 to %3.
+ male
+ %1 nastavuje poznámku pro %2 na %3.
+
+
+
+ %1 is looking at the top %2 cards %3.
+ female
+ %1 si prohlíží %2 vrchních karet %3.
+
+
+
+ %1 is looking at the top %2 cards %3.
+ male
+ %1 si prohlíží %2 vrchních karet %3.
+
+
+
+ %1 is looking at %2.
+ female
+ %1 si prohlíží %2.
+
+
+
+ %1 is looking at %2.
+ male
+ %1 si prohlíží %2.
+
+
+
+ %1 stops looking at %2.
+ female
+ %1 si přestává prohlížet %2.
+
+
+
+ %1 stops looking at %2.
+ male
+ %1 si přestává prohlížet %2.
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 female
+ %1 ukazuje %2 hráči %3.
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 male
+ %1 ukazuje %2 hráči %3.
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 female
+ %1 ukazuje %2 hráči %3.
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 male
+ %1 ukazuje %2 hráči %3.
+
+
+
+ %1 reveals %2.
+ female
+ %1 ukazuje %2.
+
+
+
+ %1 reveals %2.
+ male
+ %1 ukazuje %2.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 female, p2 female
+ %1 náhodně ukazuje %2%3 hráči %4.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 female, p2 male
+ %1 náhodně ukazuje %2%3 hráči %4.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 female
+ %1 náhodně ukazuje %2%3 hráči %4.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 male
+ %1 náhodně ukazuje %2%3 hráči %4.
+
+
+
+ %1 randomly reveals %2%3.
+ female
+ %1 náhodně ukazuje %2%3.
+
+
+
+ %1 randomly reveals %2%3.
+ male
+ %1 náhodně ukazuje %2%3.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 female, p2 female
+ %1 ukazuje %2%3 hráči %4.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 female, p2 male
+ %1 ukazuje %2%3 hráči %4.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 female
+ %1 ukazuje %2%3 hráči %4.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 male
+ %1 ukazuje %2%3 hráči %4.
+
+
+
+ %1 reveals %2%3.
+ female
+ %1 ukazuje %2%3.
+
+
+
+ %1 reveals %2%3.
+ male
+ %1 ukazuje %2%3.
+
+
+
+ It is now %1's turn.
+ female
+ Nyní je kolo hráče %1.
+
+
+
+ It is now %1's turn.
+ male
+ Nyní je kolo hráče %1.
+
+
+ %1 takes a mulligan to %n.
+
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+ %1 mulliganuje do %n.
+
+
+
+
+ %1 draws his initial hand.
+ %1 líže startovní ruku.
+
+
+ %1 flips %2 face-down.
+ %1 otáčí %2 lícem dolů.
+
+
+ %1 flips %2 face-up.
+ %1 otáčí %2 lícem vzhůru.
+
+
+ %1 destroys %2.
+ %1 ničí %2.
+
+
+ %1 attaches %2 to %3's %4.
+ %1 připojuje %2 k %3 %4.
+
+
+ %1 unattaches %2.
+ %1 odpojuje %2.
+
+
+ %1 creates token: %2%3.
+ %1 vykládá token %2%3.
+
+
+ %1 points from %2's %3 to %4.
+ %1 ukazuje kartou %3 (hráče %2) na %4.
+
+
+ %1 points from %2's %3 to %4's %5.
+ %1 ukazuje kartou %3 (hráče %2) na %5 (hráče %4).
+
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+
+ %1 pokládá %n %2 žeton na %3 (nyní %4).
+ %1 pokládá %n %2 žetony na %3 (nyní %4).
+ %1 pokládá %n %2 žetonů na %3 (nyní %4).
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+
+ %1 odebírá %n %2 žeton z %3 (nyní %4).
+ %1 odebírá %n %2 žetony z %3 (nyní %4).
+ %1 odebírá %n %2 žetonů z %3 (nyní %4).
+
+
+
+
+ red
+
+ červený
+ červené
+ červených
+
+
+
+
+ yellow
+
+ žlutý
+ žluté
+ žlutých
+
+
+
+
+ green
+
+ zelený
+ zelené
+ zelených
+
+
+
+ his permanents
+ permanenty
+
+
+ %1 %2 %3.
+ %1 %2 %3.
+
+
+ taps
+ tapuje
+
+
+ untaps
+ odtapuje
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ %1 nastavuje počet %2 žetonů na %3 (%4%5).
+
+
+ %1 sets %2 to not untap normally.
+ %1 nastavuje %2 na neodtapování.
+
+
+ %1 sets %2 to untap normally.
+ %1 nastavuje %2 na standardní odtapnutí.
+
+
+ %1 sets PT of %2 to %3.
+ %1 nastavuje sílu a odolnost pro %2 na %3.
+
+
+ %1 sets annotation of %2 to %3.
+ %1 nastavuje poznámku pro %2 na %3.
+
+
+ %1 is looking at the top %2 cards %3.
+ %1 si prohlíží %2 vrchních karet %3.
+
+
+ %1 is looking at %2.
+ %1 si prohlíží %2.
+
+
+ %1 stops looking at %2.
+ %1 si přestává prohlížet %2.
+
+
+ %1 reveals %2 to %3.
+ %1 ukazuje %2 hráči %3.
+
+
+ %1 reveals %2.
+ %1 ukazuje %2.
+
+
+ %1 randomly reveals %2%3 to %4.
+ %1 náhodně ukazuje %2%3 hráči %4.
+
+
+ %1 randomly reveals %2%3.
+ %1 náhodně ukazuje %2%3.
+
+
+ %1 reveals %2%3 to %4.
+ %1 ukazuje %2%3 hráči %4.
+
+
+ %1 reveals %2%3.
+ %1 ukazuje %2%3.
+
+
+ It is now %1's turn.
+ Nyní je kolo hráče %1.
+
+
+
+ untap step
+ Odtapovací fáze
+
+
+
+ upkeep step
+ Upkeep
+
+
+
+ draw step
+ Lízací fáze
+
+
+
+ first main phase
+ První hlavní fáze
+
+
+
+ beginning of combat step
+ Začátek bojové fáze
+
+
+
+ declare attackers step
+ Oznámení útočníků
+
+
+
+ declare blockers step
+ Oznámení blokujících
+
+
+
+ combat damage step
+ Udělení bojového zranění
+
+
+
+ end of combat step
+ Konec bojové fáze
+
+
+
+ second main phase
+ Druhá hlavní fáze
+
+
+
+ ending phase
+ Konec kola
+
+
+
+ It is now the %1.
+ Nyní je %1.
+
+
+
+ MessagesSettingsPage
+
+
+ Add message
+ Přidat zprávu
+
+
+
+ Message:
+ Zpráva:
+
+
+
+ &Add
+ &Přidat
+
+
+
+ &Remove
+ &Odstranit
+
+
+
+ PhasesToolbar
+
+
+ Untap step
+ Odtapovací fáze
+
+
+
+ Upkeep step
+ Upkeep
+
+
+
+ Draw step
+ Lízací fáze
+
+
+
+ First main phase
+ První hlavní fáze
+
+
+
+ Beginning of combat step
+ Začátek bojové fáze
+
+
+
+ Declare attackers step
+ Oznámení útočníků
+
+
+
+ Declare blockers step
+ Oznámení blokujících
+
+
+
+ Combat damage step
+ Udělení bojového zranění
+
+
+
+ End of combat step
+ Konec bojové fáze
+
+
+
+ Second main phase
+ Druhá hlavní fáze
+
+
+
+ End of turn step
+ Konec kola
+
+
+
+ Player
+
+
+ &View graveyard
+ &Zobrazit hřbitov
+
+
+
+ &View exile
+ &Zobrazit exilnuté karty
+
+
+
+ Player "%1"
+ Hráč "%1"
+
+
+
+ &Graveyard
+ &Hřbitov
+
+
+
+ &Exile
+ &Exilnuté karty
+
+
+
+
+
+ Move to &top of library
+ Přesunout na &vršek knihovny
+
+
+
+
+
+ Move to &bottom of library
+ Přesunout na &spodek knihovny
+
+
+
+
+ Move to &graveyard
+ Přesunout do &hřbitova
+
+
+
+
+ Move to &exile
+ &Exilnout
+
+
+
+
+ Move to &hand
+ Přesunout do &ruky
+
+
+
+ &View library
+ &Zobrazit knihovnu
+
+
+
+ View &top cards of library...
+ Zobrazit &vrchní karty knihovny...
+
+
+
+ Reveal &library to
+ Ukázat &knihovnu
+
+
+
+ Reveal t&op card to
+ Ukázat v&rchní kartu
+
+
+
+ &View sideboard
+ &Zobrazit sideboard
+
+
+
+ &Draw card
+ &Líznout kartu
+
+
+
+ D&raw cards...
+ L&íznout karty...
+
+
+
+ &Undo last draw
+ &Vrátit zpět poslední líznutí
+
+
+
+ Take &mulligan
+ &Mulliganovat
+
+
+
+ &Shuffle
+ &Zamíchat
+
+
+
+ Move top cards to &graveyard...
+ Přesunout vrchní karty do &hřbitova...
+
+
+
+ Move top cards to &exile...
+ &Exilnout vrchní karty...
+
+
+
+ Put top card on &bottom
+ Dát kartu na &spodek
+
+
+
+ &Hand
+ &Ruka
+
+
+
+ &Reveal to
+ &Ukázat
+
+
+
+ Reveal r&andom card to
+ Ukázat kartu n&áhodně
+
+
+
+ &Sideboard
+ &Sideboard
+
+
+
+ &Library
+ &Knihovna
+
+
+
+ &Counters
+ &Žetony
+
+
+
+ &Untap all permanents
+ &Odtapnout všechny permanenty
+
+
+
+ R&oll die...
+ H&odit kostkou...
+
+
+
+ &Create token...
+ &Vytvořit token...
+
+
+
+ C&reate another token
+ V&ytvořit další token
+
+
+
+ S&ay
+ &Chat
+
+
+
+ C&ard
+ K&arta
+
+
+
+ &All players
+ &Všem hráčům
+
+
+
+ Ctrl+F3
+ Ctrl+F3
+
+
+
+ F3
+ F3
+
+
+
+ Ctrl+W
+ Ctrl+W
+
+
+
+ F4
+ F4
+
+
+
+ Ctrl+D
+ Ctrl+D
+
+
+
+ Ctrl+E
+ Ctrl+E
+
+
+
+ Ctrl+Shift+D
+ Ctrl+Shift+D
+
+
+
+ Ctrl+M
+ Ctrl+M
+
+
+
+ Ctrl+S
+ Ctrl+S
+
+
+
+ Ctrl+U
+ Ctrl+U
+
+
+
+ Ctrl+I
+ Ctrl+I
+
+
+
+ Ctrl+T
+ Ctrl+T
+
+
+
+ Ctrl+G
+ Ctrl+G
+
+
+
+ View top cards of library
+ Zobrazit vrchní karty knihovny
+
+
+
+ Number of cards:
+ Počet karet:
+
+
+
+ Draw cards
+ Líznout karty
+
+
+
+
+
+
+ Number:
+ Počet:
+
+
+
+ Move top cards to grave
+ Přesunout vrchní karty do hřbitova
+
+
+
+ Move top cards to exile
+ Exilnout vrchní karty
+
+
+
+ Roll die
+ Hodit kostkou
+
+
+
+ Number of sides:
+ Počet stran:
+
+
+
+ Set power/toughness
+ Nastavit sílu/odolnost
+
+
+
+ Please enter the new PT:
+ Vložte novou odolnost/sílu:
+
+
+
+ Set annotation
+ Nastavit poznámku
+
+
+
+ Please enter the new annotation:
+ Vložte novou poznámku:
+
+
+
+ Set counters
+ Nastavit žetony
+
+
+
+ PlayerListWidget
+
+
+ local deck
+ lokální balíček
+
+
+
+ deck #%1
+ bal94ek #%1
+
+
+
+ User &details
+ Detaily &uživatele
+
+
+
+ Direct &chat
+ &Chatovat
+
+
+
+ Add to &buddy list
+ Přidat mezi &přátele
+
+
+
+ Remove from &buddy list
+ Odstranit z &přátel
+
+
+
+ Add to &ignore list
+ Přidat do &ignorovaných
+
+
+
+ Remove from &ignore list
+ Odstranit z &ignorovaných
+
+
+
+ Kick from &game
+ Vyhodit ze &hry
+
+
+
+ QObject
+
+
+ Maindeck
+ Maindeck
+
+
+
+ Sideboard
+ Sideboard
+
+
+
+ Cockatrice decks (*.cod)
+ Balíčky cockatrice (*.cod)
+
+
+
+ Plain text decks (*.dec *.mwDeck)
+ Čistý text (*.dec*.mwDeck)
+
+
+
+ All files (*.*)
+ Všechny soubory (*.*)
+
+
+
+ RemoteDeckList_TreeModel
+
+
+ Name
+ Jméno
+
+
+
+ ID
+ ID
+
+
+
+ Upload time
+ Průběh nahrávání
+
+
+
+ RoomSelector
+
+
+ Rooms
+ Místnosti
+
+
+
+ Joi&n
+ &Připojit
+
+
+
+ Room
+ Místnost
+
+
+
+ Description
+ Popis
+
+
+
+ Players
+ Hráči
+
+
+
+ Games
+ Hry
+
+
+
+ SetsModel
+
+
+ Short name
+ Krátký název
+
+
+
+ Long name
+ Dlouhý název
+
+
+
+ ShutdownDialog
+
+
+ &Reason for shutdown:
+
+
+
+
+ &Time until shutdown (minutes):
+
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+
+
+
+
+ Shut down server
+
+
+
+
+ TabAdmin
+
+
+ Update server &message
+ Aktualizovat &zprávu serveru
+
+
+
+ &Shut down server
+
+
+
+
+ Server administration functions
+ Administrační funkce serveru
+
+
+
+ &Unlock functions
+ &Odemknout funkce
+
+
+
+ &Lock functions
+ &Zamknout funkce
+
+
+
+ Unlock administration functions
+ Odemknout administrační funkce
+
+
+
+ Do you really want to unlock the administration functions?
+ Opravdu chcete odemknout administrační funkce?
+
+
+
+ Administration
+ Administrace
+
+
+
+ TabDeckStorage
+
+
+ Local file system
+ Lokální systém souborů
+
+
+
+ Server deck storage
+ Balíčky na serveru
+
+
+
+
+ Open in deck editor
+ Otevřít v editoru balíčků
+
+
+
+ Upload deck
+ Nahrát balíček
+
+
+
+ Download deck
+ Stáhnout balíček
+
+
+
+
+ New folder
+ Nová složka
+
+
+
+ Delete
+ Smazat
+
+
+
+ Enter deck name
+ Vložit jméno balíčku
+
+
+
+ This decklist does not have a name.
+Please enter a name:
+ Tentobalíček nemá jméno.
+Prosím vložte jméno:
+
+
+
+
+ Unnamed deck
+ Bezejmenný balíček
+
+
+
+ Name of new folder:
+ Název nové složky:
+
+
+
+ Deck storage
+ Uložiště balíčků
+
+
+
+ TabGame
+
+
+ F5
+ F5
+
+
+
+ F6
+ F6
+
+
+
+ F7
+ F7
+
+
+
+ F8
+ F8
+
+
+
+ F9
+ F9
+
+
+
+ F10
+ F10
+
+
+
+ &Phases
+ &Fáze
+
+
+
+ &Game
+ &Hra
+
+
+
+ Next &phase
+ Další &fáze
+
+
+
+ Ctrl+Space
+ Ctrl+Space
+
+
+
+ Next &turn
+ Další &kolo
+
+
+
+ Ctrl+Return
+ Ctrl+Return
+
+
+
+ Ctrl+Enter
+ Ctrl+Enter
+
+
+
+ &Remove all local arrows
+ &Odstranit všechny lokální šipky
+
+
+
+ Ctrl+R
+ CTRL+R
+
+
+
+ &Concede
+ &Ukončit hru
+
+
+
+ F2
+ F2
+
+
+
+ &Leave game
+ &Opustit hru
+
+
+
+ Ctrl+Q
+ CTRL+Q
+
+
+
+ &Say:
+ &Chat:
+
+
+
+ Concede
+ Ukončit hru
+
+
+
+ Are you sure you want to concede this game?
+ Opravdu chcete ukončit tuto hru?
+
+
+
+ Leave game
+ Opustit hru
+
+
+
+ Are you sure you want to leave this game?
+ Opravdu chcete opustit tuto hru?
+
+
+
+ Kicked
+ Vyhozen
+
+
+
+ You have been kicked out of the game.
+ Byli jste vyhozeni ze hry.
+
+
+
+ Game %1: %2
+ Hra %1: %2
+
+
+
+ TabMessage
+
+
+ Personal &talk
+ Osobní &diskuze
+
+
+
+ &Leave
+ &Odejít
+
+
+
+ This user is ignoring you.
+ Tento uživatel vás ignoruje.
+
+
+
+ %1 has left the server.
+ %1 opustil server.
+
+
+
+ %1 has joined the server.
+ %1 se připojil k serveru.
+
+
+
+ Talking to %1
+ Mlávíte k %1
+
+
+
+ TabRoom
+
+
+ &Say:
+ &Chat:
+
+
+
+ Chat
+ Chatovat
+
+
+
+ &Room
+ &Místnost
+
+
+
+ &Leave room
+ &Opustit místnost
+
+
+
+ You are flooding the chat. Please wait a couple of seconds.
+ Píšete příliš intenzivně. Počkejte pár sekund.
+
+
+
+ TabServer
+
+
+ Server
+ Server
+
+
+
+ TabUserLists
+
+
+ User lists
+ Seznam uživatelů
+
+
+
+ UserInfoBox
+
+
+ User information
+ Informace o uživateli
+
+
+
+ Real name:
+ Pravé jméno:
+
+
+
+ Gender:
+
+
+
+
+ Location:
+ Místo:
+
+
+
+ User level:
+ Úroveň:
+
+
+
+ Administrator
+ Administrátor
+
+
+
+ Moderator
+
+
+
+ Judge
+ Judge
+
+
+
+ Registered user
+ Registrovaný
+
+
+
+ Unregistered user
+ Neregistrovaný
+
+
+
+ UserInterfaceSettingsPage
+
+
+ General interface settings
+ Obecné
+
+
+
+ &Double-click cards to play them (instead of single-click)
+ &Pro zahraní karty je třeba dvojklik
+
+
+
+ Animation settings
+ Animace
+
+
+
+ &Tap/untap animation
+ &Animace tapnutí/odtapnutí
+
+
+
+ Enable &sounds
+ Povolit &zvuky
+
+
+
+ Path to sounds directory:
+ Adresář se zvuky:
+
+
+
+ Choose path
+ Vyberte cestu
+
+
+
+ UserList
+
+
+ Users online: %1
+ Připojených uživatelů: %1
+
+
+
+ Users in this room: %1
+ Uživatelů v této místnosti: %1
+
+
+
+ Buddies online: %1 / %2
+ Přátelé online: %1 / %2
+
+
+
+ Ignored users online: %1 / %2
+ Ignorovaných online: %1 / %2
+
+
+
+ %1's games
+
+
+
+
+ User &details
+ &Detaily uživatele
+
+
+
+ Direct &chat
+ &Chatovat
+
+
+
+ Show this user's &games
+
+
+
+
+ Add to &buddy list
+ Přidat mezi &přátele
+
+
+
+ Remove from &buddy list
+ Odstranit z &přátel
+
+
+
+ Add to &ignore list
+ Přidat mezi &ignorované
+
+
+
+ Remove from &ignore list
+ Odstranit z &ignorovaných
+
+
+
+ Ban from &server
+ &Zabanovat
+
+
+ Duration
+ Délka
+
+
+ Please enter the duration of the ban (in minutes).
+Enter 0 for an indefinite ban.
+ Vložte dobu trvání banu (v minutách).
+Hodnota 0 je pro ban bez omezení.
+
+
+
+ WndDeckEditor
+
+
+ &Search...
+ &Hledat...
+
+
+
+ &Clear search
+ &Vyčistit hledání
+
+
+
+ &Search for:
+ &Vyhledat:
+
+
+
+ Deck &name:
+ &Název balíčku:
+
+
+
+ &Comments:
+ &Komentář:
+
+
+
+ &Update prices
+ Akt&ualizovat ceny
+
+
+
+ Ctrl+U
+ CTRL+U
+
+
+
+ Deck editor [*]
+ Editor balíčků [*]
+
+
+
+ &New deck
+ &Nový balíček
+
+
+
+ &Load deck...
+ &Nahrát balíček...
+
+
+
+ &Save deck
+ &Uložit balíček
+
+
+
+ Save deck &as...
+ Uložit balíček &jako...
+
+
+
+ Load deck from cl&ipboard...
+ Nahrát balíček ze s&chránky...
+
+
+
+ Save deck to clip&board
+ Vložit balíček do &schránky
+
+
+
+ &Print deck...
+ &Vytisknout balíček...
+
+
+
+ &Close
+ &Zavřít
+
+
+
+ Ctrl+Q
+ CTRL+Q
+
+
+
+ &Edit sets...
+ &Upravit sasy...
+
+
+
+ &Deck
+ &Balíček
+
+
+
+ &Card database
+ Databáze &karet
+
+
+
+ Add card to &maindeck
+ Přidat kartu do &balíčku
+
+
+
+ Return
+ Return
+
+
+
+ Enter
+ Enter
+
+
+
+ Add card to &sideboard
+ Přidat kartu do &sideboardu
+
+
+
+ Ctrl+Return
+ Ctrl+Return
+
+
+
+ Ctrl+Enter
+ Ctrl+Enter
+
+
+
+ &Remove row
+ &Smazat řádek
+
+
+
+ Del
+ Del
+
+
+
+ &Increment number
+ &Zvýšit počet
+
+
+
+ +
+ +
+
+
+
+ &Decrement number
+ &Snížit počet
+
+
+
+ -
+ -
+
+
+
+ Are you sure?
+ Jste si jisti?
+
+
+
+ The decklist has been modified.
+Do you want to save the changes?
+ Balíček byl upraven.
+Chcete uložit změny?
+
+
+
+ Load deck
+ Nahrát balíček
+
+
+
+
+ Error
+ Chyba
+
+
+
+
+ The deck could not be saved.
+Please check that the directory is writable and try again.
+ Balíček nebylo možné uložit.
+Zkontrolujte, jestli lze zapisovat do cílového adresáře a zkuste to znovu.
+
+
+
+ Save deck
+ Uložit balíček
+
+
+
+ WndSets
+
+
+ Edit sets
+ Upravit edice
+
+
+
+ ZoneViewWidget
+
+
+ sort by name
+ seřadit dle jména
+
+
+
+ sort by type
+ seřadit dle typu
+
+
+
+ shuffle when closing
+ zamíchat po zavření
+
+
+
diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts
index ebf01d7f8..cd581e185 100644
--- a/cockatrice/translations/cockatrice_de.ts
+++ b/cockatrice/translations/cockatrice_de.ts
@@ -60,66 +60,71 @@
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:
-
+
Card rendering
Kartendarstellung
-
+
Display card names on cards having a picture
Kartennamen darstellen auch bei Karten, die Bilder haben
-
+
Hand layout
Kartenhand
-
+
Display hand horizontally (wastes space)
Hand horizonal anzeigen (verschwendet Platz)
-
+
Table grid layout
Spielfeldraster
+
+
+ Minimum player count for multi-column layout:
+ Mindestspielerzahl für mehrspaltige Anordnung:
+
Economical layout
Platzsparende Anordnung
-
+
Invert vertical coordinate
Vertikale Koordinate umkehren
@@ -128,17 +133,17 @@
Platzsparende Anordnung
-
+
Zone view layout
Aussehen des Zonenbetrachters
-
+
Sort by name
nach Namen sortieren
-
+
Sort by type
nach Kartentypen sortieren
@@ -147,15 +152,51 @@
standardmäßig alphabetisch sortieren
-
-
-
-
-
+
+
+
+
+
Choose path
Pfad auswählen
+
+ BanDialog
+
+
+ Please enter the duration of the ban (in minutes).
+Enter 0 for an indefinite ban.
+ Bitte geben Sie die Dauer des Banns ein (in Minuten).
+Geben Sie 0 ein für einen unbefristeten Bann.
+
+
+ Please enter the reason for the ban. This is only saved for moderators and cannot be seen by the banned person.
+ Bitte geben Sie den Grund für den Bann ein. Dies wird nur für Moderatoren gespeichert und kann von der gebannten Person nicht gesehen werden.
+
+
+
+ Please enter the reason for the ban.
+This is only saved for moderators and cannot be seen by the banned person.
+ Bitte geben Sie den Grund für den Bann ein.
+Dies wird nur für Moderatoren gespeichert und kann von der gebannten Person nicht gesehen werden.
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Abbrechen
+
+
+
+ Ban user from server
+ Benutzer vom Server bannen
+
+
CardDatabaseModel
@@ -187,22 +228,42 @@
CardInfoWidget
-
+
+ Hide card info
+ Nichts anzeigen
+
+
+
+ Show card only
+ nur Kartenbild
+
+
+
+ Show text only
+ nur Kartentext
+
+
+
+ Show full info
+ Alles anzeigen
+
+
+
Name:
Name:
-
+
Mana cost:
Manakosten:
-
+
Card type:
Kartentyp:
-
+
P / T:
S/W:
@@ -218,57 +279,57 @@
CardItem
-
+
&Play
&Ausspielen
-
+
&Hide
&Verstecken
-
+
&Tap
&Tappen
-
+
&Untap
E&nttappen
-
+
Toggle &normal untapping
N&ormales Enttappen umschalten
-
+
&Flip
&Umdrehen
-
+
&Clone
&Kopieren
-
+
Ctrl+H
Ctrl+H
-
+
&Attach to card...
&An Karte anlegen...
-
+
Ctrl+A
Ctrl+A
-
+
Unattac&h
&Von Karte lösen
@@ -277,142 +338,147 @@
&Kampfwerte setzen...
-
+
+ &Draw arrow...
+ &Pfeil zeichnen...
+
+
+
&Power / toughness
&Kampfwerte
-
+
&Increase power
&Stärke erhöhen
-
+
Ctrl++
Ctrl++
-
+
&Decrease power
S&tärke senken
-
+
Ctrl+-
Ctrl+-
-
+
I&ncrease toughness
&Widerstandskraft erhöhen
-
+
Alt++
Alt++
-
+
D&ecrease toughness
W&iderstandskraft senken
-
+
Alt+-
Alt+-
-
+
In&crease power and toughness
Stärke und Widerstandskraft &erhöhen
-
+
Ctrl+Alt++
Ctrl+Alt++
-
+
Dec&rease power and toughness
Stärke und Widerstandskraft s&enken
-
+
Ctrl+Alt+-
Ctrl+Alt+-
-
+
Set &power and toughness...
&Kampfwerte setzen...
-
+
Ctrl+P
Ctrl+P
-
+
&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
@@ -500,40 +566,34 @@
von %1s Sideboard
-
his hand
nominative
- seine Hand
+ seine Hand
-
%1's hand
nominative
- %1s Hand
+ %1s Hand
-
of his hand
genitive
- seiner Hand
+ seiner Hand
-
of %1's hand
genitive
- von %1s Hand
+ von %1s Hand
-
his hand
accusative
- seine Hand
+ seine Hand
-
%1's hand
accusative
- %1s Hand
+ %1s Hand
his hand
@@ -546,40 +606,34 @@
%1s Hand
-
his library
nominative
- seine Bibliothek
+ seine Bibliothek
-
%1's library
nominative
- %1s Bibliothek
+ %1s Bibliothek
-
of his library
genitive
- seiner Bibliothek
+ seiner Bibliothek
-
of %1's library
genitive
- von %1s Bibliothek
+ von %1s Bibliothek
-
his library
accusative
- seine Bibliothek
+ seine Bibliothek
-
%1's library
accusative
- %1s Bibliothek
+ %1s Bibliothek
his library
@@ -592,40 +646,394 @@
%1s Bibliothek
-
- his graveyard
- nominative
- sein Friedhof
+
+ her hand
+ nominative, female owner
+ ihre Hand
-
+
+ %1's hand
+ nominative, female owner
+ %1s Hand
+
+
+
+ his hand
+ nominative, male owner
+ seine Hand
+
+
+
+ %1's hand
+ nominative, male owner
+ %1s Hand
+
+
+
+ of her hand
+ genitive, female owner
+ ihrer Hand
+
+
+
+ of %1's hand
+ genitive, female owner
+ von %1s Hand
+
+
+
+ of his hand
+ genitive, male owner
+ seiner Hand
+
+
+
+ of %1's hand
+ genitive, male owner
+ von %1s Hand
+
+
+
+ her hand
+ accusative, female owner
+ ihre Hand
+
+
+
+ %1's hand
+ accusative, female owner
+ %1s Hand
+
+
+
+ his hand
+ accusative, male owner
+ seine Hand
+
+
+
+ %1's hand
+ accusative, male owner
+ %1s Hand
+
+
+
+ her library
+ nominative, female owner
+ ihre Bibliothek
+
+
+
+ %1's library
+ nominative, female owner
+ %1s Bibliothek
+
+
+
+ his library
+ nominative, male owner
+ seine Bibliothek
+
+
+
+ %1's library
+ nominative, male owner
+ %1s Bibliothek
+
+
+
+ of her library
+ genitive, female owner
+ ihrer Bibliothek
+
+
+
+ of %1's library
+ genitive, female owner
+ von %1s Bibliothek
+
+
+
+ of his library
+ genitive, male owner
+ seiner Bibliothek
+
+
+
+ of %1's library
+ genitive, male owner
+ von %1s Bibliothek
+
+
+
+ her library
+ accusative, female owner
+ ihre Bibliothek
+
+
+
+ %1's library
+ accusative, female owner
+ %1s Bibliothek
+
+
+
+ his library
+ accusative, male owner
+ seine Bibliothek
+
+
+
+ %1's library
+ accusative, male owner
+ %1s Bibliothek
+
+
+
+ her graveyard
+ nominative, female owner
+ ihr Friedhof
+
+
+
%1's graveyard
- nominative
+ nominative, female owner
%1s Friedhof
- of his graveyard
- genitive
- seines Friedhofs
+ his graveyard
+ nominative, male owner
+ sein Friedhof
+ %1's graveyard
+ nominative, male owner
+ %1s Friedhof
+
+
+
+ of her graveyard
+ genitive, female owner
+ ihres Friedhofs
+
+
+
of %1's graveyard
- genitive
+ genitive, female owner
von %1s Friedhof
- his graveyard
- accusative
- sein Friedhof
+ of his graveyard
+ genitive, male owner
+ seines Friedhofs
+ of %1's graveyard
+ genitive, male owner
+ von %1s Friedhof
+
+
+
+ her graveyard
+ accusative, female owner
+ ihren Friedhof
+
+
+
+ %1's graveyard
+ accusative, female owner
+ %1s Friedhof
+
+
+
+ his graveyard
+ accusative, male owner
+ seinen Friedhof
+
+
+
+ %1's graveyard
+ accusative, male owner
+ %1s Friedhof
+
+
+
+ her exile
+ nominative, female owner
+ ihr Exil
+
+
+
+ %1's exile
+ nominative, female owner
+ %1s Exil
+
+
+
+ his exile
+ nominative, male owner
+ sein Exil
+
+
+
+ %1's exile
+ nominative, male owner
+ %1s Exil
+
+
+
+ of her exile
+ genitive, female owner
+ ihres Exils
+
+
+
+ of %1's exile
+ genitive, female owner
+ von %1s Exil
+
+
+
+ of his exile
+ genitive, male owner
+ seines Exils
+
+
+
+ of %1's exile
+ genitive, male owner
+ von %1s Exil
+
+
+
+ her exile
+ accusative, female owner
+ ihr Exil
+
+
+
+ %1's exile
+ accusative, female owner
+ %1s Exil
+
+
+
+ his exile
+ accusative, male owner
+ sein Exil
+
+
+
+ %1's exile
+ accusative, male owner
+ %1s Exil
+
+
+
+ her sideboard
+ nominative, female owner
+ ihr Sideboard
+
+
+
+ %1's sideboard
+ nominative, female owner
+ %1s Sideboard
+
+
+
+ his sideboard
+ nominative, male owner
+ sein Sideboard
+
+
+
+ %1's sideboard
+ nominative, male owner
+ %1s Sideboard
+
+
+
+ of her sideboard
+ genitive, female owner
+ ihres Sideboards
+
+
+
+ of %1's sideboard
+ genitive, female owner
+ von %1s Sideboard
+
+
+
+ of his sideboard
+ genitive, male owner
+ seines Sideboards
+
+
+
+ of %1's sideboard
+ genitive, male owner
+ von %1s Sideboard
+
+
+
+ her sideboard
+ accusative, female owner
+ ihr Sideboard
+
+
+
+ %1's sideboard
+ accusative, female owner
+ %1s Sideboard
+
+
+
+ his sideboard
+ accusative, male owner
+ sein Sideboard
+
+
+
+ %1's sideboard
+ accusative, male owner
+ %1s Sideboard
+
+
+ his graveyard
+ nominative
+ sein Friedhof
+
+
+ %1's graveyard
+ nominative
+ %1s Friedhof
+
+
+ of his graveyard
+ genitive
+ seines Friedhofs
+
+
+ of %1's graveyard
+ genitive
+ von %1s Friedhof
+
+
+ his graveyard
+ accusative
+ sein Friedhof
+
+
%1's graveyard
accusative
- %1s Friedhof
+ %1s Friedhof
his graveyard
@@ -638,40 +1046,34 @@
%1s Friedhof
-
his exile
nominative
- sein Exil
+ sein Exil
-
%1's exile
nominative
- %1s Exil
+ %1s Exil
-
of his exile
genitive
- seines Exils
+ seines Exils
-
of %1's exile
genitive
- von %1s Exil
+ von %1s Exil
-
his exile
accusative
- sein Exil
+ sein Exil
-
%1's exile
accusative
- %1s Exil
+ %1s Exil
his exile
@@ -684,40 +1086,34 @@
%1s Exil
-
his sideboard
nominative
- sein Sideboard
+ sein Sideboard
-
%1's sideboard
nominative
- %1s Sideboard
+ %1s Sideboard
-
of his sideboard
genitive
- seines Sideboards
+ seines Sideboards
-
of %1's sideboard
genitive
- von %1s Sideboard
+ von %1s Sideboard
-
his sideboard
accusative
- sein Sideboard
+ sein Sideboard
-
%1's sideboard
accusative
- %1s Sideboard
+ %1s Sideboard
his sideboard
@@ -810,6 +1206,19 @@
Neuer Wert für den Zähler '%1':
+
+ DeckEditorSettingsPage
+
+
+ Enable &price tag feature (using data from blacklotusproject.com)
+ Karten&preisfunktionen anschalten (benutzt Daten von blacklotusproject.com)
+
+
+
+ General
+ Allgemeines
+
+
DeckList
@@ -828,35 +1237,40 @@
DeckListModel
-
+
Number
Nummer
-
+
Card
Karte
+
+
+ Price
+ Preis
+
DeckViewContainer
-
+
Load &local deck
&Lokales Deck laden
-
+
Load d&eck from server
Deck vom Server l&aden
-
+
Ready to s&tart
Bereit zum S&tarten
-
+
Load deck
Deck laden
@@ -952,42 +1366,42 @@
&Beschreibung:
-
+
&Password:
&Passwort:
-
+
P&layers:
&Spieler:
-
+
Game type
Spieltyp
-
+
Only &buddies can join
Nur &Freunde können teilnehmen
-
+
Only ®istered users can join
Nur ®istrierte Benutzer können teilnehmen
-
+
Joining restrictions
Teilnahmebedingungen
-
+
&Spectators allowed
&Zuschauer zugelassen
-
+
Spectators &need a password to join
Zuschauer brauchen &auch ein Passwort
@@ -996,37 +1410,37 @@
Zuschauer können sp&rechen
-
+
Spectators can &chat
Zuschauer können s&chreiben
-
+
Spectators see &everything
Zuschauer sehen &alles
-
+
Spectators
Zuschauer
-
+
&OK
&OK
-
+
&Cancel
&Abbruch
-
+
Create game
Spiel erstellen
-
+
Error
Fehler
@@ -1035,7 +1449,7 @@
Ungültige Anzahl an Spielern.
-
+
Server error.
Serverfehler.
@@ -1208,9 +1622,9 @@
DlgSettings
-
-
-
+
+
+
Error
Fehler
@@ -1227,47 +1641,52 @@
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
-
+
+ Deck editor
+ Deckeditor
+
+
+
Messages
Nachrichten
-
+
&Close
S&chließen
@@ -1533,23 +1952,24 @@
GameSelector
-
+
C&reate
Spiel e&rstellen
-
+
&Join
&Teilnehmen
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
Error
Fehler
@@ -1558,66 +1978,76 @@
XXX
-
+
+ Please join the appropriate room first.
+ Bitte betreten Sie erst den entsprechenden Raum.
+
+
+
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.
-
+
This game is only open to registered users.
Dieses Spiel kann nur von registrierten Benutzern betreten werden.
-
+
This game is only open to its creator's buddies.
Dieses Spiel kann nur von Freunden des Erstellers betreten werden.
-
+
You are being ignored by the creator of this game.
Der Ersteller dieses Spiels ignoriert Sie.
-
+
Join game
Spiel beitreten
-
+
Password:
Passwort:
-
+
Games
Spiele
-
+
Show &full games
&Volle Spiele anzeigen
+
+
+ Show &running games
+ &Laufende Spiele anzeigen
+
&Show full games
&Volle Spiele anzeigen
-
+
J&oin as spectator
&Zuschauen
@@ -1633,12 +2063,12 @@
GamesModel
-
+
yes
ja
-
+
no
nein
@@ -1647,57 +2077,62 @@
Spiel ID
-
+
Creator
Ersteller
-
+
Description
Beschreibung
-
+
yes, free for spectators
ja, außer für Zuschauer
-
+
buddies only
nur Freunde
-
+
reg. users only
nur reg. Benutzer
-
+
not allowed
nicht erlaubt
+ Room
+ Raum
+
+
+
Game type
Spieltyp
-
+
Password
Passwort
-
+
Restrictions
Bedingungen
-
+
Players
Spieler
-
+
Spectators
Zuschauer
@@ -1705,50 +2140,50 @@
GeneralSettingsPage
-
-
-
+
+
+
Choose path
Pfad auswählen
-
+
Personal settings
Persönliche Einstellungen
-
+
Language:
Sprache:
-
+
Download card pictures on the fly
Kartenbilder dynamisch herunterladen
-
+
Paths
Pfade
-
+
Decks directory:
Verzeichnis mit Decklisten:
-
+
Pictures directory:
Verzeichnis mit Bilddateien:
-
+
Path to card database:
Pfad zur Kartendatenbank:
-
-
+
+
English
Deutsch
@@ -1767,128 +2202,162 @@
+ Scheduled server shutdown.
+ Planmäßige Serverabschaltung.
+
+
+
Unknown reason.
Unbekannter Grund.
-
+
Connection closed
Verbindung geschlossen
-
+
The server has terminated your connection.
Reason: %1
Der Server hat Ihre Verbindung beendet.
Grund: %1
-
+
+ Scheduled server shutdown
+ Planmäßige Serverabschaltung
+
+
+
+ The server is going to be restarted in %n minute(s).
+All running games will be lost.
+Reason for shutdown: %1
+
+ Der Server wird in %n Minute neu gestartet.
+Alle laufenden Spiele werden beendet.
+Grund für die Abschaltung: %1
+ Der Server wird in %n Minuten neu gestartet.
+Alle laufenden Spiele werden beendet.
+Grund für die Abschaltung: %1
+
+
+
+
Number of players
Spieleranzahl
-
+
Please enter the number of players.
Bitte die Spieleranzahl eingeben:
-
-
+
+
Player %1
Spieler %1
-
+
About Cockatrice
Ü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:
-
+
Russian:
Russisch:
-
-
-
-
-
-
+
+ Czech:
+ Tschechisch:
+
+
+
+ Slovak:
+ Slowakisch:
+
+
+
+
+
+
+
+
Error
Fehler
-
+
Server timeout
Server Zeitüberschreitung
-
+
Invalid login data.
Ungültige Anmeldedaten.
-
+
There is already an active session using this user name.
Please close that session first and re-login.
Es gibt bereits eine aktive Verbindung mit diesem Benutzernamen.
Bitte schließen Sie diese Verbindung zuerst und versuchen Sie es dann erneut.
-
+
Socket error: %1
Netzwerkfehler: %1
-
+
You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server.
Local version is %1, remote version is %2.
Sie versuchen sich an einem veralteten Server anzumelden. Bitte verwenden Sie eine ältere Cockatrice-Version oder melden Sie sich an einem aktuellen Server an.
Lokale Version ist %1, Serverversion ist %2.
-
+
Your Cockatrice client is obsolete. Please update your Cockatrice version.
Local version is %1, remote version is %2.
Ihr Cockatrice-Client ist veraltet. Bitte laden Sie sich die neueste Version herunter.
@@ -1899,52 +2368,52 @@ Lokale Version ist %1, Serverversion ist %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?
@@ -1961,27 +2430,27 @@ Lokale Version ist %1, Serverversion ist %2.
Spiel ver&lassen
-
+
&Deck editor
&Deck-Editor
-
+
&Full screen
&Vollbild
-
+
Ctrl+F
Ctrl+F
-
+
&Settings...
&Einstellungen...
-
+
&Exit
&Beenden
@@ -1994,7 +2463,7 @@ Lokale Version ist %1, Serverversion ist %2.
Esc
-
+
&Cockatrice
&Cockatrice
@@ -2022,24 +2491,20 @@ Lokale Version ist %1, Serverversion ist %2.
MessageLogWidget
-
Connecting to %1...
- Verbinde zu %1...
+ Verbinde zu %1...
-
Connected.
- Verbunden.
+ Verbunden.
-
Disconnected from server.
- Verbindung zum Server getrennt.
+ Verbindung zum Server getrennt.
-
Invalid password.
- Ungültiges Passwort.
+ Ungültiges Passwort.
You have joined the game. Player list:
@@ -2078,8 +2543,8 @@ Lokale Version ist %1, Serverversion ist %2.
%1 zieht %2 Karten
-
-
+
+
a card
eine Karte
@@ -2136,14 +2601,13 @@ Lokale Version ist %1, Serverversion ist %2.
%1s Sideboard
-
+
The game has started.
Das Spiel hat begonnen.
-
%1 shuffles his library.
- %1 mischt seine Bibliothek.
+ %1 mischt seine Bibliothek.
%1 rolls a %2 with a %3-sided dice.
@@ -2158,74 +2622,71 @@ Lokale Version ist %1, Serverversion ist %2.
Protokollversion stimmt nicht überein.
-
- Protocol version mismatch. Client: %1, Server: %2
-
-
-
-
Protocol error.
- Protokollfehler.
+ Protokollfehler.
-
You have joined game #%1.
- Sie sind dem Spiel %1 beigetreten.
+ Sie sind dem Spiel %1 beigetreten.
-
%1 has joined the game.
- %1 ist dem Spiel beigetreten.
+ %1 ist dem Spiel beigetreten.
-
%1 has left the game.
- %1 hat das Spiel verlassen.
+ %1 hat das Spiel verlassen.
-
+
The game has been closed.
Das Spiel wurde geschlossen.
-
+
%1 is now watching the game.
%1 schaut nun dem Spiel zu.
-
+
%1 is not watching the game any more.
%1 schaut dem Spiel nicht mehr zu.
-
%1 has loaded a local deck.
- %1 hat ein lokales Deck geladen.
+ %1 hat ein lokales Deck geladen.
-
%1 has loaded deck #%2.
- %1 hat das Deck Nr. %2 geladen.
+ %1 hat das Deck Nr. %2 geladen.
-
%1 is ready to start the game.
- %1 ist bereit, das Spiel zu starten.
+ %1 ist bereit, das Spiel zu starten.
-
%1 is not ready to start the game any more.
- %1 ist nicht mehr bereit, das Spiel zu starten.
+ %1 ist nicht mehr bereit, das Spiel zu starten.
-
%1 has conceded the game.
- %1 hat das Spiel aufgegeben.
+ %1 hat das Spiel aufgegeben.
+
+
+ %1 has restored connection to the game.
+ %1 ist wieder mit dem Spiel verbunden.
+
+
+ %1 has lost connection to the game.
+ %1 hat die Verbindung zum Spiel verloren.
+
+
+ %1 shuffles %2.
+ %1 mischt %2.
-
%1 rolls a %2 with a %3-sided die.
- %1 würfelt eine %2 mit einem %3-seitigen Würfel.
+ %1 würfelt eine %2 mit einem %3-seitigen Würfel.
%1 draws a card.
@@ -2236,217 +2697,1063 @@ Lokale Version ist %1, Serverversion ist %2.
%1 zieht %2 Karten.
-
%1 draws %n card(s).
+
+ %1 zieht eine Karte.
+ %1 zieht %n Karten.
+
+
+
+
+ You have joined game #%1.
+ female
+ Sie sind dem Spiel %1 beigetreten.
+
+
+
+ You have joined game #%1.
+ male
+ Sie sind dem Spiel %1 beigetreten.
+
+
+
+ %1 has joined the game.
+ female
+ %1 ist dem Spiel beigetreten.
+
+
+
+ %1 has joined the game.
+ male
+ %1 ist dem Spiel beigetreten.
+
+
+
+ %1 has left the game.
+ female
+ %1 hat das Spiel verlassen.
+
+
+
+ %1 has left the game.
+ male
+ %1 hat das Spiel verlassen.
+
+
+
+ %1 has loaded a local deck.
+ female
+ %1 hat ein lokales Deck geladen.
+
+
+
+ %1 has loaded a local deck.
+ male
+ %1 hat ein lokales Deck geladen.
+
+
+
+ %1 has loaded deck #%2.
+ female
+ %1 hat das Deck Nr. %2 geladen.
+
+
+
+ %1 has loaded deck #%2.
+ male
+ %1 hat das Deck Nr. %2 geladen.
+
+
+
+ %1 is ready to start the game.
+ female
+ %1 ist bereit, das Spiel zu starten.
+
+
+
+ %1 is ready to start the game.
+ male
+ %1 ist bereit, das Spiel zu starten.
+
+
+
+ %1 is not ready to start the game any more.
+ female
+ %1 ist nicht mehr bereit, das Spiel zu starten.
+
+
+
+ %1 is not ready to start the game any more.
+ male
+ %1 ist nicht mehr bereit, das Spiel zu starten.
+
+
+
+ %1 has conceded the game.
+ female
+ %1 hat das Spiel aufgegeben.
+
+
+
+ %1 has conceded the game.
+ male
+ %1 hat das Spiel aufgegeben.
+
+
+
+ %1 has restored connection to the game.
+ female
+ %1 ist wieder mit dem Spiel verbunden.
+
+
+
+ %1 has restored connection to the game.
+ male
+ %1 ist wieder mit dem Spiel verbunden.
+
+
+
+ %1 has lost connection to the game.
+ female
+ %1 hat die Verbindung zum Spiel verloren.
+
+
+
+ %1 has lost connection to the game.
+ male
+ %1 hat die Verbindung zum Spiel verloren.
+
+
+
+ %1 shuffles %2.
+ female
+ %1 mischt %2.
+
+
+
+ %1 shuffles %2.
+ male
+ %1 mischt %2.
+
+
+
+ %1 rolls a %2 with a %3-sided die.
+ female
+ %1 würfelt eine %2 mit einem %3-seitigen Würfel.
+
+
+
+ %1 rolls a %2 with a %3-sided die.
+ male
+ %1 würfelt eine %2 mit einem %3-seitigen Würfel.
+
+
+
+ %1 draws %n card(s).
+ female
+
+ %1 zieht eine Karte.
+ %1 zieht %n Karten.
+
+
+
+
+ %1 draws %n card(s).
+ male
%1 zieht eine Karte.
%1 zieht %n Karten.
-
+
%1 undoes his last draw.
%1 legt die zuletzt gezogene Karte zurück.
-
+
+ %1 undoes her last draw.
+ %1 legt die zuletzt gezogene Karte zurück.
+
+
+
%1 undoes his last draw (%2).
%1 legt die zuletzt gezogene Karte zurück (%2).
-
+
+ %1 undoes her last draw (%2).
+ %1 legt die zuletzt gezogene Karte zurück (%2).
+
+
+
from table
vom Spielfeld
-
+
from graveyard
aus dem Friedhof
-
+
from exile
aus dem Exil
-
+
from hand
von der Hand
-
+
the bottom card of his library
die unterste Karte seiner Bibliothek
-
+
+ the bottom card of her library
+ die unterste Karte ihrer Bibliothek
+
+
+
from the bottom of his library
, die unterste Karte seiner Bibliothek,
-
+
+ from the bottom of her library
+ , die unterste Karte ihrer Bibliothek,
+
+
+
the top card of his library
die oberste Karte seiner Bibliothek
-
+
+ the top card of her library
+ die oberste Karte ihrer Bibliothek
+
+
+
from the top of his library
, die oberste Karte seiner Bibliothek,
-
+
+ from the top of her library
+ , die oberste Karte ihrer Bibliothek,
+
+
+
from library
aus der Bibliothek
-
+
from sideboard
aus dem Sideboard
-
+
from the stack
vom Stapel
-
+
%1 gives %2 control over %3.
%1 überlässt %2 die Kontrolle über %3.
-
+
%1 puts %2 into play tapped%3.
%1 bringt %2 getappt%3 ins Spiel.
-
+
%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 into her library.
+ %1 legt %2%3 in ihre Bibliothek.
+
+
+
%1 puts %2%3 on bottom of his library.
%1 legt %2%3 unter seine Bibliothek.
-
+
+ %1 puts %2%3 on bottom of her library.
+ %1 legt %2%3 unter ihre Bibliothek.
+
+
+
%1 puts %2%3 on top of his library.
%1 legt %2%3 auf die Bibliothek.
-
+
+ %1 puts %2%3 on top of her 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 puts %2%3 into her library at position %4.
+ %1 legt %2%3 in ihre 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 takes a mulligan to %n.
+ female
+
+ %1 nimmt einen Mulligan auf %n.
+ %1 nimmt einen Mulligan auf %n.
+
+
+
+
+ %1 takes a mulligan to %n.
+ male
+
+ %1 nimmt einen Mulligan auf %n.
+ %1 nimmt einen Mulligan auf %n.
+
+
-
+
%1 flips %2 face-down.
+ female
%1 wendet %2 auf die Rückseite.
-
+
+ %1 flips %2 face-down.
+ male
+ %1 wendet %2 auf die Rückseite.
+
+
+
%1 flips %2 face-up.
+ female
%1 wendet %2 auf die Vorderseite.
-
+
+ %1 flips %2 face-up.
+ male
+ %1 wendet %2 auf die Vorderseite.
+
+
+
%1 destroys %2.
+ female
+ %1 zerstört %2.
+
+
+
+ %1 destroys %2.
+ male
%1 zerstört %2.
-
%1 attaches %2 to %3's %4.
+ female
+ %1 legt %2 an %3s %4 an.
+
+
+ %1 attaches %2 to %3's %4.
+ male
+ %1 legt %2 an %3s %4 an.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 female
%1 legt %2 an %3s %4 an.
-
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 male
+ %1 legt %2 an %3s %4 an.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 female
+ %1 legt %2 an %3s %4 an.
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 male
+ %1 legt %2 an %3s %4 an.
+
+
+
%1 unattaches %2.
+ female
%1 löst %2 ab.
-
+
+ %1 unattaches %2.
+ male
+ %1 löst %2 ab.
+
+
+
%1 creates token: %2%3.
+ female
%1 erstellt Token: %2%3.
-
+
+ %1 creates token: %2%3.
+ male
+ %1 erstellt Token: %2%3.
+
+
+
+ %1 points from her %2 to herself.
+ female
+ %1 zeigt von ihrem %2 auf sich selbst.
+
+
+
+ %1 points from his %2 to himself.
+ male
+ %1 zeigt von seinem %2 auf sich selbst.
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 female
+ %1 zeigt von ihrem %2 auf %3.
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 male
+ %1 zeigt von ihrem %2 auf %3.
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 female
+ %1 zeigt von seinem %2 auf %3.
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 male
+ %1 zeigt von seinem %2 auf %3.
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner female, target female
+ %1 zeigt von %2s %3 auf sich selbst.
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner male, target female
+ %1 zeigt von %2s %3 auf sich selbst.
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner female, target male
+ %1 zeigt von %2s %3 auf sich selbst.
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner male, target male
+ %1 zeigt von %2s %3 auf sich selbst.
+
+
+
%1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 female
%1 zeigt von %2s %3 auf %4.
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 male
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 female
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 male
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 female
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 male
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 female
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 male
+ %1 zeigt von %2s %3 auf %4.
+
+
+
+ %1 points from her %2 to her %3.
+ female
+ %1 zeigt von ihrem %2 auf ihren %3.
+
+
+
+ %1 points from his %2 to his %3.
+ male
+ %1 zeigt von seinem %2 auf seinen %3.
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 female
+ %1 zeigt von ihrem %2 auf %3s %4.
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 male
+ %1 zeigt von ihrem %2 auf %3s %4.
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 female
+ %1 zeigt von seinem %2 auf %3s %4.
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 male
+ %1 zeigt von seinem %2 auf %3s %4.
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner female, target female
+ %1 zeigt von %2s %3 auf ihren eigenen %4.
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner male, target female
+ %1 zeigt von %2s %3 auf ihren eigenen %4.
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner female, target male
+ %1 zeigt von %2s %3 auf seinen eigenen %4.
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner male, target male
+ %1 zeigt von %2s %3 auf seinen eigenen %4.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 female
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 male
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 female
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 male
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 female
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 male
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 female
+ %1 zeigt von %2s %3 auf %4s %5.
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 male
+ %1 zeigt von %2s %3 auf %4s %5.
+
-
+
%1 places %n %2 counter(s) on %3 (now %4).
+ female
%1 legt eine %2 Marke auf %3 (jetzt %4).
%1 legt %n %2 Marken auf %3 (jetzt %4).
-
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+ male
+
+ %1 legt eine %2 Marke auf %3 (jetzt %4).
+ %1 legt %n %2 Marken auf %3 (jetzt %4).
+
+
+
+
%1 removes %n %2 counter(s) from %3 (now %4).
+ female
+
+ %1 entfernt eine %2 Marke von %3 (jetzt %4).
+ %1 entfernt %n %2 Marken von %3 (jetzt %4).
+
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+ male
%1 entfernt eine %2 Marke von %3 (jetzt %4).
%1 entfernt %n %2 Marken von %3 (jetzt %4).
-
+
+ %1 taps her permanents.
+ female
+ %1 tappt ihre bleibenden Karten.
+
+
+
+ %1 untaps her permanents.
+ female
+ %1 enttappt ihre bleibenden Karten.
+
+
+
+ %1 taps his permanents.
+ male
+ %1 tappt seine bleibenden Karten.
+
+
+
+ %1 untaps his permanents.
+ male
+ %1 enttappt seine bleibenden Karten.
+
+
+
+ %1 taps %2.
+ female
+ %1 tappt %2.
+
+
+
+ %1 untaps %2.
+ female
+ %1 enttappt %2.
+
+
+
+ %1 taps %2.
+ male
+ %1 tappt %2.
+
+
+
+ %1 untaps %2.
+ male
+ %1 enttappt %2.
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ female
+ %1 setzt Zähler %2 auf %3 (%4%5).
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ male
+ %1 setzt Zähler %2 auf %3 (%4%5).
+
+
+
+ %1 sets %2 to not untap normally.
+ female
+ %1 setzt %2 auf explizites Enttappen.
+
+
+
+ %1 sets %2 to not untap normally.
+ male
+ %1 setzt %2 auf explizites Enttappen.
+
+
+
+ %1 sets %2 to untap normally.
+ female
+ %1 setzt %2 auf normales Enttappen.
+
+
+
+ %1 sets %2 to untap normally.
+ male
+ %1 setzt %2 auf normales Enttappen.
+
+
+
+ %1 sets PT of %2 to %3.
+ female
+ %1 setzt Kampfwerte von %2 auf %3.
+
+
+
+ %1 sets PT of %2 to %3.
+ male
+ %1 setzt Kampfwerte von %2 auf %3.
+
+
+
+ %1 sets annotation of %2 to %3.
+ female
+ %1 versieht %2 mit dem Hinweis %3.
+
+
+
+ %1 sets annotation of %2 to %3.
+ male
+ %1 versieht %2 mit dem Hinweis %3.
+
+
+
+ %1 is looking at the top %2 cards %3.
+ female
+ %1 sieht sich die obersten %2 Karten %3 an.
+
+
+
+ %1 is looking at the top %2 cards %3.
+ male
+ %1 sieht sich die obersten %2 Karten %3 an.
+
+
+
+ %1 is looking at %2.
+ female
+ %1 sieht sich %2 an.
+
+
+
+ %1 is looking at %2.
+ male
+ %1 sieht sich %2 an.
+
+
+
+ %1 stops looking at %2.
+ female
+ %1 sieht sich %2 nicht mehr an.
+
+
+
+ %1 stops looking at %2.
+ male
+ %1 sieht sich %2 nicht mehr an.
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 female
+ %1 zeigt %3 %2.
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 male
+ %1 zeigt %3 %2.
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 female
+ %1 zeigt %3 %2.
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 male
+ %1 zeigt %3 %2.
+
+
+
+ %1 reveals %2.
+ female
+ %1 zeigt %2 offen vor.
+
+
+
+ %1 reveals %2.
+ male
+ %1 zeigt %2 offen vor.
+
+
+
%1 randomly reveals %2%3 to %4.
+ p1 female, p2 female
%1 zeigt %4 zufällig %2%3 vor.
-
+
+ %1 randomly reveals %2%3 to %4.
+ p1 female, p2 male
+ %1 zeigt %4 zufällig %2%3 vor.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 female
+ %1 zeigt %4 zufällig %2%3 vor.
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 male
+ %1 zeigt %4 zufällig %2%3 vor.
+
+
+
%1 randomly reveals %2%3.
+ female
%1 zeigt zufällig %2%3 offen vor.
-
+
+ %1 randomly reveals %2%3.
+ male
+ %1 zeigt zufällig %2%3 offen vor.
+
+
+
%1 reveals %2%3 to %4.
+ p1 female, p2 female
%1 zeigt %4 %2%3 vor.
-
+
+ %1 reveals %2%3 to %4.
+ p1 female, p2 male
+ %1 zeigt %4 %2%3 vor.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 female
+ %1 zeigt %4 %2%3 vor.
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 male
+ %1 zeigt %4 %2%3 vor.
+
+
+
%1 reveals %2%3.
+ female
%1 zeigt %2%3 offen vor.
+
+
+ %1 reveals %2%3.
+ male
+ %1 zeigt %2%3 offen vor.
+
+
+
+ It is now %1's turn.
+ female
+ %1 ist am Zug.
+
+
+
+ It is now %1's turn.
+ male
+ %1 ist am Zug.
+
+
+ %1 takes a mulligan to %n.
+
+ %1 nimmt einen Mulligan auf %n.
+ %1 nimmt einen Mulligan auf %n.
+
+
+
+
+ %1 draws his initial hand.
+ %1 zieht seine Starthand.
+
+
+
+ %1 draws her initial hand.
+ %1 zieht ihre Starthand.
+
+
+ %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 places %n %2 counter(s) on %3 (now %4).
+
+ %1 legt eine %2 Marke auf %3 (jetzt %4).
+ %1 legt %n %2 Marken auf %3 (jetzt %4).
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+
+ %1 entfernt eine %2 Marke von %3 (jetzt %4).
+ %1 entfernt %n %2 Marken von %3 (jetzt %4).
+
+
+
+ her permanents
+ ihre bleibenden Karten
+
+
+ %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.
+
%1 creates token: %2 (%3).
%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 zeigt von %2s %3 auf %4s %5.
%1 places %n counter(s) (%2) on %3 (now %4).
@@ -2463,7 +3770,7 @@ Lokale Version ist %1, Serverversion ist %2.
-
+
red
rote
@@ -2471,7 +3778,7 @@ Lokale Version ist %1, Serverversion ist %2.
-
+
yellow
gelbe
@@ -2479,7 +3786,7 @@ Lokale Version ist %1, Serverversion ist %2.
-
+
green
grüne
@@ -2487,24 +3794,20 @@ Lokale Version ist %1, Serverversion ist %2.
-
%1 sets counter %2 to %3 (%4%5).
- %1 setzt Zähler %2 auf %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 setzt Kampfwerte von %2 auf %3.
-
%1 sets annotation of %2 to %3.
- %1 versieht %2 mit dem Hinweis %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.
+ %1 sieht sich die obersten %2 Karten %3 an.
from graveyard
@@ -2599,9 +3902,8 @@ Lokale Version ist %1, Serverversion ist %2.
%1 entfernt %2 Zählmarken von %3 (jetzt %4).
-
%1 %2 %3.
- %1 %2 %3.
+ %1 %2 %3.
%1 sets counter "%2" to %3 (%4%5).
@@ -2612,24 +3914,20 @@ Lokale Version ist %1, Serverversion ist %2.
%1 sieht sich die obersten %2 Karten %3 an.
-
%1 is looking at %2.
- %1 sieht sich %2 an.
+ %1 sieht sich %2 an.
-
%1 stops looking at %2.
- %1 sieht sich %2 nicht mehr an.
+ %1 sieht sich %2 nicht mehr an.
-
%1 reveals %2 to %3.
- %1 zeigt %3 %2.
+ %1 zeigt %3 %2.
-
%1 reveals %2.
- %1 zeigt %2 offen vor.
+ %1 zeigt %2 offen vor.
%1 randomly reveals %2 from %3 to %4.
@@ -2648,7 +3946,7 @@ Lokale Version ist %1, Serverversion ist %2.
%1 zeigt %2 aus %3 offen vor.
-
+
ending phase
die Zugendphase
@@ -2677,57 +3975,56 @@ Lokale Version ist %1, Serverversion ist %2.
%1 sieht sich %2s %3 nicht mehr an
-
It is now %1's turn.
- %1 ist am Zug.
+ %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
@@ -2736,7 +4033,7 @@ Lokale Version ist %1, Serverversion ist %2.
das Ende-des-Zuges-Segment
-
+
It is now the %1.
Es ist nun %1.
@@ -2745,14 +4042,12 @@ Lokale Version ist %1, Serverversion ist %2.
%1 bewegt %2 %3 nach %4
-
taps
- tappt
+ tappt
-
untaps
- enttappt
+ enttappt
%1 creates token: <font color="blue">%2</font>
@@ -2775,9 +4070,8 @@ Lokale Version ist %1, Serverversion ist %2.
%1 entfernt %2 Zählmarken von %3 (jetzt %4)
-
his permanents
- seine bleibenden Karten
+ seine bleibenden Karten
%1 %2 %3
@@ -2788,14 +4082,12 @@ Lokale Version ist %1, Serverversion ist %2.
%1 setzt Zähler "%2" auf %3 (%4%5)
-
%1 sets %2 to not untap normally.
- %1 setzt %2 auf explizites Enttappen.
+ %1 setzt %2 auf explizites Enttappen.
-
%1 sets %2 to untap normally.
- %1 setzt %2 auf normales Enttappen.
+ %1 setzt %2 auf normales Enttappen.
%1 is looking at the top %2 cards of %3's %4
@@ -2809,12 +4101,12 @@ Lokale Version ist %1, Serverversion ist %2.
MessagesSettingsPage
-
+
&Add
&Hinzufügen
-
+
&Remove
&Entfernen
@@ -2827,12 +4119,12 @@ Lokale Version ist %1, Serverversion ist %2.
Entfernen
-
+
Add message
Nachricht hinzufügen
-
+
Message:
Nachricht:
@@ -2898,21 +4190,21 @@ Lokale Version ist %1, Serverversion ist %2.
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
@@ -2921,37 +4213,37 @@ Lokale Version ist %1, Serverversion ist %2.
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
-
+
Ctrl+F3
Ctrl+F3
-
+
F4
F4
@@ -2960,73 +4252,73 @@ Lokale Version ist %1, Serverversion ist %2.
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
-
+
&Undo last draw
Zuletzt gezogene Karte zur&ücklegen
-
+
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
@@ -3035,7 +4327,7 @@ Lokale Version ist %1, Serverversion ist %2.
Entfe&rnte Karten
-
+
&Sideboard
&Sideboard
@@ -3048,33 +4340,33 @@ Lokale Version ist %1, Serverversion ist %2.
&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
@@ -3083,28 +4375,28 @@ Lokale Version ist %1, Serverversion ist %2.
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
@@ -3113,37 +4405,37 @@ Lokale Version ist %1, Serverversion ist %2.
&Mulligan nehmen...
-
+
Ctrl+M
Ctrl+M
-
+
&Shuffle
Mi&schen
-
+
Ctrl+S
Ctrl+S
-
+
&Counters
&Zähler
-
+
&Untap all permanents
&Enttappe alle bleibenden Karten
-
+
Ctrl+Shift+D
Ctrl+Shift+D
-
+
Ctrl+U
Ctrl+U
@@ -3172,42 +4464,42 @@ Lokale Version ist %1, Serverversion ist %2.
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
@@ -3300,50 +4592,50 @@ Lokale Version ist %1, Serverversion ist %2.
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
@@ -3356,12 +4648,12 @@ Lokale Version ist %1, Serverversion ist %2.
Neue Lebenspunkte insgesamt:
-
+
Roll die
Würfeln
-
+
Number of sides:
Anzahl der Seiten:
@@ -3475,17 +4767,17 @@ Lokale Version ist %1, Serverversion ist %2.
Sideboard
-
+
Cockatrice decks (*.cod)
Cockatrice Decks (*.cod)
-
+
Plain text decks (*.dec *.mwDeck)
Text Decks (*.dec *.mwDeck)
-
+
All files (*.*)
Alle Dateien (*.*)
@@ -3561,40 +4853,77 @@ Lokale Version ist %1, Serverversion ist %2.
Langer Name
+
+ ShutdownDialog
+
+
+ &Reason for shutdown:
+ G&rund für die Abschaltung:
+
+
+
+ &Time until shutdown (minutes):
+ &Zeit bis zur Abschaltung (Minuten):
+
+
+
+ &OK
+ &OK
+
+
+
+ &Cancel
+ &Abbrechen
+
+
+
+ Shut down server
+ Server abschalten
+
+
TabAdmin
-
+
Update server &message
Server&nachricht aktualisieren
-
+ Shut down server
+ Server abschalten
+
+
+
+ &Shut down server
+ &Server abschalten
+
+
+
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
@@ -3689,102 +5018,107 @@ Bitte geben Sie einen Namen ein:
TabGame
-
+
F5
F5
-
+
F6
F6
-
+
F7
F7
-
+
F8
F8
-
+
F9
F9
-
+
F10
F10
-
+
&Phases
&Phasen
-
+
&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
-
+
+ Ctrl+Q
+ Ctrl+Q
+
+
+
Kicked
Herausgeworfen
-
+
You have been kicked out of the game.
Sie wurden aus dem Spiel geworfen.
@@ -3805,7 +5139,7 @@ Bitte geben Sie einen Namen ein:
Spiel s&tarten
-
+
&Say:
&Sagen:
@@ -3818,22 +5152,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?
@@ -3850,32 +5184,32 @@ Bitte geben Sie einen Namen ein:
TabMessage
-
+
Personal &talk
Persönliches &Gespräch
-
+
&Leave
Ver&lassen
-
+
This user is ignoring you.
Dieser Benutzer ignoriert Sie.
-
+
%1 has left the server.
%1 hat den Server verlassen.
-
+
%1 has joined the server.
%1 hat den Server betreten.
-
+
Talking to %1
Gespräch mit %1
@@ -3883,27 +5217,27 @@ Bitte geben Sie einen Namen ein:
TabRoom
-
+
&Say:
&Sagen:
-
+
Chat
Unterhaltung
-
+
&Room
&Raum
-
+
&Leave room
Raum ver&lassen
-
+
You are flooding the chat. Please wait a couple of seconds.
Sie überfluten den Chatraum. Bitte warten Sie ein paar Sekunden.
@@ -3950,42 +5284,51 @@ Bitte geben Sie einen Namen ein:
UserInfoBox
-
+
User information
Benutzerinformationen
-
+
Real name:
Richtiger Name:
-
+
+ Gender:
+ Geschlecht:
+
+
+
Location:
Ort:
-
+
User level:
Nutzerstatus:
-
+
Administrator
Administrator
-
- Judge
- Schiedsrichter
+
+ Moderator
+ Moderator
-
+ Judge
+ Schiedsrichter
+
+
+
Registered user
Registrierter Benutzer
-
+
Unregistered user
Unregistrierter Benutzer
@@ -3993,130 +5336,153 @@ Bitte geben Sie einen Namen ein:
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
+
+
+ Enable &sounds
+ &Sound anschalten
+
+
+
+ Path to sounds directory:
+ Pfad zum Verzeichnis mit den Sounddateien:
+
+
+
+ Choose path
+ Pfad auswählen
+
UserList
-
+
Users online: %1
Benutzer online: %1
-
+
Users in this room: %1
Benutzer in diesem Raum: %1
-
+
Buddies online: %1 / %2
Freunde online: %1 / %2
-
+
Ignored users online: %1 / %2
Ignorierte Benutzer online: %1 / %2
-
+
+ %1's games
+ %1s Spiele
+
+
+
User &details
Benutzer&details
-
+
Direct &chat
&Persönliches Gespräch
-
+
+ Show this user's &games
+ Spiele dieses &Benutzers anzeigen
+
+
+
Add to &buddy list
Zur &Freundesliste hinzufügen
-
+
Remove from &buddy list
Von &Freundesliste entfernen
-
+
Add to &ignore list
&Ignorieren
-
+
Remove from &ignore list
Nicht mehr &ignorieren
-
+
Ban from &server
Vom &Server bannen
-
Duration
- Dauer
+ Dauer
-
Please enter the duration of the ban (in minutes).
Enter 0 for an indefinite ban.
- Bitte geben Sie die Dauer des Banns ein (in Minuten).
+ Bitte geben Sie die Dauer des Banns ein (in Minuten).
Geben Sie 0 ein für einen unbefristeten Bann.
WndDeckEditor
-
+
&Search for:
&Suchen nach:
-
+
Deck &name:
Deck &Name:
-
+
&Comments:
&Kommentare:
-
+
Deck editor [*]
Deck-Editor [*]
-
+
&New deck
&Neues Deck
-
+
&Load deck...
Deck &laden...
-
+
&Save deck
Deck &speichern
@@ -4125,37 +5491,37 @@ Geben Sie 0 ein für einen unbefristeten Bann.
Deck &speichern unter...
-
+
Save deck &as...
Deck s&peichern unter...
-
+
Save deck to clip&board
Deck in Z&wischenablage speichern
-
+
&Print deck...
Deck &drucken...
-
+
&Close
S&chließen
-
+
Ctrl+Q
Ctrl+Q
-
+
&Edit sets...
&Editionen bearbeiten...
-
+
&Deck
&Deck
@@ -4164,27 +5530,27 @@ Geben Sie 0 ein für einen unbefristeten Bann.
&Editionen
-
+
Add card to &maindeck
Karte zu&m Hauptdeck hinzufügen
-
+
Return
Return
-
+
Enter
Enter
-
+
Ctrl+Return
Ctrl+Return
-
+
Ctrl+Enter
Ctrl+Enter
@@ -4193,7 +5559,7 @@ Geben Sie 0 ein für einen unbefristeten Bann.
Ctrl+M
-
+
Add card to &sideboard
Karte zum &Sideboard hinzufügen
@@ -4202,88 +5568,98 @@ Geben Sie 0 ein für einen unbefristeten Bann.
Ctrl+N
-
+
&Search...
&Suchen...
-
+
&Clear search
Suche a&ufheben
-
+
+ &Update prices
+ &Preise aktualisieren
+
+
+
+ Ctrl+U
+ Ctrl+U
+
+
+
Load deck from cl&ipboard...
Deck aus &Zwischenablage laden...
-
+
&Card database
&Kartendatenbank
-
+
&Remove row
Zeile entfe&rnen
-
+
Del
Entf
-
+
&Increment number
Anzahl er&höhen
-
+
+
+
-
+
&Decrement number
Anzahl v&erringern
-
+
-
-
-
+
Are you sure?
Bist du sicher?
-
+
The decklist has been modified.
Do you want to save the changes?
Die Deckliste wurde verändert.
Willst du die Änderungen speichern?
-
+
Load deck
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 f4912678f..4c6421f19 100644
--- a/cockatrice/translations/cockatrice_en.ts
+++ b/cockatrice/translations/cockatrice_en.ts
@@ -37,90 +37,125 @@
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:
-
+
Card rendering
-
+
Display card names on cards having a picture
-
+
Hand layout
-
+
Display hand horizontally (wastes space)
-
+
Table grid layout
-
+
Invert vertical coordinate
-
+
+ Minimum player count for multi-column layout:
+
+
+
+
Zone view layout
-
+
Sort by name
-
+
Sort by type
-
-
-
-
-
+
+
+
+
+
Choose path
+
+ BanDialog
+
+
+ Please enter the duration of the ban (in minutes).
+Enter 0 for an indefinite ban.
+
+
+
+
+ Please enter the reason for the ban.
+This is only saved for moderators and cannot be seen by the banned person.
+
+
+
+
+ &OK
+
+
+
+
+ &Cancel
+
+
+
+
+ Ban user from server
+
+
+
CardDatabaseModel
@@ -152,22 +187,42 @@
CardInfoWidget
-
+
+ Hide card info
+
+
+
+
+ Show card only
+
+
+
+
+ Show text only
+
+
+
+
+ Show full info
+
+
+
+
Name:
-
+
Mana cost:
-
+
Card type:
-
+
P / T:
@@ -175,197 +230,202 @@
CardItem
-
+
&Play
-
+
&Hide
-
+
&Tap
-
+
&Untap
-
+
Toggle &normal untapping
-
+
&Flip
-
+
&Clone
-
+
Ctrl+H
-
+
&Attach to card...
-
+
Ctrl+A
-
+
Unattac&h
-
-
- &Power / toughness
-
-
-
-
- &Increase power
-
-
-
-
- Ctrl++
-
-
-
-
- &Decrease power
-
-
-
-
- Ctrl+-
-
-
-
-
- I&ncrease toughness
-
-
- Alt++
+ &Draw arrow...
- D&ecrease toughness
+ &Power / toughness
- Alt+-
+ &Increase power
- In&crease power and toughness
+ Ctrl++
- Ctrl+Alt++
+ &Decrease power
- Dec&rease power and toughness
+ Ctrl+-
- Ctrl+Alt+-
+ I&ncrease toughness
- Set &power and toughness...
+ Alt++
- Ctrl+P
+ D&ecrease toughness
- &Set annotation...
+ Alt+-
+
+
+
+
+ In&crease power and toughness
- red
+ Ctrl+Alt++
- yellow
+ Dec&rease power and toughness
- green
+ Ctrl+Alt+-
+
+
+
+
+ Set &power and toughness...
- &Add counter (%1)
+ Ctrl+P
-
- &Remove counter (%1)
+
+ &Set annotation...
+
+
+
+
+ red
- &Set counters (%1)...
+ yellow
- &top of library
-
-
-
-
- &bottom of library
+ green
- &graveyard
-
-
-
-
- Ctrl+Del
+ &Add counter (%1)
- &exile
+ &Remove counter (%1)
+ &Set counters (%1)...
+
+
+
+
+ &top of library
+
+
+
+
+ &bottom of library
+
+
+
+
+ &graveyard
+
+
+
+
+ Ctrl+Del
+
+
+
+
+ &exile
+
+
+
+
&Move to
@@ -373,218 +433,416 @@
CardZone
-
- his hand
- nominative
+
+ her hand
+ nominative, female owner
-
+
%1's hand
- nominative
+ nominative, female owner
- of his hand
- genitive
+ his hand
+ nominative, male owner
+ %1's hand
+ nominative, male owner
+
+
+
+
+ of her hand
+ genitive, female owner
+
+
+
+
of %1's hand
- genitive
+ genitive, female owner
- his hand
- accusative
+ of his hand
+ genitive, male owner
+ of %1's hand
+ genitive, male owner
+
+
+
+
+ her hand
+ accusative, female owner
+
+
+
+
%1's hand
- accusative
+ accusative, female owner
-
- his library
- nominative
+
+ his hand
+ accusative, male owner
-
+
+ %1's hand
+ accusative, male owner
+
+
+
+
+ her library
+ nominative, female owner
+
+
+
+
%1's library
- nominative
+ nominative, female owner
- of his library
- genitive
+ his library
+ nominative, male owner
+ %1's library
+ nominative, male owner
+
+
+
+
+ of her library
+ genitive, female owner
+
+
+
+
of %1's library
- genitive
+ genitive, female owner
- his library
- accusative
+ of his library
+ genitive, male owner
+ of %1's library
+ genitive, male owner
+
+
+
+
+ her library
+ accusative, female owner
+
+
+
+
%1's library
- accusative
+ accusative, female owner
-
- his graveyard
- nominative
+
+ his library
+ accusative, male owner
-
+
+ %1's library
+ accusative, male owner
+
+
+
+
+ her graveyard
+ nominative, female owner
+
+
+
+
%1's graveyard
- nominative
+ nominative, female owner
- of his graveyard
- genitive
+ his graveyard
+ nominative, male owner
+ %1's graveyard
+ nominative, male owner
+
+
+
+
+ of her graveyard
+ genitive, female owner
+
+
+
+
of %1's graveyard
- genitive
+ genitive, female owner
- his graveyard
- accusative
+ of his graveyard
+ genitive, male owner
+ of %1's graveyard
+ genitive, male owner
+
+
+
+
+ her graveyard
+ accusative, female owner
+
+
+
+
%1's graveyard
- accusative
+ accusative, female owner
-
- his exile
- nominative
+
+ his graveyard
+ accusative, male owner
-
+
+ %1's graveyard
+ accusative, male owner
+
+
+
+
+ her exile
+ nominative, female owner
+
+
+
+
%1's exile
- nominative
+ nominative, female owner
- of his exile
- genitive
+ his exile
+ nominative, male owner
+ %1's exile
+ nominative, male owner
+
+
+
+
+ of her exile
+ genitive, female owner
+
+
+
+
of %1's exile
- genitive
+ genitive, female owner
- his exile
- accusative
+ of his exile
+ genitive, male owner
+ of %1's exile
+ genitive, male owner
+
+
+
+
+ her exile
+ accusative, female owner
+
+
+
+
%1's exile
- accusative
+ accusative, female owner
-
- his sideboard
- nominative
+
+ his exile
+ accusative, male owner
-
+
+ %1's exile
+ accusative, male owner
+
+
+
+
+ her sideboard
+ nominative, female owner
+
+
+
+
%1's sideboard
- nominative
+ nominative, female owner
- of his sideboard
- genitive
+ his sideboard
+ nominative, male owner
+ %1's sideboard
+ nominative, male owner
+
+
+
+
+ of her sideboard
+ genitive, female owner
+
+
+
+
of %1's sideboard
- genitive
+ genitive, female owner
- his sideboard
- accusative
+ of his sideboard
+ genitive, male owner
+ of %1's sideboard
+ genitive, male owner
+
+
+
+
+ her sideboard
+ accusative, female owner
+
+
+
+
%1's sideboard
- accusative
+ accusative, female owner
+
+
+
+
+ his sideboard
+ accusative, male owner
+
+
+
+
+ %1's sideboard
+ accusative, male owner
+
+
+
+
+ DeckEditorSettingsPage
+
+
+ Enable &price tag feature (using data from blacklotusproject.com)
+
+
+
+
+ General
DeckListModel
-
+
Number
-
+
Card
+
+
+ Price
+
+
DeckViewContainer
-
+
Load &local deck
-
+
Load d&eck from server
-
+
Ready to s&tart
-
+
Load deck
@@ -673,82 +931,82 @@
-
+
&Password:
-
+
P&layers:
-
+
Game type
-
+
Only &buddies can join
-
+
Only ®istered users can join
-
+
Joining restrictions
-
+
&Spectators allowed
-
+
Spectators &need a password to join
-
+
Spectators can &chat
-
+
Spectators see &everything
-
+
Spectators
-
+
&OK
-
+
&Cancel
-
+
Create game
-
+
Error
-
+
Server error.
@@ -890,54 +1148,59 @@
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
-
+
+ Deck editor
+
+
+
+
Messages
-
+
&Close
@@ -945,83 +1208,94 @@
GameSelector
-
+
C&reate
-
+
&Join
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
Error
-
+
+ Please join the appropriate room first.
+
+
+
+
Wrong password.
-
+
Spectators are not allowed in this game.
-
+
The game is already full.
-
+
The game does not exist any more.
-
+
This game is only open to registered users.
-
+
This game is only open to its creator's buddies.
-
+
You are being ignored by the creator of this game.
-
+
Join game
-
+
Password:
-
+
Games
-
+
Show &full games
-
+
+ Show &running games
+
+
+
+
J&oin as spectator
@@ -1037,67 +1311,72 @@
GamesModel
-
+
yes
-
+
no
-
+
Creator
-
+
Description
-
+
yes, free for spectators
-
+
buddies only
-
+
reg. users only
-
+
not allowed
- Game type
-
-
-
-
- Password
-
-
-
-
- Restrictions
+ Room
- Players
+ Game type
+ Password
+
+
+
+
+ Restrictions
+
+
+
+
+ Players
+
+
+
+
Spectators
@@ -1105,50 +1384,50 @@
GeneralSettingsPage
-
-
-
+
+
+
Choose path
-
+
Personal settings
-
+
Language:
-
+
Download card pictures on the fly
-
+
Paths
-
+
Decks directory:
-
+
Pictures directory:
-
+
Path to card database:
-
-
+
+
English
English
@@ -1167,206 +1446,236 @@
+ Scheduled server shutdown.
+
+
+
+
Unknown reason.
-
+
Connection closed
-
+
The server has terminated your connection.
Reason: %1
-
+
+ Scheduled server shutdown
+
+
+
+
+ The server is going to be restarted in %n minute(s).
+All running games will be lost.
+Reason for shutdown: %1
+
+
+
+
+
+
+
Number of players
-
+
Please enter the number of players.
-
-
+
+
Player %1
-
+
About Cockatrice
-
+
Version %1
-
+
Authors:
-
+
Translators:
-
+
Spanish:
-
+
Portugese (Portugal):
-
+
Portugese (Brazil):
-
+
French:
-
+
Japanese:
-
+
Russian:
-
-
-
-
-
-
+
+ Czech:
+
+
+
+
+ Slovak:
+
+
+
+
+
+
+
+
+
Error
-
+
Server timeout
-
+
Invalid login data.
-
+
There is already an active session using this user name.
Please close that session first and re-login.
-
+
Socket error: %1
-
+
You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server.
Local version is %1, remote version is %2.
-
+
Your Cockatrice client is obsolete. Please update your Cockatrice version.
Local version is %1, remote version is %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?
@@ -1374,212 +1683,962 @@ Local version is %1, remote version is %2.
MessageLogWidget
-
- Connecting to %1...
-
-
-
-
- Disconnected from server.
-
-
-
-
- Invalid password.
-
-
-
-
- Protocol error.
-
-
-
-
+
The game has been closed.
-
+
%1 is now watching the game.
-
+
%1 is not watching the game any more.
-
-
- %1 is not ready to start the game any more.
-
-
-
-
- %1 rolls a %2 with a %3-sided die.
-
-
-
%1 draws %n card(s).
-
+
%1 draws a card.
%1 draws %n cards.
-
- %1 undoes his last draw.
+
+ You have joined game #%1.
+ female
+
+
+
+
+ You have joined game #%1.
+ male
+
+
+
+
+ %1 has joined the game.
+ female
+
+
+
+
+ %1 has joined the game.
+ male
+
+
+
+
+ %1 has left the game.
+ female
+
+
+
+
+ %1 has left the game.
+ male
+
+
+
+
+ %1 has loaded a local deck.
+ female
+
+
+
+
+ %1 has loaded a local deck.
+ male
+
+
+
+
+ %1 has loaded deck #%2.
+ female
+
+
+
+
+ %1 has loaded deck #%2.
+ male
+
+
+
+
+ %1 is ready to start the game.
+ female
+
+
+
+
+ %1 is ready to start the game.
+ male
+
+
+
+
+ %1 is not ready to start the game any more.
+ female
+
+
+
+
+ %1 is not ready to start the game any more.
+ male
+
+
+
+
+ %1 has conceded the game.
+ female
+
+
+
+
+ %1 has conceded the game.
+ male
+
+
+
+
+ %1 has restored connection to the game.
+ female
+
+
+
+
+ %1 has restored connection to the game.
+ male
+
+
+
+
+ %1 has lost connection to the game.
+ female
+
+
+
+
+ %1 has lost connection to the game.
+ male
+
+
+
+
+ %1 shuffles %2.
+ female
+
+
+
+
+ %1 shuffles %2.
+ male
- %1 undoes his last draw (%2).
+ %1 rolls a %2 with a %3-sided die.
+ female
-
- from table
+
+ %1 rolls a %2 with a %3-sided die.
+ male
-
+
- from graveyard
-
+ %1 draws %n card(s).
+ female
+
+ %1 draws a card.
+ %1 draws %n cards.
+
-
+
- from exile
+ %1 draws %n card(s).
+ male
+
+ %1 draws a card.
+ %1 draws %n cards.
+
+
+
+
+ %1 undoes his last draw.
-
- from hand
-
-
-
-
- the bottom card of his library
+
+ %1 undoes her last draw.
- from the bottom of his library
+ %1 undoes his last draw (%2).
-
- the top card of his library
-
-
-
-
- from the top of his library
-
-
-
-
- from library
+
+ %1 undoes her last draw (%2).
- from sideboard
+ from table
+ from graveyard
+
+
+
+
+ from exile
+
+
+
+
+ from hand
+
+
+
+
+ the bottom card of his library
+
+
+
+
+ the bottom card of her library
+
+
+
+
+ from the bottom of his library
+
+
+
+
+ from the bottom of her library
+
+
+
+
+ the top card of his library
+
+
+
+
+ the top card of her library
+
+
+
+
+ from the top of his library
+
+
+
+
+ from the top of her library
+
+
+
+
+ from library
+
+
+
+
+ from sideboard
+
+
+
+
from the stack
-
+
%1 gives %2 control over %3.
-
+
%1 puts %2 into play tapped%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 into her library.
+
+
+
+
%1 puts %2%3 on bottom of his library.
-
+
+ %1 puts %2%3 on bottom of her library.
+
+
+
+
%1 puts %2%3 on top of his library.
-
+
+ %1 puts %2%3 on top of her library.
+
+
+
+
%1 puts %2%3 into his library at position %4.
-
+
+ %1 puts %2%3 into her library at position %4.
+
+
+
+
%1 moves %2%3 to sideboard.
-
+
%1 plays %2%3.
-
-
-
- a card
-
+
+
+ %1 takes a mulligan to %n.
+ female
+
+
+
+
+
+
+
+ %1 takes a mulligan to %n.
+ male
+
+
+
+
-
+
%1 flips %2 face-down.
+ female
-
+
+ %1 flips %2 face-down.
+ male
+
+
+
+
%1 flips %2 face-up.
+ female
-
- %1 attaches %2 to %3's %4.
+
+ %1 flips %2 face-up.
+ male
-
+
+ %1 destroys %2.
+ female
+
+
+
+
+ %1 destroys %2.
+ male
+
+
+
+
%1 unattaches %2.
+ female
-
+
+ %1 unattaches %2.
+ male
+
+
+
+
+ %1 creates token: %2%3.
+ female
+
+
+
+
+ %1 creates token: %2%3.
+ male
+
+
+
+
+ %1 points from her %2 to herself.
+ female
+
+
+
+
+ %1 points from his %2 to himself.
+ male
+
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 female
+
+
+
+
+ %1 points from her %2 to %3.
+ p1 female, p2 male
+
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 female
+
+
+
+
+ %1 points from his %2 to %3.
+ p1 male, p2 male
+
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner female, target female
+
+
+
+
+ %1 points from %2's %3 to herself.
+ card owner male, target female
+
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner female, target male
+
+
+
+
+ %1 points from %2's %3 to himself.
+ card owner male, target male
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 female, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 female, p2 male, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 female, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4.
+ p1 male, p2 male, p3 male
+
+
+
+
+ %1 points from her %2 to her %3.
+ female
+
+
+
+
+ %1 points from his %2 to his %3.
+ male
+
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 female
+
+
+
+
+ %1 points from her %2 to %3's %4.
+ p1 female, p2 male
+
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 female
+
+
+
+
+ %1 points from his %2 to %3's %4.
+ p1 male, p2 male
+
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner female, target female
+
+
+
+
+ %1 points from %2's %3 to her own %4.
+ card owner male, target female
+
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner female, target male
+
+
+
+
+ %1 points from %2's %3 to his own %4.
+ card owner male, target male
+
+
+
+
%1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 female, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 female, p2 male, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 female, p3 male
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 female
+
+
+
+
+ %1 points from %2's %3 to %4's %5.
+ p1 male, p2 male, p3 male
+
+
+
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+ female
+
+ %1 places a %2 counter on %3 (now %4).
+ %1 places %n %2 counters on %3 (now %4).
+
+
+
+
+ %1 places %n %2 counter(s) on %3 (now %4).
+ male
+
+ %1 places a %2 counter on %3 (now %4).
+ %1 places %n %2 counters on %3 (now %4).
+
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+ female
+
+ %1 removes a %2 counter from %3 (now %4).
+ %1 removes %n %2 counters from %3 (now %4).
+
+
+
+
+ %1 removes %n %2 counter(s) from %3 (now %4).
+ male
+
+ %1 removes a %2 counter from %3 (now %4).
+ %1 removes %n %2 counters from %3 (now %4).
+
+
+
+
+ %1 taps her permanents.
+ female
+
+
+
+
+ %1 untaps her permanents.
+ female
+
+
+
+
+ %1 taps his permanents.
+ male
+
+
+
+
+ %1 untaps his permanents.
+ male
+
+
+
+
+ %1 taps %2.
+ female
+
+
+
+
+ %1 untaps %2.
+ female
+
+
+
+
+ %1 taps %2.
+ male
+
+
+
+
+ %1 untaps %2.
+ male
+
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ female
+
+
+
+
+ %1 sets counter %2 to %3 (%4%5).
+ male
+
+
+
+
+ %1 sets %2 to not untap normally.
+ female
+
+
+
+
+ %1 sets %2 to not untap normally.
+ male
+
+
+
+
+ %1 sets %2 to untap normally.
+ female
+
+
+
+
+ %1 sets %2 to untap normally.
+ male
+
+
+
+
+ %1 sets PT of %2 to %3.
+ female
+
+
+
+
+ %1 sets PT of %2 to %3.
+ male
+
+
+
+
+ %1 sets annotation of %2 to %3.
+ female
+
+
+
+
+ %1 sets annotation of %2 to %3.
+ male
+
+
+
+
+ %1 is looking at the top %2 cards %3.
+ female
+
+
+
+
+ %1 is looking at the top %2 cards %3.
+ male
+
+
+
+
+ %1 is looking at %2.
+ female
+
+
+
+
+ %1 is looking at %2.
+ male
+
+
+
+
+ %1 stops looking at %2.
+ female
+
+
+
+
+ %1 stops looking at %2.
+ male
+
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 female
+
+
+
+
+ %1 reveals %2 to %3.
+ p1 female, p2 male
+
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 female
+
+
+
+
+ %1 reveals %2 to %3.
+ p1 male, p2 male
+
+
+
+
+ %1 reveals %2.
+ female
+
+
+
+
+ %1 reveals %2.
+ male
+
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 female, p2 female
+
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 female, p2 male
+
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 female
+
+
+
+
+ %1 randomly reveals %2%3 to %4.
+ p1 male, p2 male
+
+
+
+
+ %1 randomly reveals %2%3.
+ female
+
+
+
+
+ %1 randomly reveals %2%3.
+ male
+
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 female, p2 female
+
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 female, p2 male
+
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 female
+
+
+
+
+ %1 reveals %2%3 to %4.
+ p1 male, p2 male
+
+
+
+
+ %1 reveals %2%3.
+ female
+
+
+
+
+ %1 reveals %2%3.
+ male
+
+
+
+
+ It is now %1's turn.
+ female
+
+
+
+
+ It is now %1's turn.
+ male
+
+
+
+
+
+ a card
@@ -1597,7 +2656,7 @@ Local version is %1, remote version is %2.
-
+
red
@@ -1605,7 +2664,7 @@ Local version is %1, remote version is %2.
-
+
yellow
@@ -1613,7 +2672,7 @@ Local version is %1, remote version is %2.
-
+
green
@@ -1621,266 +2680,138 @@ Local version is %1, remote version is %2.
-
- %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.
-
-
-
-
+
The game has started.
-
- Connected.
+
+ %1 draws his initial hand.
-
- Protocol version mismatch. Client: %1, Server: %2
-
-
-
-
- You have joined game #%1.
-
-
-
-
- %1 has joined the game.
-
-
-
-
- %1 has left the game.
-
-
-
-
- %1 has loaded a local deck.
-
-
-
-
- %1 has loaded deck #%2.
-
-
-
-
- %1 is ready to start the game.
-
-
-
-
- %1 has conceded the game.
-
-
-
-
- %1 destroys %2.
-
-
-
-
- %1 creates token: %2%3.
-
-
-
-
- %1 points from %2's %3 to %4.
+
+ %1 draws her initial hand.
-
%1 places %n %2 counter(s) on %3 (now %4).
-
+
%1 places a %2 counter on %3 (now %4).
%1 places %n %2 counters on %3 (now %4).
-
%1 removes %n %2 counter(s) from %3 (now %4).
-
+
%1 removes a %2 counter from %3 (now %4).
%1 removes %n %2 counters from %3 (now %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.
-
-
-
-
- %1 shuffles his library.
-
-
-
-
- %1 randomly reveals %2%3 to %4.
-
-
-
-
- %1 randomly reveals %2%3.
-
-
-
-
- %1 reveals %2%3 to %4.
-
-
-
-
- %1 reveals %2%3.
-
-
-
-
+
untap step
-
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 female
+
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 female, p2 male
+
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 female
+
+
+
+
+ %1 attaches %2 to %3's %4.
+ p1 male, p2 male
+
+
+
+
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
-
-
MessagesSettingsPage
-
+
&Add
-
+
&Remove
-
+
Add message
-
+
Message:
@@ -1946,322 +2877,322 @@ Local version is %1, remote version is %2.
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 &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
-
+
&Undo last draw
-
+
Move top cards to &exile...
-
+
Put top card on &bottom
-
+
&Reveal to
-
+
Reveal r&andom card to
-
+
C&ard
-
+
&All players
-
+
Ctrl+F3
-
+
Ctrl+Shift+D
-
+
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
@@ -2327,17 +3258,17 @@ Local version is %1, remote version is %2.
-
+
Cockatrice decks (*.cod)
-
+
Plain text decks (*.dec *.mwDeck)
-
+
All files (*.*)
@@ -2406,40 +3337,73 @@ Local version is %1, remote version is %2.
+
+ ShutdownDialog
+
+
+ &Reason for shutdown:
+
+
+
+
+ &Time until shutdown (minutes):
+
+
+
+
+ &OK
+
+
+
+
+ &Cancel
+
+
+
+
+ Shut down server
+
+
+
TabAdmin
-
+
Update server &message
-
+
+ &Shut down server
+
+
+
+
Server administration functions
-
+
&Unlock functions
-
+
&Lock functions
-
+
Unlock administration functions
-
+
Do you really want to unlock the administration functions?
-
+
Administration
@@ -2514,127 +3478,132 @@ Please enter a name:
TabGame
-
+
F5
-
+
F6
-
+
F7
-
+
F8
-
+
F9
-
+
F10
-
+
&Phases
-
+
&Game
-
+
Next &phase
-
+
Ctrl+Space
-
+
Next &turn
-
+
Ctrl+Return
-
+
Ctrl+Enter
-
+
&Remove all local arrows
-
+
Ctrl+R
-
+
&Concede
-
+
F2
-
+
&Leave game
-
+
+ Ctrl+Q
+
+
+
+
&Say:
-
+
Concede
-
+
Are you sure you want to concede this game?
-
+
Leave game
-
+
Are you sure you want to leave this game?
-
+
Kicked
-
+
You have been kicked out of the game.
@@ -2647,32 +3616,32 @@ Please enter a name:
TabMessage
-
+
Personal &talk
-
+
&Leave
-
+
This user is ignoring you.
-
+
%1 has left the server.
-
+
%1 has joined the server.
-
+
Talking to %1
@@ -2680,27 +3649,27 @@ Please enter a name:
TabRoom
-
+
&Say:
-
+
Chat
-
+
&Room
-
+
&Leave room
-
+
You are flooding the chat. Please wait a couple of seconds.
@@ -2724,42 +3693,47 @@ Please enter a name:
UserInfoBox
-
+
User information
-
+
Real name:
-
+
+ Gender:
+
+
+
+
Location:
-
+
User level:
-
+
Administrator
-
- Judge
+
+ Moderator
-
+
Registered user
-
+
Unregistered user
@@ -2767,277 +3741,301 @@ Please enter a name:
UserInterfaceSettingsPage
-
+
General interface settings
-
+
&Double-click cards to play them (instead of single-click)
-
+
Animation settings
-
+
&Tap/untap animation
+
+
+ Enable &sounds
+
+
+
+
+ Path to sounds directory:
+
+
+
+
+ Choose path
+
+
UserList
-
+
Users online: %1
-
+
Users in this room: %1
-
+
Buddies online: %1 / %2
-
+
Ignored users online: %1 / %2
-
+
+ %1's games
+
+
+
+
User &details
-
+
Direct &chat
-
+
+ Show this user's &games
+
+
+
+
Add to &buddy list
-
+
Remove from &buddy list
-
+
Add to &ignore list
-
+
Remove from &ignore list
-
+
Ban from &server
-
-
- Duration
-
-
-
-
- Please enter the duration of the ban (in minutes).
-Enter 0 for an indefinite ban.
-
-
WndDeckEditor
-
+
&Search for:
-
+
Deck &name:
-
+
&Comments:
-
+
Deck editor [*]
-
+
&New deck
-
+
&Load deck...
-
+
Load deck from cl&ipboard...
-
+
&Save deck
-
+
+ &Update prices
+
+
+
+
+ Ctrl+U
+
+
+
+
Save deck &as...
-
+
Save deck to clip&board
-
+
&Print deck...
-
+
&Close
-
+
Ctrl+Q
-
+
&Edit sets...
-
+
&Deck
-
+
Load deck
-
+
Error
-
+
The deck could not be saved.
Please check that the directory is writable and try again.
-
+
Save deck
-
+
Add card to &maindeck
-
+
Return
-
+
Enter
-
+
Ctrl+Return
-
+
Ctrl+Enter
-
+
Add card to &sideboard
-
+
&Search...
-
+
&Clear search
-
+
&Card database
-
+
&Remove row
-
+
Del
-
+
&Increment number
-
+
+
-
+
&Decrement number
-
+
-
-
+
Are you sure?
-
+
The decklist has been modified.
Do you want to save the changes?
diff --git a/cockatrice/translations/cockatrice_es.ts b/cockatrice/translations/cockatrice_es.ts
index 38b6ee326..cee81068a 100644
--- a/cockatrice/translations/cockatrice_es.ts
+++ b/cockatrice/translations/cockatrice_es.ts
@@ -37,66 +37,71 @@
AppearanceSettingsPage
-