kgamechat.cpp

00001 /*
00002     This file is part of the KDE games library
00003     Copyright (C) 2001-2002 Andreas Beckermann (b_mann@gmx.de)
00004     Copyright (C) 2001 Martin Heni (martin@heni-online.de)
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License version 2 as published by the Free Software Foundation.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
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.h>
00033 #include <qintdict.h>
00034 
00035 //FIXME:
00036 #define FIRST_ID 2 // first id, that is free of use, aka not defined above
00037 
00038 class KGameChatPrivate
00039 {
00040 public:
00041     KGameChatPrivate()
00042     {
00043         mFromPlayer = 0;
00044         mGame = 0;
00045 
00046         mToMyGroup = -1;
00047     }
00048     
00049     KGame* mGame;
00050     KPlayer* mFromPlayer;
00051     int mMessageId;
00052 
00053 
00054     QIntDict<KPlayer> mIndex2Player;
00055 
00056     QMap<int, int> mSendId2PlayerId;
00057     int mToMyGroup; // just as the above - but for the group, not for players
00058 };
00059 
00060 KGameChat::KGameChat(KGame* g, int msgid, QWidget* parent) : KChatBase(parent)
00061 {
00062  init(g, msgid); 
00063 }
00064 
00065 KGameChat::KGameChat(KGame* g, int msgid, KPlayer* fromPlayer, QWidget* parent) : KChatBase(parent)
00066 {
00067  init(g, msgid);
00068  setFromPlayer(fromPlayer);
00069 }
00070 
00071 KGameChat::KGameChat(QWidget* parent) : KChatBase(parent)
00072 {
00073  init(0, -1);
00074 }
00075 
00076 KGameChat::~KGameChat()
00077 {
00078  kdDebug(11001) << k_funcinfo << endl;
00079  delete d;
00080 }
00081 
00082 void KGameChat::init(KGame* g, int msgId)
00083 {
00084  kdDebug(11001) << k_funcinfo << endl;
00085  d = new KGameChatPrivate;
00086  setMessageId(msgId);
00087 
00088  setKGame(g);
00089 }
00090 
00091 void KGameChat::addMessage(int fromId, const QString& text)
00092 {
00093  if (!d->mGame) {
00094     kdWarning(11001) << "no KGame object has been set" << endl;
00095     addMessage(i18n("Player %1").arg(fromId), text);
00096  } else {
00097     KPlayer* p = d->mGame->findPlayer(fromId);
00098     if (p) {
00099         kdDebug(11001) << "adding message of player " << p->name() << "id=" << fromId << endl;
00100         addMessage(p->name(), text);
00101     } else {
00102         kdWarning(11001) << "Could not find player id " << fromId << endl;
00103         addMessage(i18n("Unknown"), text);
00104     }
00105  }
00106 }
00107 
00108 void KGameChat::returnPressed(const QString& text)
00109 {
00110  if (!d->mFromPlayer) {
00111     kdWarning(11001) << k_funcinfo << ": You must set a player first!" << endl;
00112     return;
00113  }
00114  if (!d->mGame) {
00115     kdWarning(11001) << k_funcinfo << ": You must set a game first!" << endl;
00116     return;
00117  }
00118 
00119  kdDebug(11001) << "from: " << d->mFromPlayer->id() << "==" << d->mFromPlayer->name() << endl;
00120 
00121  int id = sendingEntry();
00122 
00123  if (isToGroupMessage(id)) {
00124     // note: there is currently no support for other groups than the players
00125     // group! It might be useful to send to other groups, too
00126     QString group = d->mFromPlayer->group();
00127     kdDebug(11001) << "send to group " << group << endl;
00128     int sender = d->mFromPlayer->id();
00129     d->mGame->sendGroupMessage(text, messageId(), sender, group);
00130 
00131     //TODO
00132     //AB: this message is never received!! we need to connect to
00133     //KPlayer::networkData!!!
00134     //TODO
00135     
00136  } else {
00137     int toPlayer = 0;
00138     if (!isSendToAllMessage(id) && isToPlayerMessage(id)) {
00139         toPlayer = playerId(id);
00140         if (toPlayer == -1) {
00141             kdError(11001) << k_funcinfo << ": don't know that player "
00142                     << "- internal ERROR" << endl;
00143         }
00144     } 
00145     int receiver = toPlayer;
00146     int sender = d->mFromPlayer->id();
00147     d->mGame->sendMessage(text, messageId(), receiver, sender);
00148  }
00149 }
00150 
00151 void KGameChat::setMessageId(int msgid)
00152 { d->mMessageId = msgid; }
00153 
00154 int KGameChat::messageId() const
00155 { return d->mMessageId; }
00156 
00157 bool KGameChat::isSendToAllMessage(int id) const
00158 { return (id == KChatBase::SendToAll); }
00159 
00160 bool KGameChat::isToGroupMessage(int id) const
00161 { return (id == d->mToMyGroup); }
00162 
00163 bool KGameChat::isToPlayerMessage(int id) const
00164 {
00165 return d->mSendId2PlayerId.contains(id); }
00166 
00167 QString KGameChat::sendToPlayerEntry(const QString& name) const
00168 { return i18n("Send to %1").arg(name); }
00169 
00170 int KGameChat::playerId(int id) const
00171 {
00172  if (!isToPlayerMessage(id)) {
00173     return -1;
00174  }
00175 
00176  return d->mSendId2PlayerId[id];
00177 }
00178 
00179 int KGameChat::sendingId(int playerId) const
00180 {
00181  QMap<int, int>::Iterator it;
00182  for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
00183     if (it.data() == playerId) {
00184         return it.key();
00185     }
00186  }
00187  return -1;
00188 }
00189 
00190 const QString& KGameChat::fromName() const
00191 { return d->mFromPlayer ? d->mFromPlayer->name() : QString::null; }
00192 
00193 bool KGameChat::hasPlayer(int id) const
00194 {
00195  return (sendingId(id) != -1);
00196 }
00197 
00198 void KGameChat::setFromPlayer(KPlayer* p)
00199 {
00200  if (!p) {
00201     kdError(11001) << k_funcinfo << ": NULL player" << endl;
00202     removeSendingEntry(d->mToMyGroup);
00203     d->mFromPlayer = 0;
00204     return;
00205  }
00206  if (d->mFromPlayer) {
00207     changeSendingEntry(p->group(), d->mToMyGroup);
00208  } else {
00209     if (d->mToMyGroup != -1) {
00210         kdWarning(11001) << "send to my group exists already - removing" << endl;
00211         removeSendingEntry(d->mToMyGroup);
00212     }
00213     d->mToMyGroup = nextId();
00214     addSendingEntry(i18n("Send to My Group (\"%1\")").arg(p->group()), d->mToMyGroup);
00215  }
00216  d->mFromPlayer = p;
00217  kdDebug(11001) << k_funcinfo << " player=" << p << endl;
00218 }
00219 
00220 
00221 void KGameChat::setKGame(KGame* g)
00222 {
00223  if (d->mGame) {
00224     slotUnsetKGame();
00225  }
00226  kdDebug(11001) << k_funcinfo << " game=" << g << endl;
00227  d->mGame = g;
00228 
00229  if (d->mGame) {
00230     connect(d->mGame, SIGNAL(signalPlayerJoinedGame(KPlayer*)), 
00231             this, SLOT(slotAddPlayer(KPlayer*)));
00232     connect(d->mGame, SIGNAL(signalPlayerLeftGame(KPlayer*)), 
00233             this, SLOT(slotRemovePlayer(KPlayer*)));
00234     connect(d->mGame, SIGNAL(signalNetworkData(int, const QByteArray&, Q_UINT32, Q_UINT32)),
00235             this, SLOT(slotReceiveMessage(int, const QByteArray&, Q_UINT32, Q_UINT32)));
00236     connect(d->mGame, SIGNAL(destroyed()), this, SLOT(slotUnsetKGame()));
00237 
00238     QPtrList<KPlayer> playerList = *d->mGame->playerList();
00239     for (int unsigned i = 0; i < playerList.count(); i++) {
00240         slotAddPlayer(playerList.at(i));
00241     }
00242  }
00243 }
00244 
00245 KGame* KGameChat::game() const
00246 {
00247  return d->mGame;
00248 }
00249 
00250 KPlayer* KGameChat::fromPlayer() const
00251 {
00252  return d->mFromPlayer;
00253 }
00254 
00255 void KGameChat::slotUnsetKGame()
00256 {
00257 //TODO: test this method!
00258 
00259  if (!d->mGame) {
00260     return;
00261  }
00262  disconnect(d->mGame, 0, this, 0);
00263  removeSendingEntry(d->mToMyGroup);
00264  QMap<int, int>::Iterator it;
00265  for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
00266     removeSendingEntry(it.data());
00267  }
00268 }
00269 
00270 void KGameChat::slotAddPlayer(KPlayer* p)
00271 {
00272  if (!p) {
00273     kdError(11001) << k_funcinfo << ": cannot add NULL player" << endl;
00274     return;
00275  }
00276  if (hasPlayer(p->id())) {
00277     kdError(11001) << k_funcinfo << ": player was added before" << endl;
00278     return;
00279  }
00280 
00281  int sendingId = nextId();
00282  addSendingEntry(comboBoxItem(p->name()), sendingId);
00283  d->mSendId2PlayerId.insert(sendingId, p->id());
00284  connect(p, SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)),
00285         this, SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*)));
00286  connect(p, SIGNAL(signalNetworkData(int, const QByteArray&, Q_UINT32, KPlayer*)),
00287         this, SLOT(slotReceivePrivateMessage(int, const QByteArray&, Q_UINT32, KPlayer*)));
00288 }
00289 
00290 void KGameChat::slotRemovePlayer(KPlayer* p)
00291 {
00292  if (!p) {
00293     kdError(11001) << k_funcinfo << ": NULL player" << endl;
00294     return;
00295  }
00296  if (!hasPlayer(p->id())) {
00297     kdError(11001) << k_funcinfo << ": cannot remove non-existent player" << endl;
00298     return;
00299  }
00300 
00301  int id = sendingId(p->id());
00302  removeSendingEntry(id);
00303  p->disconnect(this);
00304  d->mSendId2PlayerId.remove(id);
00305 }
00306 
00307 void KGameChat::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player)
00308 {
00309  if (prop->id() == KGamePropertyBase::IdName) {
00310 //  kdDebug(11001) << "new Name" << endl;
00311     changeSendingEntry(player->name(), sendingId(player->id()));
00312 /*
00313     mCombo->changeItem(comboBoxItem(player->name()), index);
00314  */
00315  } else if (prop->id() == KGamePropertyBase::IdGroup) {
00316  //TODO
00317  }
00318 }
00319 
00320 void KGameChat::slotReceivePrivateMessage(int msgid, const QByteArray& buffer, Q_UINT32 sender, KPlayer* me)
00321 {
00322  if (!me || me != fromPlayer()) {
00323     kdDebug() << k_funcinfo << "nope - not for us!"  << endl;
00324     return;
00325  }
00326  slotReceiveMessage(msgid, buffer, me->id(), sender);
00327 }
00328 
00329 void KGameChat::slotReceiveMessage(int msgid, const QByteArray& buffer, Q_UINT32 , Q_UINT32 sender)
00330 {
00331  QDataStream msg(buffer, IO_ReadOnly);
00332  if (msgid != messageId()) {
00333     return;
00334  }
00335 
00336  QString text;
00337  msg >> text;
00338 
00339  addMessage(sender, text);
00340 }
00341 
KDE Home | KDE Accessibility Home | Description of Access Keys