You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/kbackgammon/engines/fibs/kbgfibschat.cpp

827 lines
24 KiB

/*
Copyright (C) 1999-2001 Jens Hoefkens
jens@hoefkens.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
$Id$
*/
#include "kbgfibschat.h"
#include "kbgfibschat.moc"
#include <tqstring.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqpopupmenu.h>
#include <tqregexp.h>
#include <tqfont.h>
#include <tqwhatsthis.h>
#include <tqdatetime.h>
#include <tqclipboard.h>
#include <tqsimplerichtext.h>
#include <tqregion.h>
#include <tqpalette.h>
#include <tqpainter.h>
#include <tqpoint.h>
#include <tqlistbox.h>
#include <tqiconset.h>
#include <tqstringlist.h>
#include <tqdict.h>
#include <tdelocale.h>
#include <tdeconfig.h>
#include <tdeapplication.h>
#include <kdebug.h>
#include <kstdaction.h>
#include <ktabctl.h>
#include <tdeaction.h>
#include <kiconloader.h>
#include "clip.h"
#include "version.h"
/*
* Private utility class that might become more generally useful in
* the future. Basically, it implements rich text TQListBox items.
*/
class KLBT : public TQListBoxText
{
public:
/*
* Constructor
*/
KLBT(TQWidget *parent, const TQString &text = TQString(), const TQString &player = TQString())
: TQListBoxText(text)
{
w = parent;
n = new TQString(player);
t = new TQSimpleRichText(text, w->font());
// FIXME: this is not yet perfect
t->setWidth(w->width()-20);
}
/*
* Destructor
*/
virtual ~KLBT()
{
delete t;
delete n;
}
/*
* Overloaded required members returning height
*/
virtual int height(const TQListBox *) const
{
return (1+t->height());
}
/*
* Overloaded required members returning width
*/
virtual int width(const TQListBox *) const
{
return t->width();
}
/*
* The context menu needs the name of the player. It's easier
* than extracting it from the text.
*/
TQString player() const
{
return *n;
}
protected:
/*
* Required overloaded member to paint the text on the painter p.
*/
virtual void paint(TQPainter *p)
{
t->draw(p, 1, 1, TQRegion(p->viewport()), w->colorGroup());
}
private:
TQSimpleRichText *t;
TQWidget *w;
TQString *n;
};
class KBgChatPrivate
{
public:
/*
* Name of the users
*/
TQString mName[2];
/*
* Hold and assemble info text
*/
TQString mText;
/*
* Numbers of the private action list.
*/
enum Privact {Inquire, InviteD, Invite1, Invite2, Invite3, Invite4,
Invite5, Invite6, Invite7, InviteR, InviteU, Silent,
Talk, Gag, Ungag, Cleargag, Copy, Clear, Close, MaxAction};
/*
* Available actions
*/
TDEAction *mAct[MaxAction];
/*
* Context menu and invitation menu
*/
TQPopupMenu *mChat, *mInvt;
/*
* list of users we do not want to hear shouting
*/
TQStringList mGag;
/*
* Listbox needed by the setup dialog
*/
TQListBox *mLb;
/*
* Internal ID to name mapping
*/
TQDict<int> *mName2ID;
};
// == constructor, destructor ==================================================
/*
* Constructor of the chat window.
*/
KBgChat::KBgChat(TQWidget *parent, const char *name)
: KChat(parent, false)
{
d = new KBgChatPrivate();
TDEActionCollection* actions = new TDEActionCollection(this);
d->mName[0] = TQString();
d->mChat = 0;
d->mInvt = new TQPopupMenu();
setAutoAddMessages(false); // we get an echo from FIBS
setFromNickname(i18n("%1 user").arg(PROG_NAME));
if (!addSendingEntry(i18n("Kibitz to watchers and players"), CLIP_YOU_KIBITZ))
kdDebug(10500) << "adding kibitz" << endl;
if (!addSendingEntry(i18n("Whisper to watchers only"), CLIP_YOU_WHISPER))
kdDebug(10500) << "adding whisper" << endl;
connect(this, TQ_SIGNAL(rightButtonClicked(TQListBoxItem *, const TQPoint &)),
this, TQ_SLOT(contextMenu(TQListBoxItem *, const TQPoint &)));
connect(this, TQ_SIGNAL(signalSendMessage(int, const TQString &)),
this, TQ_SLOT(handleCommand(int, const TQString &)));
d->mName2ID = new TQDict<int>(17, true);
d->mName2ID->setAutoDelete(true);
/*
* some eye candy :)
*/
setIcon(kapp->miniIcon());
setCaption(i18n("Chat Window"));
TQWhatsThis::add(this, i18n("This is the chat window.\n\n"
"The text in this window is colored depending on whether "
"it is directed at you personally, shouted to the general "
"FIBS population, has been said by you, or is of general "
"interest. If you select the name of a player, the context "
"contains entries specifically geared towards that player."));
/*
* Define set of available actions
*/
d->mAct[KBgChatPrivate::Inquire] = new TDEAction(i18n("Info On"),
TQIconSet(kapp->iconLoader()->loadIcon(
"help.xpm", TDEIcon::Small)),
0, this, TQ_SLOT(slotInquire()), actions);
d->mAct[KBgChatPrivate::Talk] = new TDEAction(i18n("Talk To"),
TQIconSet(kapp->iconLoader()->loadIcon(
PROG_NAME "-chat.png", TDEIcon::Small)),
0, this, TQ_SLOT(slotTalk()), actions);
d->mAct[KBgChatPrivate::InviteD] = new TDEAction(i18n("Use Dialog"), 0, this,
TQ_SLOT(slotInviteD()), actions);
d->mAct[KBgChatPrivate::Invite1] = new TDEAction(i18n("1 Point Match"), 0, this,
TQ_SLOT(slotInvite1()), actions);
d->mAct[KBgChatPrivate::Invite2] = new TDEAction(i18n("2 Point Match"), 0, this,
TQ_SLOT(slotInvite2()), actions);
d->mAct[KBgChatPrivate::Invite3] = new TDEAction(i18n("3 Point Match"), 0, this,
TQ_SLOT(slotInvite3()), actions);
d->mAct[KBgChatPrivate::Invite4] = new TDEAction(i18n("4 Point Match"), 0, this,
TQ_SLOT(slotInvite4()), actions);
d->mAct[KBgChatPrivate::Invite5] = new TDEAction(i18n("5 Point Match"), 0, this,
TQ_SLOT(slotInvite5()), actions);
d->mAct[KBgChatPrivate::Invite6] = new TDEAction(i18n("6 Point Match"), 0, this,
TQ_SLOT(slotInvite6()), actions);
d->mAct[KBgChatPrivate::Invite7] = new TDEAction(i18n("7 Point Match"), 0, this,
TQ_SLOT(slotInvite7()), actions);
d->mAct[KBgChatPrivate::InviteU] = new TDEAction(i18n("Unlimited"), 0, this,
TQ_SLOT(slotInviteU()), actions);
d->mAct[KBgChatPrivate::InviteR] = new TDEAction(i18n("Resume"), 0, this,
TQ_SLOT(slotInviteR()), actions);
d->mAct[KBgChatPrivate::InviteD]->plug(d->mInvt);
d->mInvt->insertSeparator();
d->mAct[KBgChatPrivate::Invite1]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite2]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite3]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite4]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite5]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite6]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Invite7]->plug(d->mInvt);
d->mInvt->insertSeparator();
d->mAct[KBgChatPrivate::InviteU]->plug(d->mInvt);
d->mAct[KBgChatPrivate::InviteR]->plug(d->mInvt);
d->mAct[KBgChatPrivate::Gag] = new TDEAction(i18n("Gag"), 0, this, TQ_SLOT(slotGag()), actions);
d->mAct[KBgChatPrivate::Ungag] = new TDEAction(i18n("Ungag"), 0, this, TQ_SLOT(slotUngag()), actions);
d->mAct[KBgChatPrivate::Cleargag] = new TDEAction(i18n("Clear Gag List"), 0, this, TQ_SLOT(slotCleargag()), actions);
d->mAct[KBgChatPrivate::Copy] = KStdAction::copy(this, TQ_SLOT(slotCopy()), actions);
d->mAct[KBgChatPrivate::Clear] = new TDEAction(i18n("Clear"), 0, this, TQ_SLOT(slotClear()), actions);
d->mAct[KBgChatPrivate::Close] = KStdAction::close(this, TQ_SLOT(hide()), actions);
d->mAct[KBgChatPrivate::Silent] = new TDEToggleAction(i18n("Silent"), 0, this, TQ_SLOT(slotSilent()), actions);
}
/*
* Destructor
*/
KBgChat::~KBgChat()
{
delete d->mName2ID;
delete d->mChat; // save to delete NULL pointers
delete d->mInvt;
delete d;
}
// == configuration handling ===================================================
/*
* Restore the previously stored settings
*/
void KBgChat::readConfig()
{
TDEConfig* config = kapp->config();
config->setGroup("chat window");
TQPoint pos(10, 10);
pos = config->readPointEntry("ori", &pos);
setGeometry(pos.x(), pos.y(), config->readNumEntry("wdt",460), config->readNumEntry("hgt",200));
config->readBoolEntry("vis", false) ? show() : hide();
((TDEToggleAction *)d->mAct[KBgChatPrivate::Silent])->setChecked(config->readBoolEntry("sil", false));
d->mGag = config->readListEntry("gag");
}
/*
* Save the current settings to disk
*/
void KBgChat::saveConfig()
{
TDEConfig* config = kapp->config();
config->setGroup("chat window");
config->writeEntry("ori", pos());
config->writeEntry("hgt", height());
config->writeEntry("wdt", width());
config->writeEntry("vis", isVisible());
config->writeEntry("sil", ((TDEToggleAction *)d->mAct[KBgChatPrivate::Silent])->isChecked());
config->writeEntry("gag", d->mGag);
}
/*
* Setup dialog page of the player list - allow the user to select the
* columns to show
*
* FIXME: need to be able to set font here KChatBase::setBothFont(const TQFont& font)
*/
void KBgChat::getSetupPages(KTabCtl *nb, int space)
{
/*
* Main Widget
* ===========
*/
TQWidget *w = new TQWidget(nb);
TQGridLayout *gl = new TQGridLayout(w, 2, 1, space);
d->mLb = new TQListBox(w);
d->mLb->setMultiSelection(true);
d->mLb->insertStringList(d->mGag);
TQLabel *info = new TQLabel(w);
info->setText(i18n("Select users to be removed from the gag list."));
TQWhatsThis::add(w, i18n("Select all the users you want "
"to remove from the gag list "
"and then click OK. Afterwards "
"you will again hear what they shout."));
gl->addWidget(d->mLb, 0, 0);
gl->addWidget(info, 1, 0);
/*
* put in the page
* ===============
*/
gl->activate();
w->adjustSize();
w->setMinimumSize(w->size());
nb->addTab(w, i18n("&Gag List"));
}
/*
* Remove all the selected entries from the gag list
*/
void KBgChat::setupOk()
{
for (uint i = 0; i < d->mLb->count(); ++i) {
if (d->mLb->isSelected(i))
d->mGag.remove(d->mLb->text(i));
}
d->mLb->clear();
d->mLb->insertStringList(d->mGag);
}
/*
* Don't do anything
*/
void KBgChat::setupCancel()
{
// empty
}
/*
* By default, all players stay in the gag list
*/
void KBgChat::setupDefault()
{
d->mLb->clearSelection();
}
// == various slots and functions ==============================================
/*
* Overloaded member to create a TQListBoxItem for the chat window.
*/
TQListBoxItem* KBgChat::layoutMessage(const TQString& fromName, const TQString& text)
{
TQListBoxText* message = new KLBT(this, text, fromName);
return message;
}
/*
* Catch hide events, so the engine's menu can be update.
*/
void KBgChat::showEvent(TQShowEvent *e)
{
TQFrame::showEvent(e);
emit windowVisible(true);
}
/*
* Catch hide events, so the engine's menu can be update.
*/
void KBgChat::hideEvent(TQHideEvent *e)
{
emit windowVisible(false);
TQFrame::hideEvent(e);
}
/*
* At the beginning of a game, add the name to the list and switch to
* kibitz mode.
*/
void KBgChat::startGame(const TQString &name)
{
int *id = d->mName2ID->find(d->mName[1] = name);
if (!id) {
id = new int(nextId());
d->mName2ID->insert(name, id);
addSendingEntry(i18n("Talk to %1").arg(name), *id);
}
setSendingEntry(CLIP_YOU_KIBITZ);
}
/*
* At the end of a game, we switch to talk mode.
*/
void KBgChat::endGame()
{
int *id = d->mName2ID->find(d->mName[1]);
if (id)
setSendingEntry(*id);
else
setSendingEntry(SendToAll);
}
/*
* Set the chat window ready to talk to name
*/
void KBgChat::fibsTalk(const TQString &name)
{
int *id = d->mName2ID->find(name);
if (!id) {
id = new int(nextId());
d->mName2ID->insert(name, id);
addSendingEntry(i18n("Talk to %1").arg(name), *id);
}
setSendingEntry(*id);
}
/*
* Remove the player from the combo box when he/she logs out.
*/
void KBgChat::deletePlayer(const TQString &name)
{
int *id = d->mName2ID->find(name);
if (id) {
removeSendingEntry(*id);
d->mName2ID->remove(name);
}
}
/*
* Take action when the user presses return in the line edit control.
*/
void KBgChat::handleCommand(int id, const TQString& msg)
{
int realID = sendingEntry();
switch (realID) {
case SendToAll:
emit fibsCommand("shout " + msg);
break;
case CLIP_YOU_KIBITZ:
emit fibsCommand("kibitz " + msg);
break;
case CLIP_YOU_WHISPER:
emit fibsCommand("whisper " + msg);
break;
default:
TQDictIterator<int> it(*d->mName2ID);
while (it.current()) {
if (*it.current() == realID) {
emit fibsCommand("tell " + it.currentKey() + " " + msg);
return;
}
++it;
}
kdDebug(10500) << "unrecognized ID in KBgChat::handleCommand" << endl;
}
}
// == handle strings from the server ===========================================
/*
* A message from the server that should be handled by us. If necessary,
* we replace the CLIP number by a string and put the line into the window.
*
* This function emits the string in rich text format with the signal
* personalMessage - again: the string contains rich text!
*/
void KBgChat::handleData(const TQString &msg)
{
TQString clip = msg.left(msg.find(' ')), user, cMsg = msg;
TQDateTime date;
bool flag = false;
int cmd = clip.toInt(&flag);
if (flag) {
cMsg.replace(0, cMsg.find(' ')+1, "");
user = cMsg.left(cMsg.find(' '));
switch (cmd) {
case CLIP_SAYS:
if (!d->mGag.contains(user)) {
cMsg = i18n("<u>%1 tells you:</u> %2").arg(user).arg(cMsg.replace(TQRegExp("^" + user), ""));
cMsg = "<font color=\"red\">" + cMsg + "</font>";
emit personalMessage(cMsg);
} else
cMsg = "";
break;
case CLIP_SHOUTS:
if ((!((TDEToggleAction *)d->mAct[KBgChatPrivate::Silent])->isChecked()) && (!d->mGag.contains(user))) {
cMsg = i18n("<u>%1 shouts:</u> %2").arg(user).arg(cMsg.replace(TQRegExp("^" + user), ""));
cMsg = "<font color=\"black\">" + cMsg + "</font>";
} else
cMsg = "";
break;
case CLIP_WHISPERS:
if (!d->mGag.contains(user)) {
cMsg = i18n("<u>%1 whispers:</u> %2").arg(user).arg(cMsg.replace(TQRegExp("^" + user), ""));
cMsg = "<font color=\"red\">" + cMsg + "</font>";
emit personalMessage(cMsg);
} else
cMsg = "";
break;
case CLIP_KIBITZES:
if (!d->mGag.contains(user)) {
cMsg = i18n("<u>%1 kibitzes:</u> %2").arg(user).arg(cMsg.replace(TQRegExp("^" + user), ""));
cMsg = "<font color=\"red\">" + cMsg + "</font>";
emit personalMessage(cMsg);
} else
cMsg = "";
break;
case CLIP_YOU_SAY:
cMsg = i18n("<u>You tell %1:</u> %2").arg(user).arg(cMsg.replace(TQRegExp("^" + user), ""));
cMsg = "<font color=\"darkgreen\">" + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_YOU_SHOUT:
cMsg = i18n("<u>You shout:</u> %1").arg(cMsg);
cMsg = "<font color=\"darkgreen\">" + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_YOU_WHISPER:
cMsg = i18n("<u>You whisper:</u> %1").arg(cMsg);
cMsg = "<font color=\"darkgreen\">" + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_YOU_KIBITZ:
cMsg = i18n("<u>You kibitz:</u> %1").arg(cMsg);
cMsg = "<font color=\"darkgreen\">" + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_MESSAGE:
user = cMsg.left(cMsg.find(' ')+1);
cMsg.remove(0, cMsg.find(' ')+1);
date.setTime_t(cMsg.left(cMsg.find(' ')+1).toUInt());
cMsg.remove(0, cMsg.find(' '));
cMsg = i18n("<u>User %1 left a message at %2</u>: %3").arg(user).arg(date.toString()).arg(cMsg);
cMsg = "<font color=\"red\">" + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_MESSAGE_DELIVERED:
cMsg = i18n("Your message for %1 has been delivered.").arg(user);
cMsg = TQString("<font color=\"darkgreen\">") + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
case CLIP_MESSAGE_SAVED:
cMsg = i18n("Your message for %1 has been saved.").arg(user);
cMsg = TQString("<font color=\"darkgreen\">") + cMsg + "</font>";
emit personalMessage(cMsg);
user = TQString();
break;
default: // ignore the message
return;
}
} else {
/*
* Special treatment for non-CLIP messages
*/
if (cMsg.contains(TQRegExp("^You say to yourself: "))) {
cMsg.replace(TQRegExp("^You say to yourself: "),
i18n("<u>You say to yourself:</u> "));
} else {
kdDebug(user.isNull(), 10500) << "KBgChat::handleData unhandled message: "
<< cMsg.latin1() << endl;
return;
}
}
if (!cMsg.isEmpty())
addMessage(user, cMsg);
}
// == context menu and related slots ===========================================
/*
* RMB opens a context menu.
*/
void KBgChat::contextMenu(TQListBoxItem *i, const TQPoint &p)
{
/*
* Even if i is non-null, user might still be TQString()
*/
d->mName[0] = (i == 0) ? TQString() : ((KLBT *)i)->player();
d->mText = (i == 0) ? TQString() : ((KLBT *)i)->text();
/*
* Get a new context menu every time. Safe to delete the 0
* pointer.
*/
delete d->mChat; d->mChat = new TQPopupMenu();
/*
* Fill the context menu with actions
*/
if (!d->mName[0].isNull()) {
d->mAct[KBgChatPrivate::Talk]->setText(i18n("Talk to %1").arg(d->mName[0]));
d->mAct[KBgChatPrivate::Talk]->plug(d->mChat);
d->mAct[KBgChatPrivate::Inquire]->setText(i18n("Info on %1").arg(d->mName[0]));
d->mAct[KBgChatPrivate::Inquire]->plug(d->mChat);
// invite menu is always the same
d->mChat->insertItem(i18n("Invite %1").arg(d->mName[0]), d->mInvt);
d->mChat->insertSeparator();
if (d->mGag.contains(d->mName[0]) <= 0) {
d->mAct[KBgChatPrivate::Gag]->setText(i18n("Gag %1").arg(d->mName[0]));
d->mAct[KBgChatPrivate::Gag]->plug(d->mChat);
} else {
d->mAct[KBgChatPrivate::Ungag]->setText(i18n("Ungag %1").arg(d->mName[0]));
d->mAct[KBgChatPrivate::Ungag]->plug(d->mChat);
}
}
if (d->mGag.count() > 0)
d->mAct[KBgChatPrivate::Cleargag]->plug(d->mChat);
if ((d->mGag.count() > 0) || (!d->mName[0].isNull()))
d->mChat->insertSeparator();
d->mAct[KBgChatPrivate::Silent]->plug(d->mChat);
d->mChat->insertSeparator();
d->mAct[KBgChatPrivate::Copy ]->plug(d->mChat);
d->mAct[KBgChatPrivate::Clear]->plug(d->mChat);
d->mAct[KBgChatPrivate::Close]->plug(d->mChat);
d->mChat->popup(p);
}
/*
* Clear the gag list
*/
void KBgChat::slotCleargag()
{
d->mGag.clear();
TQString msg("<font color=\"blue\">");
msg += i18n("The gag list is now empty.");
msg += "</font>";
addMessage(TQString(), msg);
}
/*
* Gag the selected user
*/
void KBgChat::slotGag()
{
d->mGag.append(d->mName[0]);
TQString msg("<font color=\"blue\">");
msg += i18n("You won't hear what %1 says and shouts.").arg(d->mName[0]);
msg += "</font>";
addMessage(TQString(), msg);
}
/*
* Simple interface to the actual talk slot
*/
void KBgChat::slotTalk()
{
fibsTalk(d->mName[0]);
}
/*
* Remove selected user from gag list
*/
void KBgChat::slotUngag()
{
d->mGag.remove(d->mName[0]);
TQString msg("<font color=\"blue\">");
msg += i18n("You will again hear what %1 says and shouts.").arg(d->mName[0]);
msg += "</font>";
addMessage(TQString(), msg);
}
/*
* Get information on selected user
*/
void KBgChat::slotInquire()
{
kdDebug(d->mName[0].isNull(), 10500) << "KBgChat::slotInquire: user == null" << endl;
emit fibsCommand("whois " + d->mName[0]);
}
/*
* Block all shouts from the chat window
*/
void KBgChat::slotSilent()
{
TQString msg;
if (((TDEToggleAction *)d->mAct[KBgChatPrivate::Silent])->isChecked())
msg = "<font color=\"blue\">" + i18n("You will not hear what people shout.") + "</font>";
else
msg = "<font color=\"blue\">" + i18n("You will hear what people shout.") + "</font>";
addMessage(TQString(), msg);
}
/*
* Copy the selected line to the clipboard. Strip the additional HTML
* from the text before copying.
*/
void KBgChat::slotCopy()
{
d->mText.replace(TQRegExp("<u>"), "");
d->mText.replace(TQRegExp("</u>"), "");
d->mText.replace(TQRegExp("</font>"), "");
d->mText.replace(TQRegExp("^.*\">"), "");
kapp->clipboard()->setText(d->mText);
}
/*
* Invite the selected player.
*/
void KBgChat::slotInviteD()
{
kdDebug(d->mName[0].isNull(), 10500) << "KBgChat::slotInvite: user == null" << endl;
emit fibsRequestInvitation(d->mName[0]);
}
void KBgChat::slotInvite1() { emit fibsCommand("invite " + d->mName[0] + " 1"); }
void KBgChat::slotInvite2() { emit fibsCommand("invite " + d->mName[0] + " 2"); }
void KBgChat::slotInvite3() { emit fibsCommand("invite " + d->mName[0] + " 3"); }
void KBgChat::slotInvite4() { emit fibsCommand("invite " + d->mName[0] + " 4"); }
void KBgChat::slotInvite5() { emit fibsCommand("invite " + d->mName[0] + " 5"); }
void KBgChat::slotInvite6() { emit fibsCommand("invite " + d->mName[0] + " 6"); }
void KBgChat::slotInvite7() { emit fibsCommand("invite " + d->mName[0] + " 7"); }
void KBgChat::slotInviteU() { emit fibsCommand("invite " + d->mName[0] + " unlimited"); }
void KBgChat::slotInviteR() { emit fibsCommand("invite " + d->mName[0]); }
// EOF