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/libtdegames/kgame/dialogs/kgamedialogconfig.cpp

774 lines
19 KiB

/*
This file is part of the TDE games library
Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
Copyright (C) 2001 Martin Heni (martin@heni-online.de)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kgamedialogconfig.h"
#include "kgame.h"
#include "kplayer.h"
#include "kgamechat.h"
#include "kgameconnectdialog.h"
#include <tdelocale.h>
#include <knuminput.h>
#include <kdialog.h>
#include <tdelistbox.h>
#include <tdemessagebox.h>
#include <tqlayout.h>
#include <tqhgroupbox.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqlineedit.h>
#include <tqvbox.h>
#include <tqptrdict.h>
#include "kgamedialogconfig.moc"
class KGameDialogConfigPrivate
{
public:
KGameDialogConfigPrivate()
{
mOwner = 0;
mGame = 0;
mAdmin = false;
}
bool mAdmin;
KGame* mGame;
KPlayer* mOwner;
};
KGameDialogConfig::KGameDialogConfig(TQWidget* parent) : TQWidget(parent)
{
d = new KGameDialogConfigPrivate;
}
KGameDialogConfig::~KGameDialogConfig()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameDialogConfig::setKGame(KGame* g)
{
d->mGame = g;
}
void KGameDialogConfig::setOwner(KPlayer* p)
{
d->mOwner = p;
}
void KGameDialogConfig::setAdmin(bool a)
{
d->mAdmin = a;
}
KGame* KGameDialogConfig::game() const
{ return d->mGame; }
bool KGameDialogConfig::admin() const
{ return d->mAdmin; }
KPlayer* KGameDialogConfig::owner() const
{ return d->mOwner; }
/////////////////////////// KGameDialogNetworkConfig /////////////////////////
class KGameDialogNetworkConfigPrivate
{
public:
KGameDialogNetworkConfigPrivate()
{
mInitConnection = 0;
mNetworkLabel = 0;
mDisconnectButton = 0;
mConnect = 0;
mDefaultServer=true;
}
// TQPushButton* mInitConnection;
TQHGroupBox* mInitConnection;
TQLabel* mNetworkLabel;
TQPushButton *mDisconnectButton;
bool mDefaultServer;
TQString mDefaultHost;
unsigned short int mDefaultPort;
KGameConnectWidget *mConnect;
};
KGameDialogNetworkConfig::KGameDialogNetworkConfig(TQWidget* parent)
: KGameDialogConfig(parent)
{
// kdDebug(11001) << k_funcinfo << ": this=" << this << endl;
d = new KGameDialogNetworkConfigPrivate();
TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint(), "toplayout");
TQHBoxLayout *hb = new TQHBoxLayout(topLayout, KDialog::spacingHint());
d->mNetworkLabel = new TQLabel(this);
hb->addWidget(d->mNetworkLabel);
d->mDisconnectButton=new TQPushButton(i18n("Disconnect"),this);
connect(d->mDisconnectButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotExitConnection()));
hb->addWidget(d->mDisconnectButton);
d->mInitConnection = new TQHGroupBox(i18n("Network Configuration"), this);
topLayout->addWidget(d->mInitConnection);
d->mConnect = new KGameConnectWidget(d->mInitConnection);
connect(d->mConnect, TQ_SIGNAL(signalNetworkSetup()), this, TQ_SLOT(slotInitConnection()));
connect(d->mConnect, TQ_SIGNAL(signalServerTypeChanged(int)),
this, TQ_SIGNAL(signalServerTypeChanged(int)));
// Needs to be AFTER the creation of the dialogs
setConnected(false);
setDefaultNetworkInfo("localhost", 7654,true);
}
KGameDialogNetworkConfig::~KGameDialogNetworkConfig()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameDialogNetworkConfig::slotExitConnection()
{
kdDebug(11001) << k_funcinfo << " !!!!!!!!!!!!!!!!!!!!!!!" << endl;
if (game()) game()->disconnect();
setConnected(false,false);
}
void KGameDialogNetworkConfig::slotInitConnection()
{
kdDebug(11001) << k_funcinfo << endl;
bool connected = false;
bool master = true;
unsigned short int port = d->mConnect->port();
TQString host = d->mConnect->host();
if (host.isNull()) {
master = true;
if (game()) {
game()->setDiscoveryInfo(d->mConnect->type(),d->mConnect->gameName());
connected = game()->offerConnections(port);
}
} else {
master = false;
if (game()) {
connected = game()->connectToServer(host, port);
}
// We need to learn about failed connections
if (game()) {
connect(game(), TQ_SIGNAL(signalConnectionBroken()),
this, TQ_SLOT(slotConnectionBroken()));
}
}
setConnected(connected, master);
}
void KGameDialogNetworkConfig::slotConnectionBroken()
{
kdDebug(11001) << k_funcinfo << endl;
setConnected(false,false);
KMessageBox::error(this, i18n("Cannot connect to the network"));
}
void KGameDialogNetworkConfig::setConnected(bool connected, bool master)
{
if (!connected) {
d->mNetworkLabel->setText(i18n("Network status: No Network"));
d->mInitConnection->setEnabled(true);
d->mDisconnectButton->setEnabled(false);
return;
}
if (master) {
d->mNetworkLabel->setText(i18n("Network status: You are MASTER"));
} else {
d->mNetworkLabel->setText(i18n("Network status: You are connected"));
}
d->mInitConnection->setEnabled(false);
d->mDisconnectButton->setEnabled(true);
}
void KGameDialogNetworkConfig::submitToKGame(KGame* , KPlayer* )
{
}
void KGameDialogNetworkConfig::setKGame(KGame* g)
{
KGameDialogConfig::setKGame(g);
if (!game()) {
setConnected(false);
return;
}
setConnected(game()->isNetwork(), game()->isMaster());
}
void KGameDialogNetworkConfig::setDefaultNetworkInfo(const TQString& host, unsigned short int port,bool server)
{
d->mDefaultPort = port;
d->mDefaultHost = host;
d->mDefaultServer = server;
d->mConnect->setHost(host);
d->mConnect->setPort(port);
if (server) {
d->mConnect->setDefault(0);
} else {
d->mConnect->setDefault(1);
}
}
void KGameDialogNetworkConfig::setDiscoveryInfo(const TQString& type, const TQString& name)
{
d->mConnect->setType(type);
d->mConnect->setName(name);
}
/////////////////////////// KGameDialogGeneralConfig /////////////////////////
class KGameDialogGeneralConfigPrivate
{
public:
KGameDialogGeneralConfigPrivate()
{
mTopLayout = 0;
mName = 0;
}
TQLineEdit* mName;
TQVBoxLayout* mTopLayout;
};
KGameDialogGeneralConfig::KGameDialogGeneralConfig(TQWidget* parent, bool initializeGUI)
: KGameDialogConfig(parent)
{
// kdDebug(11001) << k_funcinfo << ": this=" << this << endl;
d = new KGameDialogGeneralConfigPrivate;
if (initializeGUI) {
d->mTopLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
d->mTopLayout->setAutoAdd(true);
TQWidget* nameWidget = new TQWidget(this);
TQHBoxLayout* l = new TQHBoxLayout(nameWidget);
TQLabel* nameLabel = new TQLabel(i18n("Your name:"), nameWidget);
l->addWidget(nameLabel);
d->mName = new TQLineEdit(nameWidget);
l->addWidget(d->mName);
}
}
KGameDialogGeneralConfig::~KGameDialogGeneralConfig()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameDialogGeneralConfig::setPlayerName(const TQString& name)
{
if (d->mName) {
d->mName->setText(name);
}
}
TQString KGameDialogGeneralConfig::playerName() const
{
return d->mName ? d->mName->text() : TQString();
}
void KGameDialogGeneralConfig::setOwner(KPlayer* p)
{
if (owner()) {
owner()->disconnect(this);
}
KGameDialogConfig::setOwner(p);
if (!owner()) {
// can this config be used at all?
// maybe call hide()
return;
}
connect(owner(), TQ_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)),
this, TQ_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*)));
setPlayerName(p->name());
//TODO: connect signalPropertyChanged and check for playername changes!
}
void KGameDialogGeneralConfig::setKGame(KGame* g)
{
KGameDialogConfig::setKGame(g);
if (!g) {
// TODO
// can this config be used at all?
// maybe call hide()
return;
}
}
void KGameDialogGeneralConfig::setAdmin(bool admin)
{
KGameDialogConfig::setAdmin(admin);
// enable/disable widgets
}
void KGameDialogGeneralConfig::submitToKGame(KGame* g, KPlayer* p)
{
//FIXME
if (p) {
p->setName(playerName());
}
if (g) {
}
}
void KGameDialogGeneralConfig::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* p)
{
if (!prop || !p || p != owner()) {
return;
}
switch (prop->id()) {
case KGamePropertyBase::IdName:
setPlayerName(p->name());
break;
default:
break;
}
}
class KGameDialogMsgServerConfigPrivate
{
public:
KGameDialogMsgServerConfigPrivate()
{
senderLayout = 0;
localLayout = 0;
changeMaxClients = 0;
changeAdmin= 0;
removeClient= 0;
noAdmin = 0;
noMaster = 0;
}
TQVBoxLayout* senderLayout;
TQHBoxLayout* localLayout;
TQPushButton* changeMaxClients;
TQPushButton* changeAdmin;
TQPushButton* removeClient;
TQLabel* noAdmin;
TQLabel* noMaster;
};
// TODO: change ADMIN ID, remove CLIENTS, change MAXCLIENTS
// we do everything here with TQPushButtons as we want to wait a moment before
// continuing - the message must be sent over network first
KGameDialogMsgServerConfig::KGameDialogMsgServerConfig(TQWidget* parent)
: KGameDialogConfig(parent)
{
d = new KGameDialogMsgServerConfigPrivate;
TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
d->senderLayout = new TQVBoxLayout(topLayout);
d->localLayout = new TQHBoxLayout(topLayout);
}
KGameDialogMsgServerConfig::~KGameDialogMsgServerConfig()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameDialogMsgServerConfig::setKGame(KGame* g)
{
KGameDialogConfig::setKGame(g);
//TODO display the ID of the admin if we aren't
// connect(g, TQ_SIGNAL(signalAdminChanged(int)), this, TQ_SLOT(slotChangeIsAdmin(int)));//TODO
if (!game()) {
// we cannot do anything without a KGame object!
setAdmin(false);
return;
}
setAdmin(game()->isAdmin());
setHasMsgServer(game()->messageServer());
}
void KGameDialogMsgServerConfig::slotChangeMaxClients()
{
if (!game()) {
kdError(11001) << k_funcinfo << ": no valid game object available!" << endl;
return;
}
if (!game()->isAdmin()) {
kdError(11001) << k_funcinfo << ": only ADMIN is allowed to call this!" << endl;
return;
}
int max;
// edit->setText(TQString::number()); // current max clients! //TODO
TQDialog* dialog = new TQDialog();
dialog->setCaption(i18n("Maximal Number of Clients"));
TQHBoxLayout* l = new TQHBoxLayout(dialog, KDialog::marginHint(), KDialog::spacingHint());
l->setAutoAdd(true);
(void) new TQLabel(i18n("Maximal number of clients (-1 = infinite):"), dialog);
TQLineEdit* edit = new TQLineEdit(dialog);//TODO: use KIntNumInput
// edit->setText(TQString::number(max)); // current max clients! //TODO
if (dialog->exec() == TQDialog::Accepted) {
bool ok;
max = edit->text().toInt(&ok);
if (ok) {
game()->setMaxClients(max);
}
}
}
void KGameDialogMsgServerConfig::slotRemoveClient()
{
}
void KGameDialogMsgServerConfig::slotChangeAdmin()
{
if (!game()) {
kdError(11001) << k_funcinfo << ": no valid game object available!" << endl;
return;
}
if (!admin()) {
kdError(11001) << k_funcinfo << ": only ADMIN is allowed to call this!" << endl;
return;
}
//TODO
TQ_UINT32 newAdmin = 0;
// newAdmin = ;
game()->electAdmin(newAdmin);
}
void KGameDialogMsgServerConfig::removeClient(TQ_UINT32 /*id*/)
{
//TODO
}
void KGameDialogMsgServerConfig::setAdmin(bool a)
{
if (admin() == a) {
// no need to do anything
return;
}
KGameDialogConfig::setAdmin(a);
if (admin()) {
if (d->noAdmin) {
delete d->noAdmin;
d->noAdmin = 0;
}
d->changeMaxClients = new TQPushButton(i18n("Change Maximal Number of Clients"), this);
connect(d->changeMaxClients, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotChangeMaxClients()));
d->changeAdmin = new TQPushButton(i18n("Change Admin"), this);
connect(d->changeAdmin, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotChangeAdmin()));
d->removeClient = new TQPushButton(i18n("Remove Client with All Players"), this);
connect(d->removeClient, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotRemoveClient()));
d->senderLayout->addWidget(d->changeMaxClients);
d->senderLayout->addWidget(d->changeAdmin);
d->senderLayout->addWidget(d->removeClient);
} else {
if (d->changeMaxClients) {
delete d->changeMaxClients;
d->changeMaxClients = 0;
}
if (d->changeAdmin) {
delete d->changeAdmin;
d->changeAdmin = 0;
}
if (d->removeClient) {
delete d->removeClient;
d->removeClient = 0;
}
d->noAdmin = new TQLabel(i18n("Only the admin can configure the message server!"), this);
d->senderLayout->addWidget(d->noAdmin);
}
}
void KGameDialogMsgServerConfig::setHasMsgServer(bool has)
{
if (!has) {
// delete all inputs
if (!d->noMaster) {
d->noMaster = new TQLabel(i18n("You don't own the message server"), this);
d->localLayout->addWidget(d->noMaster);
}
return;
}
if (d->noMaster) {
delete d->noMaster;
d->noMaster = 0;
}
//TODO
// list all connections, data (max clients) and so on
// cannot be done above (together with TQPushButtons) as it is possible that
// this client is ADMIN but not MASTER (i.e. doesn't own the messageserver)
}
class KGameDialogChatConfigPrivate
{
public:
KGameDialogChatConfigPrivate()
{
mChat = 0;
}
KGameChat* mChat;
};
KGameDialogChatConfig::KGameDialogChatConfig(int chatMsgId, TQWidget* parent)
: KGameDialogConfig(parent)
{
d = new KGameDialogChatConfigPrivate;
TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
topLayout->setAutoAdd(true);
TQHGroupBox* b = new TQHGroupBox(i18n("Chat"), this);
d->mChat = new KGameChat(0, chatMsgId, b);
}
KGameDialogChatConfig::~KGameDialogChatConfig()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameDialogChatConfig::setKGame(KGame* g)
{
KGameDialogConfig::setKGame(g);
d->mChat->setKGame(game());
if (!game()) {
hide();
} else {
show();
}
}
void KGameDialogChatConfig::setOwner(KPlayer* p)
{
KGameDialogConfig::setOwner(p);
if (!owner()) {
hide();
return;
}
d->mChat->setFromPlayer(owner());
show();
}
class KGameDialogConnectionConfigPrivate
{
public:
KGameDialogConnectionConfigPrivate()
{
mPlayerBox = 0;
}
TQPtrDict<KPlayer> mItem2Player;
TDEListBox* mPlayerBox;
};
KGameDialogConnectionConfig::KGameDialogConnectionConfig(TQWidget* parent)
: KGameDialogConfig(parent)
{
//TODO: prevent player to ban himself
d = new KGameDialogConnectionConfigPrivate;
TQVBoxLayout* topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
topLayout->setAutoAdd(true);
TQHGroupBox* b = new TQHGroupBox(i18n("Connected Players"), this);
d->mPlayerBox = new TDEListBox(b);
setMinimumHeight(100);
}
KGameDialogConnectionConfig::~KGameDialogConnectionConfig()
{
kdDebug(11001) << k_funcinfo << endl;
// d->mIem2Player.clear();
delete d;
}
void KGameDialogConnectionConfig::setKGame(KGame* g)
{
if (game()) {
disconnect(game(), 0, this, 0);
}
KGameDialogConfig::setKGame(g);
slotClearPlayers();
if (game()) {
// react to changes in KGame::playerList()
connect(game(), TQ_SIGNAL(signalPlayerJoinedGame(KPlayer*)),
this, TQ_SLOT(slotPlayerJoinedGame(KPlayer*)));
connect(game(), TQ_SIGNAL(signalPlayerLeftGame(KPlayer*)),
this, TQ_SLOT(slotPlayerLeftGame(KPlayer*)));
KGame::KGamePlayerList l = *game()->playerList();
for (KPlayer* p = l.first(); p; p = l.next()) {
slotPlayerJoinedGame(p);
}
}
}
void KGameDialogConnectionConfig::setOwner(KPlayer* p)
{
KGameDialogConfig::setOwner(p);
}
void KGameDialogConnectionConfig::setAdmin(bool a)
{
if (!game()) {// not possible... in theory
return;
}
if (admin()) {
disconnect(game(), TQ_SIGNAL(executed(TQListBoxItem*)), this, 0);
}
KGameDialogConfig::setAdmin(a);
if (admin()) {
connect(d->mPlayerBox, TQ_SIGNAL(executed(TQListBoxItem*)), this,
TQ_SLOT(slotKickPlayerOut(TQListBoxItem*)));
}
}
TQListBoxItem* KGameDialogConnectionConfig::item(KPlayer* p) const
{
TQPtrDictIterator<KPlayer> it(d->mItem2Player);
while (it.current()) {
if (it.current() == p) {
return (TQListBoxItem*)it.currentKey();
}
++it;
}
return 0;
}
void KGameDialogConnectionConfig::slotClearPlayers()
{
TQPtrDictIterator<KPlayer> it(d->mItem2Player);
while (it.current()) {
slotPlayerLeftGame(it.current());
++it;
}
if (d->mItem2Player.count() > 0) {
kdWarning(11001) << k_funcinfo << ": itemList wasn't cleared properly" << endl;
d->mItem2Player.clear();
}
if (d->mPlayerBox->count() > 0) {
kdWarning(11001) << k_funcinfo << ": listBox wasn't cleared properly" << endl;
d->mPlayerBox->clear();
}
}
void KGameDialogConnectionConfig::slotPlayerJoinedGame(KPlayer* p)
{
if (!p) {
kdError(11001) << k_funcinfo << ": Cannot add NULL player" << endl;
}
if (d->mItem2Player[p]) {
kdError(11001) << k_funcinfo << ": attempt to double add player" << endl;
return;
}
kdDebug(11001) << k_funcinfo << ": add player " << p->id() << endl;
TQListBoxText* t = new TQListBoxText(p->name());
d->mItem2Player.insert(t, p);
d->mPlayerBox->insertItem(t);
connect(p, TQ_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)),
this, TQ_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*)));
}
void KGameDialogConnectionConfig::slotPlayerLeftGame(KPlayer* p)
{
// disconnect first
this->disconnect(p);
if (!item(p)) {
kdError(11001) << k_funcinfo << ": cannot find " << p->id()
<< " in list" << endl;
return;
}
d->mPlayerBox->removeItem(d->mPlayerBox->index(item(p)));
}
void KGameDialogConnectionConfig::slotKickPlayerOut(TQListBoxItem* item)
{
kdDebug(11001) << "kick player out" << endl;
KPlayer* p = d->mItem2Player[item];
if (!p) {
kdError(11001) << "invalid item selected - no player found" << endl;
return;
}
if (!game()) {
kdWarning(11001) << "no game set" << endl;
return;
}
if (!admin()) {
kdDebug(11001) << "Only the ADMIN can kick players" << endl;
return;
}
if (p == owner()) { // you wanna ban the ADMIN ??
kdDebug(11001) << "you cannot kick the ADMIN" << endl;
return;
}
if (KMessageBox::questionYesNo(this, i18n("Do you want to ban player \"%1\" from the game?").arg(
p->name()), TQString(), i18n("Ban Player"), i18n("Do Not Ban")) == KMessageBox::Yes) {
kdDebug(11001) << "will remove player " << p << endl;
game()->removePlayer(p);
// d->mPlayerBox->removeItem(d->mPlayerBox->index(item)); // should be done by signalPlayerLeftGame
} else {
kdDebug(11001) << "will NOT remove player " << p << endl;
}
}
void KGameDialogConnectionConfig::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player)
{
if(prop->id() == KGamePropertyBase::IdName) {
TQListBoxText* old = 0;
TQPtrDictIterator<KPlayer> it(d->mItem2Player);
while (it.current() && !old) {
if (it.current() == player) {
old = (TQListBoxText*)it.currentKey();
}
++it;
}
TQListBoxText* t = new TQListBoxText(player->name());
d->mPlayerBox->changeItem(t, d->mPlayerBox->index(old));
d->mItem2Player.remove(old);
d->mItem2Player.insert(t, player);
}
}