KDEGames

kgamechat.cpp
1/*
2 This file is part of the KDE games library
3 SPDX-FileCopyrightText: 2001-2002 Andreas Beckermann <b_mann@gmx.de>
4 SPDX-FileCopyrightText: 2001 Martin Heni <kde at heni-online.de>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include "kgamechat.h"
10
11// own
12#include "../kchatbase_p.h"
13#include "kgame.h"
14#include "kgamemessage.h"
15#include "kgameproperty.h"
16#include "kplayer.h"
17#include <kdegamesprivate_kgame_logging.h>
18// KF
19#include <KLocalizedString>
20// Qt
21#include <QMap>
22
23// FIXME:
24#define FIRST_ID 2 // first id, that is free of use, aka not defined above
25
26class KGameChatPrivate : public KChatBasePrivate
27{
28public:
29 KGameChatPrivate(KChatBaseModel *model, KChatBaseItemDelegate *delegate, QWidget *parent)
30 : KChatBasePrivate(model, delegate, parent)
31 {
32 }
33
34public:
35 KGame *mGame = nullptr;
36 KPlayer *mFromPlayer = nullptr;
37 int mMessageId;
38
39 QMap<int, int> mSendId2PlayerId;
40 int mToMyGroup = -1; // just as the above - but for the group, not for players
41};
42
43KGameChat::KGameChat(KGame *g, int msgid, QWidget *parent, KChatBaseModel *model, KChatBaseItemDelegate *delegate)
44 : KChatBase(*new KGameChatPrivate(model, delegate, parent), parent, false)
45{
46 init(g, msgid);
47}
48
49KGameChat::KGameChat(KGame *g, int msgid, KPlayer *fromPlayer, QWidget *parent, KChatBaseModel *model, KChatBaseItemDelegate *delegate)
50 : KChatBase(*new KGameChatPrivate(model, delegate, parent), parent, false)
51{
52 init(g, msgid);
53 setFromPlayer(fromPlayer);
54}
55
57 : KChatBase(*new KGameChatPrivate(nullptr, nullptr, parent), parent, false)
58{
59 init(nullptr, -1);
60}
61
62KGameChat::~KGameChat()
63{
64 qCDebug(KDEGAMESPRIVATE_KGAME_LOG);
65}
66
67void KGameChat::init(KGame *g, int msgId)
68{
69 qCDebug(KDEGAMESPRIVATE_KGAME_LOG);
70 setMessageId(msgId);
71
72 setKGame(g);
73}
74
75void KGameChat::addMessage(int fromId, const QString &text)
76{
78
79 if (!d->mGame) {
80 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << "no KGame object has been set";
81 addMessage(i18n("Player %1", fromId), text);
82 } else {
83 KPlayer *p = d->mGame->findPlayer(fromId);
84 if (p) {
85 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "adding message of player" << p->name() << "id=" << fromId;
86 addMessage(p->name(), text);
87 } else {
88 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << "Could not find player id" << fromId;
89 addMessage(i18nc("Unknown player", "Unknown"), text);
90 }
91 }
92}
93
95{
97
98 if (!d->mFromPlayer) {
99 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << ": You must set a player first!";
100 return;
101 }
102 if (!d->mGame) {
103 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << ": You must set a game first!";
104 return;
105 }
106
107 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "from:" << d->mFromPlayer->id() << "==" << d->mFromPlayer->name();
108
109 int id = sendingEntry();
110
111 if (isToGroupMessage(id)) {
112 // note: there is currently no support for other groups than the players
113 // group! It might be useful to send to other groups, too
114 QString group = d->mFromPlayer->group();
115 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "send to group" << group;
116 int sender = d->mFromPlayer->id();
117 d->mGame->sendGroupMessage(text, messageId(), sender, group);
118
119 // TODO
120 // AB: this message is never received!! we need to connect to
121 // KPlayer::networkData!!!
122 // TODO
123
124 } else {
125 int toPlayer = 0;
126 if (!isSendToAllMessage(id) && isToPlayerMessage(id)) {
127 toPlayer = playerId(id);
128 if (toPlayer == -1) {
129 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": don't know that player "
130 << "- internal ERROR";
131 }
132 }
133 int receiver = toPlayer;
134 int sender = d->mFromPlayer->id();
135 d->mGame->sendMessage(text, messageId(), receiver, sender);
136 }
137}
138
140{
141 Q_D(KGameChat);
142
143 d->mMessageId = msgid;
144}
145
147{
148 Q_D(const KGameChat);
149
150 return d->mMessageId;
151}
152
154{
155 return (id == KChatBase::SendToAll);
156}
157
159{
160 Q_D(const KGameChat);
161
162 return (id == d->mToMyGroup);
163}
164
166{
167 Q_D(const KGameChat);
168
169 return d->mSendId2PlayerId.contains(id);
170}
171
173{
174 return i18n("Send to %1", name);
175}
176
177int KGameChat::playerId(int id) const
178{
179 Q_D(const KGameChat);
180
181 if (!isToPlayerMessage(id)) {
182 return -1;
183 }
184
185 return d->mSendId2PlayerId[id];
186}
187
188int KGameChat::sendingId(int playerId) const
189{
190 Q_D(const KGameChat);
191
193 for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
194 if (it.value() == playerId) {
195 return it.key();
196 }
197 }
198 return -1;
199}
200
202{
203 Q_D(const KGameChat);
204
205 return d->mFromPlayer ? d->mFromPlayer->name() : QString();
206}
207
208bool KGameChat::hasPlayer(int id) const
209{
210 return (sendingId(id) != -1);
211}
212
214{
215 Q_D(KGameChat);
216
217 if (!p) {
218 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": NULL player";
219 removeSendingEntry(d->mToMyGroup);
220 d->mFromPlayer = nullptr;
221 return;
222 }
223 if (d->mFromPlayer) {
224 changeSendingEntry(p->group(), d->mToMyGroup);
225 } else {
226 if (d->mToMyGroup != -1) {
227 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << "send to my group exists already - removing";
228 removeSendingEntry(d->mToMyGroup);
229 }
230 d->mToMyGroup = nextId();
231 addSendingEntry(i18n("Send to My Group (\"%1\")", p->group()), d->mToMyGroup);
232 }
233 d->mFromPlayer = p;
234 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "player=" << p;
235}
236
238{
239 Q_D(KGameChat);
240
241 if (d->mGame) {
243 }
244 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "game=" << g;
245 d->mGame = g;
246
247 if (d->mGame) {
248 connect(d->mGame, &KGame::signalPlayerJoinedGame, this, &KGameChat::slotAddPlayer);
249 connect(d->mGame, &KGame::signalPlayerLeftGame, this, &KGameChat::slotRemovePlayer);
250 connect(d->mGame, &KGame::signalNetworkData, this, &KGameChat::slotReceiveMessage);
252
253 const QList<KPlayer *> playerList = *d->mGame->playerList();
254 for (KPlayer *player : playerList) {
255 slotAddPlayer(player);
256 }
257 }
258}
259
260KGame *KGameChat::game() const
261{
262 Q_D(const KGameChat);
263
264 return d->mGame;
265}
266
267KPlayer *KGameChat::fromPlayer() const
268{
269 Q_D(const KGameChat);
270
271 return d->mFromPlayer;
272}
273
275{
276 // TODO: test this method!
277 Q_D(KGameChat);
278
279 if (!d->mGame) {
280 return;
281 }
282 disconnect(d->mGame, nullptr, this, nullptr);
283 removeSendingEntry(d->mToMyGroup);
285 for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
287 }
288}
289
290void KGameChat::slotAddPlayer(KPlayer *p)
291{
292 Q_D(KGameChat);
293
294 if (!p) {
295 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": cannot add NULL player";
296 return;
297 }
298 if (hasPlayer(p->id())) {
299 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": player was added before";
300 return;
301 }
302
303 int sendingId = nextId();
305 d->mSendId2PlayerId.insert(sendingId, p->id());
306 connect(p, &KPlayer::signalPropertyChanged, this, &KGameChat::slotPropertyChanged);
308}
309
310void KGameChat::slotRemovePlayer(KPlayer *p)
311{
312 Q_D(KGameChat);
313
314 if (!p) {
315 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": NULL player";
316 return;
317 }
318 if (!hasPlayer(p->id())) {
319 qCCritical(KDEGAMESPRIVATE_KGAME_LOG) << ": cannot remove non-existent player";
320 return;
321 }
322
323 int id = sendingId(p->id());
325 p->disconnect(this);
326 d->mSendId2PlayerId.remove(id);
327}
328
329void KGameChat::slotPropertyChanged(KGamePropertyBase *prop, KPlayer *player)
330{
331 if (prop->id() == KGamePropertyBase::IdName) {
332 // qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "new Name";
333 changeSendingEntry(player->name(), sendingId(player->id()));
334 /*
335 mCombo->changeItem(comboBoxItem(player->name()), index);
336 */
337 } else if (prop->id() == KGamePropertyBase::IdGroup) {
338 // TODO
339 }
340}
341
342void KGameChat::slotReceivePrivateMessage(int msgid, const QByteArray &buffer, quint32 sender, KPlayer *me)
343{
344 if (!me || me != fromPlayer()) {
345 qCDebug(KDEGAMESPRIVATE_KGAME_LOG) << "nope - not for us!";
346 return;
347 }
348 slotReceiveMessage(msgid, buffer, me->id(), sender);
349}
350
351void KGameChat::slotReceiveMessage(int msgid, const QByteArray &buffer, quint32, quint32 sender)
352{
353 QDataStream msg(buffer);
354 if (msgid != messageId()) {
355 return;
356 }
357
358 QString text;
359 msg >> text;
360
361 addMessage(sender, text);
362}
363
364#include "moc_kgamechat.cpp"
A delegate (see the Qt Model/View module for details) to paint the lines of the KChatBase list model ...
The model used to store messages displayed in the chat dialog messages list.
The base class for chat widgets.
Definition kchatbase.h:64
void changeSendingEntry(const QString &text, int id)
This changes a combo box entry.
int nextId() const
int sendingEntry() const
virtual QString comboBoxItem(const QString &name) const
Replace to customize the combo box.
bool addSendingEntry(const QString &text, int id)
Adds a new entry in the combo box.
void removeSendingEntry(int id)
Removes the entry with the ID id from the combo box.
A Chat widget for KGame-based games.
Definition kgamechat.h:36
void slotReceivePrivateMessage(int msgid, const QByteArray &buffer, quint32 sender, KPlayer *me)
Called when KPlayer::signalNetworkData is emitted.
void slotUnsetKGame()
Unsets a KGame object that has been set using setKGame before.
void setKGame(KGame *g)
Set the KGame object for this chat widget.
bool isToPlayerMessage(int id) const
Used to indicate whether the message shall be sent to a single player only.
KGameChat(KGame *game, int msgid, KPlayer *fromPlayer, QWidget *parent, KChatBaseModel *model=nullptr, KChatBaseItemDelegate *delegate=nullptr)
Construct a KGame chat widget on game that used msgid for the chat message.
Definition kgamechat.cpp:49
bool hasPlayer(int id) const
bool isToGroupMessage(int id) const
Used to indicate whether a message shall be sent to a group of players.
QString fromName() const override
reimplemented from KChatBase
int sendingId(int playerId) const
int messageId() const
void setMessageId(int msgid)
Change the message id of the chat widget.
void returnPressed(const QString &text) override
This is called whenever the user pushed return ie wants to send a message.
Definition kgamechat.cpp:94
bool isSendToAllMessage(int id) const
virtual QString sendToPlayerEntry(const QString &name) const
int playerId(int id) const
void setFromPlayer(KPlayer *player)
This sets the fromPlayer to player.
Base class of KGameProperty.
The main KDE game object.
Definition kgame.h:47
void signalNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender)
We got an user defined update message.
void signalPlayerJoinedGame(KPlayer *player)
a player joined the game
void signalPlayerLeftGame(KPlayer *player)
a player left the game because of a broken connection or so!
Base class for a game player.
Definition kplayer.h:60
void signalPropertyChanged(KGamePropertyBase *property, KPlayer *me)
This signal is emitted if a player property changes its value and the property is set to notify this ...
quint32 id() const
Returns the id of the player.
Definition kplayer.cpp:227
virtual const QString & name() const
Definition kplayer.cpp:222
virtual const QString & group() const
Query the group the player belongs to.
Definition kplayer.cpp:212
void signalNetworkData(int msgid, const QByteArray &buffer, quint32 sender, KPlayer *me)
The player object got a message which was targeted at it but has no default method to process it.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ConstIterator
iterator begin()
iterator end()
Key key(const T &value, const Key &defaultKey) const const
T value(const Key &key, const T &defaultValue) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
bool disconnect(const QMetaObject::Connection &connection)
QObject * sender() const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:09:35 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.