/* This file is part of the KDE 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 #include #include #include #include #include #include #include #include #include #include #include #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, TQT_SIGNAL(clicked()), this, TQT_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, TQT_SIGNAL(signalNetworkSetup()), this, TQT_SLOT(slotInitConnection())); connect(d->mConnect, TQT_SIGNAL(signalServerTypeChanged(int)), this, TQT_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(), TQT_SIGNAL(signalConnectionBroken()), this, TQT_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::null; } 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(), TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)), this, TQT_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 QPushButtons 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, TQT_SIGNAL(signalAdminChanged(int)), this, TQT_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 Q_UINT32 newAdmin = 0; // newAdmin = ; game()->electAdmin(newAdmin); } void KGameDialogMsgServerConfig::removeClient(Q_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, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotChangeMaxClients())); d->changeAdmin = new TQPushButton(i18n("Change Admin"), this); connect(d->changeAdmin, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotChangeAdmin())); d->removeClient = new TQPushButton(i18n("Remove Client with All Players"), this); connect(d->removeClient, TQT_SIGNAL(pressed()), this, TQT_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 QPushButtons) 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 mItem2Player; KListBox* 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 KListBox(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(), TQT_SIGNAL(signalPlayerJoinedGame(KPlayer*)), this, TQT_SLOT(slotPlayerJoinedGame(KPlayer*))); connect(game(), TQT_SIGNAL(signalPlayerLeftGame(KPlayer*)), this, TQT_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(), TQT_SIGNAL(executed(TQListBoxItem*)), this, 0); } KGameDialogConfig::setAdmin(a); if (admin()) { connect(d->mPlayerBox, TQT_SIGNAL(executed(TQListBoxItem*)), this, TQT_SLOT(slotKickPlayerOut(TQListBoxItem*))); } } TQListBoxItem* KGameDialogConnectionConfig::item(KPlayer* p) const { TQPtrDictIterator it(d->mItem2Player); while (it.current()) { if (it.current() == p) { return (TQListBoxItem*)it.currentKey(); } ++it; } return 0; } void KGameDialogConnectionConfig::slotClearPlayers() { TQPtrDictIterator 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, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)), this, TQT_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::null, 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 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); } }