diff --git a/client/selectconfiguration_widget.cpp b/client/selectconfiguration_widget.cpp index a70efb5..bd3537b 100644 --- a/client/selectconfiguration_widget.cpp +++ b/client/selectconfiguration_widget.cpp @@ -1,206 +1,209 @@ // Copyright (c) 2002-2004 Rob Kaper // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // 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; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301, USA. #include #include #include #include #include #include -#include +#include +#include #include #include #include #include #include "selectconfiguration_widget.h" #include SelectConfiguration::SelectConfiguration(AtlanticCore *atlanticCore, QWidget *parent) : QWidget(parent) { m_atlanticCore = atlanticCore; m_game = 0; m_mainLayout = new QVBoxLayout(this ); m_mainLayout->setMargin(0); Q_CHECK_PTR(m_mainLayout); + const QPair icons = KStandardGuiItem::backAndForward(); + // Game configuration. m_configBox = new QGroupBox(i18n("Game Configuration"), this); m_configBox->setObjectName("configBox"); m_mainLayout->addWidget(m_configBox); QVBoxLayout *configBoxLayout = new QVBoxLayout(m_configBox); Q_UNUSED(configBoxLayout) // Player buttons. QHBoxLayout *playerButtons = new QHBoxLayout(); m_mainLayout->addItem( playerButtons ); playerButtons->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); // Vertical spacer. m_mainLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); // Server buttons. QHBoxLayout *serverButtons = new QHBoxLayout(); m_mainLayout->addItem( serverButtons ); - m_backButton = new QPushButton(KDE::icon("go-previous"), i18n("Leave Game"), this); + m_backButton = new QPushButton(icons.first.icon(), i18n("Leave Game"), this); serverButtons->addWidget(m_backButton); connect(m_backButton, SIGNAL(clicked()), this, SIGNAL(leaveGame())); serverButtons->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); - m_startButton = new QPushButton(KDE::icon("go-next"), i18n("Start Game"), this); + m_startButton = new QPushButton(icons.second.icon(), i18n("Start Game"), this); serverButtons->addWidget(m_startButton); m_startButton->setEnabled(false); connect(m_startButton, SIGNAL(clicked()), this, SIGNAL(startGame())); Player *playerSelf = m_atlanticCore->playerSelf(); if (playerSelf) { playerChanged(playerSelf); connect(playerSelf, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); } emit statusMessage(i18n("Retrieving configuration list...")); foreach (ConfigOption *opt, m_atlanticCore->configOptions()) addConfigOption(opt); } void SelectConfiguration::initGame() { emit statusMessage(i18n("Game started. Retrieving full game data...")); } void SelectConfiguration::addConfigOption(ConfigOption *configOption) { // FIXME: only bool types supported! QCheckBox *checkBox = new QCheckBox(configOption->description(), m_configBox); m_configBox->layout()->addWidget(checkBox); checkBox->setObjectName("checkbox"); m_configMap[(QObject *)checkBox] = configOption; m_configBoxMap[configOption] = checkBox; checkBox->setChecked( configOption->value().toInt() ); checkBox->setEnabled( configOption->edit() && m_atlanticCore->selfIsMaster() ); checkBox->show(); connect(checkBox, SIGNAL(clicked()), this, SLOT(changeOption())); connect(configOption, SIGNAL(changed(ConfigOption *)), this, SLOT(optionChanged(ConfigOption *))); } void SelectConfiguration::gameOption(const QString &title, const QString &type, const QString &value, const QString &edit, const QString &command) { // Find if option exists in GUI yet if (QCheckBox *checkBox = dynamic_cast(m_checkBoxMap[command])) { checkBox->setChecked(value.toInt()); checkBox->setEnabled(edit.toInt()); return; } // Create option if (type == "bool") { QCheckBox *checkBox = new QCheckBox(title, m_configBox); m_configBox->layout()->addWidget(checkBox); checkBox->setObjectName("checkbox"); m_optionCommandMap[(QObject *)checkBox] = command; m_checkBoxMap[command] = checkBox; checkBox->setChecked(value.toInt()); checkBox->setEnabled(edit.toInt()); checkBox->show(); connect(checkBox, SIGNAL(clicked()), this, SLOT(optionChanged())); } // TODO: create options other than type=bool // TODO: Enable edit for master only } void SelectConfiguration::changeOption() { ConfigOption *configOption = m_configMap[(QObject *)QObject::sender()]; if (configOption) { qCDebug(ATLANTIK_LOG) << "checked" << ((QCheckBox *)QObject::sender())->isChecked(); emit changeOption( configOption->id(), QString::number( ((QCheckBox *)QObject::sender())->isChecked() ) ); } } void SelectConfiguration::optionChanged(ConfigOption *configOption) { QCheckBox *checkBox = m_configBoxMap[configOption]; if (checkBox) { checkBox->setText( configOption->description() ); checkBox->setChecked( configOption->value().toInt() ); checkBox->setEnabled( configOption->edit() && m_atlanticCore->selfIsMaster() ); } } void SelectConfiguration::optionChanged() { QString command = m_optionCommandMap[(QObject *)QObject::sender()]; if (QCheckBox *checkBox = m_checkBoxMap[command]) { command.append(QString::number(checkBox->isChecked())); emit buttonCommand(command); } } void SelectConfiguration::slotEndUpdate() { emit statusMessage(i18n("Retrieved configuration list.")); } void SelectConfiguration::playerChanged(Player *player) { qCDebug(ATLANTIK_LOG); if (player->game() != m_game) { qCDebug(ATLANTIK_LOG) << "change"; if (m_game) disconnect(m_game, SIGNAL(changed(Game *)), this, SLOT(gameChanged(Game *))); m_game = player->game(); if (m_game) connect(m_game, SIGNAL(changed(Game *)), this, SLOT(gameChanged(Game *))); } } void SelectConfiguration::gameChanged(Game *game) { m_startButton->setEnabled( game->master() == m_atlanticCore->playerSelf() ); QMapIterator it(m_configBoxMap); while (it.hasNext()) { it.next(); it.value()->setEnabled(it.key()->edit() && m_atlanticCore->selfIsMaster() ); } } diff --git a/client/selectgame_widget.cpp b/client/selectgame_widget.cpp index a4a2382..d04d163 100644 --- a/client/selectgame_widget.cpp +++ b/client/selectgame_widget.cpp @@ -1,194 +1,198 @@ // Copyright (c) 2002-2003 Rob Kaper // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // 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; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301, USA. #include #include #include #include #include #include #include #include #include +#include +#include #include #include #include #include "selectgame_widget.h" enum { GameTypeRole = Qt::UserRole + 1 }; SelectGame::SelectGame(AtlanticCore *atlanticCore, QWidget *parent) : QWidget(parent) { m_atlanticCore = atlanticCore; connect(m_atlanticCore, SIGNAL(createGUI(Game *)), this, SLOT(addGame(Game *))); connect(m_atlanticCore, SIGNAL(removeGUI(Game *)), this, SLOT(delGame(Game *))); setupUi(this); layout()->setMargin(0); + const QPair icons = KStandardGuiItem::backAndForward(); + // List of games m_gameList->header()->setSectionsClickable(false); connect(m_gameList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(validateConnectButton())); connect(m_gameList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(connectClicked())); connect(m_gameList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(validateConnectButton())); - backButton->setIcon(KDE::icon("go-previous")); + backButton->setIcon(icons.first.icon()); connect(backButton, SIGNAL(clicked()), this, SIGNAL(leaveServer())); - m_connectButton->setIcon(KDE::icon("go-next")); + m_connectButton->setIcon(icons.second.icon()); m_connectButton->setEnabled(false); connect(m_connectButton, SIGNAL(clicked()), this, SLOT(connectClicked())); } void SelectGame::addGame(Game *game) { connect(game, SIGNAL(changed(Game *)), this, SLOT(updateGame(Game *))); if (game->id() == -1) { QTreeWidgetItem *item = new QTreeWidgetItem(); item->setText(0, i18n("Create a new %1 Game", game->name())); item->setText(1, game->description()); item->setData(0, GameTypeRole, game->type()); item->setIcon(0, KDE::icon("document-new")); m_gameList->addTopLevelItem(item); } else { Player *master = game->master(); QTreeWidgetItem *item = new QTreeWidgetItem(); item->setText(0, i18n("Join %1's %2 Game", (master ? master->name() : QString()), game->name())); item->setText(1, game->description()); item->setText(2, QString::number(game->id())); item->setText(3, QString::number(game->players())); item->setData(0, GameTypeRole, game->type()); item->setIcon(0, KDE::icon("atlantik")); item->setDisabled(!game->canBeJoined()); m_gameList->addTopLevelItem(item); KNotification::event("newgame", i18n("New game available.")); connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); } m_gameList->resizeColumnToContents(0); m_gameList->resizeColumnToContents(1); m_gameList->resizeColumnToContents(2); m_gameList->resizeColumnToContents(3); // validateConnectButton(); } void SelectGame::delGame(Game *game) { QTreeWidgetItem *item = findItem(game); if (!item) return; delete item; validateConnectButton(); } void SelectGame::updateGame(Game *game) { QTreeWidgetItem *item = findItem(game); if (!item) return; item->setText( 1, game->description() ); if (game->id() == -1) item->setText(0, i18n("Create a new %1 Game", game->name())); else { Player *master = game->master(); item->setText( 0, i18n("Join %1's %2 Game", (master ? master->name() : QString()), game->name() ) ); item->setText( 3, QString::number( game->players() ) ); item->setDisabled(!game->canBeJoined()); connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); } validateConnectButton(); } void SelectGame::playerChanged(Player *player) { const int count = m_gameList->topLevelItemCount(); Game *game = 0; for (int i = 0; i < count; ++i) { QTreeWidgetItem *item = m_gameList->topLevelItem(i); game = m_atlanticCore->findGame( item->text(2).toInt() ); if ( game && game->master() == player ) { item->setText( 0, i18n("Join %1's %2 Game", player->name(), game->name() ) ); return; } } } QTreeWidgetItem *SelectGame::findItem(Game *game) { const int count = m_gameList->topLevelItemCount(); for (int i = 0; i < count; ++i) { QTreeWidgetItem *item = m_gameList->topLevelItem(i); if ( (game->id() == -1 || item->text(2) == QString::number(game->id())) && item->data(0, GameTypeRole).toString() == game->type() ) return item; } return 0; } void SelectGame::validateConnectButton() { const QList items = m_gameList->selectedItems(); if (!items.isEmpty()) { const QTreeWidgetItem *item = items.first(); if (item->text(2).toInt() > 0) m_connectButton->setText(i18n("Join Game")); else m_connectButton->setText(i18n("Create Game")); m_connectButton->setEnabled(true); } else m_connectButton->setEnabled(false); } void SelectGame::connectClicked() { const QList items = m_gameList->selectedItems(); if (!items.isEmpty()) { const QTreeWidgetItem *item = items.first(); if (int gameId = item->text(2).toInt()) emit joinGame(gameId); else emit newGame(item->data(0, GameTypeRole).toString()); } } diff --git a/client/selectserver_widget.cpp b/client/selectserver_widget.cpp index ac515fa..3444ce2 100644 --- a/client/selectserver_widget.cpp +++ b/client/selectserver_widget.cpp @@ -1,235 +1,236 @@ // Copyright (c) 2002-2004 Rob Kaper // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // 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; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301, USA. #include #include #include #include #include #include +#include #include #include "metatlantic.h" #include "selectserver_widget.h" #include MetaserverEntry::MetaserverEntry(const QString &host, int port, const QString &version, int users) : QObject(), QTreeWidgetItem(MetaserverType), m_latency(9999), m_users(users), m_port(port) { setText(0, host); setText(1, QString::number(m_latency)); setText(2, version); setText(3, users == -1 ? i18n("unknown") : QString::number(m_users)); setIcon(0, KDE::icon("atlantik")); setDisabled(true); m_isDev = version.indexOf("CVS") != -1 || version.indexOf("-dev") != -1; m_latencySocket = new QTcpSocket(); m_latencySocket->setSocketOption(QAbstractSocket::LowDelayOption, true); connect(m_latencySocket, SIGNAL(hostFound()), this, SLOT(resolved())); connect(m_latencySocket, SIGNAL(connected()), this, SLOT(connected())); m_latencySocket->connectToHost(host, m_port); } bool MetaserverEntry::isDev() const { return m_isDev; } QString MetaserverEntry::host() const { return text(0); } int MetaserverEntry::port() const { return m_port; } bool MetaserverEntry::operator<(const QTreeWidgetItem &other) const { if (other.type() != MetaserverType) return QTreeWidgetItem::operator<(other); // sort by (less) latency first, then (most) users, then by host const MetaserverEntry *e = static_cast(&other); if (m_latency < e->m_latency) return true; if (m_users > e->m_users) return true; return QString::compare(host(), e->host()) > 0; } void MetaserverEntry::resolved() { m_timer.start(); qCDebug(ATLANTIK_LOG) << host() << "resolved; timer starts"; } void MetaserverEntry::connected() { m_latency = m_timer.elapsed(); m_latencySocket->abort(); qCDebug(ATLANTIK_LOG) << "connected to" << host() << "- latency =" << m_latency; setDisabled(false); setText(1, QString::number(m_latency)); disconnect(m_latencySocket, 0, this, 0); m_latencySocket->deleteLater(); m_latencySocket = 0; } void MetaserverEntry::showDevelopmentServers(bool show) { setHidden(!show); } SelectServer::SelectServer(bool useMonopigatorOnStart, bool hideDevelopmentServers, QWidget *parent) : QWidget(parent) { m_hideDevelopmentServers = hideDevelopmentServers; setupUi(this); layout()->setMargin(0); connect(m_hostEdit, SIGNAL(returnPressed()), this, SLOT(customConnect())); m_portEdit->setText(QString::number(MONOPD_PORT)); m_portEdit->setValidator(new QIntValidator(1, 65535, m_portEdit)); connect(m_portEdit, SIGNAL(returnPressed()), this, SLOT(customConnect())); connectButton->setIcon(KDE::icon("network-wired")); connect(connectButton, SIGNAL(clicked()), this, SLOT(customConnect())); // List of servers m_serverList->sortItems(1, Qt::AscendingOrder); m_serverList->header()->setSectionsClickable(false); m_serverList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); m_serverList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); m_serverList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); connect(m_serverList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(validateConnectButton())); connect(m_serverList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotConnect())); connect(m_serverList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(validateConnectButton())); // Server List / Refresh KGuiItem::assign(m_refreshButton, useMonopigatorOnStart ? KGuiItem(i18n("Reload Server List"), "view-refresh") : KGuiItem(i18n("Get Server List"), "network-wired")); connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(slotRefresh())); // Connect - m_connectButton->setIcon(KDE::icon("go-next")); + m_connectButton->setIcon(KStandardGuiItem::forward(KStandardGuiItem::UseRTL).icon()); connect(m_connectButton, SIGNAL(clicked()), this, SLOT(slotConnect())); // Monopigator m_metatlantic = new Metatlantic(); connect(m_metatlantic, SIGNAL(metatlanticAdd(QString,int,QString,int)), this, SLOT(slotMetatlanticAdd(QString,int,QString,int))); connect(m_metatlantic, SIGNAL(finished()), SLOT(metatlanticFinished())); connect(m_metatlantic, SIGNAL(timeout()), SLOT(metatlanticTimeout())); } SelectServer::~SelectServer() { delete m_metatlantic; } void SelectServer::setHideDevelopmentServers(bool hideDevelopmentServers) { if ( m_hideDevelopmentServers != hideDevelopmentServers ) { m_hideDevelopmentServers = hideDevelopmentServers; emit showDevelopmentServers( !m_hideDevelopmentServers ); } } void SelectServer::initMonopigator() { // Hardcoded, but there aren't any other Metatlantic root servers at the moment emit msgStatus(i18n("Retrieving server list...")); KGuiItem::assign(m_refreshButton, KGuiItem(i18n("Reload Server List"), "view-refresh")); m_metatlantic->loadData(METATLANTIC_HOST, METATLANTIC_PORT); } void SelectServer::slotMetatlanticAdd(const QString &host, int port, const QString &version, int users) { MetaserverEntry *item = new MetaserverEntry(host, port, version, users); m_serverList->addTopLevelItem(item); m_serverList->resizeColumnToContents(0); if ( item->isDev() ) { item->setHidden(m_hideDevelopmentServers); connect(this, SIGNAL(showDevelopmentServers(bool)), item, SLOT(showDevelopmentServers(bool))); } validateConnectButton(); } void SelectServer::metatlanticFinished() { emit msgStatus(i18n("Retrieved server list.")); m_refreshButton->setEnabled(true); } void SelectServer::metatlanticTimeout() { emit msgStatus(i18n("Error while retrieving the server list.")); m_refreshButton->setEnabled(true); } void SelectServer::validateConnectButton() { if (!m_serverList->selectedItems().isEmpty()) m_connectButton->setEnabled(true); else m_connectButton->setEnabled(false); } void SelectServer::slotRefresh(bool useMonopigator) { m_serverList->clear(); validateConnectButton(); if (useMonopigator) { m_refreshButton->setEnabled(false); initMonopigator(); } } void SelectServer::slotConnect() { const QList items = m_serverList->selectedItems(); if (!items.isEmpty()) { const QTreeWidgetItem *item = items.first(); Q_ASSERT(item->type() == MetaserverEntry::MetaserverType); const MetaserverEntry *e = static_cast(item); emit serverConnect(e->host(), e->port()); } } void SelectServer::customConnect() { if (!m_hostEdit->text().isEmpty() && !m_portEdit->text().isEmpty()) emit serverConnect(m_hostEdit->text(), m_portEdit->text().toInt()); }