summaryrefslogtreecommitdiffstats
path: root/atlantik/client
diff options
context:
space:
mode:
Diffstat (limited to 'atlantik/client')
-rw-r--r--atlantik/client/Makefile.am11
-rw-r--r--atlantik/client/atlantik.cpp853
-rw-r--r--atlantik/client/atlantik.h268
-rw-r--r--atlantik/client/configdlg.cpp334
-rw-r--r--atlantik/client/configdlg.h139
-rw-r--r--atlantik/client/event.cpp42
-rw-r--r--atlantik/client/event.h40
-rw-r--r--atlantik/client/eventlogwidget.cpp123
-rw-r--r--atlantik/client/eventlogwidget.h73
-rw-r--r--atlantik/client/main.cpp78
-rw-r--r--atlantik/client/main.h29
-rw-r--r--atlantik/client/monopigator.cpp164
-rw-r--r--atlantik/client/monopigator.h79
-rw-r--r--atlantik/client/selectconfiguration_widget.cpp189
-rw-r--r--atlantik/client/selectconfiguration_widget.h80
-rw-r--r--atlantik/client/selectgame_widget.cpp192
-rw-r--r--atlantik/client/selectgame_widget.h65
-rw-r--r--atlantik/client/selectserver_widget.cpp178
-rw-r--r--atlantik/client/selectserver_widget.h73
19 files changed, 3010 insertions, 0 deletions
diff --git a/atlantik/client/Makefile.am b/atlantik/client/Makefile.am
new file mode 100644
index 00000000..25eb24e1
--- /dev/null
+++ b/atlantik/client/Makefile.am
@@ -0,0 +1,11 @@
+bin_PROGRAMS = atlantik
+INCLUDES = -I$(top_srcdir)/libkdegames -I$(srcdir)/../libatlantic -I$(srcdir)/../libatlantikclient -I$(srcdir)/../libatlantikui $(all_includes)
+atlantik_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+atlantik_LDADD = ../libatlantikui/libatlantikui.la ../libatlantikclient/libatlantikclient.la $(LIB_KDEGAMES) $(LIB_KIO)
+atlantik_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+atlantik_SOURCES = atlantik.cpp configdlg.cpp event.cpp eventlogwidget.cpp \
+ main.cpp monopigator.cpp selectconfiguration_widget.cpp \
+ selectgame_widget.cpp selectserver_widget.cpp
+
+METASOURCES = AUTO
diff --git a/atlantik/client/atlantik.cpp b/atlantik/client/atlantik.cpp
new file mode 100644
index 00000000..56bae64b
--- /dev/null
+++ b/atlantik/client/atlantik.cpp
@@ -0,0 +1,853 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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 <errno.h>
+
+#include <qcolor.h>
+#include <qdatetime.h>
+#include <qlineedit.h>
+#include <qscrollview.h>
+#include <qpopupmenu.h>
+
+#include <kaboutapplication.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <knotifyclient.h>
+#include <knotifydialog.h>
+#include <kstatusbar.h>
+#include <kstdgameaction.h>
+#include <kstdaction.h>
+#include <ktoolbar.h>
+
+#include <kdeversion.h>
+#undef KDE_3_2_FEATURES
+#if defined(KDE_MAKE_VERSION)
+#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,0)
+ #define KDE_3_2_FEATURES
+#endif
+#endif
+
+#include <kdebug.h>
+
+#include <atlantic_core.h>
+#include <auction.h>
+#include <estate.h>
+#include <player.h>
+#include <trade.h>
+#include "atlantik.moc"
+
+#include <atlantik_network.h>
+
+#include <board.h>
+#include <trade_widget.h>
+
+#include "eventlogwidget.h"
+#include "main.h"
+#include "selectserver_widget.h"
+#include "selectgame_widget.h"
+#include "selectconfiguration_widget.h"
+
+LogTextEdit::LogTextEdit( QWidget *parent, const char *name ) : QTextEdit( parent, name )
+{
+#ifdef KDE_3_2_FEATURES
+ m_clear = KStdAction::clear( this, SLOT( clear() ), 0 );
+#else
+ m_clear = new KAction( i18n("Clear"), "clear", NULL, this, SLOT( clear() ), static_cast<KActionCollection *>(0), "clear" );
+#endif
+ m_selectAll = KStdAction::selectAll( this, SLOT( selectAll() ), 0 );
+ m_copy = KStdAction::copy( this, SLOT( copy() ), 0 );
+}
+
+LogTextEdit::~LogTextEdit()
+{
+ delete m_clear;
+ delete m_selectAll;
+ delete m_copy;
+}
+
+QPopupMenu *LogTextEdit::createPopupMenu( const QPoint & )
+{
+ QPopupMenu *rmbMenu = new QPopupMenu( this );
+ m_clear->plug( rmbMenu );
+ rmbMenu->insertSeparator();
+ m_copy->setEnabled( hasSelectedText() );
+ m_copy->plug( rmbMenu );
+ m_selectAll->plug( rmbMenu );
+
+ return rmbMenu;
+}
+
+Atlantik::Atlantik ()
+ : KMainWindow (),
+ m_runningGame( false )
+{
+ // Read application configuration
+ readConfig();
+
+ // Toolbar: Game
+// KStdGameAction::gameNew(this, SLOT(slotNewGame()), actionCollection(), "game_new");
+ m_showEventLog = new KAction(i18n("Show Event &Log")/*, "atlantik_showeventlog"*/, CTRL+Key_L, this, SLOT(showEventLog()), actionCollection(), "showeventlog");
+ KStdGameAction::quit(kapp, SLOT(closeAllWindows()), actionCollection(), "game_quit");
+
+ // Toolbar: Settings
+ KStdAction::preferences(this, SLOT(slotConfigure()), actionCollection());
+ KStdAction::configureNotifications(this, SLOT(configureNotifications()), actionCollection());
+
+ // Initialize pointers to 0L
+ m_configDialog = 0;
+ m_board = 0;
+ m_eventLogWidget = 0;
+ m_selectServer = 0;
+ m_selectGame = 0;
+ m_selectConfiguration = 0;
+ m_atlantikNetwork = 0;
+
+ // Game and network core
+ m_atlanticCore = new AtlanticCore(this, "atlanticCore");
+ connect(m_atlanticCore, SIGNAL(createGUI(Player *)), this, SLOT(newPlayer(Player *)));
+ connect(m_atlanticCore, SIGNAL(removeGUI(Player *)), this, SLOT(removeGUI(Player *)));
+ connect(m_atlanticCore, SIGNAL(createGUI(Trade *)), this, SLOT(newTrade(Trade *)));
+ connect(m_atlanticCore, SIGNAL(removeGUI(Trade *)), this, SLOT(removeGUI(Trade *)));
+
+ initEventLog();
+ initNetworkObject();
+
+ // Menu,toolbar: Move
+ m_roll = KStdGameAction::roll(this, SIGNAL(rollDice()), actionCollection());
+ m_roll->setEnabled(false);
+ m_buyEstate = new KAction(i18n("&Buy"), "atlantik_buy_estate", CTRL+Key_B, this, SIGNAL(buyEstate()), actionCollection(), "buy_estate");
+ m_buyEstate->setEnabled(false);
+ m_auctionEstate = new KAction(i18n("&Auction"), "auction", CTRL+Key_A, this, SIGNAL(auctionEstate()), actionCollection(), "auction");
+ m_auctionEstate->setEnabled(false);
+ m_endTurn = KStdGameAction::endTurn(this, SIGNAL(endTurn()), actionCollection());
+ m_endTurn->setEnabled(false);
+ m_jailCard = new KAction(i18n("Use Card to Leave Jail")/*, "atlantik_move_jail_card"*/, 0, this, SIGNAL(jailCard()), actionCollection(), "move_jailcard");
+ m_jailCard->setEnabled(false);
+ m_jailPay = new KAction(i18n("&Pay to Leave Jail"), "jail_pay", CTRL+Key_P, this, SIGNAL(jailPay()), actionCollection(), "move_jailpay");
+ m_jailPay->setEnabled(false);
+ m_jailRoll = new KAction(i18n("Roll to Leave &Jail")/*, "atlantik_move_jail_roll"*/, CTRL+Key_J, this, SIGNAL(jailRoll()), actionCollection(), "move_jailroll");
+ m_jailRoll->setEnabled(false);
+
+ // Mix code and XML into GUI
+ KMainWindow::createGUI();
+ applyMainWindowSettings( KGlobal::config(), "AtlantikMainWindow" );
+ KMainWindow::statusBar()->insertItem("Atlantik " ATLANTIK_VERSION_STRING, 0);
+ KMainWindow::statusBar()->insertItem(QString::null, 1);
+ connect(statusBar(), SIGNAL(released(int)), this, SLOT(statusBarClick(int)));
+
+ // Main widget, containing all others
+ m_mainWidget = new QWidget(this, "main");
+ m_mainWidget->show();
+ m_mainLayout = new QGridLayout(m_mainWidget, 3, 2);
+ setCentralWidget(m_mainWidget);
+
+ // Vertical view area for portfolios.
+ m_portfolioScroll = new QScrollView(m_mainWidget, "pfScroll");
+ m_mainLayout->addWidget( m_portfolioScroll, 0, 0 );
+ m_portfolioScroll->setHScrollBarMode( QScrollView::AlwaysOff );
+ m_portfolioScroll->setResizePolicy( QScrollView::AutoOneFit );
+ m_portfolioScroll->setFixedHeight( 200 );
+ m_portfolioScroll->hide();
+
+ m_portfolioWidget = new QWidget( m_portfolioScroll->viewport(), "pfWidget" );
+ m_portfolioScroll->addChild( m_portfolioWidget );
+ m_portfolioWidget->show();
+
+ m_portfolioLayout = new QVBoxLayout(m_portfolioWidget);
+ m_portfolioViews.setAutoDelete(true);
+
+ // Nice label
+// m_portfolioLabel = new QLabel(i18n("Players"), m_portfolioWidget, "pfLabel");
+// m_portfolioLayout->addWidget(m_portfolioLabel);
+// m_portfolioLabel->show();
+
+ // Text view for chat and status messages from server.
+ m_serverMsgs = new LogTextEdit(m_mainWidget, "serverMsgs");
+ m_serverMsgs->setTextFormat(QTextEdit::PlainText);
+ m_serverMsgs->setReadOnly(true);
+ m_serverMsgs->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_serverMsgs->setMinimumWidth(200);
+ m_mainLayout->addWidget(m_serverMsgs, 1, 0);
+
+ // LineEdit to enter commands and chat messages.
+ m_input = new QLineEdit(m_mainWidget, "input");
+ m_mainLayout->addWidget(m_input, 2, 0);
+
+ m_serverMsgs->setFocusProxy(m_input);
+
+ connect(m_input, SIGNAL(returnPressed()), this, SLOT(slotSendMsg()));
+
+ // Set stretching where we want it.
+ m_mainLayout->setRowStretch(1, 1); // make m_board+m_serverMsgs stretch vertically, not the rest
+ m_mainLayout->setColStretch(1, 1); // make m_board stretch horizontally, not the rest
+
+ // Check command-line args to see if we need to connect or show Monopigator window
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ QCString host = args->getOption("host");
+ QCString port = args->getOption("port");
+ if (!host.isNull() && !port.isNull())
+ m_atlantikNetwork->serverConnect(host, port.toInt());
+ else
+ showSelectServer();
+}
+
+void Atlantik::readConfig()
+{
+ // Read configuration settings
+ KConfig *config = kapp->config();
+
+ // General configuration
+ config->setGroup("General");
+ m_config.chatTimestamps = config->readBoolEntry("ChatTimeStamps", false);
+
+ // Personalization configuration
+ config->setGroup("Personalization");
+ m_config.playerName = config->readEntry("PlayerName", "Atlantik");
+ m_config.playerImage = config->readEntry("PlayerImage", "cube.png");
+
+ // Board configuration
+ config->setGroup("Board");
+ m_config.indicateUnowned = config->readBoolEntry("IndicateUnowned", true);
+ m_config.highliteUnowned = config->readBoolEntry("HighliteUnowned", false);
+ m_config.darkenMortgaged = config->readBoolEntry("DarkenMortgaged", true);
+ m_config.animateTokens = config->readBoolEntry("AnimateToken", false);
+ m_config.quartzEffects = config->readBoolEntry("QuartzEffects", true);
+
+ // Meta server configuation
+ config->setGroup("Monopigator");
+ m_config.connectOnStart = config->readBoolEntry("ConnectOnStart", false);
+ m_config.hideDevelopmentServers = config->readBoolEntry("HideDevelopmentServers", true);
+
+ // Portfolio colors
+ config->setGroup("WM");
+ QColor activeDefault(204, 204, 204), inactiveDefault(153, 153, 153);
+ m_config.activeColor = config->readColorEntry("activeBackground", &activeDefault);
+ m_config.inactiveColor = config->readColorEntry("inactiveBlend", &inactiveDefault);
+}
+
+void Atlantik::newPlayer(Player *player)
+{
+ initBoard();
+ m_board->addToken(player);
+ addPortfolioView(player);
+
+ // Player::changed() is not connected until later this method, so
+ // we'd better force an update.
+ playerChanged(player);
+
+ connect(player, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *)));
+ connect(player, SIGNAL(gainedTurn()), this, SLOT(gainedTurn()));
+ connect(player, SIGNAL(changed(Player *)), m_board, SLOT(playerChanged(Player *)));
+
+ KNotifyClient::event(winId(), "newplayer");
+}
+
+void Atlantik::newEstate(Estate *estate)
+{
+ initBoard();
+ m_board->addEstateView(estate, m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects);
+}
+
+void Atlantik::newTrade(Trade *trade)
+{
+ TradeDisplay *tradeDisplay = new TradeDisplay(trade, m_atlanticCore, 0, "tradeDisplay");
+ m_tradeGUIMap[trade] = tradeDisplay;
+ tradeDisplay->show();
+}
+
+void Atlantik::newAuction(Auction *auction)
+{
+ initBoard();
+ m_board->addAuctionWidget(auction);
+}
+
+void Atlantik::removeGUI(Player *player)
+{
+ // Find and remove portfolioview
+ PortfolioView *portfolioView = findPortfolioView(player);
+ if (portfolioView)
+ m_portfolioViews.remove(portfolioView);
+
+ if (m_board)
+ m_board->removeToken(player);
+}
+
+void Atlantik::removeGUI(Trade *trade)
+{
+ if (TradeDisplay *tradeDisplay = m_tradeGUIMap[trade])
+ delete tradeDisplay;
+}
+
+void Atlantik::showSelectServer()
+{
+ if (m_selectServer)
+ return;
+
+ m_selectServer = new SelectServer(m_config.connectOnStart, m_config.hideDevelopmentServers, m_mainWidget, "selectServer");
+ m_mainLayout->addMultiCellWidget(m_selectServer, 0, 2, 1, 1);
+ m_selectServer->show();
+
+ if (m_selectGame)
+ {
+ delete m_selectGame;
+ m_selectGame = 0;
+ }
+
+ m_atlanticCore->reset(true);
+ initNetworkObject();
+
+ connect(m_selectServer, SIGNAL(serverConnect(const QString, int)), m_atlantikNetwork, SLOT(serverConnect(const QString, int)));
+ connect(m_selectServer, SIGNAL(msgStatus(const QString &)), this, SLOT(slotMsgStatus(const QString &)));
+
+ m_selectServer->slotRefresh( m_config.connectOnStart );
+}
+
+void Atlantik::showSelectGame()
+{
+ if (m_selectGame)
+ return;
+
+ m_selectGame = new SelectGame(m_atlanticCore, m_mainWidget, "selectGame");
+ m_atlanticCore->emitGames();
+
+ m_mainLayout->addMultiCellWidget(m_selectGame, 0, 2, 1, 1);
+ m_selectGame->show();
+
+ // Reset core and GUI
+ if (m_board)
+ {
+ m_board->hide();
+ m_board->reset();
+// delete m_board;
+// m_board = 0;
+
+ // m_portfolioViews.clear();
+ m_atlanticCore->reset();
+ }
+
+ if (m_selectServer)
+ {
+ delete m_selectServer;
+ m_selectServer = 0;
+ }
+ if (m_selectConfiguration)
+ {
+ delete m_selectConfiguration;
+ m_selectConfiguration = 0;
+ }
+
+ connect(m_selectGame, SIGNAL(joinGame(int)), m_atlantikNetwork, SLOT(joinGame(int)));
+ connect(m_selectGame, SIGNAL(newGame(const QString &)), m_atlantikNetwork, SLOT(newGame(const QString &)));
+ connect(m_selectGame, SIGNAL(leaveServer()), this, SLOT(showSelectServer()));
+ connect(m_selectGame, SIGNAL(msgStatus(const QString &)), this, SLOT(slotMsgStatus(const QString &)));
+}
+
+void Atlantik::showSelectConfiguration()
+{
+ if (m_selectConfiguration)
+ return;
+
+ if (m_selectGame)
+ {
+ delete m_selectGame;
+ m_selectGame = 0;
+ }
+
+ m_selectConfiguration = new SelectConfiguration(m_atlanticCore, m_mainWidget, "selectConfiguration");
+ m_mainLayout->addMultiCellWidget(m_selectConfiguration, 0, 2, 1, 1);
+ m_selectConfiguration->show();
+
+ connect(m_atlanticCore, SIGNAL(createGUI(ConfigOption *)), m_selectConfiguration, SLOT(addConfigOption(ConfigOption *)));
+ connect(m_atlantikNetwork, SIGNAL(gameOption(QString, QString, QString, QString, QString)), m_selectConfiguration, SLOT(gameOption(QString, QString, QString, QString, QString)));
+ connect(m_atlantikNetwork, SIGNAL(gameInit()), m_selectConfiguration, SLOT(initGame()));
+ connect(m_selectConfiguration, SIGNAL(startGame()), m_atlantikNetwork, SLOT(startGame()));
+ connect(m_selectConfiguration, SIGNAL(leaveGame()), m_atlantikNetwork, SLOT(leaveGame()));
+ connect(m_selectConfiguration, SIGNAL(changeOption(int, const QString &)), m_atlantikNetwork, SLOT(changeOption(int, const QString &)));
+ connect(m_selectConfiguration, SIGNAL(buttonCommand(QString)), m_atlantikNetwork, SLOT(writeData(QString)));
+ connect(m_selectConfiguration, SIGNAL(iconSelected(const QString &)), m_atlantikNetwork, SLOT(setImage(const QString &)));
+ connect(m_selectConfiguration, SIGNAL(statusMessage(const QString &)), this, SLOT(slotMsgStatus(const QString &)));
+}
+
+void Atlantik::initBoard()
+{
+ if (m_board)
+ return;
+
+ m_board = new AtlantikBoard(m_atlanticCore, 40, AtlantikBoard::Play, m_mainWidget, "board");
+ m_board->setViewProperties(m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects, m_config.animateTokens);
+
+ connect(m_atlantikNetwork, SIGNAL(displayDetails(QString, bool, bool, Estate *)), m_board, SLOT(insertDetails(QString, bool, bool, Estate *)));
+ connect(m_atlantikNetwork, SIGNAL(addCommandButton(QString, QString, bool)), m_board, SLOT(displayButton(QString, QString, bool)));
+ connect(m_atlantikNetwork, SIGNAL(addCloseButton()), m_board, SLOT(addCloseButton()));
+ connect(m_board, SIGNAL(tokenConfirmation(Estate *)), m_atlantikNetwork, SLOT(tokenConfirmation(Estate *)));
+ connect(m_board, SIGNAL(buttonCommand(QString)), m_atlantikNetwork, SLOT(writeData(QString)));
+}
+
+void Atlantik::showBoard()
+{
+ if (m_selectGame)
+ {
+ delete m_selectGame;
+ m_selectGame = 0;
+ }
+
+ if (m_selectConfiguration)
+ {
+ delete m_selectConfiguration;
+ m_selectConfiguration = 0;
+ }
+
+ if (!m_board)
+ initBoard();
+
+ m_runningGame = true;
+
+ m_mainLayout->addMultiCellWidget(m_board, 0, 2, 1, 1);
+ m_board->displayDefault();
+ m_board->show();
+
+ PortfolioView *portfolioView = 0;
+ for (QPtrListIterator<PortfolioView> it(m_portfolioViews); *it; ++it)
+ if ((portfolioView = dynamic_cast<PortfolioView*>(*it)))
+ portfolioView->buildPortfolio();
+}
+
+void Atlantik::freezeBoard()
+{
+ if (!m_board)
+ showBoard();
+
+ m_runningGame = false;
+ // TODO: m_board->freeze();
+}
+
+void Atlantik::slotNetworkConnected()
+{
+}
+
+void Atlantik::slotNetworkError(int errnum)
+{
+ QString errMsg(i18n("Error connecting: "));
+
+ switch (m_atlantikNetwork->status())
+ {
+ case IO_ConnectError:
+ if (errnum == ECONNREFUSED)
+ errMsg.append(i18n("connection refused by host."));
+ else
+ errMsg.append(i18n("could not connect to host."));
+ break;
+
+ case IO_LookupError:
+ errMsg.append(i18n("host not found."));
+ break;
+
+ default:
+ errMsg.append(i18n("unknown error."));
+ }
+
+ serverMsgsAppend(errMsg);
+
+ // Re-init network object
+ initNetworkObject();
+}
+
+void Atlantik::networkClosed(int status)
+{
+ switch( status )
+ {
+ case KBufferedIO::involuntary:
+ slotMsgStatus( i18n("Connection with server %1:%2 lost.").arg(m_atlantikNetwork->host()).arg(m_atlantikNetwork->port()), QString("connect_no") );
+ showSelectServer();
+ break;
+ default:
+ if ( !m_atlantikNetwork->host().isEmpty() )
+ slotMsgStatus( i18n("Disconnected from %1:%2.").arg(m_atlantikNetwork->host()).arg(m_atlantikNetwork->port()), QString("connect_no") );
+ break;
+ }
+}
+
+void Atlantik::slotConfigure()
+{
+ if (m_configDialog == 0)
+ m_configDialog = new ConfigDialog(this);
+ m_configDialog->show();
+
+ connect(m_configDialog, SIGNAL(okClicked()), this, SLOT(slotUpdateConfig()));
+}
+
+void Atlantik::showEventLog()
+{
+ if (!m_eventLogWidget)
+ m_eventLogWidget = new EventLogWidget(m_eventLog, 0);
+ m_eventLogWidget->show();
+}
+
+void Atlantik::configureNotifications()
+{
+ KNotifyDialog::configure(this);
+}
+
+void Atlantik::slotUpdateConfig()
+{
+ KConfig *config=kapp->config();
+ bool optBool, configChanged = false;
+ QString optStr;
+
+ optBool = m_configDialog->chatTimestamps();
+ if (m_config.chatTimestamps != optBool)
+ {
+ m_config.chatTimestamps = optBool;
+ configChanged = true;
+ }
+
+ optStr = m_configDialog->playerName();
+ if (m_config.playerName != optStr)
+ {
+ m_config.playerName = optStr;
+ m_atlantikNetwork->setName(optStr);
+ }
+
+ optStr = m_configDialog->playerImage();
+ if (m_config.playerImage != optStr)
+ {
+ m_config.playerImage = optStr;
+ m_atlantikNetwork->setImage(optStr);
+ }
+
+ optBool = m_configDialog->indicateUnowned();
+ if (m_config.indicateUnowned != optBool)
+ {
+ m_config.indicateUnowned = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->highliteUnowned();
+ if (m_config.highliteUnowned != optBool)
+ {
+ m_config.highliteUnowned = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->darkenMortgaged();
+ if (m_config.darkenMortgaged != optBool)
+ {
+ m_config.darkenMortgaged = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->animateToken();
+ if (m_config.animateTokens != optBool)
+ {
+ m_config.animateTokens = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->quartzEffects();
+ if (m_config.quartzEffects != optBool)
+ {
+ m_config.quartzEffects = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->connectOnStart();
+ if (m_config.connectOnStart != optBool)
+ {
+ m_config.connectOnStart = optBool;
+ configChanged = true;
+ }
+
+ optBool = m_configDialog->hideDevelopmentServers();
+ if (m_config.hideDevelopmentServers != optBool)
+ {
+ m_config.hideDevelopmentServers = optBool;
+ if (m_selectServer)
+ m_selectServer->setHideDevelopmentServers(optBool);
+
+ configChanged = true;
+ }
+
+ config->setGroup("General");
+ config->writeEntry("ChatTimeStamps", m_config.chatTimestamps);
+
+ config->setGroup("Personalization");
+ config->writeEntry("PlayerName", m_config.playerName);
+ config->writeEntry("PlayerImage", m_config.playerImage);
+
+ config->setGroup("Board");
+ config->writeEntry("IndicateUnowned", m_config.indicateUnowned);
+ config->writeEntry("HighliteUnowned", m_config.highliteUnowned);
+ config->writeEntry("DarkenMortgaged", m_config.darkenMortgaged);
+ config->writeEntry("AnimateToken", m_config.animateTokens);
+ config->writeEntry("QuartzEffects", m_config.quartzEffects);
+
+ config->setGroup("Monopigator");
+ config->writeEntry("ConnectOnStart", m_config.connectOnStart);
+ config->writeEntry("HideDevelopmentServers", m_config.hideDevelopmentServers);
+
+ config->sync();
+
+ if (configChanged && m_board)
+ m_board->setViewProperties(m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects, m_config.animateTokens);
+}
+
+void Atlantik::slotSendMsg()
+{
+ m_atlantikNetwork->cmdChat(m_input->text());
+ m_input->setText(QString::null);
+}
+
+void Atlantik::slotMsgInfo(QString msg)
+{
+ serverMsgsAppend(msg);
+}
+
+void Atlantik::slotMsgError(QString msg)
+{
+ serverMsgsAppend("Error: " + msg);
+}
+
+void Atlantik::slotMsgStatus(const QString &message, const QString &icon)
+{
+ KMainWindow::statusBar()->changeItem(message, 1);
+ m_eventLog->addEvent(message, icon);
+}
+
+void Atlantik::slotMsgChat(QString player, QString msg)
+{
+ if (m_config.chatTimestamps)
+ {
+ QTime time = QTime::currentTime();
+ serverMsgsAppend(QString("[%1] %2: %3").arg(time.toString("hh:mm")).arg(player).arg(msg));
+ }
+ else
+ serverMsgsAppend(player + ": " + msg);
+ KNotifyClient::event(winId(), "chat");
+}
+
+void Atlantik::serverMsgsAppend(QString msg)
+{
+ // Use append, not setText(old+new) because that one doesn't wrap
+ m_serverMsgs->append(msg);
+ m_serverMsgs->ensureVisible(0, m_serverMsgs->contentsHeight());
+}
+
+void Atlantik::playerChanged(Player *player)
+{
+ PortfolioView *portfolioView = findPortfolioView(player);
+ if (!portfolioView)
+ portfolioView = addPortfolioView(player);
+
+ Player *playerSelf = m_atlanticCore->playerSelf();
+ if (player == playerSelf)
+ {
+ // We changed ourselves..
+ PortfolioView *portfolioView = 0;
+ for (QPtrListIterator<PortfolioView> it(m_portfolioViews); *it; ++it)
+ if ((portfolioView = dynamic_cast<PortfolioView*>(*it)))
+ {
+ // Clear all portfolios if we're not in game
+ if ( !player->game() )
+ portfolioView->clearPortfolio();
+
+ // Show players in our game, hide the rest
+ Player *pTmp = portfolioView->player();
+ if (pTmp->game() == playerSelf->game())
+ portfolioView->show();
+ else
+ portfolioView->hide();
+ }
+ if (!player->game())
+ showSelectGame();
+ else
+ {
+ if ( !m_board || m_board->isHidden() )
+ showSelectConfiguration();
+ }
+
+ m_roll->setEnabled(player->canRoll());
+ m_buyEstate->setEnabled(player->canBuy());
+ m_auctionEstate->setEnabled(player->canAuction());
+
+ // TODO: Should be more finetuned, but monopd doesn't send can_endturn can_payjail can_jailroll yet
+ m_endTurn->setEnabled(player->hasTurn() && !(player->canRoll() || player->canBuy() || player->inJail()));
+ m_jailCard->setEnabled(player->canUseCard());
+ m_jailPay->setEnabled(player->hasTurn() && player->inJail());
+ m_jailRoll->setEnabled(player->hasTurn() && player->inJail());
+ }
+ else
+ {
+ // Another player changed, check if we need to show or hide
+ // his/her portfolioView.
+ if (playerSelf)
+ {
+ if (player->game() == playerSelf->game())
+ portfolioView->show();
+ else
+ portfolioView->hide();
+ }
+ else if ( !player->game() )
+ portfolioView->hide();
+ }
+}
+
+void Atlantik::gainedTurn()
+{
+ KNotifyClient::event(winId(), "gainedturn", i18n("It is your turn now.") );
+}
+
+void Atlantik::initEventLog()
+{
+ m_eventLog = new EventLog();
+}
+
+void Atlantik::initNetworkObject()
+{
+ if (m_atlantikNetwork)
+ {
+ m_atlantikNetwork->reset();
+ return;
+ }
+
+ m_atlantikNetwork = new AtlantikNetwork(m_atlanticCore);
+ connect(m_atlantikNetwork, SIGNAL(msgInfo(QString)), this, SLOT(slotMsgInfo(QString)));
+ connect(m_atlantikNetwork, SIGNAL(msgError(QString)), this, SLOT(slotMsgError(QString)));
+ connect(m_atlantikNetwork, SIGNAL(msgStatus(const QString &, const QString &)), this, SLOT(slotMsgStatus(const QString &, const QString &)));
+ connect(m_atlantikNetwork, SIGNAL(msgChat(QString, QString)), this, SLOT(slotMsgChat(QString, QString)));
+
+ connect(m_atlantikNetwork, SIGNAL(connectionSuccess()), this, SLOT(slotNetworkConnected()));
+ connect(m_atlantikNetwork, SIGNAL(connectionFailed(int)), this, SLOT(slotNetworkError(int)));
+ connect(m_atlantikNetwork, SIGNAL(closed(int)), this, SLOT(networkClosed(int)));
+
+ connect(m_atlantikNetwork, SIGNAL(receivedHandshake()), this, SLOT(sendHandshake()));
+
+ connect(m_atlantikNetwork, SIGNAL(gameConfig()), this, SLOT(showSelectConfiguration()));
+ connect(m_atlantikNetwork, SIGNAL(gameInit()), this, SLOT(initBoard()));
+ connect(m_atlantikNetwork, SIGNAL(gameRun()), this, SLOT(showBoard()));
+ connect(m_atlantikNetwork, SIGNAL(gameEnd()), this, SLOT(freezeBoard()));
+
+ connect(m_atlantikNetwork, SIGNAL(newEstate(Estate *)), this, SLOT(newEstate(Estate *)));
+ connect(m_atlantikNetwork, SIGNAL(newAuction(Auction *)), this, SLOT(newAuction(Auction *)));
+
+ connect(m_atlantikNetwork, SIGNAL(clientCookie(QString)), this, SLOT(clientCookie(QString)));
+ connect(m_atlantikNetwork, SIGNAL(networkEvent(const QString &, const QString &)), m_eventLog, SLOT(addEvent(const QString &, const QString &)));
+
+ connect(this, SIGNAL(rollDice()), m_atlantikNetwork, SLOT(rollDice()));
+ connect(this, SIGNAL(buyEstate()), m_atlantikNetwork, SLOT(buyEstate()));
+ connect(this, SIGNAL(auctionEstate()), m_atlantikNetwork, SLOT(auctionEstate()));
+ connect(this, SIGNAL(endTurn()), m_atlantikNetwork, SLOT(endTurn()));
+ connect(this, SIGNAL(jailCard()), m_atlantikNetwork, SLOT(jailCard()));
+ connect(this, SIGNAL(jailPay()), m_atlantikNetwork, SLOT(jailPay()));
+ connect(this, SIGNAL(jailRoll()), m_atlantikNetwork, SLOT(jailRoll()));
+}
+
+void Atlantik::clientCookie(QString cookie)
+{
+ KConfig *config = kapp->config();
+
+ if (cookie.isNull())
+ {
+ if (config->hasGroup("Reconnection"))
+ config->deleteGroup("Reconnection", true);
+ }
+ else if (m_atlantikNetwork)
+ {
+ config->setGroup("Reconnection");
+ config->writeEntry("Host", m_atlantikNetwork->host());
+ config->writeEntry("Port", m_atlantikNetwork->port());
+ config->writeEntry("Cookie", cookie);
+ }
+ else
+ return;
+
+ config->sync();
+}
+
+void Atlantik::sendHandshake()
+{
+ m_atlantikNetwork->setName(m_config.playerName);
+ m_atlantikNetwork->setImage(m_config.playerImage);
+
+ // Check command-line args to see if we need to auto-join
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ QCString game = args->getOption("game");
+ if (!game.isNull())
+ m_atlantikNetwork->joinGame(game.toInt());
+}
+
+void Atlantik::statusBarClick(int item)
+{
+ if ( item == 0 )
+ {
+ KAboutApplication dialog(kapp->aboutData(), this);
+ dialog.exec();
+ }
+ else if ( item == 1)
+ showEventLog();
+}
+
+PortfolioView *Atlantik::addPortfolioView(Player *player)
+{
+ PortfolioView *portfolioView = new PortfolioView(m_atlanticCore, player, m_config.activeColor, m_config.inactiveColor, m_portfolioWidget);
+ m_portfolioViews.append(portfolioView);
+ if ( m_portfolioViews.count() > 0 && m_portfolioScroll->isHidden() )
+ m_portfolioScroll->show();
+
+ connect(player, SIGNAL(changed(Player *)), portfolioView, SLOT(playerChanged()));
+ connect(portfolioView, SIGNAL(newTrade(Player *)), m_atlantikNetwork, SLOT(newTrade(Player *)));
+ connect(portfolioView, SIGNAL(kickPlayer(Player *)), m_atlantikNetwork, SLOT(kickPlayer(Player *)));
+ connect(portfolioView, SIGNAL(estateClicked(Estate *)), m_board, SLOT(prependEstateDetails(Estate *)));
+
+ m_portfolioLayout->addWidget(portfolioView);
+ portfolioView->show();
+
+ return portfolioView;
+}
+
+PortfolioView *Atlantik::findPortfolioView(Player *player)
+{
+ PortfolioView *portfolioView = 0;
+ for (QPtrListIterator<PortfolioView> it(m_portfolioViews); (portfolioView = *it) ; ++it)
+ if (player == portfolioView->player())
+ return portfolioView;
+
+ return 0;
+}
+
+void Atlantik::closeEvent(QCloseEvent *e)
+{
+ Game *gameSelf = m_atlanticCore->gameSelf();
+ Player *playerSelf = m_atlanticCore->playerSelf();
+
+ int result = KMessageBox::Continue;
+ if ( gameSelf && !playerSelf->isBankrupt() && m_runningGame )
+ result = KMessageBox::warningContinueCancel( this, i18n("You are currently part of an active game. Are you sure you want to close Atlantik? If you do, you forfeit the game."), i18n("Close & Forfeit?"), i18n("Close && Forfeit") );
+
+ if ( result == KMessageBox::Continue )
+ {
+ if ( m_atlantikNetwork )
+ m_atlantikNetwork->leaveGame();
+
+ saveMainWindowSettings(kapp->config(), "AtlantikMainWindow");
+ KMainWindow::closeEvent(e);
+ }
+}
diff --git a/atlantik/client/atlantik.h b/atlantik/client/atlantik.h
new file mode 100644
index 00000000..94f2ca7c
--- /dev/null
+++ b/atlantik/client/atlantik.h
@@ -0,0 +1,268 @@
+// Copyright (c) 2002-2003 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_ATLANTIK_H
+#define ATLANTIK_ATLANTIK_H
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qtextedit.h>
+#include <qlabel.h>
+#include <qptrlist.h>
+
+#include <kmainwindow.h>
+
+#include "configdlg.h"
+#include "portfolioview.h"
+#include "board.h"
+
+class QScrollView;
+
+class AtlanticCore;
+class AtlantikNetwork;
+
+struct AtlantikConfig
+{
+ // General options;
+ bool chatTimestamps;
+
+ // Personalization options
+ QString playerName, playerImage;
+
+ // Board options
+ bool indicateUnowned;
+ bool highliteUnowned;
+ bool darkenMortgaged;
+ bool quartzEffects;
+ bool animateTokens;
+
+ // Meta server options
+ bool connectOnStart;
+ bool hideDevelopmentServers;
+
+ // Portfolio colors
+ QColor activeColor, inactiveColor;
+};
+
+class EventLog;
+class EventLogWidget;
+class SelectServer;
+class SelectGame;
+class SelectConfiguration;
+class TradeDisplay;
+
+class Player;
+class Estate;
+class Trade;
+
+class LogTextEdit : public QTextEdit
+{
+Q_OBJECT
+
+public:
+ LogTextEdit( QWidget *parent = 0, const char *name = 0 );
+ virtual ~LogTextEdit();
+
+ QPopupMenu *createPopupMenu( const QPoint & pos );
+
+private:
+ KAction *m_clear, *m_selectAll, *m_copy;
+};
+
+/**
+ * Main Atlantik window.
+ * Manages gameboard, portfolios and pretty much everything else.
+ *
+ * @author Rob Kaper <[email protected]>
+ */
+class Atlantik : public KMainWindow
+{
+Q_OBJECT
+
+public:
+ /**
+ * Create an Atlantik window.
+ *
+ */
+ Atlantik();
+
+ /**
+ * Read the configuration settings using KConfig.
+ *
+ */
+ void readConfig();
+
+ /**
+ * Appends a message the text view.
+ *
+ * @param msg Message to be appended.
+ */
+ void serverMsgsAppend(QString msg);
+
+ AtlantikConfig config() { return m_config; }
+
+private slots:
+ void showSelectServer();
+ void showSelectGame();
+ void showSelectConfiguration();
+ void initBoard();
+ void showBoard();
+ void freezeBoard();
+ void clientCookie(QString cookie);
+ void sendHandshake();
+ void statusBarClick(int);
+
+public slots:
+
+ /**
+ * A network connection has been established, so we can show the game
+ * list instead of the server list.
+ *
+ */
+ void slotNetworkConnected();
+
+ /**
+ * An error occurred while setting up the network connection. Inform the
+ * user.
+ *
+ * @param errno See http://doc.trolltech.com/3.0/qsocket.html#Error-enum
+ */
+ void slotNetworkError(int errnum);
+
+ void networkClosed(int status);
+
+ /**
+ * Creates a new modeless configure dialog or raises it when it already exists.
+ *
+ */
+ void slotConfigure();
+
+ /**
+ * Opens the event log widget.
+ *
+ */
+ void showEventLog();
+
+ /**
+ * Opens the KNotify dialog for configuration events.
+ *
+ */
+ void configureNotifications();
+
+ /**
+ * Reads values from configuration dialog and stores them into
+ * global configuration struct. If values have changed, appropriate
+ * methods within the application are called. Configuration is saved
+ * to file in any case.
+ *
+ */
+ void slotUpdateConfig();
+
+ /**
+ * Writes the contents of the text input field to the network
+ * interface and clears the text input field.
+ *
+ */
+ void slotSendMsg();
+
+ /**
+ * Informs serverMsgs() to append an incoming message from the
+ * server to the text view as informational message.
+ *
+ * @param msg The message to be appended.
+ */
+ void slotMsgInfo(QString msg);
+
+ void slotMsgStatus(const QString &message, const QString &icon = QString::null);
+
+ /**
+ * Informs serverMsgs() to append an incoming message from the
+ * server to the text view as error message.
+ *
+ * @param msg The error message to be appended.
+ */
+ void slotMsgError(QString msg);
+
+ /**
+ * Informs serverMsgs() to append an incoming message from the
+ * server to the text view as chat message.
+ *
+ * @param player The name of the player chatting.
+ * @param msg The chat message to be appended.
+ */
+ void slotMsgChat(QString player, QString msg);
+
+ void newPlayer(Player *player);
+ void newEstate(Estate *estate);
+ void newTrade(Trade *trade);
+ void newAuction(Auction *auction);
+
+ void removeGUI(Player *player);
+ void removeGUI(Trade *trade);
+
+ void playerChanged(Player *player);
+ void gainedTurn();
+
+signals:
+ void rollDice();
+ void buyEstate();
+ void auctionEstate();
+ void endTurn();
+ void jailCard();
+ void jailPay();
+ void jailRoll();
+
+protected:
+ void closeEvent(QCloseEvent *);
+
+private:
+ void initEventLog();
+ void initNetworkObject();
+ PortfolioView *addPortfolioView(Player *player);
+ PortfolioView *findPortfolioView(Player *player);
+
+ QScrollView *m_portfolioScroll;
+ QWidget *m_mainWidget, *m_portfolioWidget;
+ QGridLayout *m_mainLayout;
+ QVBoxLayout *m_portfolioLayout;
+
+ QLabel *m_portfolioLabel;
+ QLineEdit *m_input;
+ QTextEdit *m_serverMsgs;
+
+ KAction *m_roll, *m_buyEstate, *m_auctionEstate, *m_endTurn,
+ *m_jailCard, *m_jailPay, *m_jailRoll, *m_configure,
+ *m_showEventLog;
+
+ AtlanticCore *m_atlanticCore;
+ AtlantikNetwork *m_atlantikNetwork;
+ AtlantikConfig m_config;
+
+ ConfigDialog *m_configDialog;
+ AtlantikBoard *m_board;
+ SelectServer *m_selectServer;
+ SelectGame *m_selectGame;
+ SelectConfiguration *m_selectConfiguration;
+ EventLog *m_eventLog;
+ EventLogWidget *m_eventLogWidget;
+
+ QPtrList<PortfolioView> m_portfolioViews;
+ QMap<Trade *, TradeDisplay *> m_tradeGUIMap;
+
+ bool m_runningGame;
+};
+
+#endif
diff --git a/atlantik/client/configdlg.cpp b/atlantik/client/configdlg.cpp
new file mode 100644
index 00000000..a8e152b5
--- /dev/null
+++ b/atlantik/client/configdlg.cpp
@@ -0,0 +1,334 @@
+// Copyright (c) 2002-2003 Rob Kaper <[email protected]>
+//
+// 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 <qlayout.h>
+#include <qgroupbox.h>
+#include <qwhatsthis.h>
+#include <qlabel.h>
+
+#include <kdeversion.h>
+#undef KDE_3_1_FEATURES
+#undef KDE_3_3_FEATURES
+#if defined(KDE_MAKE_VERSION)
+#if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
+#define KDE_3_1_FEATURES
+#endif
+#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,90)
+#define KDE_3_3_FEATURES
+#endif
+#endif
+
+#include <kicondialog.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstandarddirs.h>
+
+#include "atlantik.h"
+#include "configdlg.moc"
+
+ConfigDialog::ConfigDialog(Atlantik* parent, const char *name) : KDialogBase(IconList, i18n("Configure Atlantik"), Ok|Cancel, Ok, parent, "config_atlantik", false, name)
+{
+ m_parent = parent;
+ p_general = addPage(i18n("General"), i18n("General"), BarIcon("configure", KIcon::SizeMedium));
+ p_p13n = addPage(i18n("Personalization"), i18n("Personalization"), BarIcon("personal", KIcon::SizeMedium));
+ p_board = addPage(i18n("Board"), i18n("Board"), BarIcon("monop_board", KIcon::SizeMedium));
+ p_monopigator = addPage(i18n("Meta Server"), i18n("Meta Server"), BarIcon("network", KIcon::SizeMedium));
+
+ configGeneral = new ConfigGeneral(this, p_general, "configGeneral");
+ configPlayer = new ConfigPlayer(this, p_p13n, "configPlayer");
+ configBoard = new ConfigBoard(this, p_board, "configBoard");
+ configMonopigator = new ConfigMonopigator(this, p_monopigator, "configMonopigator");
+
+ setMinimumSize(sizeHint());
+}
+
+bool ConfigDialog::chatTimestamps()
+{
+ return configGeneral->chatTimestamps();
+}
+
+bool ConfigDialog::indicateUnowned()
+{
+ return configBoard->indicateUnowned();
+}
+
+bool ConfigDialog::highliteUnowned()
+{
+ return configBoard->highliteUnowned();
+}
+
+bool ConfigDialog::darkenMortgaged()
+{
+ return configBoard->darkenMortgaged();
+}
+
+bool ConfigDialog::animateToken()
+{
+ return configBoard->animateToken();
+}
+
+bool ConfigDialog::quartzEffects()
+{
+ return configBoard->quartzEffects();
+}
+
+QString ConfigDialog::playerName()
+{
+ return configPlayer->playerName();
+}
+
+QString ConfigDialog::playerImage()
+{
+ return configPlayer->playerImage();
+}
+
+bool ConfigDialog::connectOnStart()
+{
+ return configMonopigator->connectOnStart();
+}
+
+bool ConfigDialog::hideDevelopmentServers()
+{
+ return configMonopigator->hideDevelopmentServers();
+}
+
+AtlantikConfig ConfigDialog::config()
+{
+ return m_parent->config();
+}
+
+ConfigPlayer::ConfigPlayer(ConfigDialog* configDialog, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_configDialog = configDialog;
+ QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint());
+
+ QLabel *label = new QLabel(i18n("Player name:"), parent);
+ layout->addWidget(label);
+
+ m_playerName = new QLineEdit(parent);
+ layout->addWidget(m_playerName);
+
+ QLabel *label2 = new QLabel(i18n("Player image:"), parent);
+ layout->addWidget(label2);
+
+ m_playerIcon = new KPushButton(parent, "playerIcon");
+ layout->addWidget(m_playerIcon);
+
+ connect( m_playerIcon, SIGNAL(clicked()), this, SLOT(chooseImage()) );
+
+ layout->addStretch(1);
+
+ reset();
+}
+
+QString ConfigPlayer::playerName()
+{
+ return m_playerName->text();
+}
+
+QString ConfigPlayer::playerImage()
+{
+ return m_playerImage;
+}
+void ConfigPlayer::chooseImage()
+{
+ KIconDialog iconDialog( this, "iconDialog" );
+#ifdef KDE_3_1_FEATURES
+ iconDialog.setCustomLocation( locate("appdata", "themes/default/tokens/") );
+#endif
+
+#ifdef KDE_3_3_FEATURES
+ iconDialog.setup( KIcon::Desktop, KIcon::Application, false, 0, true, true, true ); // begin with user icons, lock editing
+#else
+ iconDialog.setup( KIcon::Desktop, KIcon::Application, false, 0, true ); // begin with user icons
+#endif
+
+ QString image = iconDialog.openDialog();
+
+ if ( image.isEmpty() )
+ return;
+
+ QStringList splitPath = QStringList::split( '/', image );
+ m_playerImage = splitPath[ splitPath.count()-1 ];
+
+ setImage();
+}
+
+void ConfigPlayer::setImage()
+{
+ QString filename = locate("data", "atlantik/themes/default/tokens/" + m_playerImage);
+ if (KStandardDirs::exists(filename))
+ m_playerIcon->setPixmap( QPixmap(filename) );
+}
+
+void ConfigPlayer::reset()
+{
+ m_playerName->setText(m_configDialog->config().playerName);
+ m_playerImage = m_configDialog->config().playerImage;
+ setImage();
+}
+
+ConfigMonopigator::ConfigMonopigator(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_configDialog = configDialog;
+ QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint());
+
+ m_connectOnStart = new QCheckBox(i18n("Request list of Internet servers on start-up"), parent);
+ layout->addWidget(m_connectOnStart);
+
+ QString message=i18n(
+ "If checked, Atlantik connects to a meta server on start-up to\n"
+ "request a list of Internet servers.\n");
+ QWhatsThis::add(m_connectOnStart, message);
+
+ m_hideDevelopmentServers = new QCheckBox(i18n("Hide development servers"), parent);
+ layout->addWidget(m_hideDevelopmentServers);
+
+ message=i18n(
+ "Some of the Internet servers might be running development\n"
+ "versions of the server software. If checked, Atlantik will not\n"
+ "display these servers.\n");
+ QWhatsThis::add(m_hideDevelopmentServers, message);
+
+ layout->addStretch(1);
+
+ reset();
+}
+
+bool ConfigMonopigator::connectOnStart()
+{
+ return m_connectOnStart->isChecked();
+}
+
+bool ConfigMonopigator::hideDevelopmentServers()
+{
+ return m_hideDevelopmentServers->isChecked();
+}
+
+void ConfigMonopigator::reset()
+{
+ m_connectOnStart->setChecked(m_configDialog->config().connectOnStart);
+ m_hideDevelopmentServers->setChecked(m_configDialog->config().hideDevelopmentServers);
+}
+
+ConfigGeneral::ConfigGeneral(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_configDialog = configDialog;
+ QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint());
+
+ m_chatTimestamps = new QCheckBox(i18n("Show timestamps in chat messages"), parent);
+ layout->addWidget(m_chatTimestamps);
+
+ QString message=i18n(
+ "If checked, Atlantik will add timestamps in front of chat\n"
+ "messages.\n");
+ QWhatsThis::add(m_chatTimestamps, message);
+
+ layout->addStretch(1);
+
+ reset();
+}
+
+bool ConfigGeneral::chatTimestamps()
+{
+ return m_chatTimestamps->isChecked();
+}
+
+void ConfigGeneral::reset()
+{
+ m_chatTimestamps->setChecked(m_configDialog->config().chatTimestamps);
+}
+
+ConfigBoard::ConfigBoard(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_configDialog = configDialog;
+ QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint());
+
+ QGroupBox *box = new QGroupBox(1, Qt::Horizontal, i18n("Game Status Feedback"), parent);
+ layout->addWidget(box);
+
+ m_indicateUnowned = new QCheckBox(i18n("Display title deed card on unowned properties"), box);
+ QString message=i18n(
+ "If checked, unowned properties on the board display an estate\n"
+ "card to indicate the property is for sale.\n");
+ QWhatsThis::add(m_indicateUnowned, message);
+
+ m_highliteUnowned = new QCheckBox(i18n("Highlight unowned properties"), box);
+ message=i18n(
+ "If checked, unowned properties on the board are highlighted to\n"
+ "indicate the property is for sale.\n");
+ QWhatsThis::add(m_highliteUnowned, message);
+
+ m_darkenMortgaged = new QCheckBox(i18n("Darken mortgaged properties"), box);
+ message=i18n(
+ "If checked, mortgaged properties on the board will be colored\n"
+ "darker than of the default color.\n");
+ QWhatsThis::add(m_darkenMortgaged, message);
+
+ m_animateToken = new QCheckBox(i18n("Animate token movement"), box);
+ message=i18n(
+ "If checked, tokens will move across the board\n"
+ "instead of jumping directly to their new location.\n");
+ QWhatsThis::add(m_animateToken, message);
+
+ m_quartzEffects = new QCheckBox(i18n("Quartz effects"), box);
+ message=i18n(
+ "If checked, the colored headers of street estates on the board "
+ "will have a Quartz effect similar to the Quartz KWin style.\n");
+ QWhatsThis::add(m_quartzEffects, message);
+
+// box = new QGroupBox(1, Qt::Horizontal, i18n("Size"), parent);
+// layout->addWidget(box);
+
+ layout->addStretch(1);
+
+ reset();
+}
+
+bool ConfigBoard::indicateUnowned()
+{
+ return m_indicateUnowned->isChecked();
+}
+
+bool ConfigBoard::highliteUnowned()
+{
+ return m_highliteUnowned->isChecked();
+}
+
+bool ConfigBoard::darkenMortgaged()
+{
+ return m_darkenMortgaged->isChecked();
+}
+
+bool ConfigBoard::animateToken()
+{
+ return m_animateToken->isChecked();
+}
+
+bool ConfigBoard::quartzEffects()
+{
+ return m_quartzEffects->isChecked();
+}
+
+void ConfigBoard::reset()
+{
+ m_indicateUnowned->setChecked(m_configDialog->config().indicateUnowned);
+ m_highliteUnowned->setChecked(m_configDialog->config().highliteUnowned);
+ m_darkenMortgaged->setChecked(m_configDialog->config().darkenMortgaged);
+ m_animateToken->setChecked(m_configDialog->config().animateTokens);
+ m_quartzEffects->setChecked(m_configDialog->config().quartzEffects);
+}
diff --git a/atlantik/client/configdlg.h b/atlantik/client/configdlg.h
new file mode 100644
index 00000000..c1f74294
--- /dev/null
+++ b/atlantik/client/configdlg.h
@@ -0,0 +1,139 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_CONFIGDLG_H
+#define ATLANTIK_CONFIGDLG_H
+
+#include <qwidget.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+
+#include <kdialogbase.h>
+
+class QString;
+
+class KPushButton;
+
+class Atlantik;
+class ConfigDialog;
+
+struct AtlantikConfig;
+
+class ConfigPlayer : public QWidget
+{
+Q_OBJECT
+
+public:
+ ConfigPlayer(ConfigDialog *configDialog, QWidget *parent, const char *name=0);
+
+ QString playerName();
+ QString playerImage();
+
+private slots:
+ void chooseImage();
+
+private:
+ void setImage();
+ void reset();
+
+ ConfigDialog *m_configDialog;
+ QLineEdit *m_playerName;
+ QString m_playerImage;
+ KPushButton *m_playerIcon;
+};
+
+class ConfigBoard : public QWidget
+{
+Q_OBJECT
+
+public:
+ ConfigBoard(ConfigDialog *configDialog, QWidget *parent, const char *name=0);
+
+ bool indicateUnowned();
+ bool highliteUnowned();
+ bool darkenMortgaged();
+ bool animateToken();
+ bool quartzEffects();
+
+private:
+ void reset();
+
+ ConfigDialog *m_configDialog;
+ QCheckBox *m_indicateUnowned, *m_highliteUnowned, *m_darkenMortgaged, *m_animateToken, *m_quartzEffects;
+};
+
+class ConfigMonopigator : public QWidget
+{
+Q_OBJECT
+
+public:
+ ConfigMonopigator(ConfigDialog *dialog, QWidget *parent, const char *name = 0);
+
+ bool connectOnStart();
+ bool hideDevelopmentServers();
+
+private:
+ void reset();
+
+ ConfigDialog *m_configDialog;
+ QCheckBox *m_connectOnStart, *m_hideDevelopmentServers;
+};
+
+class ConfigGeneral : public QWidget
+{
+Q_OBJECT
+
+public:
+ ConfigGeneral(ConfigDialog *dialog, QWidget *parent, const char *name = 0);
+
+ bool chatTimestamps();
+
+private:
+ void reset();
+
+ ConfigDialog *m_configDialog;
+ QCheckBox *m_chatTimestamps;
+};
+
+class ConfigDialog : public KDialogBase
+{
+Q_OBJECT
+
+public:
+ ConfigDialog(Atlantik *parent, const char *name=0);
+
+ bool chatTimestamps();
+ bool indicateUnowned();
+ bool highliteUnowned();
+ bool darkenMortgaged();
+ bool animateToken();
+ bool quartzEffects();
+ AtlantikConfig config();
+ QString playerName();
+ QString playerImage();
+ bool connectOnStart();
+ bool hideDevelopmentServers();
+
+private:
+ Atlantik *m_parent;
+ QFrame *p_general, *p_p13n, *p_board, *p_monopigator;
+ ConfigPlayer *configPlayer;
+ ConfigBoard *configBoard;
+ ConfigMonopigator *configMonopigator;
+ ConfigGeneral *configGeneral;
+};
+
+#endif
diff --git a/atlantik/client/event.cpp b/atlantik/client/event.cpp
new file mode 100644
index 00000000..218f6b87
--- /dev/null
+++ b/atlantik/client/event.cpp
@@ -0,0 +1,42 @@
+// Copyright (c) 2003 Rob Kaper <[email protected]>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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 <qdatetime.h>
+#include <qstring.h>
+
+#include "event.moc"
+
+Event::Event(const QDateTime &dateTime, const QString &description, const QString &icon)
+{
+ m_dateTime = dateTime;
+ m_description = description;
+ m_icon = icon;
+}
+
+QDateTime Event::dateTime() const
+{
+ return m_dateTime;
+}
+
+QString Event::description() const
+{
+ return m_description;
+}
+
+QString Event::icon() const
+{
+ return m_icon;
+}
diff --git a/atlantik/client/event.h b/atlantik/client/event.h
new file mode 100644
index 00000000..f2f56444
--- /dev/null
+++ b/atlantik/client/event.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2003 Rob Kaper <[email protected]>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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.
+
+#ifndef ATLANTIK_EVENT_H
+#define ATLANTIK_EVENT_H
+
+#include <qobject.h>
+
+class QDateTime;
+class QString;
+
+class Event : public QObject
+{
+Q_OBJECT
+
+public:
+ Event(const QDateTime &dateTime, const QString &description, const QString &icon = QString::null);
+ QDateTime dateTime() const;
+ QString description() const;
+ QString icon() const;
+
+private:
+ QDateTime m_dateTime;
+ QString m_description, m_icon;
+};
+
+#endif
diff --git a/atlantik/client/eventlogwidget.cpp b/atlantik/client/eventlogwidget.cpp
new file mode 100644
index 00000000..b0f77ab8
--- /dev/null
+++ b/atlantik/client/eventlogwidget.cpp
@@ -0,0 +1,123 @@
+// Copyright (c) 2003-2004 Rob Kaper <[email protected]>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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 <iostream>
+
+#include <qheader.h>
+#include <qlayout.h>
+#include <qdatetime.h>
+
+#include <klocale.h>
+#include <klistview.h>
+#include <kdialogbase.h>
+#include <kfiledialog.h>
+#include <kiconloader.h>
+#include <kpushbutton.h>
+#include <kstringhandler.h>
+
+#include "event.h"
+#include "eventlogwidget.moc"
+
+EventLog::EventLog()
+{
+}
+
+void EventLog::addEvent(const QString &description, const QString &icon)
+{
+ Event *event = new Event(QDateTime::currentDateTime(), description, icon);
+ m_events.append(event);
+ emit newEvent(event);
+}
+
+QPtrList<Event> EventLog::events()
+{
+ return m_events;
+}
+
+EventLogWidget::EventLogWidget(EventLog *eventLog, QWidget *parent, const char *name)
+ : QWidget(parent, name,
+ WType_Dialog | WStyle_Customize | WStyle_DialogBorder | WStyle_Title |
+ WStyle_Minimize | WStyle_ContextHelp )
+{
+ m_eventLog = eventLog;
+
+ connect(m_eventLog, SIGNAL(newEvent(Event *)), this, SLOT(addEvent(Event *)));
+
+ setCaption(i18n("Event Log"));
+
+ QVBoxLayout *listCompBox = new QVBoxLayout(this, KDialog::marginHint());
+
+ m_eventList = new KListView(this, "eventList");
+ listCompBox->addWidget(m_eventList);
+
+ m_eventList->addColumn(i18n("Date/Time"));
+ m_eventList->addColumn(i18n("Description"));
+ m_eventList->header()->setClickEnabled( false );
+
+ QHBoxLayout *actionBox = new QHBoxLayout(this, 0, KDialog::spacingHint());
+ listCompBox->addItem(actionBox);
+
+ actionBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ m_saveButton = new KPushButton(BarIcon("filesave", KIcon::SizeSmall), i18n("&Save As..."), this);
+ actionBox->addWidget(m_saveButton);
+
+ connect(m_saveButton, SIGNAL(clicked()), this, SLOT(save()));
+
+ // Populate
+ QPtrList<Event> events = m_eventLog->events();
+ for (QPtrListIterator<Event> it( events ); (*it) ; ++it)
+ addEvent( (*it) );
+}
+
+void EventLogWidget::addEvent(Event *event)
+{
+ // FIXME: allow a way to view non-squeezed message
+ // FIXME: allow a way to show older messages
+
+ if ( m_eventList->childCount() >= 25 )
+ delete m_eventList->firstChild();
+
+ QString description = KStringHandler::rsqueeze( event->description(), 200 );
+ KListViewItem *item = new KListViewItem(m_eventList, event->dateTime().toString("yyyy-MM-dd hh:mm:ss zzz"), description);
+ if (event->icon().isEmpty())
+ item->setPixmap(1, QPixmap(SmallIcon("atlantik")));
+ else
+ item->setPixmap(1, QPixmap(SmallIcon(event->icon())));
+
+ m_eventList->ensureItemVisible(item);
+}
+
+void EventLogWidget::closeEvent(QCloseEvent *e)
+{
+ e->accept();
+}
+
+void EventLogWidget::save()
+{
+ QFile file( KFileDialog::getSaveFileName() );
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream stream(&file);
+
+ stream << i18n( "Atlantik log file, saved at %1." ).arg( QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") ) << endl;
+
+ QPtrList<Event> events = m_eventLog->events();
+ for (QPtrListIterator<Event> it( events ); (*it) ; ++it)
+ stream << (*it)->dateTime().toString("yyyy-MM-dd hh:mm:ss") << " " << (*it)->description() << endl;
+ file.close();
+ }
+}
diff --git a/atlantik/client/eventlogwidget.h b/atlantik/client/eventlogwidget.h
new file mode 100644
index 00000000..4b925d47
--- /dev/null
+++ b/atlantik/client/eventlogwidget.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2003 Rob Kaper <[email protected]>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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.
+
+#ifndef ATLANTIK_EVENTLOGWIDGET_H
+#define ATLANTIK_EVENTLOGWIDGET_H
+
+#include <qwidget.h>
+#include <qmap.h>
+
+class QString;
+
+class Event;
+
+class KListView;
+class KListViewItem;
+class KPushButton;
+
+class EventLog : public QObject
+{
+Q_OBJECT
+
+public:
+ EventLog();
+ QPtrList<Event> events();
+
+public slots:
+ void addEvent(const QString &description, const QString &icon = QString::null);
+
+signals:
+ void newEvent(Event *event);
+
+private:
+ QPtrList<Event> m_events;
+};
+
+class EventLogWidget : public QWidget
+{
+Q_OBJECT
+
+public:
+ enum EventLogType { Default, Net_In, Net_Out };
+
+ EventLogWidget(EventLog *eventLog, QWidget *parent=0, const char *name = 0);
+
+public slots:
+ void addEvent(Event *event);
+
+protected:
+ void closeEvent(QCloseEvent *e);
+
+private slots:
+ void save();
+
+private:
+ EventLog *m_eventLog;
+ KListView *m_eventList;
+ KPushButton *m_saveButton;
+};
+
+#endif
diff --git a/atlantik/client/main.cpp b/atlantik/client/main.cpp
new file mode 100644
index 00000000..5f0e2fc6
--- /dev/null
+++ b/atlantik/client/main.cpp
@@ -0,0 +1,78 @@
+// Copyright (c) 2002-2003 Rob Kaper <[email protected]>
+//
+// 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 <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kglobal.h>
+
+#include "main.h"
+#include "atlantik.h"
+
+static KCmdLineOptions options[] =
+{
+ { "h", 0, 0 },
+ { "host <argument>", I18N_NOOP("Connect to this host"), 0 },
+ { "p", 0, 0 },
+ { "port <argument>", I18N_NOOP("Connect at this port"), "1234" },
+ { "g", 0, 0 },
+ { "game <argument>", I18N_NOOP("Join this game"), 0 },
+ KCmdLineLastOption
+};
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData(
+ "atlantik",
+ I18N_NOOP("Atlantik"), ATLANTIK_VERSION_STRING,
+ I18N_NOOP("The Atlantic board game"),
+ KAboutData::License_GPL,
+ I18N_NOOP("(c) 1998-2004 Rob Kaper"),
+ I18N_NOOP("KDE client for playing Monopoly-like games on the monopd network."),
+ "http://unixcode.org/atlantik/"
+ );
+
+ aboutData.addAuthor("Rob Kaper", I18N_NOOP("main author"), "[email protected]", "http://capsi.com/");
+
+ // Patches and artists
+ aboutData.addCredit("Thiago Macieira", I18N_NOOP("KExtendedSocket support"), "[email protected]");
+ aboutData.addCredit("Albert Astals Cid", I18N_NOOP("various patches"), "[email protected]");
+
+ aboutData.addCredit("Bart Szyszka", I18N_NOOP("application icon"), "[email protected]", "http://www.gigabee.com/");
+ aboutData.addCredit("Rob Malda", I18N_NOOP("token icons"), "", "http://cmdrtaco.net/");
+ aboutData.addCredit("Elhay Achiam", I18N_NOOP("icons"), "[email protected]");
+ aboutData.addCredit("Carlo Caneva", I18N_NOOP("icons"), "[email protected]", "http://www.molecola.com/");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions (options);
+
+ KApplication::addCmdLineOptions();
+ KApplication kapplication;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ if (kapplication.isRestored())
+ RESTORE(Atlantik)
+ else
+ {
+ Atlantik *atlantik = new Atlantik;
+ atlantik->setMinimumSize(640, 480);
+ atlantik->setCaption(i18n("The Atlantic Board Game"));
+ atlantik->show();
+ }
+
+ return kapplication.exec();
+}
diff --git a/atlantik/client/main.h b/atlantik/client/main.h
new file mode 100644
index 00000000..4c2f00c6
--- /dev/null
+++ b/atlantik/client/main.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_MAIN_H
+#define ATLANTIK_MAIN_H
+
+#define ATLANTIK_VERSION 075
+#define ATLANTIK_VERSION_STRING "0.7.5"
+
+#define ATLANTIK_VERSION_MAJOR 0
+#define ATLANTIK_VERSION_MINOR 7
+#define ATLANTIK_VERSION_RELEASE 5
+
+int main(int, char *[]);
+
+#endif
diff --git a/atlantik/client/monopigator.cpp b/atlantik/client/monopigator.cpp
new file mode 100644
index 00000000..83ef0d42
--- /dev/null
+++ b/atlantik/client/monopigator.cpp
@@ -0,0 +1,164 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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 <qdom.h>
+#include <qptrlist.h>
+#include <qregexp.h>
+
+#include <kextendedsocket.h>
+
+#include "monopigator.moc"
+#include "main.h"
+
+Monopigator::Monopigator()
+{
+ m_downloadData = 0;
+ m_job = 0;
+ m_timer = 0;
+}
+
+Monopigator::~Monopigator()
+{
+ if (m_job)
+ m_job -> kill();
+ delete m_downloadData;
+ m_downloadData=0L;
+}
+
+void Monopigator::loadData(const KURL &url)
+{
+ delete m_downloadData;
+ m_downloadData = new QBuffer();
+ m_downloadData->open(IO_WriteOnly);
+ m_downloadData->reset();
+
+ m_job = KIO::get(url, true, false);
+ m_job->addMetaData(QString::fromLatin1("UserAgent"), QString::fromLatin1("Atlantik/" ATLANTIK_VERSION_STRING));
+
+ if (!m_timer)
+ {
+ m_timer = new QTimer(this);
+ m_timer->start(10000, true);
+ }
+
+ connect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), SLOT(slotData(KIO::Job *, const QByteArray &)));
+ connect(m_job, SIGNAL(result(KIO::Job *)), SLOT(slotResult(KIO::Job *)));
+ connect(m_timer, SIGNAL(timeout()), SLOT(slotTimeout()));
+}
+
+void Monopigator::slotData(KIO::Job *, const QByteArray &data)
+{
+ m_timer->stop();
+ m_downloadData->writeBlock(data.data(), data.size());
+}
+
+void Monopigator::slotResult(KIO::Job *job)
+{
+ processData(m_downloadData->buffer(), !job->error());
+ m_job = 0;
+}
+
+void Monopigator::slotTimeout()
+{
+ if (m_job)
+ m_job -> kill();
+ m_job = 0;
+
+ emit timeout();
+}
+
+void Monopigator::processData(const QByteArray &data, bool okSoFar)
+{
+ if (okSoFar)
+ {
+ QString xmlData(data);
+ QDomDocument domDoc;
+ if (domDoc.setContent(xmlData))
+ {
+ QDomElement eTop = domDoc.documentElement();
+ if (eTop.tagName() != "monopigator")
+ return;
+
+ QDomNode n = eTop.firstChild();
+ while(!n.isNull())
+ {
+ QDomElement e = n.toElement();
+ if(!e.isNull())
+ {
+ if (e.tagName() == "server")
+ emit monopigatorAdd(e.attributeNode(QString("ip")).value(), e.attributeNode(QString("host")).value(), e.attributeNode(QString("port")).value(), e.attributeNode(QString("version")).value(), e.attributeNode(QString("users")).value().toInt());
+ }
+ n = n.nextSibling();
+ }
+ emit finished();
+ }
+ }
+}
+
+MonopigatorEntry::MonopigatorEntry(QListView *parent, QString host, QString latency, QString version, QString users, QString port, QString ip) : QObject(), QListViewItem(parent, host, latency, version, users, port)
+{
+ m_isDev = ( version.find( QRegExp("(CVS|-dev)") ) != -1 ) ? true : false;
+
+ setEnabled(false);
+ parent->sort();
+
+ if ( !ip.isEmpty() )
+ host = ip;
+ m_latencySocket = new KExtendedSocket( host, port.toInt(), KExtendedSocket::inputBufferedSocket | KExtendedSocket::noResolve );
+ connect(m_latencySocket, SIGNAL(lookupFinished(int)), this, SLOT(resolved()));
+ connect(m_latencySocket, SIGNAL(connectionSuccess()), this, SLOT(connected()));
+ m_latencySocket->startAsyncConnect();
+}
+
+void MonopigatorEntry::resolved()
+{
+ time.start();
+}
+
+void MonopigatorEntry::connected()
+{
+ setText( 1, QString::number(time.elapsed()) );
+ setEnabled(true);
+ listView()->sort();
+ delete m_latencySocket;
+}
+
+int MonopigatorEntry::compare(QListViewItem *i, int col, bool ascending) const
+{
+ // Colums 1 and 3 are integers (latency and users)
+ if (col == 1 || col == 3)
+ {
+ int myVal = text(col).toInt(), iVal = i->text(col).toInt();
+ if (myVal == iVal)
+ return 0;
+ else if (myVal > iVal)
+ return 1;
+ else
+ return -1;
+ }
+ return key( col, ascending ).compare( i->key( col, ascending) );
+}
+
+bool MonopigatorEntry::isDev() const
+{
+ return m_isDev;
+}
+
+void MonopigatorEntry::showDevelopmentServers(bool show)
+{
+ if ( isVisible() != show )
+ setVisible(show);
+}
diff --git a/atlantik/client/monopigator.h b/atlantik/client/monopigator.h
new file mode 100644
index 00000000..1fd57b1b
--- /dev/null
+++ b/atlantik/client/monopigator.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_MONOPIGATOR_H
+#define ATLANTIK_MONOPIGATOR_H
+
+#include <qobject.h>
+#include <qbuffer.h>
+#include <qlistview.h>
+#include <qtimer.h>
+
+#include <kio/job.h>
+#include <kurl.h>
+
+class KExtendedSocket;
+class QTime;
+
+class Monopigator : public QObject
+{
+Q_OBJECT
+
+public:
+ Monopigator();
+ ~Monopigator();
+ void loadData(const KURL &);
+
+signals:
+ void monopigatorAdd(QString ip, QString host, QString port, QString version, int users);
+ void finished();
+ void timeout();
+
+private slots:
+ void slotData(KIO::Job *, const QByteArray &);
+ void slotResult(KIO::Job *);
+ void slotTimeout();
+
+private:
+ void processData(const QByteArray &, bool = true);
+
+ QBuffer *m_downloadData;
+ QTimer *m_timer;
+ KIO::Job *m_job;
+};
+
+class MonopigatorEntry : public QObject, public QListViewItem
+{
+Q_OBJECT
+
+public:
+ MonopigatorEntry(QListView *parent, QString host, QString latency, QString version, QString users, QString port, QString ip);
+ int compare(QListViewItem *i, int col, bool ascending) const;
+ bool isDev() const;
+
+private slots:
+ void resolved();
+ void connected();
+ void showDevelopmentServers(bool show);
+
+private:
+ KExtendedSocket *m_latencySocket;
+ QTime time;
+ QListView *m_parent;
+ bool m_isDev;
+};
+
+#endif
diff --git a/atlantik/client/selectconfiguration_widget.cpp b/atlantik/client/selectconfiguration_widget.cpp
new file mode 100644
index 00000000..0e7d5cdb
--- /dev/null
+++ b/atlantik/client/selectconfiguration_widget.cpp
@@ -0,0 +1,189 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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 <iostream>
+
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+
+#include <atlantic_core.h>
+#include <configoption.h>
+#include <game.h>
+#include <player.h>
+
+#include "selectconfiguration_widget.moc"
+
+SelectConfiguration::SelectConfiguration(AtlanticCore *atlanticCore, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_atlanticCore = atlanticCore;
+ m_game = 0;
+
+ m_mainLayout = new QVBoxLayout(this, KDialog::marginHint());
+ Q_CHECK_PTR(m_mainLayout);
+
+ // Game configuration.
+ m_configBox = new QVGroupBox(i18n("Game Configuration"), this, "configBox");
+ m_mainLayout->addWidget(m_configBox);
+
+ // Player buttons.
+ QHBoxLayout *playerButtons = new QHBoxLayout(m_mainLayout, KDialog::spacingHint());
+ playerButtons->setMargin(0);
+
+ 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, KDialog::spacingHint());
+ serverButtons->setMargin(0);
+
+ m_backButton = new KPushButton(SmallIcon("back"), 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 KPushButton(SmallIconSet("forward"), 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();
+ playerChanged(playerSelf);
+ connect(playerSelf, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *)));
+
+ emit statusMessage(i18n("Retrieving configuration list..."));
+}
+
+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, "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(QString title, QString type, QString value, QString edit, QString command)
+{
+ // Find if option exists in GUI yet
+ if (QCheckBox *checkBox = dynamic_cast<QCheckBox *>(m_checkBoxMap[command]))
+ {
+ checkBox->setChecked(value.toInt());
+ checkBox->setEnabled(edit.toInt());
+ return;
+ }
+
+ // Create option
+ if (type == "bool")
+ {
+ QCheckBox *checkBox = new QCheckBox(title, m_configBox, "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)
+ {
+ kdDebug() << "checked " << ((QCheckBox *)QObject::sender())->isChecked() << endl;
+ 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)
+{
+ kdDebug() << "playerChanged" << endl;
+
+ if (player->game() != m_game)
+ {
+ kdDebug() << "playerChanged::change" << endl;
+
+ 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() );
+
+ for (QMapIterator<ConfigOption *, QCheckBox *> it = m_configBoxMap.begin() ; it != m_configBoxMap.end() ; ++it)
+ (*it)->setEnabled( it.key()->edit() && m_atlanticCore->selfIsMaster() );
+}
diff --git a/atlantik/client/selectconfiguration_widget.h b/atlantik/client/selectconfiguration_widget.h
new file mode 100644
index 00000000..033a0eb0
--- /dev/null
+++ b/atlantik/client/selectconfiguration_widget.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_SELECTCONFIGURATION_WIDGET_H
+#define ATLANTIK_SELECTCONFIGURATION_WIDGET_H
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qvgroupbox.h>
+
+#include <klistview.h>
+#include <kpushbutton.h>
+
+class QCheckBox;
+class QListViewItem;
+
+class AtlanticCore;
+class ConfigOption;
+class Game;
+class Player;
+
+class SelectConfiguration : public QWidget
+{
+Q_OBJECT
+
+public:
+ SelectConfiguration(AtlanticCore *atlanticCore, QWidget *parent, const char *name=0);
+
+ void setCanStart(const bool &canStart);
+ QString hostToConnect() const;
+ int portToConnect();
+
+private slots:
+ void addConfigOption(ConfigOption *configOption);
+ void changeOption();
+ void gameOption(QString title, QString type, QString value, QString edit, QString command);
+ void optionChanged(ConfigOption *configOption);
+ void optionChanged();
+ void slotEndUpdate();
+ void initGame();
+ void playerChanged(Player *player);
+ void gameChanged(Game *game);
+
+signals:
+ void startGame();
+ void leaveGame();
+ void joinConfiguration(int configurationId);
+ void newConfiguration();
+ void changeOption(int configId, const QString &value);
+ void buttonCommand(QString);
+ void iconSelected(const QString &);
+ void statusMessage(const QString &message);
+
+private:
+ QVBoxLayout *m_mainLayout;
+ QVGroupBox *m_configBox, *m_messageBox;
+ KPushButton *m_backButton, *m_startButton;
+ QMap <QObject *, QString> m_optionCommandMap;
+ QMap <QObject *, ConfigOption *> m_configMap;
+ QMap <ConfigOption *, QCheckBox *> m_configBoxMap;
+ QMap <QString, QCheckBox *> m_checkBoxMap;
+ QMap <Player *, QListViewItem *> m_items;
+ Game *m_game;
+ AtlanticCore *m_atlanticCore;
+};
+
+#endif
diff --git a/atlantik/client/selectgame_widget.cpp b/atlantik/client/selectgame_widget.cpp
new file mode 100644
index 00000000..85d4f886
--- /dev/null
+++ b/atlantik/client/selectgame_widget.cpp
@@ -0,0 +1,192 @@
+// Copyright (c) 2002-2003 Rob Kaper <[email protected]>
+//
+// 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 <qvgroupbox.h>
+#include <qradiobutton.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <knotifyclient.h>
+
+#include <atlantic_core.h>
+#include <game.h>
+#include <player.h>
+
+#include "selectgame_widget.h"
+
+SelectGame::SelectGame(AtlanticCore *atlanticCore, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_atlanticCore = atlanticCore;
+
+ connect(m_atlanticCore, SIGNAL(createGUI(Game *)), this, SLOT(addGame(Game *)));
+ connect(m_atlanticCore, SIGNAL(removeGUI(Game *)), this, SLOT(delGame(Game *)));
+
+ m_mainLayout = new QVBoxLayout(this, KDialog::marginHint());
+ Q_CHECK_PTR(m_mainLayout);
+
+ QVGroupBox *groupBox;
+ groupBox = new QVGroupBox(i18n("Create or Select monopd Game"), this, "groupBox");
+ m_mainLayout->addWidget(groupBox);
+
+ // List of games
+ m_gameList = new KListView(groupBox, "m_gameList");
+ m_gameList->addColumn(i18n("Game"));
+ m_gameList->addColumn(i18n("Description"));
+ m_gameList->addColumn(i18n("Id"));
+ m_gameList->addColumn(i18n("Players"));
+ m_gameList->setAllColumnsShowFocus(true);
+// m_mainLayout->addWidget(m_gameList);
+
+ connect(m_gameList, SIGNAL(clicked(QListViewItem *)), this, SLOT(validateConnectButton()));
+ connect(m_gameList, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(connectClicked()));
+ connect(m_gameList, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int)), this, SLOT(validateConnectButton()));
+ connect(m_gameList, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(validateConnectButton()));
+
+ QHBoxLayout *buttonBox = new QHBoxLayout(m_mainLayout, KDialog::spacingHint());
+
+ KPushButton *backButton = new KPushButton(SmallIcon("back"), i18n("Server List"), this);
+ buttonBox->addWidget(backButton);
+
+ connect(backButton, SIGNAL(clicked()), this, SIGNAL(leaveServer()));
+
+ buttonBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ m_connectButton = new KPushButton(SmallIconSet("forward"), i18n("Create Game"), this);
+ m_connectButton->setEnabled(false);
+ buttonBox->addWidget(m_connectButton);
+
+ 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)
+ {
+ QListViewItem *item = new QListViewItem( m_gameList, i18n("Create a new %1 Game").arg(game->name()), game->description(), QString::null, QString::null, game->type() );
+ item->setPixmap(0, QPixmap(SmallIcon("filenew")));
+ }
+ else
+ {
+ Player *master = game->master();
+ QListViewItem *item = new QListViewItem( m_gameList, i18n("Join %1's %2 Game").arg( (master ? master->name() : QString::null), game->name() ), game->description(), QString::number(game->id()), QString::number(game->players()), game->type() );
+ item->setPixmap( 0, QPixmap(SmallIcon("atlantik")) );
+ item->setEnabled(game->canBeJoined());
+
+ KNotifyClient::event(winId(), "newgame");
+
+ connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *)));
+ }
+
+// validateConnectButton();
+}
+
+void SelectGame::delGame(Game *game)
+{
+ QListViewItem *item = findItem(game);
+ if (!item)
+ return;
+
+ delete item;
+
+ validateConnectButton();
+}
+
+void SelectGame::updateGame(Game *game)
+{
+ QListViewItem *item = findItem(game);
+ if (!item)
+ return;
+
+ item->setText( 1, game->description() );
+
+ if (game->id() == -1)
+ item->setText(0, i18n("Create a new %1 Game").arg(game->name()));
+ else
+ {
+ Player *master = game->master();
+ item->setText( 0, i18n("Join %1's %2 Game").arg( (master ? master->name() : QString::null), game->name() ) );
+ item->setText( 3, QString::number( game->players() ) );
+ item->setEnabled( game->canBeJoined() );
+
+ connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *)));
+ }
+ m_gameList->triggerUpdate();
+
+ validateConnectButton();
+}
+
+void SelectGame::playerChanged(Player *player)
+{
+ QListViewItem *item = m_gameList->firstChild();
+ Game *game = 0;
+
+ while (item)
+ {
+ game = m_atlanticCore->findGame( item->text(2).toInt() );
+ if ( game && game->master() == player )
+ {
+ item->setText( 0, i18n("Join %1's %2 Game").arg( player->name(), game->name() ) );
+ return;
+ }
+ item = item->nextSibling();
+ }
+}
+
+QListViewItem *SelectGame::findItem(Game *game)
+{
+ QListViewItem *item = m_gameList->firstChild();
+ while (item)
+ {
+ if ( (game->id() == -1 || item->text(2) == QString::number(game->id())) && item->text(4) == game->type() )
+ return item;
+
+ item = item->nextSibling();
+ }
+ return 0;
+}
+
+void SelectGame::validateConnectButton()
+{
+ if (QListViewItem *item = m_gameList->selectedItem())
+ {
+ 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()
+{
+ if (QListViewItem *item = m_gameList->selectedItem())
+ {
+ if (int gameId = item->text(2).toInt())
+ emit joinGame(gameId);
+ else
+ emit newGame(item->text(4));
+ }
+}
+
+#include "selectgame_widget.moc"
diff --git a/atlantik/client/selectgame_widget.h b/atlantik/client/selectgame_widget.h
new file mode 100644
index 00000000..d47e905e
--- /dev/null
+++ b/atlantik/client/selectgame_widget.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2002-2003 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_SELECTGAME_WIDGET_H
+#define ATLANTIK_SELECTGAME_WIDGET_H
+
+#include <qwidget.h>
+#include <qlayout.h>
+
+#include <klistview.h>
+#include <kpushbutton.h>
+
+class AtlanticCore;
+class Game;
+class Player;
+
+class SelectGame : public QWidget
+{
+Q_OBJECT
+
+public:
+ SelectGame(AtlanticCore *atlanticCore, QWidget *parent, const char *name=0);
+
+ void initPage();
+ bool validateNext();
+ QString hostToConnect() const;
+ int portToConnect();
+
+private slots:
+ void connectClicked();
+ void addGame(Game *game);
+ void delGame(Game *game);
+ void updateGame(Game *game);
+ void playerChanged(Player *player);
+ void validateConnectButton();
+
+signals:
+ void joinGame(int gameId);
+ void newGame(const QString &gameType);
+ void leaveServer();
+ void msgStatus(const QString &status);
+
+private:
+ QListViewItem *findItem(Game *game);
+
+ AtlanticCore *m_atlanticCore;
+ QVBoxLayout *m_mainLayout;
+ KListView *m_gameList;
+ KPushButton *m_connectButton;
+};
+
+#endif
diff --git a/atlantik/client/selectserver_widget.cpp b/atlantik/client/selectserver_widget.cpp
new file mode 100644
index 00000000..39c07b50
--- /dev/null
+++ b/atlantik/client/selectserver_widget.cpp
@@ -0,0 +1,178 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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 <qlabel.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qsizepolicy.h>
+#include <qvbuttongroup.h>
+#include <qhgroupbox.h>
+
+#include <kdialog.h>
+#include <kextendedsocket.h>
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "selectserver_widget.moc"
+
+SelectServer::SelectServer(bool useMonopigatorOnStart, bool hideDevelopmentServers, QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_hideDevelopmentServers = hideDevelopmentServers;
+
+ m_mainLayout = new QVBoxLayout(this, KDialog::marginHint());
+ Q_CHECK_PTR(m_mainLayout);
+
+ // Custom server group
+ QHGroupBox *customGroup = new QHGroupBox(i18n("Enter Custom monopd Server"), this, "customGroup");
+ m_mainLayout->addWidget(customGroup);
+
+ QLabel *hostLabel = new QLabel(i18n("Hostname:"), customGroup);
+
+ m_hostEdit = new KLineEdit(customGroup);
+ m_hostEdit->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum));
+
+ QLabel *portLabel = new QLabel(i18n("Port:"), customGroup);
+
+ m_portEdit = new KLineEdit(QString::number(1234), customGroup);
+ m_portEdit->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum));
+
+ KPushButton *connectButton = new KPushButton( KGuiItem(i18n("Connect"), "network"), customGroup);
+ connect(connectButton, SIGNAL(clicked()), this, SLOT(customConnect()));
+
+ // Server list group
+ QVButtonGroup *bgroup = new QVButtonGroup(i18n("Select monopd Server"), this, "bgroup");
+ bgroup->setExclusive(true);
+ m_mainLayout->addWidget(bgroup);
+
+ // List of servers
+ m_serverList = new KListView(bgroup, "m_serverList");
+ m_serverList->addColumn(i18n("Host"));
+ m_serverList->addColumn(i18n("Latency"));
+ m_serverList->addColumn(i18n("Version"));
+ m_serverList->addColumn(i18n("Users"));
+ m_serverList->setAllColumnsShowFocus(true);
+ m_serverList->setSorting(1);
+// m_mainLayout->addWidget(m_serverList);
+
+ connect(m_serverList, SIGNAL(clicked(QListViewItem *)), this, SLOT(validateConnectButton()));
+ connect(m_serverList, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(slotConnect()));
+ connect(m_serverList, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int)), this, SLOT(validateConnectButton()));
+ connect(m_serverList, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(validateConnectButton()));
+
+ QHBoxLayout *buttonBox = new QHBoxLayout(m_mainLayout, KDialog::spacingHint());
+ buttonBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ // Server List / Refresh
+ m_refreshButton = new KPushButton( KGuiItem(useMonopigatorOnStart ? i18n("Reload Server List") : i18n("Get Server List"), useMonopigatorOnStart ? "reload" : "network"), this);
+ buttonBox->addWidget(m_refreshButton);
+
+ connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(slotRefresh()));
+
+ // Connect
+ m_connectButton = new KPushButton(BarIconSet("forward", KIcon::SizeSmall), i18n("Connect"), this);
+ m_connectButton->setEnabled(false);
+ buttonBox->addWidget(m_connectButton);
+
+ connect(m_connectButton, SIGNAL(clicked()), this, SLOT(slotConnect()));
+
+ // Monopigator
+ m_monopigator = new Monopigator();
+
+ connect(m_monopigator, SIGNAL(monopigatorAdd(QString, QString, QString, QString, int)), this, SLOT(slotMonopigatorAdd(QString, QString, QString, QString, int)));
+ connect(m_monopigator, SIGNAL(finished()), SLOT(monopigatorFinished()));
+ connect(m_monopigator, SIGNAL(timeout()), SLOT(monopigatorTimeout()));
+}
+
+SelectServer::~SelectServer()
+{
+ delete m_monopigator;
+}
+
+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 Monopigator root servers at the moment
+ emit msgStatus(i18n("Retrieving server list..."));
+
+ m_refreshButton->setGuiItem(KGuiItem(i18n("Reload Server List"), "reload"));
+ m_monopigator->loadData(KURL( "http://monopd-gator.kde.org/"));
+}
+
+void SelectServer::slotMonopigatorAdd(QString ip, QString host, QString port, QString version, int users)
+{
+ MonopigatorEntry *item = new MonopigatorEntry(m_serverList, host, QString::number(9999), version, (users == -1) ? i18n("unknown") : QString::number(users), port, ip);
+ item->setPixmap(0, BarIcon("atlantik", KIcon::SizeSmall));
+
+ if ( item->isDev() )
+ {
+ item->setVisible( !m_hideDevelopmentServers );
+ connect(this, SIGNAL(showDevelopmentServers(bool)), item, SLOT(showDevelopmentServers(bool)));
+ }
+
+ validateConnectButton();
+}
+
+void SelectServer::monopigatorFinished()
+{
+ emit msgStatus(i18n("Retrieved server list."));
+ m_refreshButton->setEnabled(true);
+}
+
+void SelectServer::monopigatorTimeout()
+{
+ emit msgStatus(i18n("Error while retrieving the server list."));
+ m_refreshButton->setEnabled(true);
+}
+
+void SelectServer::validateConnectButton()
+{
+ if (m_serverList->selectedItem())
+ 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()
+{
+ if (QListViewItem *item = m_serverList->selectedItem())
+ emit serverConnect(item->text(0), item->text(4).toInt());
+}
+
+void SelectServer::customConnect()
+{
+ if (!m_hostEdit->text().isEmpty() && !m_portEdit->text().isEmpty())
+ emit serverConnect(m_hostEdit->text(), m_portEdit->text().toInt());
+}
diff --git a/atlantik/client/selectserver_widget.h b/atlantik/client/selectserver_widget.h
new file mode 100644
index 00000000..c5d1b586
--- /dev/null
+++ b/atlantik/client/selectserver_widget.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2002-2004 Rob Kaper <[email protected]>
+//
+// 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.
+
+#ifndef ATLANTIK_SELECTSERVER_WIDGET_H
+#define ATLANTIK_SELECTSERVER_WIDGET_H
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+
+#include <klineedit.h>
+#include <klistview.h>
+#include <kpushbutton.h>
+
+#include "monopigator.h"
+
+class KExtendedSocket;
+
+class SelectServer : public QWidget
+{
+Q_OBJECT
+
+public:
+ SelectServer(bool useMonopigatorOnStart, bool hideDevelopmentServers, QWidget *parent, const char *name=0);
+ virtual ~SelectServer();
+
+ void initPage();
+ void setHideDevelopmentServers(bool hideDevelopmentServers);
+ bool validateNext();
+ QString hostToConnect() const;
+ int portToConnect();
+
+public slots:
+ void validateConnectButton();
+ void slotRefresh(bool useMonopigator = true);
+ void slotMonopigatorAdd(QString ip, QString host, QString port, QString version, int users);
+
+private slots:
+ void slotConnect();
+ void customConnect();
+ void monopigatorFinished();
+ void monopigatorTimeout();
+
+signals:
+ void serverConnect(const QString host, int port);
+ void msgStatus(const QString &message);
+ void showDevelopmentServers(bool show);
+
+private:
+ void initMonopigator();
+
+ QVBoxLayout *m_mainLayout;
+ KListView *m_serverList;
+ KLineEdit *m_hostEdit, *m_portEdit;
+ KPushButton *m_addServerButton, *m_refreshButton, *m_customConnect, *m_connectButton;
+ Monopigator *m_monopigator;
+ bool m_hideDevelopmentServers;
+};
+
+#endif