00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kgamechat.h"
00022 #include "kgamechat.moc"
00023
00024 #include "kgame.h"
00025 #include "kplayer.h"
00026 #include "kgameproperty.h"
00027 #include "kgamemessage.h"
00028
00029 #include <klocale.h>
00030 #include <kdebug.h>
00031
00032 #include <QMap>
00033
00034
00035 #define FIRST_ID 2 // first id, that is free of use, aka not defined above
00036
00037 class KGameChatPrivate
00038 {
00039 public:
00040 KGameChatPrivate()
00041 {
00042 mFromPlayer = 0;
00043 mGame = 0;
00044
00045 mToMyGroup = -1;
00046 }
00047
00048 KGame* mGame;
00049 KPlayer* mFromPlayer;
00050 int mMessageId;
00051
00052
00053 QMap<int, int> mSendId2PlayerId;
00054 int mToMyGroup;
00055 };
00056
00057 KGameChat::KGameChat(KGame* g, int msgid, QWidget* parent, KChatBaseModel* model, KChatBaseItemDelegate* delegate)
00058 : KChatBase(parent, model, delegate),
00059 d( new KGameChatPrivate )
00060 {
00061 init(g, msgid);
00062 }
00063
00064 KGameChat::KGameChat(KGame* g, int msgid, KPlayer* fromPlayer, QWidget* parent, KChatBaseModel* model, KChatBaseItemDelegate* delegate)
00065 : KChatBase(parent,model,delegate),
00066 d( new KGameChatPrivate )
00067 {
00068 init(g, msgid);
00069 setFromPlayer(fromPlayer);
00070 }
00071
00072 KGameChat::KGameChat(QWidget* parent)
00073 : KChatBase(parent),
00074 d( new KGameChatPrivate )
00075 {
00076 init(0, -1);
00077 }
00078
00079 KGameChat::~KGameChat()
00080 {
00081 kDebug(11001) ;
00082 delete d;
00083 }
00084
00085 void KGameChat::init(KGame* g, int msgId)
00086 {
00087 kDebug(11001) ;
00088 setMessageId(msgId);
00089
00090 setKGame(g);
00091 }
00092
00093 void KGameChat::addMessage(int fromId, const QString& text)
00094 {
00095 if (!d->mGame) {
00096 kWarning(11001) << "no KGame object has been set";
00097 addMessage(i18n("Player %1", fromId), text);
00098 } else {
00099 KPlayer* p = d->mGame->findPlayer(fromId);
00100 if (p) {
00101 kDebug(11001) << "adding message of player" << p->name() << "id=" << fromId;
00102 addMessage(p->name(), text);
00103 } else {
00104 kWarning(11001) << "Could not find player id" << fromId;
00105 addMessage(i18nc("Unknown player", "Unknown"), text);
00106 }
00107 }
00108 }
00109
00110 void KGameChat::returnPressed(const QString& text)
00111 {
00112 if (!d->mFromPlayer) {
00113 kWarning(11001) << ": You must set a player first!";
00114 return;
00115 }
00116 if (!d->mGame) {
00117 kWarning(11001) << ": You must set a game first!";
00118 return;
00119 }
00120
00121 kDebug(11001) << "from:" << d->mFromPlayer->id() << "==" << d->mFromPlayer->name();
00122
00123 int id = sendingEntry();
00124
00125 if (isToGroupMessage(id)) {
00126
00127
00128 QString group = d->mFromPlayer->group();
00129 kDebug(11001) << "send to group" << group;
00130 int sender = d->mFromPlayer->id();
00131 d->mGame->sendGroupMessage(text, messageId(), sender, group);
00132
00133
00134
00135
00136
00137
00138 } else {
00139 int toPlayer = 0;
00140 if (!isSendToAllMessage(id) && isToPlayerMessage(id)) {
00141 toPlayer = playerId(id);
00142 if (toPlayer == -1) {
00143 kError(11001) << ": don't know that player "
00144 << "- internal ERROR";
00145 }
00146 }
00147 int receiver = toPlayer;
00148 int sender = d->mFromPlayer->id();
00149 d->mGame->sendMessage(text, messageId(), receiver, sender);
00150 }
00151 }
00152
00153 void KGameChat::setMessageId(int msgid)
00154 { d->mMessageId = msgid; }
00155
00156 int KGameChat::messageId() const
00157 { return d->mMessageId; }
00158
00159 bool KGameChat::isSendToAllMessage(int id) const
00160 { return (id == KChatBase::SendToAll); }
00161
00162 bool KGameChat::isToGroupMessage(int id) const
00163 { return (id == d->mToMyGroup); }
00164
00165 bool KGameChat::isToPlayerMessage(int id) const
00166 {
00167 return d->mSendId2PlayerId.contains(id); }
00168
00169 QString KGameChat::sendToPlayerEntry(const QString& name) const
00170 { return i18n("Send to %1", name); }
00171
00172 int KGameChat::playerId(int id) const
00173 {
00174 if (!isToPlayerMessage(id)) {
00175 return -1;
00176 }
00177
00178 return d->mSendId2PlayerId[id];
00179 }
00180
00181 int KGameChat::sendingId(int playerId) const
00182 {
00183 QMap<int, int>::Iterator it;
00184 for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
00185 if (it.value() == playerId) {
00186 return it.key();
00187 }
00188 }
00189 return -1;
00190 }
00191
00192 QString KGameChat::fromName() const
00193 { return d->mFromPlayer ? d->mFromPlayer->name() : QString(); }
00194
00195 bool KGameChat::hasPlayer(int id) const
00196 {
00197 return (sendingId(id) != -1);
00198 }
00199
00200 void KGameChat::setFromPlayer(KPlayer* p)
00201 {
00202 if (!p) {
00203 kError(11001) << ": NULL player";
00204 removeSendingEntry(d->mToMyGroup);
00205 d->mFromPlayer = 0;
00206 return;
00207 }
00208 if (d->mFromPlayer) {
00209 changeSendingEntry(p->group(), d->mToMyGroup);
00210 } else {
00211 if (d->mToMyGroup != -1) {
00212 kWarning(11001) << "send to my group exists already - removing";
00213 removeSendingEntry(d->mToMyGroup);
00214 }
00215 d->mToMyGroup = nextId();
00216 addSendingEntry(i18n("Send to My Group (\"%1\")", p->group()), d->mToMyGroup);
00217 }
00218 d->mFromPlayer = p;
00219 kDebug(11001) << "player=" << p;
00220 }
00221
00222
00223 void KGameChat::setKGame(KGame* g)
00224 {
00225 if (d->mGame) {
00226 slotUnsetKGame();
00227 }
00228 kDebug(11001) << "game=" << g;
00229 d->mGame = g;
00230
00231 if (d->mGame) {
00232 connect(d->mGame, SIGNAL(signalPlayerJoinedGame(KPlayer*)),
00233 this, SLOT(slotAddPlayer(KPlayer*)));
00234 connect(d->mGame, SIGNAL(signalPlayerLeftGame(KPlayer*)),
00235 this, SLOT(slotRemovePlayer(KPlayer*)));
00236 connect(d->mGame, SIGNAL(signalNetworkData(int, const QByteArray&, quint32, quint32)),
00237 this, SLOT(slotReceiveMessage(int, const QByteArray&, quint32, quint32)));
00238 connect(d->mGame, SIGNAL(destroyed()), this, SLOT(slotUnsetKGame()));
00239
00240 QList<KPlayer*> playerList = *d->mGame->playerList();
00241 for (int i = 0; i < playerList.count(); i++) {
00242 slotAddPlayer(playerList.at(i));
00243 }
00244 }
00245 }
00246
00247 KGame* KGameChat::game() const
00248 {
00249 return d->mGame;
00250 }
00251
00252 KPlayer* KGameChat::fromPlayer() const
00253 {
00254 return d->mFromPlayer;
00255 }
00256
00257 void KGameChat::slotUnsetKGame()
00258 {
00259
00260
00261 if (!d->mGame) {
00262 return;
00263 }
00264 disconnect(d->mGame, 0, this, 0);
00265 removeSendingEntry(d->mToMyGroup);
00266 QMap<int, int>::Iterator it;
00267 for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
00268 removeSendingEntry(it.value());
00269 }
00270 }
00271
00272 void KGameChat::slotAddPlayer(KPlayer* p)
00273 {
00274 if (!p) {
00275 kError(11001) << ": cannot add NULL player";
00276 return;
00277 }
00278 if (hasPlayer(p->id())) {
00279 kError(11001) << ": player was added before";
00280 return;
00281 }
00282
00283 int sendingId = nextId();
00284 addSendingEntry(comboBoxItem(p->name()), sendingId);
00285 d->mSendId2PlayerId.insert(sendingId, p->id());
00286 connect(p, SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)),
00287 this, SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*)));
00288 connect(p, SIGNAL(signalNetworkData(int, const QByteArray&, quint32, KPlayer*)),
00289 this, SLOT(slotReceivePrivateMessage(int, const QByteArray&, quint32, KPlayer*)));
00290 }
00291
00292 void KGameChat::slotRemovePlayer(KPlayer* p)
00293 {
00294 if (!p) {
00295 kError(11001) << ": NULL player";
00296 return;
00297 }
00298 if (!hasPlayer(p->id())) {
00299 kError(11001) << ": cannot remove non-existent player";
00300 return;
00301 }
00302
00303 int id = sendingId(p->id());
00304 removeSendingEntry(id);
00305 p->disconnect(this);
00306 d->mSendId2PlayerId.remove(id);
00307 }
00308
00309 void KGameChat::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player)
00310 {
00311 if (prop->id() == KGamePropertyBase::IdName) {
00312
00313 changeSendingEntry(player->name(), sendingId(player->id()));
00314
00315
00316
00317 } else if (prop->id() == KGamePropertyBase::IdGroup) {
00318
00319 }
00320 }
00321
00322 void KGameChat::slotReceivePrivateMessage(int msgid, const QByteArray& buffer, quint32 sender, KPlayer* me)
00323 {
00324 if (!me || me != fromPlayer()) {
00325 kDebug() << "nope - not for us!";
00326 return;
00327 }
00328 slotReceiveMessage(msgid, buffer, me->id(), sender);
00329 }
00330
00331 void KGameChat::slotReceiveMessage(int msgid, const QByteArray& buffer, quint32 , quint32 sender)
00332 {
00333 QDataStream msg(buffer);
00334 if (msgid != messageId()) {
00335 return;
00336 }
00337
00338 QString text;
00339 msg >> text;
00340
00341 addMessage(sender, text);
00342 }
00343