summaryrefslogtreecommitdiffstats
path: root/knights
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-17 01:24:36 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-17 01:24:36 +0000
commita8c9924456e5335c964e4e55b2dde1963c88726f (patch)
treef5bf107ba079ae460536da778ce2da5e6c68aa69 /knights
downloadknights-a8c9924456e5335c964e4e55b2dde1963c88726f.tar.gz
knights-a8c9924456e5335c964e4e55b2dde1963c88726f.zip
Added KDE3 version of Knights
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/knights@1091568 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'knights')
-rw-r--r--knights/Makefile.am61
-rw-r--r--knights/accel.cpp60
-rw-r--r--knights/accel.h59
-rw-r--r--knights/audio.cpp177
-rw-r--r--knights/audio.h64
-rw-r--r--knights/board_2d.cpp807
-rw-r--r--knights/board_2d.h99
-rw-r--r--knights/board_base.cpp125
-rw-r--r--knights/board_base.h68
-rw-r--r--knights/challenge_game.cpp37
-rw-r--r--knights/challenge_game.h47
-rw-r--r--knights/challenge_graph.cpp460
-rw-r--r--knights/challenge_graph.h93
-rw-r--r--knights/challenge_graph_view.cpp112
-rw-r--r--knights/challenge_graph_view.h50
-rw-r--r--knights/challenge_rectangle.cpp34
-rw-r--r--knights/challenge_rectangle.h36
-rw-r--r--knights/chessclock.cpp195
-rw-r--r--knights/chessclock.h75
-rw-r--r--knights/command.cpp98
-rw-r--r--knights/command.h194
-rw-r--r--knights/console.cpp264
-rw-r--r--knights/console.h87
-rw-r--r--knights/core.cpp892
-rw-r--r--knights/core.h107
-rw-r--r--knights/definitions.h292
-rw-r--r--knights/dlg_challenge.cpp159
-rw-r--r--knights/dlg_challenge.h69
-rw-r--r--knights/dlg_engine.cpp226
-rw-r--r--knights/dlg_engine.h77
-rw-r--r--knights/dlg_login.cpp161
-rw-r--r--knights/dlg_login.h73
-rw-r--r--knights/dlg_newmatch.cpp385
-rw-r--r--knights/dlg_newmatch.h110
-rw-r--r--knights/dlg_promote.cpp123
-rw-r--r--knights/dlg_promote.h58
-rw-r--r--knights/dlg_selectemail.cpp46
-rw-r--r--knights/dlg_selectemail.h52
-rw-r--r--knights/dlg_selectengine.cpp201
-rw-r--r--knights/dlg_selectengine.h72
-rw-r--r--knights/dlg_server.cpp240
-rw-r--r--knights/dlg_server.h92
-rw-r--r--knights/dlg_settings.cpp201
-rw-r--r--knights/dlg_settings.h80
-rw-r--r--knights/idmanager.cpp37
-rw-r--r--knights/idmanager.h42
-rw-r--r--knights/io_base.cpp57
-rw-r--r--knights/io_base.h68
-rw-r--r--knights/io_engine.cpp312
-rw-r--r--knights/io_engine.h81
-rw-r--r--knights/io_internet.cpp1138
-rw-r--r--knights/io_internet.h138
-rw-r--r--knights/knights.cpp1024
-rw-r--r--knights/knights.desktop16
-rw-r--r--knights/knights.h145
-rw-r--r--knights/knightsmap.h178
-rw-r--r--knights/knightspixcache.cpp156
-rw-r--r--knights/knightspixcache.h104
-rw-r--r--knights/knightstextview.cpp238
-rw-r--r--knights/knightstextview.h54
-rw-r--r--knights/list_pgn.cpp145
-rw-r--r--knights/list_pgn.h66
-rw-r--r--knights/logic.cpp1495
-rw-r--r--knights/logic.h88
-rw-r--r--knights/main.cpp85
-rw-r--r--knights/match.cpp1120
-rw-r--r--knights/match.h133
-rw-r--r--knights/match_param.cpp243
-rw-r--r--knights/match_param.h100
-rw-r--r--knights/pgn.cpp1464
-rw-r--r--knights/pgn.desktop11
-rw-r--r--knights/pgn.h153
-rw-r--r--knights/proto_base.cpp34
-rw-r--r--knights/proto_base.h54
-rw-r--r--knights/proto_uci.cpp218
-rw-r--r--knights/proto_uci.h55
-rw-r--r--knights/proto_xboard.cpp687
-rw-r--r--knights/proto_xboard.h78
-rw-r--r--knights/resource.cpp1048
-rw-r--r--knights/resource.h240
-rw-r--r--knights/setpageaudio.cpp133
-rw-r--r--knights/setpageaudio.h69
-rw-r--r--knights/setpagedisplay.cpp563
-rw-r--r--knights/setpagedisplay.h139
-rw-r--r--knights/setpageengines.cpp362
-rw-r--r--knights/setpageengines.h90
-rw-r--r--knights/setpagegeneral.cpp224
-rw-r--r--knights/setpagegeneral.h80
-rw-r--r--knights/setpageservers.cpp379
-rw-r--r--knights/setpageservers.h112
-rw-r--r--knights/splash.cpp40
-rw-r--r--knights/splash.h35
-rw-r--r--knights/tab_pgnview.cpp160
-rw-r--r--knights/tab_pgnview.h47
-rw-r--r--knights/tab_seeklist.cpp209
-rw-r--r--knights/tab_seeklist.h75
-rw-r--r--knights/tabbox.cpp208
-rw-r--r--knights/tabbox.h65
-rw-r--r--knights/tabgrip.cpp109
-rw-r--r--knights/tabgrip.h47
-rw-r--r--knights/tabmanager.cpp202
-rw-r--r--knights/tabmanager.h62
-rw-r--r--knights/tabpage.cpp164
-rw-r--r--knights/tabpage.h64
-rw-r--r--knights/thinbuttons.cpp262
-rw-r--r--knights/thinbuttons.h71
-rw-r--r--knights/wiz_setup.cpp360
-rw-r--r--knights/wiz_setup.h96
108 files changed, 22750 insertions, 0 deletions
diff --git a/knights/Makefile.am b/knights/Makefile.am
new file mode 100644
index 0000000..4bbec46
--- /dev/null
+++ b/knights/Makefile.am
@@ -0,0 +1,61 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+bin_PROGRAMS = knights
+
+## INCLUDES were found outside kdevelop specific part
+
+knights_SOURCES = board_2d.cpp board_base.cpp setpagedisplay.cpp proto_xboard.cpp dlg_selectengine.cpp thinbuttons.cpp pgn.cpp io_engine.cpp dlg_challenge.cpp idmanager.cpp challenge_graph.cpp dlg_login.cpp tabgrip.cpp tabpage.cpp tab_seeklist.cpp dlg_engine.cpp setpageaudio.cpp proto_base.cpp dlg_server.cpp core.cpp match_param.cpp knightspixcache.cpp dlg_settings.cpp console.cpp match.cpp setpagegeneral.cpp splash.cpp audio.cpp main.cpp logic.cpp list_pgn.cpp challenge_graph_view.cpp accel.cpp dlg_selectemail.cpp challenge_rectangle.cpp knightstextview.cpp tabmanager.cpp command.cpp dlg_newmatch.cpp chessclock.cpp dlg_promote.cpp resource.cpp tabbox.cpp io_internet.cpp challenge_game.cpp knights.cpp tab_pgnview.cpp io_base.cpp wiz_setup.cpp setpageservers.cpp proto_uci.cpp setpageengines.cpp
+knights_LDADD = -lqt-mt -lartskde -lkio -lkdeprint -lkdeui -lkdecore $(LIBSOCKET)
+
+EXTRA_DIST = setpageengines.cpp proto_uci.cpp setpageservers.cpp wiz_setup.cpp setpageengines.h io_base.cpp knightsmap.h tab_pgnview.cpp knights.cpp challenge_game.cpp io_internet.cpp challenge_graph_view.h resource.h tabbox.cpp resource.cpp dlg_promote.cpp dlg_server.h pgn.h chessclock.cpp dlg_newmatch.cpp command.h io_internet.h challenge_rectangle.h command.cpp tabmanager.cpp dlg_promote.h definitions.h knightstextview.cpp challenge_rectangle.cpp dlg_selectemail.cpp splash.h list_pgn.h accel.cpp tabmanager.h match.h setpagedisplay.h challenge_graph_view.cpp list_pgn.cpp logic.h logic.cpp knightstextview.h main.cpp audio.cpp splash.cpp setpagegeneral.cpp match.cpp io_base.h console.h idmanager.h dlg_selectemail.h console.cpp tab_pgnview.h knights.h dlg_settings.cpp core.h knightspixcache.cpp thinbuttons.h dlg_settings.h setpageservers.h tab_seeklist.h match_param.cpp core.cpp match_param.h dlg_server.cpp pgn.desktop tabbox.h accel.h io_engine.h proto_base.cpp setpageaudio.cpp dlg_engine.cpp tab_seeklist.cpp tabpage.cpp challenge_graph.h tabgrip.cpp dlg_login.cpp challenge_graph.cpp proto_uci.h setpageaudio.h proto_base.h chessclock.h setpagegeneral.h idmanager.cpp dlg_challenge.cpp io_engine.cpp audio.h dlg_newmatch.h pgn.cpp dlg_engine.h thinbuttons.cpp wiz_setup.h dlg_selectengine.cpp challenge_game.h proto_xboard.cpp knightspixcache.h setpagedisplay.cpp tabgrip.h knights.desktop dlg_login.h proto_xboard.h dlg_challenge.h dlg_selectengine.h tabpage.h board_base.cpp board_base.h board_2d.cpp board_2d.h Makefile.am
+
+install-data-local:
+ $(mkinstalldirs) $(kde_mimedir)/application/
+ $(INSTALL_DATA) $(srcdir)/pgn.desktop $(kde_mimedir)/application/pgn.desktop
+ $(mkinstalldirs) $(kde_appsdir)/Games/Board/
+ $(INSTALL_DATA) $(srcdir)/knights.desktop $(kde_appsdir)/Games/Board/knights.desktop
+
+uninstall-local:
+ -rm -f $(kde_mimedir)/application/pgn.desktop
+ -rm -f $(kde_appsdir)/Games/Board/knights.desktop
+
+####### kdevelop will overwrite this part!!! (end)############
+# this 10 paths are KDE specific. Use them:
+# kde_htmldir Where your docs should go to. (contains lang subdirs)
+# kde_appsdir Where your application file (.kdelnk) should go to.
+# kde_icondir Where your icon should go to.
+# kde_minidir Where your mini icon should go to.
+# kde_datadir Where you install application data. (Use a subdir)
+# kde_locale Where translation files should go to.(contains lang subdirs)
+# kde_cgidir Where cgi-bin executables should go to.
+# kde_confdir Where config files should go to.
+# kde_mimedir Where mimetypes should go to.
+# kde_toolbardir Where general toolbar icons should go to.
+# kde_wallpaperdir Where general wallpapers should go to.
+
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+
+METASOURCES = AUTO
+
+# the library search path.
+knights_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# Uncomment the following two lines if you add a ui.rc file for your application to make use of
+# KDE´s XML GUI builing
+#rcdir = $(kde_datadir)/knights
+#rc_DATA = knightsui.rc
+
+#WARNING: if you use a ui.rc file above, use:
+
+# messages: rc.cpp
+
+# instead of
+
+# messages:
+
+messages:
+ LIST=`find $(srcdir) -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \
+ if test -n "$$LIST"; then \
+ $(XGETTEXT) $$LIST -o $(podir)/knights.pot; \
+ fi
+
diff --git a/knights/accel.cpp b/knights/accel.cpp
new file mode 100644
index 0000000..c2ef168
--- /dev/null
+++ b/knights/accel.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ accel.cpp - description
+ -------------------
+ begin : Wed Nov 6 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "accel.moc"
+#include <klocale.h>
+
+Accel::Accel( QWidget *parent, QObject *target ) : KAccel( parent )
+{
+ insertItem( i18n("Previous Move"), "Previous Move", Key_Up, TRUE );
+ insertItem( i18n("Next Move"), "Next Move", Key_Down, TRUE );
+ insertItem( i18n("Enter Text"), "Enter Text", Key_Return, TRUE );
+ insertItem( i18n("Page Up"), "Page Up", Key_PageUp, TRUE );
+ insertItem( i18n("Page Down"), "Page Down", Key_PageDown, TRUE );
+ insertItem( i18n("Increase Board Size"), "Board Up", ALT + Key_Plus, TRUE );
+ insertItem( i18n("Decrease Board Size"), "Board Down", ALT + Key_Minus, TRUE );
+ insertItem( i18n("Last History Item"), "Last History Item", SHIFT + Key_Up, TRUE );
+ insertItem( i18n("Next History Item"), "Next History Item", SHIFT + Key_Down, TRUE );
+ insertItem( i18n("Reply to the Last Tell"), "Tell Reply", ALT + Key_R, TRUE );
+ insertItem( i18n("Reply to the Channel"), "Channel Reply", ALT + Key_C, TRUE );
+ insertItem( i18n("Kibitz"), "Kibitz", ALT + Key_K, TRUE );
+ insertItem( i18n("Whisper"), "Whisper", ALT + Key_W, TRUE );
+ readSettings();
+
+ if( target )
+ setTarget( target );
+}
+Accel::~Accel()
+{
+ writeSettings();
+}
+void Accel::setTarget( QObject *target )
+{
+ connectItem( "Board Down" , target, SIGNAL( board_down() ) );
+ connectItem( "Board Up" , target, SIGNAL( board_up() ) );
+ connectItem( "Previous Move" , target, SIGNAL( move_prev() ) );
+ connectItem( "Next Move" , target, SIGNAL( move_next() ) );
+ connectItem( "Page Up", target, SIGNAL( page_up() ) );
+ connectItem( "Page Down", target, SIGNAL( page_down() ) );
+ connectItem( "Last History Item", target, SIGNAL( history_prev() ) );
+ connectItem( "Next History Item", target, SIGNAL( history_next() ) );
+ connectItem( "Tell Reply", target, SIGNAL( reply_tell() ) );
+ connectItem( "Channel Reply", target, SIGNAL( reply_channel() ) );
+ connectItem( "Enter Text", target, SIGNAL( focus() ) );
+ connectItem( "Kibitz", target, SIGNAL( kibitz() ) );
+ connectItem( "Whisper", target, SIGNAL( whisper() ) );
+}
diff --git a/knights/accel.h b/knights/accel.h
new file mode 100644
index 0000000..6767a3e
--- /dev/null
+++ b/knights/accel.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ accel.h - description
+ -------------------
+ begin : Wed Nov 6 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef ACCEL_H
+#define ACCEL_H
+
+#include <kaccel.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class Accel : public KAccel
+{
+ Q_OBJECT
+
+ public:
+ Accel( QWidget *parent=0, QObject *target=0 );
+ ~Accel();
+ void setTarget( QObject* );
+
+ signals:
+ void focus( void );
+ void focus( const QChar& );
+
+ void board_up( void );
+ void board_down( void );
+
+ void move_prev( void );
+ void move_next( void );
+
+ void page_up( void );
+ void page_down( void );
+
+ void history_prev( void );
+ void history_next( void );
+
+ void reply_tell( void );
+ void reply_channel( void );
+
+ void kibitz( void );
+ void whisper( void );
+};
+
+#endif
diff --git a/knights/audio.cpp b/knights/audio.cpp
new file mode 100644
index 0000000..f1b0d34
--- /dev/null
+++ b/knights/audio.cpp
@@ -0,0 +1,177 @@
+/***************************************************************************
+ audio.cpp - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "audio.h"
+#include <arts/soundserver.h>
+#include <arts/dispatcher.h>
+#include <arts/flowsystem.h>
+#include <arts/connect.h>
+#include <ksimpleconfig.h>
+#include <kio/netaccess.h>
+#include <qptrlist.h>
+#include <qfile.h>
+#include <qmap.h>
+
+class audioPrivate
+{
+ public:
+ bool enabled;
+ bool firstTime;
+ QString theme;
+ Arts::Dispatcher dispatcher;
+ Arts::SoundServerV2 server;
+ Arts::PlayObjectFactory playObjectFactory;
+ QMap<int, Arts::PlayObject> audioMap;
+ QPtrList<KTempFile> fileRef;
+};
+
+audio::audio()
+{
+ a = new audioPrivate;
+ a->server = Arts::Reference("global:Arts_SoundServerV2");
+ a->fileRef.setAutoDelete( TRUE );
+ if( a->server.isNull() )
+ {
+ a->enabled = FALSE;
+ kdWarning() << "audio::audio: Can not create Arts::SoundServerV2" << endl;
+ }
+ else
+ {
+ a->enabled = TRUE;
+ a->playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
+ }
+ a->firstTime = TRUE;
+}
+audio::~audio()
+{
+ a->audioMap.clear();
+ a->fileRef.clear();
+ delete a;
+}
+void audio::play( const int snd )
+{
+ if( a->firstTime || !enabled || !a->enabled )
+ return;
+
+ QMap<int, Arts::PlayObject>::Iterator IT = a->audioMap.find( snd );
+
+ if( IT == a->audioMap.end() )
+ {
+ return;
+ }
+
+ Arts::PlayObject* current = &IT.data();
+
+ if( volume )
+ {
+ Arts::Synth_BUS_UPLINK uplink = Arts::DynamicCast( current->_getChild( "uplink" ) );
+ uplink.stop();
+ current->_node()->stop();
+ Arts::disconnect( *current, "left", uplink, "left" );
+ Arts::disconnect( *current, "right", uplink, "right" );
+ Arts::StereoVolumeControl volumeControl = Arts::DynamicCast( a->server.createObject( "Arts::StereoVolumeControl" ) );
+ current->_addChild( volumeControl, "volume" );
+ uplink.start();
+ volumeControl.start();
+ current->_node()->start();
+ Arts::connect( *current, "left", volumeControl, "inleft" );
+ Arts::connect( *current, "right", volumeControl, "inright" );
+ Arts::connect( volumeControl, "outleft", uplink, "left" );
+ Arts::connect( volumeControl, "outright", uplink, "right" );
+ volumeControl.scaleFactor( ( 100 - volume ) / 100.0 );
+ }
+
+ Arts::poTime time = current->currentTime();
+ time.seconds = 0;
+ time.ms = 0;
+ current->seek( time );
+ current->play();
+}
+
+void audio::setTheme( const QString &newTheme )
+{
+ QString configFile;
+ KSimpleConfig *themeConfig;
+
+ if( !enabled || !a->enabled )
+ return;
+
+ a->audioMap.clear();
+ a->fileRef.clear();
+
+ if( !KIO::NetAccess::download( newTheme + "theme.conf" , configFile ) )
+ {
+ kdWarning() << "audio::setTheme: Can not access theme.conf from " << newTheme << endl;
+ return;
+ }
+ themeConfig = new KSimpleConfig( configFile, TRUE );
+
+ /* Read the details about this theme */
+ themeConfig->setGroup( "General" );
+ themeHeader.name = themeConfig->readEntry( "Name", "Unknown" );
+ themeHeader.version = themeConfig->readEntry( "Version", "Unknown" );
+ themeHeader.author = themeConfig->readEntry( "Author", "Unknown" );
+ themeHeader.authorEmail = themeConfig->readEntry( "AuthorEmail", "Unknown" );
+ themeHeader.authorWWW = themeConfig->readEntry( "AuthorWWW", "Unknown" );
+ themeHeader.notes = themeConfig->readEntry( "Notes", "Unknown" );
+
+ /* Read the sounds */
+ themeConfig->setGroup( "Audio" );
+ a->theme = newTheme;
+ prepFile( a->theme + themeConfig->readEntry("Select"), SND_SELECT );
+ prepFile( a->theme + themeConfig->readEntry("Move"), SND_MOVE );
+ prepFile( a->theme + themeConfig->readEntry("Check"), SND_CHECK );
+ prepFile( a->theme + themeConfig->readEntry("MatchOver"), SND_MATCH_OVER );
+ prepFile( a->theme + themeConfig->readEntry("Challenge"), SND_CHALLENGE );
+ prepFile( a->theme + themeConfig->readEntry("Tell"), SND_TELL );
+ prepFile( a->theme + themeConfig->readEntry("Notification"), SND_NOTIFICATION );
+ prepFile( a->theme + themeConfig->readEntry("DrawOffer"), SND_DRAW_OFFER );
+ prepFile( a->theme + themeConfig->readEntry("Say"), SND_SAY );
+ prepFile( a->theme + themeConfig->readEntry("Promote"), SND_PROMOTE );
+ a->firstTime = FALSE;
+
+ delete themeConfig;
+ KIO::NetAccess::removeTempFile( configFile );
+}
+void audio::prepFile( const QString &source, const int &ref )
+{
+ Arts::PlayObject player;
+ KTempFile *dest;
+ QString filename;
+ if( source.isEmpty() )
+ return;
+
+ dest = new KTempFile( QString::null, source.right(4), 700 );
+ dest->setAutoDelete( TRUE );
+ filename = dest->name();
+
+ if( !KIO::NetAccess::download( source, filename ) )
+ {
+ kdWarning() << "audio::prepFile: Can not download " << source << endl;
+ delete dest;
+ return;
+ }
+ player = a->playObjectFactory.createPlayObject( QFile::encodeName( dest->name() ).data() );
+ if( player.isNull() )
+ {
+ delete dest;
+ return;
+ }
+ a->fileRef.append( dest );
+ a->audioMap[ ref ] = player;
+ return;
+}
diff --git a/knights/audio.h b/knights/audio.h
new file mode 100644
index 0000000..1270b85
--- /dev/null
+++ b/knights/audio.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ audio.h - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include "definitions.h"
+#include <kurl.h>
+#include <ktempfile.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+/*
+ These represent the various sounds that can be played.
+*/
+
+const int SND_NONE = 0x00;
+const int SND_SELECT = 0x01;
+const int SND_MOVE = 0x02;
+const int SND_MATCH_OVER = 0x03; // Deprecieated
+const int SND_CHECK = 0x04;
+const int SND_FLAG = 0x05;
+const int SND_CHALLENGE = 0x50;
+const int SND_TELL = 0x51;
+const int SND_NOTIFICATION = 0x52;
+const int SND_DRAW_OFFER = 0x53;
+const int SND_SAY = 0x54;
+const int SND_PROMOTE = 0x55;
+
+class audioPrivate;
+class audio
+{
+ public:
+ audio();
+ ~audio();
+ void play( const int );
+ void setTheme( const QString& );
+
+ bool enabled;
+ int volume;
+ ThemeHeader themeHeader;
+ protected:
+ void prepFile( const QString&, const int& );
+ private:
+ audioPrivate *a;
+};
+
+#endif
diff --git a/knights/board_2d.cpp b/knights/board_2d.cpp
new file mode 100644
index 0000000..f3a9b49
--- /dev/null
+++ b/knights/board_2d.cpp
@@ -0,0 +1,807 @@
+/***************************************************************************
+ board_2d.cpp - description
+ -------------------
+ begin : Fri Feb 28 2003
+ copyright : (C) 2003 by The Knights Project
+ email : knights-general@lists.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "board_2d.moc"
+#include "resource.h"
+#include "logic.h"
+#include "knightspixcache.h"
+#include <kiconeffect.h>
+#include <qpainter.h>
+#include <qtimer.h>
+
+static int MAX_STEPS = 18;
+
+board_2d::board_2d(QWidget *parent, const char *name, resource *Rsrc, logic *Lgc ) : board_base(parent,name,Rsrc,Lgc)
+{
+ updateX1 = updateY1 = 4000;
+ updateX2 = updateY2 = -4000;
+ init = TRUE;
+ premoveFrom = Null;
+ premoveTo = Null;
+ DragSprite = NULL;
+ lastMoveWasDrag = FALSE;
+ cache = myResource->pixCache;
+ int size = 8 + ( 1 * ( myResource->ThemeBorder == TRUE ) );
+ sprites.setAutoDelete( TRUE );
+
+ /* Setup Pixmaps */
+ myself.setOptimization( QPixmap::BestOptim );
+ myself.resize( myResource->ThemeSize * size, myResource->ThemeSize * size);
+ myself.fill();
+
+ /* Setup self */
+ setBackgroundMode( Qt::NoBackground );
+ show();
+}
+board_2d::~board_2d()
+{
+}
+///////////////////////////////////////
+//
+// board_2d::coords
+//
+///////////////////////////////////////
+QPoint board_2d::coords( const int &rank, const int &file )
+{
+ QPoint tmp;
+ if( orientation == 0 )
+ {
+ tmp.setX( myResource->ThemeSize * file );
+ tmp.setY( myResource->ThemeSize * ( 7 - rank ) );
+ }
+ else
+ {
+ tmp.setX( myResource->ThemeSize * ( 7 - file ) );
+ tmp.setY( myResource->ThemeSize * rank );
+ }
+ if( myResource->ThemeBorder )
+ {
+ tmp.setX( tmp.x() + ( myResource->ThemeSize >> 1 ) );
+ tmp.setY( tmp.y() + ( myResource->ThemeSize >> 1 ) );
+ }
+ return tmp;
+}
+///////////////////////////////////////
+//
+// board_2d::position
+//
+///////////////////////////////////////
+int board_2d::position( const QPoint &_point )
+{
+ int file, rank;
+ int themeSize = myResource->ThemeSize;
+ QPoint point( _point );
+
+ if( myResource->ThemeBorder )
+ {
+ point.setX( point.x() - ( themeSize >> 1 ) );
+ point.setY( point.y() - ( themeSize >> 1 ) );
+ }
+ if( !orientation )
+ {
+ file = point.x() / themeSize;
+ rank = 7 - ( point.y() / themeSize );
+ }
+ else
+ {
+ file = 7 - ( point.x() / themeSize );
+ rank = point.y() / themeSize;
+ }
+ return ( ( rank << 3 ) + file );
+}
+///////////////////////////////////////
+//
+// board_2d::drawMove
+//
+///////////////////////////////////////
+void board_2d::drawMove( const ChessMove &chessMove, const bool &reverse )
+{
+ char fromPtr, toPtr, takenPtr(Null);
+ if( reverse )
+ {
+ fromPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
+ toPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
+ }
+ else
+ {
+ fromPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
+ toPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
+ }
+
+ /* Position where Man was taken != Target Position; ie. en passant */
+ if( chessMove.ManTaken != Null )
+ {
+ takenPtr = myLogic->Pointer( myLogic->chessman[ chessMove.ManTaken ].File, myLogic->chessman[ chessMove.ManTaken ].Rank );
+ }
+
+ /* Show Highlights */
+ if( myResource->OPTION_Show_Last_Move )
+ {
+ myLogic->current[ fromPtr ].Note = NOTE_MOVE;
+ if( chessMove.ManTaken != Null )
+ {
+ myLogic->current[ toPtr ].Note = NOTE_ATTACK;
+ }
+ else
+ {
+ myLogic->current[ toPtr ].Note = NOTE_MOVE;
+ }
+ }
+
+ /* Show Animation */
+ if( myResource->OPTION_Animate_Moves && !lastMoveWasDrag && isVisible() )
+ {
+ QTimer::singleShot( 0, this, SLOT( updateSprites() ) );
+ sprite *spritePtr = new sprite;
+ spritePtr->Steps = 1;
+ spritePtr->Restore = FALSE;
+ spritePtr->POSITION_Origin = fromPtr;
+ spritePtr->POSITION_Destination = toPtr;
+ spritePtr->POSITION_TargetTaken = takenPtr;
+ if( !reverse )
+ {
+ spritePtr->POINT_Origin = coords( chessMove.fromRank, chessMove.fromFile );
+ spritePtr->POINT_Destination = coords( chessMove.toRank, chessMove.toFile );
+ spritePtr->PIXMAP_Sprite = getChessman( spritePtr->POSITION_Destination );
+ }
+ else
+ {
+ spritePtr->POINT_Origin = coords( chessMove.toRank, chessMove.toFile );
+ spritePtr->POINT_Destination = coords( chessMove.fromRank, chessMove.fromFile );
+ spritePtr->PIXMAP_Sprite = getChessman( spritePtr->POSITION_Origin );
+ }
+ spritePtr->POINT_Current = spritePtr->POINT_Origin;
+ spritePtr->PIXMAP_FlipFrame.resize( spritePtr->PIXMAP_Sprite.size() );
+ sprites.append( spritePtr );
+ }
+ else
+ {
+ /* Draw this position only if we're not animating */
+ drawPosition( toPtr );
+ if( takenPtr != Null )
+ {
+ drawPosition( takenPtr );
+ }
+ }
+ /* Draw the originating position */
+ drawPosition( fromPtr );
+
+ if( QString( chessMove.SAN ).contains( "o-o", FALSE ) )
+ {
+ /* This is a castle */
+ ChessMove newMove;
+ strcpy( newMove.SAN, QString( "no" ).latin1() );
+ newMove.fromRank = chessMove.fromRank;
+ newMove.toRank = chessMove.toRank;
+ newMove.ManTaken = Null;
+ if( QString( chessMove.SAN ).contains( "o-o-o", FALSE ) )
+ {
+ /* Queenside */
+ newMove.fromFile = 0;
+ newMove.toFile = 3;
+ }
+ else
+ {
+ /* Kingside */
+ newMove.fromFile = 7;
+ newMove.toFile = 5;
+ }
+ drawMove( newMove, reverse );
+ }
+ lastMoveWasDrag = FALSE;
+}
+///////////////////////////////////////
+//
+// board_2d::resizeBoard( SLOT )
+//
+///////////////////////////////////////
+void board_2d::resizeBoard( void )
+{
+ int size = 8 + ( 1 * ( myResource->ThemeBorder == TRUE ) );
+ init = FALSE;
+
+ /* Resize myself */
+ myself.resize( myResource->ThemeSize * size, myResource->ThemeSize * size);
+ myself.fill();
+
+ /* Finish up */
+ setFixedSize( myResource->ThemeSize * size, myResource->ThemeSize * size);
+ redrawAll();
+
+ int inverseSize = IMAGE_MAX - myResource->ThemeSize;
+ MAX_STEPS = ( ( inverseSize * inverseSize ) / IMAGE_MAX ) + 7;
+}
+///////////////////////////////////////
+//
+// board_2d::redrawAll
+//
+///////////////////////////////////////
+void board_2d::redrawAll( void )
+{
+ register char tmp(0);
+
+ if( init )
+ return;
+
+ /* Set Orientation */
+ orientation = myResource->OPTION_Board_Orientation;
+ if( localArmy != WHITE )
+ orientation = !orientation;
+ if( flip )
+ orientation = !orientation;
+
+ /* Set Border */
+ if( myResource->ThemeBorder )
+ {
+ if( orientation )
+ {
+ QWMatrix matrix;
+ matrix.rotate( 180.0 );
+ myself = cache->Border.xForm( matrix );
+ }
+ else
+ myself = cache->Border;
+ }
+
+ /* Redraw All Positions */
+ while( tmp < 64 )
+ drawPosition( tmp++ );
+ redrawLights();
+
+ /* Make sure everything is repainted */
+ updateX1 = updateY1 = 0;
+ updateX2 = updateY2 = IMAGE_MAX * 9;
+
+ commit();
+}
+///////////////////////////////////////
+//
+// board_2d::redrawLights
+//
+///////////////////////////////////////
+void board_2d::redrawLights( void )
+{
+ int half, four;
+ QPoint black, white;
+ if( myResource->ThemeBorder )
+ {
+ half = myResource->ThemeSize >> 1;
+ four = myResource->ThemeSize << 2;
+ if( !orientation )
+ {
+ black.setX( 0 );
+ black.setY( four );
+ white.setX( 0 );
+ white.setY( four + half );
+ }
+ else
+ {
+ black.setX( myself.width() - half );
+ black.setY( four + half );
+ white.setX( myself.width() - half );
+ white.setY( four );
+ }
+ if( myLogic->OnMove != WHITE )
+ {
+ myBlit( black, &cache->BorderLightOn, cache->BorderLightOn.rect() );
+ myBlit( white, &cache->BorderLightOff, cache->BorderLightOff.rect() );
+ }
+ else
+ {
+ myBlit( black, &cache->BorderLightOff, cache->BorderLightOff.rect() );
+ myBlit( white, &cache->BorderLightOn, cache->BorderLightOn.rect() );
+ }
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::drawPosition
+//
+///////////////////////////////////////
+void board_2d::drawPosition( const int &pos )
+{
+ int rank = pos >> 3;
+ int file = pos % 8;
+ QPixmap buffer;
+ QString cacheName = QString::number( myResource->ThemeSize );
+ QImage tempImage;
+
+ if( ( pos < 0 ) || ( pos > 63 ) ) return;
+ /*
+ Build the cache ref name
+ */
+ if( color( rank, file ) )
+ cacheName += "L";
+ else
+ cacheName += "D";
+ if( !paused )
+ {
+ switch( myLogic->current[pos].Note )
+ {
+ case NOTE_SELECT:
+ case NOTE_HIGHLIGHT:
+ cacheName += "S";
+ break;
+ case NOTE_MOVE:
+ case NOTE_CASTLE:
+ case NOTE_PAWN_DOUBLE:
+ cacheName += "M";
+ break;
+ case NOTE_ATTACK:
+ case NOTE_ENPASSANT:
+ cacheName += "A";
+ break;
+ default:
+ cacheName += " ";
+ }
+ if( ( myLogic->current[pos].ManPtr != Null ) && ( !isSprite( pos ) ) )
+ {
+ if( myLogic->chessman[ myLogic->current[pos].ManPtr ].Army == WHITE )
+ cacheName += "W";
+ else
+ cacheName += "B";
+ switch( myLogic->chessman[myLogic->current[pos].ManPtr].Type )
+ {
+ case King:
+ cacheName += "K";
+ break;
+ case Queen:
+ cacheName += "Q";
+ break;
+ case Bishop:
+ cacheName += "B";
+ break;
+ case Knight:
+ cacheName += "N";
+ break;
+ case Rook:
+ cacheName += "R";
+ break;
+ case Pawn:
+ cacheName += "P";
+ break;
+ default:
+ break;
+ }
+ if( ( pos == premoveFrom ) || ( pos == premoveTo ) )
+ cacheName += "t"; // The means it's transparent
+ }
+ }
+ else
+ cacheName += " ";
+ if( cache->find( cacheName, buffer ) )
+ {
+ /*
+ Cache Hit... no need to redraw
+ */
+ if( myResource->OPTION_Show_Coord )
+ drawCoords( &buffer, pos );
+ myBlit( coords( rank, file ), &buffer, buffer.rect() );
+ return;
+ }
+
+ /*
+ Cache miss
+ Draw the pixmap
+ */
+ if( color( rank, file ) )
+ buffer = cache->SquareLight;
+ else
+ buffer = cache->SquareDark;
+
+ switch( myLogic->current[pos].Note )
+ {
+ case NOTE_HIGHLIGHT: // Fall Through
+ case NOTE_SELECT:
+ bitBlt( &buffer, 0, 0, &cache->HighlightSelect, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ break;
+ case NOTE_MOVE: // Fall Through
+ case NOTE_CASTLE: // Fall Through
+ case NOTE_PAWN_DOUBLE:
+ bitBlt( &buffer, 0, 0, &cache->HighlightMove, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ break;
+ case NOTE_ATTACK: // Fall Through
+ case NOTE_ENPASSANT:
+ bitBlt( &buffer, 0, 0, &cache->HighlightAttack, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ break;
+ default:
+ break;
+ }
+ if( !isSprite(pos) )
+ {
+ QPixmap chessman = getChessman( pos );
+ bitBlt( &buffer, 0, 0, &chessman, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ }
+ /* Now add this pixmap to the cache */
+ cache->add( cacheName, buffer );
+ /* */
+ if( myResource->OPTION_Show_Coord )
+ drawCoords( &buffer, pos );
+ myBlit( coords( rank, file ), &buffer, buffer.rect() );
+}
+///////////////////////////////////////
+//
+// board_2d::drawCoords
+//
+///////////////////////////////////////
+void board_2d::drawCoords( QPixmap *pic, const int &pos )
+{
+ QPainter painter;
+ QString letter;
+ int themeSize = myResource->ThemeSize - 4;
+ int targetRank, targetFile;
+
+ if( orientation == 0 )
+ {
+ targetRank = 0;
+ targetFile = 0;
+ }
+ else
+ {
+ targetRank = 7;
+ targetFile = 7;
+ }
+ /* Draw Rank */
+ if( ( pos >> 3 ) == targetRank )
+ {
+ letter = QString( QString("abcdefgh").at( pos % 8 ) );
+ painter.begin( pic );
+ painter.setFont( myResource->FONT_Standard );
+ painter.setPen( myResource->COLOR_Notation_Shadow );
+ painter.drawText( 3, 3, themeSize, themeSize,
+ Qt::AlignRight | Qt::AlignBottom, letter );
+ painter.setPen( myResource->COLOR_Notation );
+ painter.drawText( 2, 2, themeSize, themeSize,
+ Qt::AlignRight | Qt::AlignBottom, letter );
+ painter.end();
+ }
+ /* Draw File */
+ if( ( pos % 8 ) == targetFile )
+ {
+ letter = QString( QString("12345678").at( pos >> 3 ) );
+ painter.begin( pic );
+ painter.setFont( myResource->FONT_Standard );
+ painter.setPen( myResource->COLOR_Black );
+ painter.drawText( 3, 3, themeSize, themeSize,
+ Qt::AlignLeft | Qt::AlignTop, letter );
+ painter.setPen( myResource->COLOR_White );
+ painter.drawText( 2, 2, themeSize, themeSize,
+ Qt::AlignLeft | Qt::AlignTop, letter );
+ painter.end();
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::mouseReleaseEvent
+//
+///////////////////////////////////////
+void board_2d::mouseReleaseEvent( QMouseEvent *event )
+{
+ event->accept();
+
+ if( DragSprite != NULL )
+ {
+ /* Destroy any sprites being dragged */
+ int tmp = DragSprite->POSITION_Origin;
+ myBlit( DragSprite->POINT_LastUpdate,
+ &DragSprite->PIXMAP_FlipFrame,
+ DragSprite->PIXMAP_FlipFrame.rect() );
+ sprites.removeRef( DragSprite );
+ DragSprite = NULL;
+ drawPosition( tmp );
+ commit();
+ lastMoveWasDrag = TRUE;
+ }
+
+ if(event->button() == Qt::LeftButton)
+ {
+ emit leftClick( position( event->pos() ) );
+ }
+ if(event->button() == Qt::RightButton)
+ {
+ emit rightClick( position( event->pos() ) );
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::mousePressEvent
+//
+///////////////////////////////////////
+void board_2d::mousePressEvent( QMouseEvent *event )
+{
+ pressPoint = event->pos();
+ event->accept();
+}
+///////////////////////////////////////
+//
+// board_2d::mouseMoveEvent
+//
+///////////////////////////////////////
+void board_2d::mouseMoveEvent( QMouseEvent *event )
+{
+ event->accept();
+ if( DragSprite == NULL )
+ {
+ if( event->state() & Qt::LeftButton )
+ {
+ if( abs( pressPoint.x() - event->pos().x() ) + abs( pressPoint.y() - event->pos().y() ) > 6 )
+ {
+ /* Begin Dragging a piece */
+ DragSprite = new sprite;
+ sprites.append( DragSprite );
+ DragSprite->POINT_Origin = pressPoint;
+ DragSprite->POSITION_Origin = position( pressPoint );
+ emit leftClick( DragSprite->POSITION_Origin ); // Tell match that we just clicked on this piece
+
+ if( myLogic->current[ DragSprite->POSITION_Origin ].Note != NOTE_SELECT )
+ {
+ /* The selection didn't take.. back out. */
+ sprites.removeRef( DragSprite );
+ DragSprite = NULL;
+ drawPosition( position( pressPoint ) );
+ commit();
+ return;
+ }
+
+ /* Get the piece image and store it in dragPix */
+ DragSprite->PIXMAP_Sprite = getChessman( DragSprite->POSITION_Origin );
+ DragSprite->PIXMAP_FlipFrame.resize( DragSprite->PIXMAP_Sprite.size() );
+ DragSprite->Restore = FALSE;
+ }
+ else
+ /* Not enough dragging */
+ return;
+ } // End ( event->state() & Qt::LeftButton )
+ else
+ return; /* No dragging. Most events should end up here */
+ }
+
+ int halfSize = myResource->ThemeSize >> 1;
+ DragSprite->POINT_Current.setX( event->x() - halfSize );
+ DragSprite->POINT_Current.setY( event->y() - halfSize );
+ commit();
+}
+///////////////////////////////////////
+//
+// board_2d::getChessman
+//
+///////////////////////////////////////
+QPixmap board_2d::getChessman( const int &pos )
+{
+ QPixmap tmp;
+ register char type, army;
+
+ if( pos == premoveTo )
+ {
+ type = myLogic->chessman[myLogic->current[premoveFrom].ManPtr].Type;
+ army = myLogic->chessman[myLogic->current[premoveFrom].ManPtr].Army;
+ }
+ else
+ {
+ type = myLogic->chessman[myLogic->current[pos].ManPtr].Type;
+ army = myLogic->chessman[myLogic->current[pos].ManPtr].Army;
+ }
+ switch( type )
+ {
+ case King:
+ if( army == WHITE )
+ tmp = cache->WhiteKing;
+ else
+ tmp = cache->BlackKing;
+ break;
+ case Queen:
+ if( army == WHITE )
+ tmp = cache->WhiteQueen;
+ else
+ tmp = cache->BlackQueen;
+ break;
+ case Bishop:
+ if( army == WHITE )
+ tmp = cache->WhiteBishop;
+ else
+ tmp = cache->BlackBishop;
+ break;
+ case Knight:
+ if( army == WHITE )
+ tmp = cache->WhiteKnight;
+ else
+ tmp = cache->BlackKnight;
+ break;
+ case Rook:
+ if( army == WHITE )
+ tmp = cache->WhiteRook;
+ else
+ tmp = cache->BlackRook;
+ break;
+ case Pawn:
+ if( army == WHITE )
+ tmp = cache->WhitePawn;
+ else
+ tmp = cache->BlackPawn;
+ break;
+ default:
+ break;
+ }
+ if( ( pos == premoveFrom ) || ( pos == premoveTo ) )
+ {
+ KIconEffect::semiTransparent( tmp );
+ }
+ return tmp;
+}
+///////////////////////////////////////
+//
+// board_2d::setPremovePositions
+//
+///////////////////////////////////////
+void board_2d::setPremovePositions( const int &posF, const int &posT )
+{
+ premoveFrom = posF;
+ premoveTo = posT;
+ if( ( posF != Null ) && ( posT != Null ) )
+ {
+ myLogic->current[posF].Note = NOTE_NONE;
+ myLogic->current[posT].Note = NOTE_NONE;
+ drawPosition( posF );
+ drawPosition( posT );
+ commit();
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::commit
+//
+///////////////////////////////////////
+void board_2d::commit( void )
+{
+ drawSprites();
+ bitBlt( this, updateX1, updateY1, &myself, updateX1, updateY1, updateX2, updateY2, Qt::CopyROP );
+ updateX1 = updateY1 = 4000;
+ updateX2 = updateY2 = -4000;
+}
+///////////////////////////////////////
+//
+// board_2d::paintEvent
+//
+///////////////////////////////////////
+void board_2d::paintEvent( QPaintEvent *event )
+{
+ /* Paint the Widget */
+ bitBlt( this, event->rect().topLeft(), &myself, event->rect(), Qt::CopyROP );
+}
+///////////////////////////////////////
+//
+// board_2d::drawSprites
+//
+///////////////////////////////////////
+void board_2d::drawSprites( void )
+{
+ int index;
+ sprite *spritePtr;
+
+ /* Remove all sprites from the pixmap */
+ for( index = (signed int)sprites.count() - 1; index > -1; index-- )
+ {
+ spritePtr = sprites.at(index);
+ if( spritePtr->Restore == FALSE )
+ {
+ spritePtr->Restore = TRUE;
+ }
+ else
+ {
+ myBlit( spritePtr->POINT_LastUpdate,
+ &spritePtr->PIXMAP_FlipFrame,
+ spritePtr->PIXMAP_FlipFrame.rect() );
+ }
+ }
+ /* Redraw all sprites */
+ for( index = 0; index < (signed int)sprites.count(); index++ )
+ {
+ spritePtr = sprites.at(index);
+
+ if( ( spritePtr == DragSprite ) || ( spritePtr->Steps < MAX_STEPS ) )
+ {
+ /* Redraw Sprite */
+ bitBlt( &spritePtr->PIXMAP_FlipFrame,
+ 0,
+ 0,
+ &myself,
+ spritePtr->POINT_Current.x(),
+ spritePtr->POINT_Current.y(),
+ spritePtr->PIXMAP_FlipFrame.width(),
+ spritePtr->PIXMAP_FlipFrame.height(),
+ Qt::CopyROP );
+ myBlit( spritePtr->POINT_Current,
+ &spritePtr->PIXMAP_Sprite,
+ spritePtr->PIXMAP_Sprite.rect() );
+ spritePtr->POINT_LastUpdate = spritePtr->POINT_Current;
+ }
+ else
+ {
+ /* Animation finished */
+ int origin = spritePtr->POSITION_Origin;
+ int destination = spritePtr->POSITION_Destination;
+ int target = spritePtr->POSITION_TargetTaken;
+ sprites.removeRef( spritePtr );
+ drawPosition( origin );
+ drawPosition( destination );
+ drawPosition( target );
+ index = -1;
+ }
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::updateSprites
+//
+///////////////////////////////////////
+void board_2d::updateSprites( void )
+{
+ if( myResource->OPTION_Animate_Moves )
+ {
+ for( int index = 0; index < (signed int)sprites.count(); index++ )
+ {
+ sprite *spritePtr = sprites.at( index );
+ if( spritePtr == DragSprite )
+ continue;
+
+ QTimer::singleShot( 0, this, SLOT( updateSprites() ) );
+ if( spritePtr->Steps < MAX_STEPS )
+ {
+ double factor = ( 1.0 / (double)MAX_STEPS ) * (double)spritePtr->Steps;
+ int newX = (int)( ( spritePtr->POINT_Destination.x() - spritePtr->POINT_Origin.x() ) * factor );
+ int newY = (int)( ( spritePtr->POINT_Destination.y() - spritePtr->POINT_Origin.y() ) * factor );
+ spritePtr->POINT_Current = spritePtr->POINT_Origin + QPoint( newX, newY );
+ spritePtr->Steps += sprites.count();
+ }
+ }
+ commit();
+ }
+}
+///////////////////////////////////////
+//
+// board_2d::isSprite
+//
+///////////////////////////////////////
+bool board_2d::isSprite( const int &pos )
+{
+ for( unsigned int index = 0; index < sprites.count(); index++ )
+ {
+ sprite *tmpSprite = sprites.at( index );
+ if( tmpSprite->POSITION_Origin == pos )
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+///////////////////////////////////////
+//
+// board_2d::myBlit
+//
+///////////////////////////////////////
+void board_2d::myBlit( const QPoint &dp, const QPaintDevice *src, const QRect &sr )
+{
+ bitBlt( &myself, dp.x(), dp.y(), src, sr.x(), sr.y(), sr.width(), sr.height(), Qt::CopyROP );
+ if( dp.x() < updateX1 )
+ updateX1 = dp.x();
+ if( dp.y() < updateY1 )
+ updateY1 = dp.y();
+ if( dp.x() + sr.width() > updateX2 )
+ updateX2 = dp.x() + sr.width();
+ if( dp.y() + sr.height() > updateX2 )
+ updateX2 = dp.y() + sr.height();
+}
diff --git a/knights/board_2d.h b/knights/board_2d.h
new file mode 100644
index 0000000..f2291e2
--- /dev/null
+++ b/knights/board_2d.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ board_2d.h - description
+ -------------------
+ begin : Fri Feb 28 2003
+ copyright : (C) 2003 by The Knights Project
+ email : knights-general@lists.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef BOARD_2D_H
+#define BOARD_2D_H
+
+#include <board_base.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+
+/**
+ *@author The Knights Team
+ */
+
+typedef struct sprite
+{
+ bool Restore;
+ int Steps;
+ int POSITION_Origin;
+ int POSITION_Destination;
+ int POSITION_TargetTaken;
+ QPoint POINT_Origin;
+ QPoint POINT_Current;
+ QPoint POINT_LastUpdate;
+ QPoint POINT_Destination;
+ QPixmap PIXMAP_Sprite;
+ QPixmap PIXMAP_FlipFrame;
+};
+
+typedef QPtrList<sprite> SpriteList;
+class KnightsPixCache;
+
+class board_2d : public board_base
+{
+ Q_OBJECT
+ public:
+ board_2d(QWidget *parent=0, const char *name=0, resource *Rsrc=0, logic *Lgc=0);
+ ~board_2d();
+ virtual void drawMove( const ChessMove &chessMove, const bool &reverse=FALSE );
+ virtual void setPremovePositions( const int&, const int& );
+ virtual void redrawLights( void );
+ void paintEvent( QPaintEvent *event );
+ void mouseReleaseEvent( QMouseEvent *event );
+ void mousePressEvent( QMouseEvent *event );
+ void mouseMoveEvent( QMouseEvent *event );
+
+ public slots:
+ virtual void resizeBoard( void );
+ virtual void redrawAll( void );
+ virtual void drawPosition( const int& );
+ virtual void commit( void );
+
+ protected:
+ void drawCoords( QPixmap *pic, const int &pos );
+ QPoint coords( const int&, const int&);
+ int position( const QPoint& );
+ void drawSprites( void );
+ QPixmap getChessman( const int &pos );
+ bool isSprite( const int &pos );
+ void myBlit( const QPoint &dp, const QPaintDevice *src, const QRect &sr );
+
+ protected slots:
+ void updateSprites( void );
+
+ private:
+ SpriteList sprites;
+ sprite *DragSprite;
+ KnightsPixCache *cache;
+ QPixmap myself;
+ QPoint pressPoint;
+ bool orientation;
+ bool lastMoveWasDrag;
+ bool init;
+
+ int updateX1;
+ int updateY1;
+ int updateX2;
+ int updateY2;
+
+ /* Premove Positions */
+ int premoveFrom;
+ int premoveTo;
+};
+
+#endif
diff --git a/knights/board_base.cpp b/knights/board_base.cpp
new file mode 100644
index 0000000..6370644
--- /dev/null
+++ b/knights/board_base.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ board_base.cpp - description
+ -------------------
+ begin : Fri Feb 28 2003
+ copyright : (C) 2003 by The Knights Team
+ email : knights-general@lists.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "board_base.moc"
+#include "resource.h"
+#include "logic.h"
+
+board_base::board_base(QWidget *parent, const char *name, resource *Rsrc, logic *Lgc ) : QWidget(parent,name)
+{
+ /* Setup Variables */
+ myResource = Rsrc;
+ myLogic = Lgc;
+
+ paused = false;
+ flip = false;
+ localArmy = WHITE;
+}
+board_base::~board_base()
+{
+}
+///////////////////////////////////////
+//
+// board_base::setPaused
+//
+///////////////////////////////////////
+void board_base::setPaused( const bool &state )
+{
+ paused = state;
+ redrawAll();
+}
+///////////////////////////////////////
+//
+// board_base::setLocalArmy
+//
+///////////////////////////////////////
+void board_base::setLocalArmy( const bool &state )
+{
+ if( state == localArmy )
+ return;
+ localArmy = state;
+ redrawAll();
+}
+///////////////////////////////////////
+//
+// board_base::flipBoard
+//
+///////////////////////////////////////
+void board_base::flipBoard( void )
+{
+ flip = !flip;
+ redrawAll();
+}
+///////////////////////////////////////
+//
+// board_base::drawMove
+//
+///////////////////////////////////////
+void board_base::drawMove( const ChessMove&, const bool& )
+{
+ /* Subclasses MUST reimplement this */
+}
+///////////////////////////////////////
+//
+// board_base::resizeBoard
+//
+///////////////////////////////////////
+void board_base::resizeBoard( void )
+{
+ /* Subclasses MUST reimplement this */
+}
+///////////////////////////////////////
+//
+// board_base::redrawAll
+//
+///////////////////////////////////////
+void board_base::redrawAll( void )
+{
+ /* Subclasses MUST reimplement this */
+}
+///////////////////////////////////////
+//
+// board_base::drawPosition
+//
+///////////////////////////////////////
+void board_base::drawPosition( const int& )
+{
+}
+///////////////////////////////////////
+//
+// board_base::setPremovePositions
+//
+///////////////////////////////////////
+void board_base::setPremovePositions( const int&, const int& )
+{
+}
+///////////////////////////////////////
+//
+// board_base::commit
+//
+///////////////////////////////////////
+void board_base::commit( void )
+{
+}
+///////////////////////////////////////
+//
+// board_base::redrawLights
+//
+///////////////////////////////////////
+void board_base::redrawLights( void )
+{
+}
diff --git a/knights/board_base.h b/knights/board_base.h
new file mode 100644
index 0000000..305e686
--- /dev/null
+++ b/knights/board_base.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ board_base.h - description
+ -------------------
+ begin : Fri Feb 28 2003
+ copyright : (C) 2003 by The Knights Project
+ email : knights-general@lists.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef BOARD_BASE_H
+#define BOARD_BASE_H
+
+#include <stdlib.h>
+#include <qwidget.h>
+#include "definitions.h"
+
+/**
+ *@author The Knights Project
+ */
+
+class resource;
+class logic;
+
+class board_base : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ board_base(QWidget *parent=0, const char *name=0, resource *Rsrc=0, logic *Lgc=0);
+ virtual ~board_base();
+ virtual void drawMove( const ChessMove &chessMove, const bool &reverse=FALSE );
+ virtual void setPremovePositions( const int&, const int& );
+ virtual void redrawLights( void );
+
+ public slots:
+ virtual void resizeBoard( void );
+ virtual void redrawAll( void );
+ virtual void setPaused( const bool& );
+ virtual void setLocalArmy( const bool& );
+ virtual void drawPosition( const int& );
+ virtual void commit( void );
+ void flipBoard( void );
+
+ signals:
+ void leftClick( int );
+ void rightClick( int );
+
+ protected:
+ resource *myResource;
+ logic *myLogic;
+ bool paused;
+ bool localArmy;
+ bool flip;
+
+ protected:
+ inline bool color( const int &rank, const int &file )
+ { return abs( ( rank % 2 ) - ( file % 2 ) ); }
+};
+
+#endif
diff --git a/knights/challenge_game.cpp b/knights/challenge_game.cpp
new file mode 100644
index 0000000..b7d37cc
--- /dev/null
+++ b/knights/challenge_game.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ game.cpp - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qapplication.h>
+#include "challenge_game.h"
+
+
+Challenge_Game::Challenge_Game(QString seeker, QString seeker_rating, QString match_kind, QString rated, QString time, QString incr, QString uid)
+: _player(seeker), _match_type(match_kind), _is_rated(rated)
+{
+ _id = uid.toInt();
+ if( seeker_rating == "++++" )
+ _player_rating = 0;
+ else
+ _player_rating = seeker_rating.toInt();
+ _clock = time.toInt();
+ _increment = incr.toInt();
+ if( _is_rated == "unrated" )
+ _rated = false;
+ else
+ _rated = true;
+}
+
diff --git a/knights/challenge_game.h b/knights/challenge_game.h
new file mode 100644
index 0000000..6857492
--- /dev/null
+++ b/knights/challenge_game.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ game.h - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef GAME_H
+#define GAME_H
+#include <qstring.h>
+
+class Challenge_Game {
+
+ public:
+ Challenge_Game(QString seeker, QString seeker_rating, QString match_kind, QString rated, QString time, QString incr, QString uid);
+
+ public:
+
+ int id() { return _id; };
+ int clock() { return _clock; };
+ int increment() { return _increment; };
+ bool rated() { return _rated; };
+ int rating() { return _player_rating; };
+ QString _player;
+ QString _match_type;
+ QString _is_rated;
+
+ private:
+ int _id;
+ bool _rated;
+ int _player_rating;
+ int _clock;
+ int _increment;
+};
+
+#endif
+
diff --git a/knights/challenge_graph.cpp b/knights/challenge_graph.cpp
new file mode 100644
index 0000000..5d36ff1
--- /dev/null
+++ b/knights/challenge_graph.cpp
@@ -0,0 +1,460 @@
+/***************************************************************************
+ challenge_graph.cpp - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <kiconloader.h>
+#include <kstddirs.h>
+#include <kpopupmenu.h>
+
+#include <qapplication.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+#include <qpen.h>
+#include <qscrollview.h>
+#include <qwidget.h>
+#include <qrect.h>
+#include <qbrush.h>
+#include <qpainter.h>
+#include <qregexp.h>
+
+#include "challenge_graph.moc"
+#include "challenge_graph_view.h"
+#include "challenge_rectangle.h"
+#include "command.h"
+#include "definitions.h"
+
+/* SIZE is for the size of the challenge square. It could become a class variable */
+#define SIZE 8
+#define OFFSET 2
+#define SPACER SIZE+OFFSET
+
+///////////////////////////////////////
+//
+// Challenge_Graph::Constructor
+//
+///////////////////////////////////////
+Challenge_Graph::Challenge_Graph( QWidget* parent, const char* name, resource *Rsrc )
+ : QVBox(parent, name), myResource(Rsrc)
+{
+ max_rating = 2600;
+ max_time = 60;
+ seek = FALSE;
+
+ graph = new QCanvas( 0, "Challenge_Graph" );
+ myStatusBar = new QLabel( this, "Challenge_Graph_Status_Bar" );
+ myView = new Challenge_Graph_View( *graph, this, "Challenge_Graph_View", 0, myStatusBar );
+
+ QObject::connect(myView, SIGNAL(leftClick(int)), SLOT(selectMatch(int)));
+ QObject::connect(myView, SIGNAL(rightClick(Challenge_Game*, const QPoint&)), SLOT(display_menuSeek(Challenge_Game*, const QPoint&)));
+
+
+ /* Setup Style for myStatusBar */
+ myStatusBar->setAlignment( Qt::AlignAuto | Qt::AlignVCenter | Qt::SingleLine );
+ myStatusBar->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ clear();
+
+ menuSeek = new KPopupMenu( this );
+ menuSeek->setCheckable( TRUE );
+ menuSeek->insertItem( i18n("Seek Matches"), this, SLOT( menuFunct(int) ), 0, MENU_SEEK );
+ menuSeek->insertSeparator();
+ menuSeek->insertItem( i18n("Accept This Match"), this, SLOT( menuFunct(int) ), 0, MENU_ACCEPT_MATCH );
+ menuSeek->insertItem( i18n("Tell..."), this, SLOT( menuFunct(int) ), 0, MENU_TELL );
+ menuSeek->insertItem( i18n("Assess..."), this, SLOT( menuFunct(int) ), 0, MENU_ASSESS );
+ menuSeek->insertItem( i18n("Player Info"), this, SLOT( menuFunct(int) ), 0, MENU_FINGER );
+ menuSeek->insertItem( QIconSet( myResource->LoadIcon( QString("history"), KIcon::Small ) ),
+ i18n("Player History"), this, SLOT( menuFunct(int) ), 0, MENU_HISTORY );
+ menuSeek->insertSeparator();
+ menuSeek->insertItem( i18n("Add to Friends"), this, SLOT( menuFunct(int) ), 0, MENU_NOTIFY );
+ menuSeek->insertItem( i18n("Ignore This Player"), this, SLOT( menuFunct(int) ), 0, MENU_CENSOR );
+ menuSeek->setItemChecked( MENU_SEEK, FALSE );
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::Destructor
+//
+///////////////////////////////////////
+Challenge_Graph::~Challenge_Graph()
+{
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::resizeEvent
+//
+///////////////////////////////////////
+void Challenge_Graph::resizeEvent( QResizeEvent *e )
+{
+ if( e->size() != e->oldSize() )
+ {
+ QSize newsize = e->size();
+ x_size = newsize.width() - 8;
+ y_size = newsize.height() - myStatusBar->height();
+ graph->resize( x_size, y_size );
+ createBackground();
+ }
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::add
+//
+///////////////////////////////////////
+void Challenge_Graph::add(Challenge_Game *seek)
+{
+ double AdjustedClock = (float)seek->clock() + ( ( (float)seek->increment() / 60.0 ) * 20.0 );
+ double my_x = (float)x_size / (float)max_time * AdjustedClock;
+ double mag = (float)max_rating / (float)y_size;
+ double my_y = ( max_rating - seek->rating() ) / mag;
+
+ //bleah
+ //a bit of a hack for the status bar real estate & values larger then MAX
+ if ( seek->rating() < 250)
+ my_y = (max_rating - 250) / mag;
+ else if ( seek->rating() >= max_rating )
+ my_y = 10;
+
+ if ( seek->clock() > (max_time-3) )
+ my_x = x_size/max_time * (max_time-3);
+
+ int time_control_x = (int)(my_x);
+ int rating_y = (int)(my_y);
+
+ if ( isEmpty(time_control_x, rating_y) )
+ drawChallenge(time_control_x, rating_y, seek->rated(), seek);
+ else
+ addTo_Nearest_Neighbour(time_control_x, rating_y, seek->rated(), seek);
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::clear
+//
+///////////////////////////////////////
+void Challenge_Graph::clear()
+{
+ myView->reset();
+ graph->update();
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::drawChallenge
+//
+///////////////////////////////////////
+void Challenge_Graph::drawChallenge(int time_control_x, int rating_y, bool rated, Challenge_Game *challenge)
+{
+ /* This next peice of unelegant code is fairly unnecessary. It is to keep everything on the screen */
+ /* It's based on the theory of prophylaxis */
+ int my_x = time_control_x;
+ int my_y = rating_y;
+
+ if( my_y >= y_size - SPACER)
+ my_y = y_size - SPACER;
+ if( my_y < SPACER )
+ my_y = SPACER;
+ if( my_x >= x_size - ( SPACER ) )
+ my_x = x_size - ( SPACER ); /*Since squares draw from the top left */
+ if( my_x < SPACER )
+ my_x = SIZE;
+
+ QCanvasPolygonalItem *item = new Challenge_Rectangle(my_x, my_y, SIZE, SIZE, graph, challenge);
+
+ item->setPen( myResource->COLOR_GraphForeground );
+ item->move( time_control_x, rating_y );
+ item->show();
+
+ if( rated )
+ item->setBrush( QBrush(myResource->COLOR_GraphForeground) );
+ else
+ item->setBrush( QBrush(myResource->COLOR_GraphBackground, Qt::SolidPattern) );
+
+ item->show();
+ graph->update();
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::isEmpty
+//
+///////////////////////////////////////
+bool Challenge_Graph::isEmpty(int x, int y)
+{
+ QCanvasItemList l = graph->collisions( QRect(x, y, SIZE, SIZE) );
+
+ if( l.count() )
+ return false;
+ return true;
+}
+
+/* This function does a spiral search for the nearest neighbour */
+/* Pre: TRUE
+ Post: Finds the nearest non-overlapping position to the original coordinates */
+///////////////////////////////////////
+//
+// Challenge_Graph::addTo_Nearest_Neighbour
+//
+///////////////////////////////////////
+bool Challenge_Graph::addTo_Nearest_Neighbour(int orig_x, int orig_y, bool rated, Challenge_Game * challenge, int searchdepth)
+{
+ int right = 1;
+ int down = 2;
+ int left = 2;
+ int up = 3;
+
+ int x = orig_x;
+ int y = orig_y - ( SIZE + OFFSET );
+
+ /* Check the location on top*/
+ if ( isEmpty( x, y ) )
+ {
+ drawChallenge( x, y, rated, challenge );
+ return true;
+ }
+
+ /* Now search in a spiral */
+ while( right < searchdepth )
+ {
+ for( int i = 0; i < right; i++ )
+ {
+ x += SPACER;
+ if( isEmpty( x, y ) )
+ {
+ drawChallenge( x, y, rated, challenge );
+ return true;
+ }
+ }
+ for( int i = 0; i < down; i++ )
+ {
+ y += SPACER;
+ if( isEmpty( x, y ) )
+ {
+ drawChallenge( x, y, rated, challenge );
+ return true;
+ }
+ }
+ for( int i = 0; i < left; i++ )
+ {
+ x -= SPACER;
+ if( isEmpty( x, y) )
+ {
+ drawChallenge( x, y, rated, challenge );
+ return true;
+ }
+ }
+ for( int i = 0; i < up; i++ )
+ {
+ y -= SPACER;
+ if( isEmpty( x, y ) )
+ {
+ drawChallenge( x, y, rated, challenge );
+ return true;
+ }
+ }
+
+ /* Grow the spiral bounds */
+ right += 2;
+ down += 2;
+ left += 2;
+ up += 2;
+ }
+ return false;
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::createBackground
+//
+///////////////////////////////////////
+void Challenge_Graph::createBackground( void )
+{
+ QPainter painter;
+ QColor ink;
+ QWMatrix matrix;
+ int colorTotal;
+
+ background.resize( y_size, x_size );
+ background.fill( myResource->COLOR_GraphBackground );
+
+ /* Find out if we have a dark bgcolor or a light one. */
+ colorTotal = ( myResource->COLOR_GraphBackground.red() +
+ myResource->COLOR_GraphBackground.blue() +
+ myResource->COLOR_GraphBackground.green() );
+
+ /* Set our ink to something that will contrast well */
+ if( colorTotal < 384 ) // 384 = 50% gray
+ ink = myResource->COLOR_GraphBackground.light();
+ else
+ ink = myResource->COLOR_GraphBackground.dark();
+
+ /* Paint the text on */
+ painter.begin( &background );
+ painter.setFont( myResource->FONT_Standard );
+ painter.setPen( ink );
+ painter.drawText( 64, 12, i18n( "Rating" ) );
+ painter.end();
+ matrix.rotate( -90.0 );
+ background = background.xForm( matrix );
+ painter.begin( &background );
+ painter.setFont( myResource->FONT_Standard );
+ painter.setPen( ink );
+ painter.drawText( 64, y_size - 8, i18n( "Time" ) );
+ painter.end();
+
+ graph->setBackgroundPixmap( background );
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::selectMatch
+//
+///////////////////////////////////////
+void Challenge_Graph::selectMatch( int matchID )
+{
+ if( matchID )
+ emit sendCMD( Command( 0, CMD_Start_Match, QString::number( matchID ) ) );
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::menuFunct
+//
+///////////////////////////////////////
+void Challenge_Graph::menuFunct( int funct )
+{
+ switch( funct )
+ {
+ case MENU_SEEK:
+ emit sendCMD( Command( 0, CMD_Toggle_Seek ) );
+ break;
+ case MENU_FINGER:
+ emit sendCMD( Command( 0, CMD_Player_Finger, selectedPlayerName ) );
+ break;
+ case MENU_TELL:
+ emit sendCMD( Command( 0, CMD_Set_Input, QString( "tell %1 " ).arg( selectedPlayerName ) ) );
+ break;
+ case MENU_NOTIFY:
+ emit sendCMD( Command( 0, CMD_Add_Friend, selectedPlayerName ) );
+ break;
+ case MENU_CENSOR:
+ emit sendCMD( Command( 0, CMD_Ignore_Player, selectedPlayerName ) );
+ break;
+ case MENU_HISTORY:
+ emit sendCMD( Command( 0, CMD_Player_History, selectedPlayerName ) );
+ break;
+ case MENU_ACCEPT_MATCH:
+ emit sendCMD( Command( 0, CMD_Start_Match, QString::number( selectedMatchID ) ) );
+ break;
+ case MENU_ASSESS:
+ emit sendCMD( Command( 0, CMD_Assess, selectedPlayerName ) );
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::updateSoughtList
+//
+///////////////////////////////////////
+void Challenge_Graph::updateSoughtList( void )
+{
+ unsigned int loop;
+ Challenge_Game *cg;
+
+ clear();
+ for( loop = 0; loop < SF_01.count(); loop++ )
+ {
+ cg = new Challenge_Game( SF_01[loop],
+ SF_02[loop],
+ SF_03[loop],
+ SF_04[loop],
+ SF_05[loop],
+ SF_06[loop],
+ SF_07[loop] );
+ add( cg );
+ }
+ SF_01.clear();
+ SF_02.clear();
+ SF_03.clear();
+ SF_04.clear();
+ SF_05.clear();
+ SF_06.clear();
+ SF_07.clear();
+ seek = TRUE;
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::addSoughtItem
+//
+///////////////////////////////////////
+void Challenge_Graph::addSoughtItem( const QString &src )
+{
+ QStringList fields = QStringList::split( QChar(' '), src, FALSE );
+ SF_01 << fields[2]; // Name
+ SF_02 << fields[1]; // Rating
+ SF_03 << fields[6]; // Match Type
+ SF_04 << fields[5]; // Is Rated?
+ SF_05 << fields[3]; // Base Time
+ SF_06 << fields[4]; // Increment
+ SF_07 << fields[0]; // ID#
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::display_menuSeek
+//
+///////////////////////////////////////
+void Challenge_Graph::display_menuSeek( Challenge_Game *Item, const QPoint &Pos )
+{
+ bool enable;
+ if( Item != NULL )
+ {
+ selectedPlayerName = Item->_player.replace( QRegExp("\\(.+\\)"), QString("") );
+ selectedMatchID = Item->id();
+ enable = TRUE;
+ }
+ else
+ {
+ enable = FALSE;
+ }
+ menuSeek->setItemChecked( MENU_SEEK, seek );
+ menuSeek->setItemEnabled( MENU_FINGER, enable );
+ menuSeek->setItemEnabled( MENU_TELL, enable );
+ menuSeek->setItemEnabled( MENU_NOTIFY, enable );
+ menuSeek->setItemEnabled( MENU_CENSOR, enable );
+ menuSeek->setItemEnabled( MENU_HISTORY, enable );
+ menuSeek->setItemEnabled( MENU_ACCEPT_MATCH, enable );
+ menuSeek->setItemEnabled( MENU_ASSESS, enable );
+ menuSeek->popup( Pos );
+}
+///////////////////////////////////////
+//
+// Challenge_Graph::recvCMD
+//
+///////////////////////////////////////
+void Challenge_Graph::recvCMD( const Command& command )
+{
+ switch(((Command)command).getCommand())
+ {
+ case CMD_Add_Sought_Match:
+ addSoughtItem( ((Command)command).getData() );
+ break;
+ case CMD_Show_Sought_List:
+ updateSoughtList();
+ break;
+ case CMD_Hide_Sought_List:
+ clear();
+ seek = FALSE;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/knights/challenge_graph.h b/knights/challenge_graph.h
new file mode 100644
index 0000000..e7963a3
--- /dev/null
+++ b/knights/challenge_graph.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ challenge_graph.h - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CHALLENGE_GRAPH_H
+#define CHALLENGE_GRAPH_H
+
+#include <qstringlist.h>
+#include <qvbox.h>
+#include <qevent.h>
+#include <qcolor.h>
+
+#include "resource.h"
+#include "challenge_game.h"
+
+class KPopupMenu;
+class QCanvas;
+class QLabel;
+class Challenge_Graph_View;
+class Command;
+
+class Challenge_Graph : public QVBox
+{
+ Q_OBJECT
+
+ public:
+ Challenge_Graph(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ virtual ~Challenge_Graph();
+ void resizeEvent( QResizeEvent* );
+ void add( Challenge_Game *seek );
+ void clear();
+
+ signals:
+ void sendCMD( const Command& );
+
+ public slots:
+ void recvCMD( const Command& );
+ void display_menuSeek( Challenge_Game*, const QPoint& );
+ void selectMatch( int );
+ void menuFunct( int );
+
+ protected:
+ virtual bool isEmpty( int x, int y );
+ void drawChallenge( int time_control_x, int rating_y, bool rated, Challenge_Game *challenge );
+ bool addTo_Nearest_Neighbour( int orig_x, int orig_y, bool rated, Challenge_Game *challenge, int searchdepth=10 );
+ void createBackground( void );
+ void addSoughtItem( const QString& );
+ void updateSoughtList( void );
+
+ private:
+ int x_size;
+ int y_size;
+ int max_rating;
+ int max_time;
+ bool seek;
+
+ resource *myResource;
+ QCanvas *graph;
+ Challenge_Graph_View *myView;
+ QLabel *myStatusBar;
+ QPixmap background;
+
+ KPopupMenu *menuSeek;
+ int selectedMatchID;
+ QString selectedPlayerName;
+ /*
+ These StringLists temporarily store Sought Game data
+ until all ads have been displayed.
+ */
+ QStringList SF_01;
+ QStringList SF_02;
+ QStringList SF_03;
+ QStringList SF_04;
+ QStringList SF_05;
+ QStringList SF_06;
+ QStringList SF_07;
+};
+
+#endif
+
diff --git a/knights/challenge_graph_view.cpp b/knights/challenge_graph_view.cpp
new file mode 100644
index 0000000..734ed99
--- /dev/null
+++ b/knights/challenge_graph_view.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ challenge_graph_view.cpp - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <string>
+#include <qpoint.h>
+#include <qstring.h>
+
+#include "challenge_graph_view.moc"
+
+#include "challenge_graph.h"
+#include "challenge_rectangle.h"
+
+///////////////////////////////////////
+//
+// Challenge_Graph_View::Constructor
+//
+///////////////////////////////////////
+Challenge_Graph_View::Challenge_Graph_View(QCanvas& c, QWidget * parent,const char* name, WFlags f, QLabel *qsb)
+ : QCanvasView(&c,parent,name,f), canvas(c), statusbar(qsb)
+{
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ setVScrollBarMode( QScrollView::AlwaysOff );
+
+ if ( parent )
+ parent->installEventFilter( this );
+ QScrollView::viewport()->setMouseTracking(true);
+}
+///////////////////////////////////////
+//
+// Challenge_Graph_View::Destructor
+//
+///////////////////////////////////////
+Challenge_Graph_View::~Challenge_Graph_View()
+{
+}
+///////////////////////////////////////
+//
+// Challenge_Graph_View::contentsMousePressEvent
+//
+///////////////////////////////////////
+void Challenge_Graph_View::contentsMousePressEvent(QMouseEvent* e)
+{
+ QCanvasItemList l = canvas.collisions(e->pos());
+ QCanvasItemList::Iterator it = l.begin();
+ for(; it != l.end(); ++it )
+ {
+ Challenge_Rectangle *cr = dynamic_cast<Challenge_Rectangle *>(*it);
+ Challenge_Game *g = cr->getGame();
+ if( e->button() == Qt::LeftButton )
+ emit leftClick( g->id() );
+ if( e->button() == Qt::RightButton )
+ emit rightClick( g, e->globalPos() );
+ return;
+ }
+ if( e->button() == Qt::RightButton )
+ emit rightClick( NULL, e->globalPos() ); // We need to catch all right clicks
+}
+///////////////////////////////////////
+//
+// Challenge_Graph_View::reset
+//
+///////////////////////////////////////
+void Challenge_Graph_View::reset()
+{
+ QCanvasItemList list = canvas.allItems();
+ QCanvasItemList::Iterator it = list.begin();
+ for(; it != list.end(); ++it )
+ {
+ Challenge_Rectangle *cr = dynamic_cast<Challenge_Rectangle *>(*it);
+ Challenge_Game *g = cr->getGame();
+ delete g;
+ if ( *it )
+ delete *it;
+ }
+}
+///////////////////////////////////////
+//
+// Challenge_Graph_View::contentsMouseMoveEvent
+//
+///////////////////////////////////////
+void Challenge_Graph_View::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ QString match;
+ QCanvasItemList l = canvas.collisions(e->pos());
+ QCanvasItemList::Iterator it = l.begin();
+ for(; it!=l.end(); ++it)
+ {
+ Challenge_Rectangle *cr = dynamic_cast<Challenge_Rectangle *>(*it);
+ Challenge_Game *g = cr->getGame();
+
+ match = i18n( " Name: %1 Rating: %2 Match Type: %3 %4 Base Time: %5 Increment: %6" )
+ .arg( g->_player ).arg( g->rating() ).arg( g->_match_type ).arg( g->_is_rated )
+ .arg( g->clock() ).arg( g->increment() );
+ break;
+ }
+ statusbar->setText( match );
+}
+
diff --git a/knights/challenge_graph_view.h b/knights/challenge_graph_view.h
new file mode 100644
index 0000000..f1e89ba
--- /dev/null
+++ b/knights/challenge_graph_view.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ challenge_graph_view.h - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CHALLENGE_GRAPH_VIEW_H
+#define CHALLENGE_GRAPH_VIEW_H
+
+#include <qevent.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+#include "challenge_game.h"
+
+
+class Challenge_Graph_View : public QCanvasView
+{
+ Q_OBJECT
+
+ public:
+ Challenge_Graph_View(QCanvas&, QWidget* parent=0, const char* name=0, WFlags f=0, QLabel *qsb=0);
+ ~Challenge_Graph_View();
+ void reset();
+
+ signals:
+ void leftClick(int);
+ void rightClick(Challenge_Game*, const QPoint&);
+
+ protected:
+ void contentsMousePressEvent(QMouseEvent*);
+ void contentsMouseMoveEvent(QMouseEvent*);
+ void updateStatusBar(QString msg);
+
+ private:
+ QCanvas &canvas;
+ QLabel *statusbar;
+};
+
+#endif
diff --git a/knights/challenge_rectangle.cpp b/knights/challenge_rectangle.cpp
new file mode 100644
index 0000000..2587623
--- /dev/null
+++ b/knights/challenge_rectangle.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ challenge_rectangle.cpp - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "challenge_rectangle.h"
+
+Challenge_Rectangle::Challenge_Rectangle
+ (int x, int y, int width, int height, QCanvas * canvas, Challenge_Game * ptr)
+ : QCanvasRectangle(x,y,width,height,canvas), challenge(ptr)
+{
+}
+
+Challenge_Game* Challenge_Rectangle::getGame()
+{
+ return challenge;
+}
+
+Challenge_Rectangle::~Challenge_Rectangle()
+{
+ this->hide();
+}
diff --git a/knights/challenge_rectangle.h b/knights/challenge_rectangle.h
new file mode 100644
index 0000000..02488ff
--- /dev/null
+++ b/knights/challenge_rectangle.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ challenge_rectangle.h - description
+ -------------------
+ begin : Mon Jan 7 2002
+ copyright : (C) 2003 by Eric Faccer
+ email : e.faccer@qut.edu.au
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CHALLENGE_RECTANGLE_H
+#define CHALLENGE_RECTANGLE_H
+
+#include <qcanvas.h>
+#include "challenge_game.h"
+
+class Challenge_Rectangle : public QCanvasRectangle
+{
+ public:
+ Challenge_Rectangle(int x=0, int y=0, int width=0, int height=0, QCanvas * canvas=0, Challenge_Game * ptr=0);
+ ~Challenge_Rectangle();
+ Challenge_Game* getGame();
+
+ private:
+ Challenge_Game * challenge;
+
+};
+#endif
+
diff --git a/knights/chessclock.cpp b/knights/chessclock.cpp
new file mode 100644
index 0000000..bde4745
--- /dev/null
+++ b/knights/chessclock.cpp
@@ -0,0 +1,195 @@
+/***************************************************************************
+ chessclock.cpp - description
+ -------------------
+ begin : Mon Jul 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "chessclock.moc"
+#include "audio.h"
+
+chessclock::chessclock(QWidget *parent, const char *name, resource *Rsrc ) : QWidget(parent,name)
+{
+ Resource = Rsrc;
+ Silent = TRUE;
+ WhiteIndex = 0;
+ BlackIndex = 0;
+ Flag[WHITE] = FALSE;
+ Flag[BLACK] = FALSE;
+ whiteClock = " 0:00:00 ";
+ blackClock = " 0:00:00 ";
+}
+chessclock::~chessclock()
+{
+}
+///////////////////////////////////////
+//
+// chessclock::Set
+//
+///////////////////////////////////////
+void chessclock::Set( const int WhiteSec, const int BlackSec, const bool onMove )
+{
+ /* these times are in centi seconds */
+ White.Seconds = WhiteSec / 10;
+ Black.Seconds = BlackSec / 10;
+ ArmyOnMove = onMove;
+}
+///////////////////////////////////////
+//
+// chessclock::Reset
+//
+///////////////////////////////////////
+void chessclock::Reset( void )
+{
+ Pause();
+ WhiteIndex = 0;
+ BlackIndex = 0;
+
+ White = Resource->TCPWhite[WhiteIndex];
+ Black = Resource->TCPBlack[BlackIndex];
+
+ White.Seconds *= 10;
+ White.Increment *= 10;
+ Black.Seconds *= 10;
+ Black.Increment *= 10;
+
+ ArmyOnMove = WHITE;
+ External = FALSE;
+ UpdateStrings();
+}
+///////////////////////////////////////
+//
+// chessclock::Pause
+//
+///////////////////////////////////////
+void chessclock::Pause( void )
+{
+ Silent = TRUE;
+}
+///////////////////////////////////////
+//
+// chessclock::Resume
+//
+///////////////////////////////////////
+void chessclock::Resume( void )
+{
+ Silent = FALSE;
+}
+///////////////////////////////////////
+//
+// chessclock::getCentiseconds
+//
+///////////////////////////////////////
+int chessclock::getCentiseconds( const bool Army )
+{
+ if( Army == WHITE )
+ {
+ return White.Seconds * 10;
+ }
+ return Black.Seconds * 10;
+}
+///////////////////////////////////////
+//
+// chessclock::Moved
+//
+///////////////////////////////////////
+void chessclock::Moved( void )
+{
+ Pause();
+ if( ArmyOnMove == WHITE )
+ {
+ ArmyOnMove = BLACK;
+ White.Moves--;
+ White.Seconds += White.Increment;
+ if( White.Moves < 1 )
+ {
+ WhiteIndex++;
+ if( WhiteIndex == (signed)Resource->TCPWhite.count() ) WhiteIndex--;
+ White = Resource->TCPWhite[WhiteIndex];
+ White.Seconds *= 10;
+ White.Increment *= 10;
+ }
+ }
+ else
+ {
+ ArmyOnMove = WHITE;
+ Black.Moves--;
+ Black.Seconds += Black.Increment;
+ if( Black.Moves < 1 )
+ {
+ BlackIndex++;
+ if( BlackIndex == (signed)Resource->TCPBlack.count() ) BlackIndex--;
+ Black = Resource->TCPBlack[BlackIndex];
+ Black.Seconds *= 10;
+ Black.Increment *= 10;
+ }
+ }
+ Resume();
+}
+///////////////////////////////////////
+//
+// chessclock::Tick
+//
+///////////////////////////////////////
+void chessclock::Tick( void )
+{
+ if( Silent ) return;
+ if( ArmyOnMove == WHITE )
+ {
+ White.Seconds--;
+ if( ( White.Seconds < 0 ) && ( Flag[WHITE] == FALSE ) )
+ {
+ Flag[WHITE] = TRUE;
+ emit flagFell( WHITE );
+ Resource->play( SND_FLAG );
+ }
+ }
+ else
+ {
+ Black.Seconds--;
+ if( ( Black.Seconds < 0 ) && ( Flag[BLACK] == FALSE ) )
+ {
+ Flag[BLACK] = TRUE;
+ emit flagFell( BLACK );
+ Resource->play( SND_FLAG );
+ }
+ }
+ UpdateStrings();
+}
+///////////////////////////////////////
+//
+// chessclock::UpdateStrings
+//
+///////////////////////////////////////
+void chessclock::UpdateStrings( void )
+{
+ int tmp;
+ int h, m, s;
+ char sign;
+
+ sign = ' ';
+ if( White.Seconds < 0 ) sign = '-';
+ tmp = abs(White.Seconds / 10);
+ s = ( tmp % 60 );
+ m = ( ( tmp / 60 ) % 60 );
+ h = ( ( tmp / 60 ) / 60 );
+ whiteClock.sprintf( " %c%.1d:%.2d:%.2d ", sign, h, m, s );
+
+ sign = ' ';
+ if( Black.Seconds < 0 ) sign = '-';
+ tmp = abs(Black.Seconds / 10);
+ s = ( tmp % 60 );
+ m = ( ( tmp / 60 ) % 60 );
+ h = ( ( tmp / 60 ) / 60 );
+ blackClock.sprintf( " %c%.1d:%.2d:%.2d ", sign, h, m, s );
+}
diff --git a/knights/chessclock.h b/knights/chessclock.h
new file mode 100644
index 0000000..ce2a1fd
--- /dev/null
+++ b/knights/chessclock.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ chessclock.h - description
+ -------------------
+ begin : Mon Jul 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CHESSCLOCK_H
+#define CHESSCLOCK_H
+
+#include <qwidget.h>
+#include <qstring.h>
+#include <stdlib.h>
+#include "definitions.h"
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class chessclock : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ chessclock( QWidget *parent=0, const char *name=0, resource *Rsrc=0 );
+ ~chessclock();
+
+ /* The Set function accepts Centiseconds ( 1/100 second ) */
+ void Set( const int WhiteSec, const int BlackSec, const bool onMove );
+ void Reset( void );
+ void Pause( void );
+ void Resume( void );
+ void Moved( void );
+ int getCentiseconds( const bool Army );
+
+ QString whiteClock;
+ QString blackClock;
+ bool Silent;
+ bool Flag[2];
+
+ public slots:
+ void Tick( void );
+
+ signals:
+ void flagFell( const bool );
+
+ private:
+
+ resource *Resource;
+
+ TCP White;
+ TCP Black;
+
+ int WhiteIndex;
+ int BlackIndex;
+
+ bool ArmyOnMove;
+ bool External;
+
+ void UpdateStrings( void );
+};
+
+#endif
diff --git a/knights/command.cpp b/knights/command.cpp
new file mode 100644
index 0000000..a67088a
--- /dev/null
+++ b/knights/command.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ command.cpp - description
+ -------------------
+ begin : Sun Jun 30 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "command.h"
+
+Command::Command( int ID, int Command, int WhiteTime, int BlackTime, struct ChessMove Move )
+{
+ white_time = WhiteTime;
+ black_time = BlackTime;
+ move = Move;
+ id = ID;
+ command = Command;
+}
+
+Command::Command( int ID, int Command, int WhiteTime, int BlackTime, struct ChessMove Move, QString Data )
+{
+ white_time = WhiteTime;
+ black_time = BlackTime;
+ data = Data;
+ move = Move;
+ id = ID;
+ command = Command;
+}
+
+Command::Command( int ID, int Command, int WhiteTime, int BlackTime, QString Data )
+{
+ white_time = WhiteTime;
+ black_time = BlackTime;
+ data = Data;
+ id = ID;
+ command = Command;
+}
+
+Command::Command( int ID, int Command )
+{
+ clear();
+ id = ID;
+ command = Command;
+}
+
+Command::Command( int ID, int Command, QString Data )
+{
+ clear();
+ id = ID;
+ command = Command;
+ data = Data;
+}
+
+Command::Command()
+{
+ clear();
+}
+
+Command::~Command()
+{
+}
+
+void Command::clear(void)
+{
+ white_time = 0;
+ black_time = 0;
+ command = CMD_None;
+ clearMove( &move );
+}
+///////////////////////////////////////
+//
+// Command::clearMove
+//
+///////////////////////////////////////
+void Command::clearMove( ChessMove *Move )
+{
+ Move->fromFile = Null;
+ Move->fromRank = Null;
+ Move->toFile = Null;
+ Move->toRank = Null;
+ Move->Promote = Null;
+ Move->ManTaken = Null;
+ Move->NAG = 0;
+ Move->ICS_MoveCounter = 0;
+ Move->ICS_PawnPushFile = Null;
+ Move->ICS_Mode = Null;
+ Move->ICS_OnMove = 0;
+ Move->ICS_ClockTicking = TRUE;
+}
diff --git a/knights/command.h b/knights/command.h
new file mode 100644
index 0000000..c10e300
--- /dev/null
+++ b/knights/command.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ command.h - description
+ -------------------
+ begin : Sun Jun 30 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#include <qstring.h>
+#include "definitions.h"
+
+/**
+ *@author Alexander Wels.
+ */
+ /* Commands */
+
+/*
+ These constants represent the game's desire to send the IOs a command.
+ SendCMD will convert them to the correct command for the current protocol.
+*/
+
+const int CMD_None = 0x00000000;
+const int CMD_Init = 0x00000001;
+const int CMD_NewGame = 0x00000002;
+const int CMD_Exit = 0x00000003;
+const int CMD_MoveNow = 0x00000004;
+const int CMD_Pause = 0x00000005;
+const int CMD_Resume = 0x00000006;
+const int CMD_Move = 0x00000007;
+const int CMD_Illegal = 0x00000008;
+const int CMD_Play_White = 0x00000009;
+const int CMD_Play_Black = 0x0000000a;
+const int CMD_Result_White = 0x0000000b;
+const int CMD_Result_Black = 0x0000000c;
+const int CMD_Result_Draw = 0x0000000d;
+const int CMD_Your_Time = 0x0000000e;
+const int CMD_Enemy_Time = 0x0000000f;
+const int CMD_Offer_Draw = 0x00000010;
+const int CMD_Ponder = 0x00000011;
+const int CMD_No_Pondering = 0x00000012;
+const int CMD_Book_Mode = 0x00000013;
+const int CMD_Out_Of_Book = 0x00000014;
+const int CMD_Check_Book = 0x00000015;
+const int CMD_Retract_Move = 0x00000016;
+const int CMD_Hint = 0x00000017;
+const int CMD_Listen = 0x00000018;
+const int CMD_Play = 0x00000019;
+const int CMD_Tell_User = 0x0000001a;
+const int CMD_Tell_User_Error = 0x0000001b;
+const int CMD_White_Resign = 0x0000001c;
+const int CMD_Black_Resign = 0x0000001d;
+const int CMD_White_Called_Flag = 0x0000001e;
+const int CMD_Black_Called_Flag = 0x0000001f;
+const int CMD_Set_Depth = 0x00000020;
+const int CMD_Set_Board = 0x00000021;
+const int CMD_Set_Difficulty = 0x00000022;
+const int CMD_Tell_Opponent = 0x00000023;
+const int CMD_Tell_Others = 0x00000024;
+const int CMD_Tell_All = 0x00000025;
+const int CMD_Tell_ICS = 0x00000026;
+const int CMD_Set_Name = 0x00000028;
+
+/* Engine Specific */
+const int CMD_UCI_Hint = 0x00100001;
+const int CMD_Send_SIGTERM = 0x00100002;
+const int CMD_Send_SIGINT = 0x00100003;
+
+/* Internet specific commands */
+const int CMD_Reject_Draw = 0x01000001;
+const int CMD_Reset_Server = 0x01000002;
+const int CMD_Examine_Forward = 0x01000003;
+const int CMD_Examine_Backward = 0x01000004;
+const int CMD_Lost_Contact = 0x01000005;
+const int CMD_Bad_Login = 0x01000006;
+const int CMD_Toggle_Seek = 0x01000007;
+const int CMD_Assess = 0x01000008;
+const int CMD_Player_Finger = 0x01000009;
+const int CMD_Player_History = 0x0100000a;
+const int CMD_Add_Friend = 0x0100000b;
+const int CMD_Ignore_Player = 0x0100000c;
+const int CMD_Start_Match = 0x0100000d;
+
+/* These commands are from Match to Core ONLY */
+const int CMD_New_Players = 0x02000001;
+
+/* These commands are sent to ICS Related Widgets */
+const int CMD_Add_Sought_Match = 0x03000001;
+const int CMD_Show_Sought_List = 0x03000002;
+const int CMD_Hide_Sought_List = 0x03000003;
+const int CMD_Set_Input = 0x03000004;
+const int CMD_Set_Src_Tell = 0x03000005;
+const int CMD_Set_Src_Channel = 0x03000006;
+const int CMD_Append_To_Console = 0x03000007;
+const int CMD_Send_To_ICS = 0x03000008;
+
+class Command
+{
+
+protected:
+ int white_time; // Centiseconds
+ int black_time; // Centiseconds
+ struct ChessMove move;
+ int command;
+ int id;
+ QString data; // Generic String... used for ICS and FEN, etc.
+
+public:
+ Command( int ID, int Command );
+ Command( int ID, int Command, QString Data );
+ Command( int ID, int Command, int WhiteTime, int BlackTime, struct ChessMove Move );
+ Command( int ID, int Command, int WhiteTime, int BlackTime, struct ChessMove Move, QString Data );
+ Command( int ID, int Command, int WhiteTime, int BlackTime, QString Data );
+ Command();
+ ~Command();
+ void clear( void );
+
+ /* Static Public Members */
+ static void clearMove( struct ChessMove *Move );
+
+ /* Inline Members */
+ int getWhiteTime( void )
+ {
+ return white_time;
+ }
+
+ int getBlackTime( void )
+ {
+ return black_time;
+ }
+
+ struct ChessMove& getMove( void )
+ {
+ return move;
+ }
+
+ int getID( void )
+ {
+ return id;
+ }
+
+ int getCommand( void )
+ {
+ return command;
+ }
+
+ QString& getData( void )
+ {
+ return data;
+ }
+
+ void setWhiteTime( int time )
+ {
+ white_time = time;
+ }
+
+ void setBlackTime( int time )
+ {
+ black_time = time;
+ }
+
+ void setMove( struct ChessMove &NewMove )
+ {
+ move = NewMove;
+ }
+
+ void setID( int NewID )
+ {
+ id = NewID;
+ }
+
+ void setCommand( int &NewCommand )
+ {
+ command = NewCommand;
+ }
+
+ void setData( QString &NewData )
+ {
+ data = NewData;
+ }
+};
+
+#endif
diff --git a/knights/console.cpp b/knights/console.cpp
new file mode 100644
index 0000000..33bbbd5
--- /dev/null
+++ b/knights/console.cpp
@@ -0,0 +1,264 @@
+/***************************************************************************
+ console.cpp - description
+ -------------------
+ begin : Sun May 27 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "console.moc"
+#include "knightstextview.h"
+#include "accel.h"
+#include "tabmanager.h"
+
+/* KDE */
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <qregexp.h>
+#include <qstyle.h>
+
+Console::Console(QWidget *parent,
+ const char *name,
+ resource *Rsrc ) : QVBox(parent,name)
+{
+ myResource = Rsrc;
+ SelfMoving = FALSE;
+ QStyle& Style = QApplication::style();
+
+ margin = Style.defaultFrameWidth();
+ myTextView = new KnightsTextView( this, myResource );
+ myLineEdit = new KLineEdit( this, "console_edit" );
+ /* Configure misc */
+ setBG();
+ myTextView->setStaticBackground( FALSE );
+
+ connect( myLineEdit, SIGNAL( returnPressed( const QString& ) ), this, SLOT( getText( const QString& ) ) );
+ connect( myResource->myAccel, SIGNAL( history_prev() ), this, SLOT( historyBackward() ) );
+ connect( myResource->myAccel, SIGNAL( history_next() ), this, SLOT( historyForward() ) );
+ connect( myResource->myAccel, SIGNAL( page_up() ), this, SLOT( pageUp() ) );
+ connect( myResource->myAccel, SIGNAL( page_down() ), this, SLOT( pageDown() ) );
+ connect( myResource->myAccel, SIGNAL( kibitz() ), this, SLOT( kibitz() ) );
+ connect( myResource->myAccel, SIGNAL( whisper() ), this, SLOT( whisper() ) );
+ connect( myResource->myAccel, SIGNAL( reply_tell() ), this, SLOT( replyPrivate() ) );
+ connect( myResource->myAccel, SIGNAL( reply_channel() ), this, SLOT( replyChannel() ) );
+ connect( myResource->myAccel, SIGNAL( focus() ), this, SLOT( getFocus() ) );
+ connect( myResource->myAccel, SIGNAL( focus( const QChar& ) ), this, SLOT( getFocus( const QChar& ) ) );
+
+ myTextView->show();
+ myLineEdit->show();
+ show();
+}
+Console::~Console()
+{
+ delete myLineEdit;
+ delete myTextView;
+}
+///////////////////////////////////////
+//
+// Console::pageDown
+//
+///////////////////////////////////////
+void Console::pageDown( void )
+{
+ myTextView->pageMove( Qt::Key_PageDown );
+}
+///////////////////////////////////////
+//
+// Console::pageUp
+//
+///////////////////////////////////////
+void Console::pageUp( void )
+{
+ myTextView->pageMove();
+}
+///////////////////////////////////////
+//
+// Console::recvCMD
+//
+///////////////////////////////////////
+void Console::recvCMD( const Command& command )
+{
+ QString modText; /* this will hold the text to append after it has been modified with anchors */
+
+ switch(((Command)command).getCommand())
+ {
+ case CMD_Append_To_Console:
+ if( myTextView->contentsY() >= ( myTextView->contentsHeight() - myTextView->visibleHeight() - 12 ) )
+ {
+ modText = insertTags(((Command)command).getData());
+ myTextView->append(modText);
+ myTextView->scrollToBottom();
+ }
+ else
+ {
+ modText = insertTags(((Command)command).getData());
+ myTextView->append(modText);
+ }
+ break;
+ case CMD_Set_Input:
+ myLineEdit->setText( ((Command)command).getData() );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+ break;
+ case CMD_Set_Src_Tell:
+ lastPrivateSource = ((Command)command).getData();
+ break;
+ case CMD_Set_Src_Channel:
+ lastChannelSource = ((Command)command).getData();
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// Console::getText
+//
+///////////////////////////////////////
+void Console::getText( const QString &text )
+{
+ /* Append this text into our history */
+ history.append( text );
+ if( history.count() > 100 )
+ history.remove( history.begin() );
+ historyIT = history.end();
+ emit sendCMD( Command( 0, CMD_Send_To_ICS, text ) );
+ myLineEdit->clear();
+}
+///////////////////////////////////////
+//
+// Console::historyBack
+//
+///////////////////////////////////////
+void Console::historyBackward( void )
+{
+ if( history.count() && ( historyIT != history.begin() ) )
+ {
+ historyIT--;
+ myLineEdit->setText( (*historyIT) );
+ }
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::historyForward
+//
+///////////////////////////////////////
+void Console::historyForward( void )
+{
+ if( history.count() && ( historyIT != history.end() ) )
+ {
+ historyIT++;
+ myLineEdit->setText( (*historyIT) );
+ }
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::replyPrivate
+//
+///////////////////////////////////////
+void Console::replyPrivate( void )
+{
+ myLineEdit->setText( QString( "tell %1 " ).arg( lastPrivateSource ) );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::replyChannel
+//
+///////////////////////////////////////
+void Console::replyChannel( void )
+{
+ myLineEdit->setText( QString( "tell %1 " ).arg( lastChannelSource ) );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::kibitz
+//
+///////////////////////////////////////
+void Console::kibitz( void )
+{
+ myLineEdit->setText( QString( "kibitz " ) );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::whisper
+//
+///////////////////////////////////////
+void Console::whisper( void )
+{
+ myLineEdit->setText( QString( "whisper " ) );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::getFocus
+//
+///////////////////////////////////////
+void Console::getFocus( void )
+{
+ if( myLineEdit->hasFocus() )
+ {
+ getText( myLineEdit->text() );
+ }
+ setActiveWindow();
+ myResource->tabManager->showTab( this );
+ myLineEdit->setFocus();
+}
+void Console::getFocus( const QChar &c )
+{
+ myLineEdit->setText( myLineEdit->text() + QString( c ) );
+ if( !myLineEdit->hasFocus() )
+ getFocus();
+}
+///////////////////////////////////////
+//
+// Console::setBG
+//
+///////////////////////////////////////
+void Console::setBG( void )
+{
+ myTextView->setPaper( QBrush( myResource->COLOR_Background ) );
+}
+
+///////////////////////////////////////
+//
+// Console::insertTags(QString data)
+//
+///////////////////////////////////////
+QString Console::insertTags(QString data)
+{
+ QRegExp hyperLinks("(http://(?:.)+(?:\\.(?:[^\\s\\r\\t<])+)+)");
+ QRegExp mailLinks("\\b((?:\\w|\\d)+\\@(?:\\w|\\d)+(?:\\.(?:\\d|\\w)+)+)\\b");
+ int pos = 0;
+
+ pos = hyperLinks.search(data, 0);
+ if(pos >= 0)
+ {
+ data.replace(hyperLinks, "<A HREF=\"" + hyperLinks.cap(0) + "\">" + hyperLinks.cap(0) + "</A>");
+ }
+ pos = mailLinks.search(data, 0);
+ if(pos >= 0)
+ {
+ data.replace(mailLinks, "<A HREF=\"mailto:" + mailLinks.cap(0) + "\">" + mailLinks.cap(0) + "</A>");
+ }
+ return data;
+}
diff --git a/knights/console.h b/knights/console.h
new file mode 100644
index 0000000..ec38ec9
--- /dev/null
+++ b/knights/console.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ console.h - description
+ -------------------
+ begin : Sun May 27 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+/* Qt */
+#include <qstringlist.h>
+#include <qvbox.h>
+#include <qlayout.h>
+/* Local */
+#include "definitions.h"
+#include "resource.h"
+#include "command.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class KLineEdit;
+class KnightsTextView;
+
+class Console : public QVBox
+{
+ Q_OBJECT
+
+ public:
+
+ enum Direction
+ {
+ Up = 1,
+ Down = 0
+ };
+
+ Console(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~Console();
+ void buildAccel( void );
+
+ public slots:
+ void recvCMD( const Command& );
+ void getText( const QString& );
+ void historyBackward( void );
+ void historyForward( void );
+ void pageUp( void );
+ void pageDown( void );
+ void getFocus( void );
+ void getFocus( const QChar& );
+ void setBG( void );
+ void replyPrivate( void );
+ void replyChannel( void );
+ void kibitz( void );
+ void whisper( void );
+
+ signals:
+ void sendCMD( const Command& );
+
+ private:
+ QString insertTags(QString);
+
+ resource *myResource;
+ int margin;
+ bool SelfMoving;
+
+ KnightsTextView *myTextView;
+ KLineEdit *myLineEdit;
+
+ QStringList history;
+ QStringList::Iterator historyIT;
+ QString lastPrivateSource;
+ QString lastChannelSource;
+};
+
+#endif
diff --git a/knights/core.cpp b/knights/core.cpp
new file mode 100644
index 0000000..e0b09ce
--- /dev/null
+++ b/knights/core.cpp
@@ -0,0 +1,892 @@
+/***************************************************************************
+ core.cpp - description
+ -------------------
+ begin : Tue Oct 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/* KDE */
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+
+/* Qt */
+#include <qpushbutton.h>
+
+/* Local */
+#include "core.moc"
+#include "match.h"
+#include "list_pgn.h"
+#include "thinbuttons.h"
+#include "io_engine.h"
+#include "io_internet.h"
+#include "match_param.h"
+
+/* Tabs */
+#include "tabmanager.h"
+
+///////////////////////////////////////
+//
+// core::core
+//
+///////////////////////////////////////
+core::core(QWidget *parent, const char *name, resource *Rsrc ) : QWidget(parent,name)
+{
+ myResource = Rsrc;
+ listPGN = NULL;
+ currentMatch = NULL;
+
+ myButtonGroup = new thinbuttons( this, "ButtonGroup", myResource );
+ myButtonGroup->show();
+ connect( myButtonGroup, SIGNAL( leftClick(int) ), this, SLOT( setMatch(int) ) );
+ connect( myButtonGroup, SIGNAL( menuItemSelected(int,int) ), this, SLOT( thinButtonMenu(int,int) ) );
+
+ myCoreClock.start( 100, FALSE );
+ resize();
+}
+
+///////////////////////////////////////
+//
+// core::~core
+//
+///////////////////////////////////////
+core::~core()
+{
+ myCoreClock.stop();
+ delete myButtonGroup;
+}
+
+///////////////////////////////////////
+//
+// core::createNewIO
+//
+///////////////////////////////////////
+void core::createNewIO( int type, int ID, int side, int str )
+{
+ io_internet *internetioPtr = NULL;
+ io_engine *engineioPtr = NULL;
+// io_email *ioEmailPtr = NULL;
+ switch( type )
+ {
+ /* PLAYERTCP */
+ case PLAYERTCP:
+ if( ID == Null )
+ {
+ /* Create a NEW internetIO */
+ internetioPtr = new io_internet( this, myResource );
+ myIOMap.add( ID, internetioPtr );
+ internetioPtr->setID( ID );
+ connect( internetioPtr, SIGNAL( sendCMD( const Command& ) ), this, SLOT( command2Match( const Command& ) ) );
+ }
+ else
+ {
+ /* Use an existing internetIO */
+ internetioPtr = (io_internet*) myIOMap.find(Null);
+ if( internetioPtr == NULL )
+ {
+ kdWarning() << "core::createNewIO: Trying to connect a match to an internetIO that doesn't exsist." << endl;
+ }
+ else
+ {
+ myIOMap.add( ID, internetioPtr );
+ }
+ }
+ break;
+ /* PLAYEREXAMINE */
+ case PLAYEREXAMINE:
+ /* examine mode needs only 1 io mapped to it */
+ if( ID == Null )
+ {
+ /* Create a NEW internetIO */
+ internetioPtr = new io_internet( this, myResource );
+ myIOMap.add( ID, internetioPtr );
+ internetioPtr->setID( ID );
+ connect( internetioPtr, SIGNAL( sendCMD( const Command& ) ), this, SLOT( command2Match( const Command& ) ) );
+ }
+ else
+ {
+ internetioPtr = (io_internet*) myIOMap.find(ID);
+ if( internetioPtr == NULL )
+ {
+ /* no io mapped to the ID yet, use the internetio */
+ /* Use an existing internetIO */
+ internetioPtr = (io_internet*) myIOMap.find(Null);
+ if( internetioPtr == NULL )
+ {
+ kdWarning() << "core::createNewIO: Trying to connect a match to an internetIO that doesn't exsist." << endl;
+ }
+ else
+ {
+ myIOMap.add( ID, internetioPtr );
+ }
+ }
+ /* this ID is already mapped we don't need another one */
+ }
+ break;
+ /* PLAYERPC */
+ case PLAYERPC:
+ engineioPtr = new io_engine( this, myResource );
+ myIOMap.add( ID, engineioPtr );
+ engineioPtr->setID( ID );
+ connect( engineioPtr, SIGNAL( sendCMD( const Command& ) ), this, SLOT( command2Match( const Command& ) ) );
+ engineioPtr->Start( side );
+ engineioPtr->recvCMD( Command( ID, CMD_Set_Difficulty, QString().setNum( 1 << str ) ) );
+ break;
+ /* PLAYEREMAIL */
+ case PLAYEREMAIL:
+// ioEmailPtr = new io_email( this, myResource );
+// myIOMap.add( ID, ioEmailPtr );
+// ioEmailPtr->setID( ID );
+// connect( ioEmailPtr, SIGNAL( sendCMD( const Command& ) ), this, SLOT( command2Match( const Command& ) ) );
+ break;
+ default:
+ /* No IO needed */
+ break;
+ }
+}
+
+///////////////////////////////////////
+//
+// core::newMatch(match_params* param);
+//
+///////////////////////////////////////
+match* core::newMatch( match_param* param )
+{
+ match *match_ptr = NULL;
+ int newID;
+
+ /* create a new ID for the match */
+ newID = myIDManager.getNewID();
+
+ /* Create the match navigation button */
+ myButtonGroup->create( newID );
+
+ /* Create the match */
+ match_ptr = new match(this, param, myResource);
+ match_ptr->setID( newID );
+ myMatchMap.add( newID, match_ptr );
+
+ /* Create IOs */
+ createNewIO( param->type(WHITE), newID, WHITE, param->strength(WHITE) );
+ createNewIO( param->type(BLACK), newID, BLACK, param->strength(BLACK) );
+
+ /* Connect Signals */
+ connect( match_ptr, SIGNAL( sendCMD( const Command& ) ), this, SLOT( command2IO( const Command& ) ) );
+ connect( &myCoreClock, SIGNAL( timeout() ), match_ptr, SLOT( tick() ) );
+
+ /* Set this new match as the current match */
+ setMatch( newID );
+ setActiveWindow();
+
+ /* Save our configuration settings */
+ myResource->ConfigWrite();
+
+ return match_ptr;
+}
+
+///////////////////////////////////////
+//
+// core::setMatch
+//
+///////////////////////////////////////
+void core::setMatch( int ID )
+{
+ /*
+ Disconnect the current match from the display
+ */
+ if( currentMatch != NULL )
+ {
+ currentMatch->setCurrent( FALSE );
+ disconnect( currentMatch, SIGNAL( setClocks() ), this, SLOT( slot_setClocks() ) );
+ disconnect( currentMatch, SIGNAL( setStatusBar( const int&, const QString& ) ), this, SLOT( slot_setStatusBar( const int&, const QString& ) ) );
+ disconnect( currentMatch, SIGNAL( setNotation() ), this, SLOT( slot_setNotation() ) );
+ currentMatch->setVisibility( FALSE );
+ }
+ /*
+ Now display the new match, and connect it's signals to the GUI
+ */
+ currentMatch = myMatchMap.find( ID );
+ currentMatch->setVisibility( TRUE );
+ myButtonGroup->setButton( ID );
+ connect( currentMatch, SIGNAL( setClocks() ), this, SLOT( slot_setClocks() ) );
+ connect( currentMatch, SIGNAL( setStatusBar( const int&, const QString& ) ), this, SLOT( slot_setStatusBar( const int&, const QString& ) ) );
+ connect( currentMatch, SIGNAL( setNotation() ), this, SLOT( slot_setNotation() ) );
+ currentMatch->setCurrent( TRUE );
+ emit requestResize();
+ emit initMatch();
+ currentMatch->resendStatusBar();
+
+ /* Give Ourselves Focus */
+ setActiveWindow();
+ topLevelWidget()->raise();
+}
+
+///////////////////////////////////////
+//
+// core::clearAll
+//
+///////////////////////////////////////
+bool core::clearAll( void )
+{
+ while( myMatchMap.count() )
+ {
+ if( clearMatch() != TRUE ) return FALSE;
+ }
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// core::clearMatch
+//
+///////////////////////////////////////
+bool core::clearMatch( int id )
+{
+ match *departingMatch, *nextMatch;
+ io_base *ioPtr;
+
+ if( id == Null )
+ {
+ if( currentMatch != NULL )
+ {
+ id = currentMatch->getID();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ departingMatch = myMatchMap.find(id);
+
+ /* A bad ID was passed */
+ if( departingMatch == NULL )
+ {
+ kdError() << "core::clearMatch: Bad matchID " << id << " could not be cleared." << endl;
+ return FALSE;
+ }
+
+ /* Save if needed */
+ if( departingMatch->modified() )
+ {
+ if( save( id, TRUE, FALSE ) == FALSE )
+ {
+ return FALSE;
+ }
+ }
+
+ /* Get ID of another match so it can become the current match */
+ if( departingMatch == currentMatch )
+ {
+ /* Find another match in the map */
+ nextMatch = --myMatchMap;
+ if( nextMatch == NULL )
+ {
+ ++myMatchMap;
+ nextMatch = ++myMatchMap;
+ }
+ /* Set the new current match */
+ if( nextMatch != NULL )
+ {
+ setMatch( nextMatch->getID() );
+ }
+ else
+ {
+ currentMatch = NULL;
+ emit initMatch();
+ }
+ }
+
+ /* Remove IOs in this match... */
+ ioPtr = myIOMap.find(id);
+ while( ioPtr != NULL )
+ {
+ myIOMap.remove( id );
+ if( ioPtr->getType() != io_base::INTERNET )
+ {
+ delete ioPtr;
+ }
+ ioPtr = myIOMap.find(id);
+ }
+
+ /* ...and remove the match */
+ myMatchMap.remove( id );
+ myButtonGroup->remove( id );
+ delete departingMatch;
+
+ resize();
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// core::resize
+//
+///////////////////////////////////////
+void core::resize( void )
+{
+ int size = 8 + ( 1 * ( myResource->ThemeBorder == TRUE ) );
+
+ if( currentMatch != NULL )
+ {
+ currentMatch->resize();
+ myButtonGroup->resize( currentMatch->width() );
+ myButtonGroup->move( 0, currentMatch->height() );
+ setFixedSize( currentMatch->width(), currentMatch->height() + myButtonGroup->height() );
+ }
+ else
+ {
+ myButtonGroup->resize( myResource->ThemeSize * size );
+ myButtonGroup->move( 0, myResource->ThemeSize * size );
+ setFixedSize( myResource->ThemeSize * size, ( myResource->ThemeSize * size ) + myButtonGroup->height() );
+ }
+}
+///////////////////////////////////////
+//
+// core::command2IO
+//
+///////////////////////////////////////
+void core::command2IO( const Command &command )
+{
+ io_base *io;
+ int id = ((Command)command).getID();
+
+ io = myIOMap.find(id);
+ while( io != NULL )
+ {
+ io->recvCMD(command);
+ io = myIOMap.findNext();
+ }
+}
+///////////////////////////////////////
+//
+// core::command2Match
+//
+///////////////////////////////////////
+void core::command2Match( const Command &command )
+{
+ match_param *paramPtr;
+ match *matchPtr;
+ Command cmd = command;
+
+ matchPtr = myMatchMap.find( cmd.getID() );
+ while( matchPtr != NULL )
+ {
+ /* Catch Commands Meant for Core */
+ switch( cmd.getCommand() )
+ {
+ case CMD_Hint:
+ KMessageBox::information( this, cmd.getData(), i18n("Hint") );
+ break;
+ case CMD_Tell_User:
+ KMessageBox::information( this, cmd.getData(), i18n( "Tell User" ) );
+ break;
+ case CMD_Tell_User_Error:
+ KMessageBox::sorry( this, cmd.getData(), i18n( "Tell User Error" ) );
+ break;
+ case CMD_Tell_Opponent:
+ paramPtr = matchPtr->getParam();
+ if( ( paramPtr->type( WHITE ) == PLAYERLOCAL ) ||
+ ( paramPtr->type( BLACK ) == PLAYERLOCAL ) )
+ KMessageBox::information( this, cmd.getData(), i18n( "Tell Opponent" ) );
+ else
+ command2IO( command );
+ break;
+ case CMD_Tell_Others:
+ command2IO( command );
+ break;
+ case CMD_Tell_ICS:
+ command2IO( command );
+ break;
+ case CMD_Tell_All:
+ paramPtr = matchPtr->getParam();
+ if( ( paramPtr->type( WHITE ) == PLAYERLOCAL ) ||
+ ( paramPtr->type( BLACK ) == PLAYERLOCAL ) )
+ KMessageBox::information( this, cmd.getData(), i18n( "Tell All" ) );
+ command2IO( command );
+ break;
+ case CMD_Out_Of_Book:
+// engine[enginePtr - 1]->sendCMD( CMD_Check_Book );
+ break;
+ default:
+ /* Just send it to the Match */
+ matchPtr->recvCMD( command );
+ break;
+ }
+ matchPtr = myMatchMap.findNext();
+ }
+}
+///////////////////////////////////////
+//
+// core::flag
+//
+///////////////////////////////////////
+bool core::flag( const bool Army )
+{
+ if( currentMatch == NULL ) return FALSE;
+ return currentMatch->flag( Army );
+ return false;
+}
+///////////////////////////////////////
+//
+// core::clock
+//
+///////////////////////////////////////
+QString core::clock( const bool Army )
+{
+ if( currentMatch == NULL ) return QString::null;
+ return currentMatch->clock( Army );
+ return "";
+}
+///////////////////////////////////////
+//
+// core::modified
+//
+///////////////////////////////////////
+bool core::modified( void )
+{
+ if( currentMatch == NULL ) return FALSE;
+ return currentMatch->modified();
+ return false;
+}
+///////////////////////////////////////
+//
+// core::paused
+//
+///////////////////////////////////////
+bool core::paused( void )
+{
+ if( currentMatch == NULL ) return FALSE;
+ return currentMatch->paused();
+ return false;
+}
+///////////////////////////////////////
+//
+// core::isOnline
+//
+///////////////////////////////////////
+bool core::isOnline( void )
+{
+ unsigned int index;
+ for( index=0; index < myIOMap.count(); index++ )
+ {
+ if( myIOMap[index]->getType() == io_base::INTERNET )
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+///////////////////////////////////////
+//
+// core::onMove
+//
+///////////////////////////////////////
+char core::onMove( void )
+{
+ if( currentMatch == NULL ) return Null;
+ return currentMatch->onMove();
+}
+///////////////////////////////////////
+//
+// core::caption
+//
+///////////////////////////////////////
+QString core::caption( void )
+{
+ QButton *Button;
+ if( currentMatch == NULL ) return QString::null;
+ Button = myButtonGroup->find( currentMatch->getID() );
+ if( Button != NULL ) Button->setText( currentMatch->caption() );
+ return currentMatch->caption();
+}
+///////////////////////////////////////
+//
+// core::whiteInput
+//
+///////////////////////////////////////
+char core::whiteInput(void)
+{
+ if( currentMatch == NULL ) return Null;
+ return currentMatch->input(WHITE);
+}
+///////////////////////////////////////
+//
+// core::blackInput
+//
+///////////////////////////////////////
+char core::blackInput(void)
+{
+ if( currentMatch == NULL ) return Null;
+ return currentMatch->input(BLACK);
+}
+///////////////////////////////////////
+//
+// core::review
+//
+///////////////////////////////////////
+void core::review( int Index )
+{
+ if( currentMatch == NULL ) return;
+ currentMatch->review( Index );
+}
+///////////////////////////////////////
+//
+// core::inputOnMove
+//
+///////////////////////////////////////
+char core::inputOnMove( bool reverse )
+{
+ if( currentMatch == NULL ) return Null;
+ return currentMatch->inputOnMove( reverse );
+}
+///////////////////////////////////////
+//
+// core::notation
+//
+///////////////////////////////////////
+QStringList* core::notation( void )
+{
+ if( currentMatch == NULL ) return NULL;
+ return currentMatch->notation();
+}
+///////////////////////////////////////
+//
+// core::slot_setNotation
+//
+///////////////////////////////////////
+void core::slot_setNotation( void )
+{
+ emit setNotation();
+}
+///////////////////////////////////////
+//
+// core::slot_setStatusBar
+//
+///////////////////////////////////////
+void core::slot_setStatusBar( const int &ID, const QString& MSG )
+{
+ emit setStatusBar( ID, MSG );
+}
+///////////////////////////////////////
+//
+// core::slot_setClocks
+//
+///////////////////////////////////////
+void core::slot_setClocks( void )
+{
+ emit setClocks();
+}
+///////////////////////////////////////
+//
+// core::print
+//
+///////////////////////////////////////
+void core::print( int ID )
+{
+ match *m2p;
+
+ if( ID == Null )
+ {
+ m2p = currentMatch;
+ }
+ else
+ {
+ m2p = myMatchMap.find( ID );
+ }
+ if( m2p == NULL ) return;
+ m2p->print();
+ return;
+}
+///////////////////////////////////////
+//
+// core::load
+//
+///////////////////////////////////////
+bool core::load( void )
+{
+ const QString fileFilter( "*.pgn *.Pgn *.PGN|Portable Game Notation (.pgn)\n*|All Files" );
+ QString URL;
+ URL = KFileDialog::getOpenFileName( QString::null, QString( fileFilter ), this, i18n( "Load PGN..." ) );
+ if( URL.isEmpty() ) return FALSE;
+ return load( URL );
+}
+bool core::load( const QString &IncURL )
+{
+ listPGN = new list_pgn( 0, "listPGN" );
+ myResource->tabManager->addTab( listPGN, IncURL.section( '/', -1 ) );
+ connect( listPGN, SIGNAL( selected( const QString&, const int& ) ), this, SLOT( load( const QString&, const int& ) ) );
+ listPGN->setURL( IncURL );
+return TRUE;
+}
+bool core::load( const QString &url, const int &pos )
+{
+ newMatch( new match_param( myResource, PLAYERLOAD, PLAYERLOAD ) );
+ return currentMatch->load( url, pos );
+}
+///////////////////////////////////////
+//
+// core::save
+//
+///////////////////////////////////////
+bool core::save( const int ID, const bool Prompt, const bool SaveAs )
+{
+ const QString fileFilter( "*.pgn *.Pgn *.PGN|Portable Game Notation (.pgn)\n*|All Files" );
+ match *match2bSaved;
+ int answer;
+ QString URL;
+
+ if( ID == Null )
+ {
+ /* Use current match */
+ match2bSaved = currentMatch;
+ }
+ else
+ {
+ match2bSaved = myMatchMap.find( ID );
+ }
+ if( match2bSaved == NULL ) return FALSE;
+ if( Prompt )
+ {
+ /* Prompt for the save */
+ myResource->ConfigWrite();
+ answer = KMessageBox::warningYesNoCancel( this,
+ i18n("Would you like to save this match?"),
+ i18n("Save Match?"),
+ QString::null,
+ QString::null,
+ QString("PromptForSaving") );
+ myResource->ConfigRead();
+ if( answer == KMessageBox::Cancel )
+ {
+ return FALSE;
+ }
+ if( answer == KMessageBox::No )
+ {
+ return TRUE;
+ }
+ }
+ /* Get the last URL we used */
+ URL = match2bSaved->url();
+ if( ( URL.isEmpty() ) || ( SaveAs ) )
+ {
+ /* Get a new URL */
+ URL = KFileDialog::getSaveFileName( QString::null, QString( fileFilter ), this, i18n( "Save Match..." ) );
+ if( URL.isNull() )
+ {
+ return FALSE;
+ }
+ if( URL.findRev( ".pgn", -1, FALSE ) == -1 )
+ {
+ URL += ".pgn";
+ }
+ }
+ if( match2bSaved->save( URL ) == FALSE )
+ {
+ emit setStatusBar( SAVE_ERROR );
+ return FALSE;
+ }
+ emit setStatusBar( SAVE_OK );
+ match2bSaved->setModified( FALSE );
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// core::matchMenu
+//
+///////////////////////////////////////
+void core::matchMenu( int opt )
+{
+ unsigned int index;
+ switch(opt)
+ {
+ /* Offer / Accept Draw */
+ case MENU_OFFER_DRAW: // Fall Through
+ case MENU_ACCEPT_DRAW:
+ if( whiteInput() == PLAYERLOCAL )
+ {
+ command2Match( Command( currentMatch->getID(), CMD_Offer_Draw, QString("W") ) );
+ }
+ if( blackInput() == PLAYERLOCAL )
+ {
+ command2Match( Command( currentMatch->getID(), CMD_Offer_Draw, QString("B") ) );
+ }
+ command2IO( Command( currentMatch->getID(), CMD_Offer_Draw ) );
+ break;
+ /* Reject Draw */
+ case MENU_REJECT_DRAW:
+ command2IO( Command( currentMatch->getID(), CMD_Reject_Draw ) );
+ break;
+ /* Resign */
+ case MENU_RESIGN:
+ if( ( whiteInput() == PLAYERLOCAL ) && ( currentMatch->onMove() == WHITE ) )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_White_Resign ) );
+ currentMatch->recvCMD( Command( currentMatch->getID(), CMD_White_Resign ) );
+ }
+ if( ( blackInput() == PLAYERLOCAL ) && ( currentMatch->onMove() == BLACK ) )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Black_Resign ) );
+ currentMatch->recvCMD( Command( currentMatch->getID(), CMD_Black_Resign ) );
+ }
+ break;
+ /* Retract */
+ case MENU_RETRACT:
+ command2IO( Command( currentMatch->getID(), CMD_Retract_Move ) );
+ currentMatch->retract();
+ currentMatch->retract();
+ emit setNotation();
+ if( onMove() == WHITE )
+ emit setStatusBar( WHITE_TURN );
+ else
+ emit setStatusBar( BLACK_TURN );
+ break;
+ /* Move Now */
+ case MENU_MOVE_NOW:
+ command2IO( Command( currentMatch->getID(), CMD_MoveNow ) );
+ break;
+ /* Hint */
+ case MENU_HINT:
+ currentMatch->requestHint();
+ break;
+ /* Orientation */
+ case MENU_ORIENTATION:
+ currentMatch->flip();
+ break;
+ /* Ponder */
+ case MENU_PONDER:
+ if( myResource->OPTION_Ponder )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Ponder ) );
+ }
+ else
+ {
+ command2IO( Command( currentMatch->getID(), CMD_No_Pondering ) );
+ }
+ break;
+ /* Pause */
+ case MENU_PAUSE:
+ currentMatch->setPaused( !currentMatch->paused() );
+ if( currentMatch->paused() )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Pause ) );
+ }
+ else
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Resume ) );
+ }
+ break;
+ /* Pause All */
+ case MENU_PAUSEALL:
+ if( myMatchMap.count() )
+ {
+ for( index = 0; index < myMatchMap.count(); index++ )
+ {
+ if( ( whiteInput() == PLAYERTCP ) || ( blackInput() == PLAYERTCP ) )
+ continue;
+ myMatchMap[index]->setPaused( !myMatchMap[index]->paused() );
+ if( myMatchMap[index]->paused() )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Pause ) );
+ }
+ else
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Resume ) );
+ }
+ }
+ }
+ break;
+ /* Call Flag */
+ case MENU_CALL_FLAG:
+ if( whiteInput() == PLAYERLOCAL )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_White_Called_Flag ) );
+ currentMatch->recvCMD( Command( currentMatch->getID(), CMD_White_Called_Flag ) );
+ }
+ if( blackInput() == PLAYERLOCAL )
+ {
+ command2IO( Command( currentMatch->getID(), CMD_Black_Called_Flag ) );
+ currentMatch->recvCMD( Command( currentMatch->getID(), CMD_Black_Called_Flag ) );
+ }
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// core::thinButtonMenu
+//
+///////////////////////////////////////
+void core::thinButtonMenu( int id, int item )
+{
+ switch( item )
+ {
+ case MENU_SAVE:
+ save( id, FALSE, FALSE );
+ break;
+ case MENU_SAVEAS:
+ save( id, FALSE, TRUE );
+ break;
+ case MENU_PRINT:
+ print( id );
+ break;
+ case MENU_CLOSE:
+ clearMatch( id );
+ break;
+ default:
+ break;
+ }
+}
+
+///////////////////////////////////////
+//
+// core::resetServer
+//
+///////////////////////////////////////
+void core::resetServer( void )
+{
+ command2IO( Command( Null, CMD_Reset_Server ) );
+}
+
+///////////////////////////////////////
+//
+// core::goOffline()
+//
+///////////////////////////////////////
+void core::goOffline(void)
+{
+ unsigned int index(0);
+ io_base *ioPtr(NULL);
+
+ while( index < myIOMap.count() )
+ {
+ if( myIOMap[index]->getType() == io_base::INTERNET )
+ {
+ ioPtr = myIOMap[index];
+
+ if( myIOMap.keyAt(index) != Null )
+ {
+ clearMatch( myIOMap.keyAt(index) );
+ }
+ else
+ {
+ myIOMap.remove( Null );
+ }
+
+ index = 0;
+ continue;
+ }
+ index++;
+ }
+ if( ioPtr != NULL )
+ delete ioPtr;
+}
+
diff --git a/knights/core.h b/knights/core.h
new file mode 100644
index 0000000..5723112
--- /dev/null
+++ b/knights/core.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ core.h - description
+ -------------------
+ begin : Tue Oct 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CORE_H
+#define CORE_H
+
+#include <qwidget.h>
+#include <qtimer.h>
+#include "definitions.h"
+#include "resource.h"
+#include "knightsmap.h"
+#include "idmanager.h"
+#include "io_base.h"
+
+class list_pgn;
+class thinbuttons;
+class match;
+class match_param;
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+typedef KnightsMap<int, match*> MatchMap;
+typedef KnightsMap<int, io_base*> IOMap;
+
+class core : public QWidget
+{
+ Q_OBJECT
+ public:
+ core(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~core();
+ QStringList* notation( void );
+ QString caption( void );
+ bool modified( void );
+ bool paused( void );
+ bool isOnline( void );
+ bool flag( const bool );
+ char onMove( void );
+ char whiteInput( void );
+ char blackInput( void );
+ char inputOnMove( bool reverse=FALSE );
+ void createNewIO( int type, int ID, int side=BLACK, int str=0 );
+ void goOffline(void);
+
+ public slots:
+ match* newMatch( match_param* );
+ bool clearMatch( int id=Null );
+ bool clearAll( void );
+ void setMatch( int );
+ void command2IO( const Command& );
+ void command2Match( const Command& );
+ void resetServer( void );
+ void matchMenu( int );
+ void resize( void );
+ bool save( const int ID, const bool Prompt, const bool SaveAs );
+ bool load( void );
+ bool load( const QString& );
+ bool load( const QString&, const int& );
+ void slot_setNotation( void );
+ void slot_setClocks( void );
+ void slot_setStatusBar( const int&, const QString& );
+ void print( int ID=Null );
+ void review( int );
+ QString clock( const bool );
+
+ signals:
+ void requestResize( void );
+ void setStatusBar( const int &ID, const QString& MSG=QString::null );
+ void setNotation( void );
+ void setClocks( void );
+ void initMatch( void );
+ void serverDestroyed( void );
+
+ protected:
+ bool findMatch( const int );
+ void serverSelfDestruct( void );
+
+ protected slots:
+ void thinButtonMenu( int id, int item );
+
+ private:
+ IDManager myIDManager;
+ resource *myResource;
+ QTimer myCoreClock;
+ thinbuttons *myButtonGroup;
+ list_pgn *listPGN;
+ IOMap myIOMap;
+ MatchMap myMatchMap;
+ match *currentMatch;
+};
+
+#endif
diff --git a/knights/definitions.h b/knights/definitions.h
new file mode 100644
index 0000000..858331d
--- /dev/null
+++ b/knights/definitions.h
@@ -0,0 +1,292 @@
+/***************************************************************************
+ definitions.h - description
+ -------------------
+ begin : Sun Jul 1 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef _DEFINITIONS_H
+#define _DEFINITIONS_H
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif
+
+#ifndef _VERSION_
+# define _VERSION_ "0.6"
+#endif
+
+#define IMAGE_MAX 144
+#define IMAGE_MIN 32
+
+#define CONFIG_VERSION 1
+
+#include <kdebug.h>
+#include <qvaluelist.h>
+
+/*
+ These are used to define the game's states.
+*/
+const int WHITE = 0x00;
+const int BLACK = 0x01;
+const int WHITE_HELPER = 0x02;
+const int BLACK_HELPER = 0x03;
+const int BOTH = 0x04;
+
+const int PLAYERPC = 0x00; // Chess Engine
+const int PLAYEREMAIL = 0x01; // Email Opponent
+const int PLAYERTCP = 0x02; // Internet Chess Engine
+const int PLAYERLOAD = 0x03; // Load from PGN
+
+ /* Add a mask of 0x10 to players that accept user input */
+const int PLAYERLOCAL = 0x10; // Human sitting at the PC
+const int PLAYEREXAMINE = 0x11; // ICS Examine Mode
+
+const int ENGINE_WHITE = 0x01;
+const int ENGINE_WHITE_BK = 0x02;
+const int ENGINE_BLACK = 0x04;
+const int ENGINE_BLACK_BK = 0x08;
+
+ /* Menu Entries */
+
+/*
+ These represent the various choices found
+ throughout the game's menubar.
+*/
+
+/* File Menu */
+const int MENU_NEWGAME = 0x01;
+const int MENU_LOAD = 0x02;
+const int MENU_SAVE = 0x03;
+const int MENU_SAVEAS = 0x04;
+const int MENU_PRINT = 0x05;
+const int MENU_QUIT = 0x06;
+const int MENU_CLOSE = 0x08;
+const int MENU_CLOSEALL = 0x09;
+const int MENU_CONNECT = 0x0A;
+/* Options Menu */
+const int MENU_BINDINGS_DIALOG = 0x13;
+const int MENU_SETTINGS_DIALOG = 0x14;
+const int MENU_INSTALL_THEMES = 0x15;
+/* New Games Menu */
+const int MENU_SOLITARE = 0x21;
+const int MENU_VS_PC = 0x22;
+const int MENU_VS_TCPIP = 0x23;
+const int MENU_VS_EMAIL = 0x24;
+const int MENU_PC_VS_PC = 0x25;
+/* Match Menu */
+const int MENU_RETRACT = 0x31;
+const int MENU_DRAW = 0x32;
+const int MENU_MOVE_NOW = 0x33;
+const int MENU_HINT = 0x34;
+const int MENU_PONDER = 0x35;
+const int MENU_PAUSE = 0x36;
+const int MENU_PAUSEALL = 0x37;
+const int MENU_ORIENTATION = 0x38;
+const int MENU_RESIGN = 0x39;
+const int MENU_CALL_FLAG = 0x3A;
+/* Draw Menu */
+const int MENU_OFFER_DRAW = 0x41;
+const int MENU_ACCEPT_DRAW = 0x42;
+const int MENU_REJECT_DRAW = 0x43;
+const int MENU_IGNORE_DRAW = 0x44;
+/* Seek Menu */
+const int MENU_SEEK = 0x51;
+const int MENU_FINGER = 0x52;
+const int MENU_TELL = 0x53;
+const int MENU_NOTIFY = 0x54;
+const int MENU_ACCEPT_MATCH = 0x55;
+const int MENU_CENSOR = 0x56;
+const int MENU_HISTORY = 0x57;
+const int MENU_ASSESS = 0x58;
+/* View Menu */
+const int MENU_COPY = 0x61;
+const int MENU_SELECT_ALL = 0x62;
+const int MENU_CLEAR_ALL = 0x63;
+const int MENU_FIND = 0x64;
+const int MENU_FIND_NEXT = 0x65;
+const int MENU_ZOOM_IN = 0x66;
+const int MENU_ZOOM_OUT = 0x67;
+/* Tutorial Menu */
+const int MENU_OPEN_TUTORIAL = 0x71;
+
+ /* Messages */
+
+/*
+ The following constants define messages
+ viewed in the statusbar.
+*/
+const int READY = 0x00000000;
+const int WHITE_TURN = 0x00000001;
+const int BLACK_TURN = 0x00000002;
+const int WHITE_WIN = 0x00000003;
+const int BLACK_WIN = 0x00000004;
+const int GAME_DRAW = 0x00000005;
+const int GAME_50_MOVES = 0x00000006;
+const int WAITING = 0x00000007;
+const int ILLEGAL_MOVE = 0x00000008;
+const int NO_MOVE_WHILE_REVIEW = 0x00000009;
+const int LOAD_OK = 0x00000010;
+const int SAVE_OK = 0x00000011;
+const int PAUSED = 0x00000012;
+const int READING_FILE = 0x00000013;
+const int WHITE_DRAW_OFFER = 0x00000014;
+const int BLACK_DRAW_OFFER = 0x00000015;
+const int LOAD_ERROR = 0x00000020;
+const int SAVE_ERROR = 0x00000021;
+const int BOOK_ERROR_1 = 0x00000022;
+const int BOOK_ERROR_2 = 0x00000023;
+const int BOOK_ERROR_3 = 0x00000024;
+const int BOOK_ERROR_4 = 0x00000025;
+const int ENGINE_DIED_ERROR = 0x00000026;
+const int WHITE_RESIGN = 0x00000027;
+const int BLACK_RESIGN = 0x00000028;
+const int WHITE_FLAG = 0x00000029;
+const int BLACK_FLAG = 0x00000030;
+const int WHITE_CALL_FLAG = 0x00000031;
+const int BLACK_CALL_FLAG = 0x00000032;
+const int WHITE_CHECKMATE = 0x00000033;
+const int BLACK_CHECKMATE = 0x00000034;
+const int LOST_CONTACT = 0x00000035;
+const int COMMENT = 0x00010000;
+const int ERROR = 0x00100000;
+
+ /* Variations */
+/*
+ These define the variations on chess
+ that can be supported.
+*/
+
+const int Type_Standard = 0x00000001;
+const int Type_WildCastle = 0x00000002;
+const int Type_NoCastle = 0x00000004;
+const int Type_FischerRandom = 0x00000008;
+const int Type_BugHouse = 0x00000010;
+const int Type_CrazyHouse = 0x00000020;
+const int Type_Losers = 0x00000040;
+const int Type_Suicide = 0x00000080;
+const int Type_Giveaway = 0x00000100;
+const int Type_TwoKings = 0x00000200;
+const int Type_Atomic = 0x00000400;
+const int Type_Kriegspiel = 0x00000800;
+const int Type_ThreeCheck = 0x00001000;
+
+ /* Protocols */
+
+const int XBoard = 0x02;
+const int UCI = 0x04;
+
+ /* Events */
+
+/*
+ These constants represent QEvent types.
+*/
+
+const int EVENT_Del_IO_Net = 0x000003e9;
+
+
+ /* Position Notes */
+
+/*
+ These represent the various NOTES that can appear on a
+ given position
+*/
+
+const char NOTE_NONE = 0x00;
+const char NOTE_HIGHLIGHT = 0x01;
+const char NOTE_SELECT = 0x02;
+const char NOTE_MOVE = 0x10;
+const char NOTE_CASTLE = 0x11;
+const char NOTE_PAWN_DOUBLE = 0x12;
+const char NOTE_ATTACK = 0x20;
+const char NOTE_ENPASSANT = 0x21;
+
+ /* Chessmen */
+
+/*
+ These represent the various chessmen, or Types of chessmen
+ found on the playing board.
+*/
+const char Null = -1;
+const char King = 0;
+const char Queen = 1;
+const char Bishop = 2;
+const char Knight = 3;
+const char Rook = 4;
+const char Pawn = 5;
+
+ /* ICS Game Modes */
+
+const char ICS_Normal = 0;
+const char ICS_Examine = 1;
+const char ICS_Observe = 2;
+const char ICS_Movelist = 3;
+
+typedef struct ThemeHeader
+{
+ QString name;
+ QString version;
+ QString author;
+ QString authorEmail;
+ QString authorWWW;
+ QString notes;
+};
+
+typedef struct ChessMove
+{
+ char fromFile;
+ char fromRank;
+ char toFile;
+ char toRank;
+ char Promote;
+ char ManTaken;
+ char SAN[8];
+ char CAN[6];
+unsigned char NAG;
+ /* Following used for ICS Only */
+ char ICS_Mode;
+ char ICS_PawnPushFile;
+ int ICS_MoveCounter;
+ bool ICS_OnMove;
+ bool ICS_ClockTicking;
+};
+
+typedef struct Chessman
+{
+ bool Army;
+ char Type;
+ char File;
+ char Rank;
+};
+
+typedef struct Position
+{
+ char File;
+ char Rank;
+ char ManPtr;
+ char Note;
+};
+
+/* Time Control Period */
+typedef struct TCP
+{
+ int Moves;
+ int Seconds;
+ int Increment;
+};
+
+typedef QValueList<TCP> TCPList;
+
+#endif
diff --git a/knights/dlg_challenge.cpp b/knights/dlg_challenge.cpp
new file mode 100644
index 0000000..51a983f
--- /dev/null
+++ b/knights/dlg_challenge.cpp
@@ -0,0 +1,159 @@
+/***************************************************************************
+ dlg_challenge.cpp - description
+ -------------------
+ begin : Sun Jan 20 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qregexp.h>
+#include "dlg_challenge.moc"
+
+dlg_challenge::dlg_challenge(QWidget *parent, const char *name, resource *Rsrc ) :
+ KDialogBase( parent,
+ name,
+ FALSE,
+ i18n("You've Been Challenged:"),
+ User1|User2,
+ Ok,
+ TRUE,
+ i18n("Accept"),
+ i18n("Decline") )
+{
+ Resource = Rsrc;
+
+ BOX_Parent = makeVBoxMainWidget();
+
+ LABEL_Headline = new QLabel( BOX_Parent );
+ COMBO_Rated = new KComboBox( BOX_Parent );
+ BOX_Time = new QHBox( BOX_Parent );
+ BOX_White = new QGroupBox( 2, Qt::Horizontal, "-", BOX_Time );
+ BOX_WhiteBase = new QSpinBox( BOX_White );
+ LABEL_WhiteBase = new QLabel( BOX_White );
+ BOX_WhiteInc = new QSpinBox( BOX_White );
+ LABEL_WhiteInc = new QLabel( BOX_White );
+ BOX_Black = new QGroupBox( 2, Qt::Horizontal, "-", BOX_Time );
+ BOX_BlackBase = new QSpinBox( BOX_Black );
+ LABEL_BlackBase = new QLabel( BOX_Black );
+ BOX_BlackInc = new QSpinBox( BOX_Black );
+ LABEL_BlackInc = new QLabel( BOX_Black );
+ BUTTON_TimeOdds = new QCheckBox( i18n("Time Odds Match"),BOX_Parent );
+
+ LABEL_Headline->setAlignment( Qt::AlignCenter );
+ COMBO_Rated->setEditable( FALSE );
+ COMBO_Rated->insertItem( i18n("Unrated"), 0 );
+ COMBO_Rated->insertItem( i18n("Rated"), 1 );
+
+ BOX_WhiteBase->setMinValue( 0 );
+ BOX_WhiteInc->setMinValue( 0 );
+ BOX_WhiteBase->setMaxValue( 300 );
+ BOX_WhiteInc->setMaxValue( 300 );
+ BOX_WhiteBase->setSuffix( i18n(" min.") );
+ BOX_WhiteInc->setSuffix( i18n(" sec.") );
+ LABEL_WhiteBase->setText( i18n( "Base Time" ) );
+ LABEL_WhiteInc->setText( i18n( "Increment" ) );
+
+ BOX_BlackBase->setMinValue( 0 );
+ BOX_BlackInc->setMinValue( 0 );
+ BOX_BlackBase->setMaxValue( 300 );
+ BOX_BlackInc->setMaxValue( 300 );
+ BOX_BlackBase->setSuffix( i18n(" min.") );
+ BOX_BlackInc->setSuffix( i18n(" sec.") );
+ LABEL_BlackBase->setText( i18n( "Base Time" ) );
+ LABEL_BlackInc->setText( i18n( "Increment" ) );
+
+ showButton( User1, TRUE );
+ showButton( User2, TRUE );
+ enableButton( User1, TRUE );
+ enableButton( User2, TRUE );
+ show();
+}
+
+dlg_challenge::~dlg_challenge()
+{
+}
+
+void dlg_challenge::setValues( const QString &string, const QString &local )
+{
+ /* we only need the first line, strip the rest */
+ QString myString( string.section('\n', 0, 0) );
+ QStringList list;
+
+ /*remove all the white space between the rating brackets*/
+ myString.replace( QRegExp("\\(\\s"), "(" );
+ myString.replace( QRegExp("\\s\\)"), ")" );
+
+ list = QStringList::split( QChar(' '), myString, FALSE );
+ list[7].replace(QRegExp("\\."), "");
+ if( list[0] == local )
+ {
+ localRating = list[1];
+ otherPlayer = list[2];
+ otherRating = list[3];
+ }
+ else
+ {
+ otherPlayer = list[0];
+ otherRating = list[1];
+ localRating = list[3];
+ }
+ LABEL_Headline->setText( i18n("%1 %2 vs. %3 %4\nin a %5 match.")
+ .arg(local).arg(localRating).arg(otherPlayer).arg(otherRating).arg(list[5]) );
+ if( list[4].lower() == "rated" )
+ {
+ COMBO_Rated->setCurrentItem(1);
+ }
+ else
+ {
+ COMBO_Rated->setCurrentItem(0);
+ }
+ BOX_WhiteBase->setValue( list[6].toInt() );
+ BOX_WhiteInc->setValue( list[7].toInt() );
+ BOX_BlackBase->setValue( list[6].toInt() );
+ BOX_BlackInc->setValue( list[7].toInt() );
+ BOX_White->setTitle( i18n("Time Controls") );
+ BOX_Black->setTitle( i18n("Time Controls") );
+// BOX_Black->setEnabled( FALSE );
+// BUTTON_TimeOdds->setChecked( FALSE );
+
+ connect( COMBO_Rated, SIGNAL( activated(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BOX_WhiteBase, SIGNAL( valueChanged(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BOX_WhiteInc, SIGNAL( valueChanged(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BOX_BlackBase, SIGNAL( valueChanged(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BOX_BlackInc, SIGNAL( valueChanged(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BUTTON_TimeOdds, SIGNAL( stateChanged(int) ), this, SLOT( slot_changed(int) ) );
+ connect( BUTTON_TimeOdds, SIGNAL( toggled(bool) ), this, SLOT( slot_timeOdds(bool) ) );
+}
+
+QString dlg_challenge::values( void )
+{
+ QString match;
+ match = QString("match %1").arg(otherPlayer);
+ if( COMBO_Rated->currentItem() == 0 )
+ match += " unrated";
+ else
+ match += " rated";
+ match += QString(" %1 %1").arg(BOX_WhiteBase->value()).arg(BOX_WhiteInc->value());
+ if( BUTTON_TimeOdds->isChecked() )
+ match += QString(" %1 %1").arg(BOX_BlackBase->value()).arg(BOX_BlackInc->value());
+ return match;
+}
+
+void dlg_challenge::slot_changed( int )
+{
+ setButtonText( User1, i18n("Counter Offer") );
+}
+
+void dlg_challenge::slot_timeOdds( bool state )
+{
+ BOX_Black->setEnabled( state );
+}
diff --git a/knights/dlg_challenge.h b/knights/dlg_challenge.h
new file mode 100644
index 0000000..2fbfb68
--- /dev/null
+++ b/knights/dlg_challenge.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ dlg_challenge.h - description
+ -------------------
+ begin : Sun Jan 20 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_CHALLENGE_H
+#define DLG_CHALLENGE_H
+
+#include <kdialogbase.h>
+#include <kcombobox.h>
+#include <qgroupbox.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_challenge : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_challenge(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~dlg_challenge();
+ void setValues( const QString&, const QString& );
+ QString values( void );
+ public slots:
+ void slot_changed( int );
+ void slot_timeOdds( bool );
+ private:
+ resource *Resource;
+ QString otherPlayer;
+ QString localRating;
+ QString otherRating;
+
+ QVBox *BOX_Parent;
+ QLabel *LABEL_Headline;
+ KComboBox *COMBO_Rated;
+ QHBox *BOX_Time;
+ QGroupBox *BOX_White;
+ QSpinBox *BOX_WhiteBase;
+ QSpinBox *BOX_WhiteInc;
+ QLabel *LABEL_WhiteBase;
+ QLabel *LABEL_WhiteInc;
+ QGroupBox *BOX_Black;
+ QSpinBox *BOX_BlackBase;
+ QSpinBox *BOX_BlackInc;
+ QLabel *LABEL_BlackBase;
+ QLabel *LABEL_BlackInc;
+ QCheckBox *BUTTON_TimeOdds;
+};
+
+#endif
diff --git a/knights/dlg_engine.cpp b/knights/dlg_engine.cpp
new file mode 100644
index 0000000..c2f767e
--- /dev/null
+++ b/knights/dlg_engine.cpp
@@ -0,0 +1,226 @@
+/***************************************************************************
+ dlg_engine.cpp - description
+ -------------------
+ begin : Wed Jul 18 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kfiledialog.h>
+#include <kicontheme.h>
+#include "dlg_engine.moc"
+
+dlg_engine::dlg_engine(QWidget *parent, const char *name, resource *Rsrc, QString ItemName ) :
+ KDialogBase( parent,
+ name,
+ TRUE,
+ i18n("Configure Engine"),
+ Help|Ok|Apply|Cancel,
+ Ok,
+ TRUE )
+{
+ Resource = Rsrc;
+ Name = ItemName;
+
+ BOX_Parent = makeVBoxMainWidget();
+ BOX_NameProto = new QHBox( BOX_Parent );
+ BOX_Name = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Engine Name" ),
+ BOX_NameProto );
+ EDIT_Name = new KLineEdit( BOX_Name );
+ BOX_Protocol = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Protocol" ),
+ BOX_NameProto );
+ EDIT_Protocol = new KComboBox( BOX_Protocol );
+ BOX_Filename = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Engine Filename" ),
+ BOX_Parent );
+ EDIT_Filename = new KLineEdit( BOX_Filename );
+ BUTTON_Filename = new QPushButton( BOX_Filename );
+ BOX_Arguments = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Command Line Arguments" ),
+ BOX_Parent );
+ EDIT_Arguments = new KLineEdit( BOX_Arguments );
+ BOX_LogFile = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Log File" ),
+ BOX_Parent );
+ EDIT_LogFile = new KLineEdit( BOX_LogFile );
+ BUTTON_LogFile = new QPushButton( BOX_LogFile );
+ setMainWidget( BOX_Parent );
+ BUTTON_Filename->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ BUTTON_LogFile->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ EDIT_Name->setMinimumWidth( 150 );
+ EDIT_Filename->setMinimumWidth( 300 );
+ EDIT_Arguments->setMinimumWidth( 300 );
+ /* Protocol ComboBox */
+ EDIT_Protocol->insertItem( QString( "XBoard" ) );
+ EDIT_Protocol->insertItem( QString( "UCI" ) );
+ EDIT_Protocol->setEditable( FALSE );
+ /* Load in data if this is a modification */
+ if( !Name.isEmpty() )
+ {
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).Name == Name ) break;
+ }
+ EDIT_Name->setText( (*enginesIT).Name );
+ EDIT_Filename->setText( (*enginesIT).Filename );
+ EDIT_Arguments->setText( (*enginesIT).Arguments );
+ EDIT_LogFile->setText( (*enginesIT).LogFile );
+ switch( (*enginesIT).Protocol )
+ {
+ case XBoard:
+ EDIT_Protocol->setCurrentItem(0);
+ break;
+ case UCI:
+ EDIT_Protocol->setCurrentItem(1);
+ break;
+ default:
+ break;
+ }
+ }
+ /* Init the buttons */
+ showButtonCancel( TRUE );
+ showButtonOK( TRUE );
+ showButtonApply( TRUE );
+ showButton( Help, TRUE );
+
+ enableButtonCancel( TRUE );
+ enableButtonOK( TRUE );
+ enableButtonApply( FALSE );
+ enableButton( Help, TRUE );
+
+ setHelp( QString( "configure-engines" ) );
+ /* Make Connections */
+ connect( BUTTON_Filename, SIGNAL( clicked() ), this, SLOT( slotFilenameDialog() ) );
+ connect( BUTTON_LogFile, SIGNAL( clicked() ), this, SLOT( slotLogFileDialog() ) );
+ connect( EDIT_Protocol, SIGNAL( activated(int) ), this, SLOT( slotProtocol(int) ) );
+ show();
+}
+///////////////////////////////////////
+//
+// dlg_engine::~dlg_engine
+//
+///////////////////////////////////////
+dlg_engine::~dlg_engine()
+{
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotOk
+//
+///////////////////////////////////////
+void dlg_engine::slotOk( void )
+{
+ slotApply();
+ slotDelayedDestruct();
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotApply
+//
+///////////////////////////////////////
+void dlg_engine::slotApply( void )
+{
+ engineResource newEngine;
+
+ if( Name.isEmpty() )
+ {
+ enginesIT = Resource->engines.append( newEngine );
+ Name = "notemptyanymore";
+ (*enginesIT).Wins = 0;
+ (*enginesIT).Losses = 0;
+ (*enginesIT).Draws = 0;
+ (*enginesIT).CurrentRef = 0;
+ }
+ (*enginesIT).Name = EDIT_Name->text();
+ (*enginesIT).Filename = EDIT_Filename->text();
+ (*enginesIT).Arguments = EDIT_Arguments->text();
+ (*enginesIT).LogFile = EDIT_LogFile->text();
+ switch( EDIT_Protocol->currentItem() )
+ {
+ case 0:
+ (*enginesIT).Protocol = XBoard;
+ break;
+ case 1:
+ (*enginesIT).Protocol = UCI;
+ break;
+ default:
+ break;
+ }
+ enableButtonApply( FALSE );
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotCancel
+//
+///////////////////////////////////////
+void dlg_engine::slotCancel( void )
+{
+ slotDelayedDestruct();
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotFilenameDialog
+//
+///////////////////////////////////////
+void dlg_engine::slotFilenameDialog( void )
+{
+ QString temp;
+ int tmp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ this,
+ QString( "Find Engine..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_Filename->setText( temp );
+ if( EDIT_Name->text().isEmpty() )
+ {
+ tmp = temp.findRev( '/' );
+ EDIT_Name->setText( temp.remove( 0, tmp + 1 ) );
+ }
+ enableButtonApply( TRUE );
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotLogFileDialog
+//
+///////////////////////////////////////
+void dlg_engine::slotLogFileDialog( void )
+{
+ QString temp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ this,
+ QString( "Find Log..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_LogFile->setText( temp );
+ enableButtonApply( TRUE );
+}
+///////////////////////////////////////
+//
+// dlg_engine::slotProtocol
+//
+///////////////////////////////////////
+void dlg_engine::slotProtocol( int Index )
+{
+ if(Index); // No-op to stop compile warning.
+ enableButtonApply( TRUE );
+}
+
diff --git a/knights/dlg_engine.h b/knights/dlg_engine.h
new file mode 100644
index 0000000..0bd13af
--- /dev/null
+++ b/knights/dlg_engine.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ dlg_engine.h - description
+ -------------------
+ begin : Wed Jul 18 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_ENGINE_H
+#define DLG_ENGINE_H
+
+#include <kdialogbase.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <qgroupbox.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qstring.h>
+#include "definitions.h"
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_engine : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_engine(QWidget *parent=0, const char *name=0, resource *Rsrc=0, QString ItemName="" );
+ ~dlg_engine();
+
+ public slots:
+ void slotOk( void );
+ void slotApply( void );
+ void slotCancel( void );
+ void slotFilenameDialog( void );
+ void slotLogFileDialog( void );
+ void slotProtocol( int Index );
+
+ private:
+ engineList::Iterator enginesIT;
+ resource *Resource;
+ QString Name;
+
+ QVBox *BOX_Parent;
+ QHBox *BOX_NameProto;
+
+ QGroupBox *BOX_Name;
+ KLineEdit *EDIT_Name;
+
+ QGroupBox *BOX_Protocol;
+ KComboBox *EDIT_Protocol;
+
+ QGroupBox *BOX_Filename;
+ KLineEdit *EDIT_Filename;
+ QPushButton *BUTTON_Filename;
+
+ QGroupBox *BOX_LogFile;
+ KLineEdit *EDIT_LogFile;
+ QPushButton *BUTTON_LogFile;
+
+ QGroupBox *BOX_Arguments;
+ KLineEdit *EDIT_Arguments;
+};
+
+#endif
diff --git a/knights/dlg_login.cpp b/knights/dlg_login.cpp
new file mode 100644
index 0000000..103ff91
--- /dev/null
+++ b/knights/dlg_login.cpp
@@ -0,0 +1,161 @@
+/***************************************************************************
+ dlg_login.cpp - description
+ -------------------
+ begin : Sat Sep 29 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "dlg_login.moc"
+
+dlg_login::dlg_login(QWidget *parent, const char *name, resource *rsrc) :
+ KDialogBase(parent, name, TRUE, i18n("Login Prompt"), Help|Ok|Cancel, Ok,TRUE )
+{
+ serverList::Iterator i;
+ serverList::Iterator currentServer;
+ int counter = 0;
+
+ myResource = rsrc;
+
+ BOX_Parent = makeVBoxMainWidget();
+
+ /* Select which server to connect to */
+ GROUP_Select_Server = new QGroupBox( 1, Qt::Vertical, i18n( "Select Server" ), BOX_Parent );
+
+ COMBO_Select_Server = new KComboBox ( GROUP_Select_Server );
+ COMBO_Select_Server->setEditable( FALSE );
+
+ /* fill the combobox with servers */
+ for(i = myResource->servers.begin(); i != myResource->servers.end(); i++)
+ {
+ COMBO_Select_Server->insertItem((*i).Name);
+ if((*i).CurrentRef == TRUE)
+ {
+ COMBO_Select_Server->setCurrentItem(counter);
+ currentServer = i;
+ }
+ counter++;
+ }
+ /* connect to right signal to the combobox */
+ connect( COMBO_Select_Server, SIGNAL( activated(const QString &) ), this, SLOT( slotUpdateUser(const QString &) ) );
+
+ GROUP_Username = new QGroupBox( 1, Qt::Horizontal, i18n("User info"), BOX_Parent);
+ BOX_ALIGN = new QHBox( GROUP_Username );
+ BOX_TEXT = new QVBox( BOX_ALIGN );
+ TEXT_Login = new QLabel( BOX_TEXT );
+ TEXT_Password = new QLabel( BOX_TEXT );
+
+ TEXT_Login->setText( i18n("Login:") );
+ TEXT_Password->setText( i18n("Password:") );
+
+ BOX_EDIT = new QVBox( BOX_ALIGN );
+ EDIT_Login = new KLineEdit( BOX_EDIT );
+ EDIT_Password = new KLineEdit( BOX_EDIT );
+
+ CHECKBOX_GUEST = new QCheckBox(i18n("Log in as guest"), GROUP_Username);
+
+ EDIT_Password->setEchoMode( QLineEdit::Password );
+
+ connect(CHECKBOX_GUEST, SIGNAL(toggled(bool)), this, SLOT(slotGuestToggle(bool)));
+
+ /* Init the buttons */
+ showButtonCancel( TRUE );
+ showButtonOK( TRUE );
+ showButton( Help, TRUE );
+
+ enableButtonCancel( TRUE );
+ enableButtonOK( TRUE );
+ enableButton( Help, TRUE );
+ setButtonOKText( i18n("Login"), i18n("Log in to the chess server using this name and password.") );
+ setButtonCancelText( i18n("Cancel"), i18n("Abort logging into the server") );
+ setHelp("prefs");
+ disableResize();
+ show();
+ /* make sure the username for the default server is displayed */
+ slotUpdateUser((*currentServer).Name);
+}
+///////////////////////////////////////
+//
+// dlg_login::~dlg_login
+//
+///////////////////////////////////////
+dlg_login::~dlg_login()
+{
+}
+///////////////////////////////////////
+//
+// dlg_login::slotOk
+//
+///////////////////////////////////////
+void dlg_login::slotOk( void )
+{
+ if(BOX_ALIGN->isEnabled())
+ {
+ emit login(EDIT_Login->text(), EDIT_Password->text());
+ }
+ else
+ {
+ emit login("guest", "");
+ }
+ emit okClicked();
+ slotDelayedDestruct();
+}
+
+///////////////////////////////////////
+//
+// dlg_login::slotGuestToggle
+//
+///////////////////////////////////////
+void dlg_login::slotGuestToggle( bool on )
+{
+ BOX_ALIGN->setEnabled(!on);
+}
+
+///////////////////////////////////////
+//
+// dlg_login::slotUpdateUser
+//
+///////////////////////////////////////
+void dlg_login::slotUpdateUser(const QString &name)
+{
+ /* this function retrieves the correct serverResource from
+ the resources and uses that to fill in the username and
+ password fields */
+ serverList::Iterator i;
+
+ for(i = myResource->servers.begin(); i != myResource->servers.end(); i++)
+ {
+ if((*i).CurrentRef)
+ {
+ (*i).CurrentRef = FALSE;
+ }
+ if((*i).Name == name )
+ {
+ (*i).CurrentRef = TRUE;
+ EDIT_Login->setText((*i).UserName);
+ EDIT_Password->setText((*i).Password);
+ server = &(*i);
+ }
+ }
+}
+
+///////////////////////////////////////
+//
+// dlg_login::slotUpdateUser
+//
+///////////////////////////////////////
+void dlg_login::disableServerSelect()
+{
+ COMBO_Select_Server->setEnabled(false);
+}
+
+
diff --git a/knights/dlg_login.h b/knights/dlg_login.h
new file mode 100644
index 0000000..1c02f18
--- /dev/null
+++ b/knights/dlg_login.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ dlg_login.h - description
+ -------------------
+ begin : Sat Sep 29 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_LOGIN_H
+#define DLG_LOGIN_H
+
+#include <qwidget.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+
+#include <kdialogbase.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr. / Alexander Wels
+ */
+
+class dlg_login : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ dlg_login(QWidget *parent, const char *name=0, resource *rsrc = NULL);
+ ~dlg_login();
+ void disableServerSelect();
+
+ public slots:
+ void slotOk( void );
+ void slotGuestToggle( bool );
+ void slotUpdateUser(const QString&);
+
+ signals:
+ void login(QString userName, QString passWord);
+
+ private:
+ QVBox *BOX_Parent;
+ QVBox *BOX_TEXT;
+ QVBox *BOX_EDIT;
+ QHBox *BOX_ALIGN;
+ KLineEdit *EDIT_Login;
+ KLineEdit *EDIT_Password;
+ QLabel *TEXT_Login;
+ QLabel *TEXT_Password;
+ QCheckBox *CHECKBOX_GUEST;
+ QGroupBox *GROUP_Select_Server;
+ QGroupBox *GROUP_Username;
+ KComboBox *COMBO_Select_Server;
+
+ resource *myResource;
+ struct serverResource *server;
+};
+
+#endif
diff --git a/knights/dlg_newmatch.cpp b/knights/dlg_newmatch.cpp
new file mode 100644
index 0000000..ff85497
--- /dev/null
+++ b/knights/dlg_newmatch.cpp
@@ -0,0 +1,385 @@
+/***************************************************************************
+ dlg_newmatch.cpp - description
+ -------------------
+ begin : Tue Jun 25 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "dlg_newmatch.moc"
+#include <kcombobox.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qspinbox.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qgrid.h>
+#include "resource.h"
+#include "dlg_selectengine.h"
+#include "dlg_selectemail.h"
+
+#define _TYPE_HUMAN_ 0
+#define _TYPE_PC_ 1
+#define _TYPE_EMAIL_ 2
+
+dlg_newmatch::dlg_newmatch(QWidget *parent, const char *name, resource *Rsrc ) :
+KDialogBase(parent, name, TRUE, i18n("Start a New Match"), Cancel|Ok|Help, Ok, TRUE )
+{
+ myResource = Rsrc;
+ Param = new match_param( myResource );
+ BOX_Parent = makeHBoxMainWidget();
+ BOX_Players = new QVBox( BOX_Parent );
+
+ BOX_White = new QGroupBox(3, Qt::Horizontal, i18n("White"), BOX_Players );
+ BOX_Black = new QGroupBox(3, Qt::Horizontal, i18n("Black"), BOX_Players );
+
+ IMAGE_White = new QLabel( BOX_White );
+ IMAGE_Black = new QLabel( BOX_Black );
+
+ BOX_White_Detail = new QVBox( BOX_White );
+ BOX_Black_Detail = new QVBox( BOX_Black );
+
+ LABEL_White_Name = new QLabel( BOX_White_Detail );
+ LABEL_Black_Name = new QLabel( BOX_Black_Detail );
+
+ GROUP_White_Type = new QButtonGroup( 3, Qt::Vertical, BOX_White_Detail );
+ GROUP_White_Type->setExclusive( TRUE );
+ RADIO_White_Human = new QRadioButton( i18n("Human"), GROUP_White_Type );
+ RADIO_White_PC = new QRadioButton( i18n("Computer"), GROUP_White_Type );
+ RADIO_White_Email = new QRadioButton( i18n("Email"), GROUP_White_Type );
+ connect( GROUP_White_Type, SIGNAL( clicked(int)), this, SLOT( slotWhiteType(int)));
+
+ GROUP_Black_Type = new QButtonGroup( 3, Qt::Vertical, BOX_Black_Detail );
+ GROUP_Black_Type->setExclusive( TRUE );
+ RADIO_Black_Human = new QRadioButton( i18n("Human"), GROUP_Black_Type );
+ RADIO_Black_PC = new QRadioButton( i18n("Computer"), GROUP_Black_Type );
+ RADIO_Black_Email = new QRadioButton( i18n("Email"), GROUP_Black_Type );
+ connect( GROUP_Black_Type, SIGNAL( clicked(int)), this, SLOT( slotBlackType(int)));
+
+ /* Disable Unconfigured Types */
+ if( !myResource->engines.count() )
+ {
+ RADIO_White_PC->setEnabled( FALSE );
+ RADIO_Black_PC->setEnabled( FALSE );
+ }
+ if( 1 )
+ {
+ RADIO_White_Email->setEnabled( FALSE );
+ RADIO_Black_Email->setEnabled( FALSE );
+ }
+
+ /* Time for White */
+ GRID_White_Time = new QGrid( 2, Qt::Horizontal, BOX_White );
+ LABEL_White_Base = new QLabel( i18n("Base Time:"), GRID_White_Time );
+ SPIN_White_Base = new QSpinBox( 0, 120, 1, GRID_White_Time );
+ SPIN_White_Base->setSuffix( i18n(" min.") );
+ connect( SPIN_White_Base, SIGNAL( valueChanged(int)), this, SLOT( slotWhiteBase(int)));
+
+ LABEL_White_Moves = new QLabel( i18n("Moves Per Base Time"), GRID_White_Time );
+ SPIN_White_Moves = new QSpinBox( 0, 100, 5, GRID_White_Time );
+ SPIN_White_Moves->setSuffix( i18n(" moves") );
+ connect( SPIN_White_Moves, SIGNAL( valueChanged(int)), this, SLOT( slotWhiteMoves(int)));
+
+ LABEL_White_Inc = new QLabel( i18n("Increment Per Move"), GRID_White_Time );
+ SPIN_White_Inc = new QSpinBox( 0, 120, 1, GRID_White_Time );
+ SPIN_White_Inc->setSuffix( i18n(" sec.") );
+ connect( SPIN_White_Inc, SIGNAL( valueChanged(int)), this, SLOT( slotWhiteInc(int)));
+
+ /* Time for Black */
+ GRID_Black_Time = new QGrid( 2, Qt::Horizontal, BOX_Black );
+ LABEL_Black_Base = new QLabel( i18n("Base Time:"), GRID_Black_Time );
+ SPIN_Black_Base = new QSpinBox( 0, 120, 1, GRID_Black_Time );
+ SPIN_Black_Base->setSuffix( i18n(" min.") );
+ connect( SPIN_Black_Base, SIGNAL( valueChanged(int)), this, SLOT( slotBlackBase(int)));
+
+ LABEL_Black_Moves = new QLabel( i18n("Moves Per Base Time"), GRID_Black_Time );
+ SPIN_Black_Moves = new QSpinBox( 0, 100, 5, GRID_Black_Time );
+ SPIN_Black_Moves->setSuffix( i18n(" moves") );
+ connect( SPIN_Black_Moves, SIGNAL( valueChanged(int)), this, SLOT( slotBlackMoves(int)));
+
+ LABEL_Black_Inc = new QLabel( i18n("Increment Per Move"), GRID_Black_Time );
+ SPIN_Black_Inc = new QSpinBox( 0, 120, 1, GRID_Black_Time );
+ SPIN_Black_Inc->setSuffix( i18n(" sec.") );
+ connect( SPIN_Black_Inc, SIGNAL( valueChanged(int)), this, SLOT( slotBlackInc(int)));
+
+ setTCP();
+ setTypes();
+ setNames();
+ setImages();
+ setHelp( QString( "new-match-dialog" ) );
+}
+
+dlg_newmatch::~dlg_newmatch()
+{
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::setTCP
+//
+///////////////////////////////////////
+void dlg_newmatch::setTCP( void )
+{
+ TCPList tmpList( Param->time(WHITE) );
+ TCP tmpTCP = tmpList[0];
+
+ SPIN_White_Base->setValue( tmpTCP.Seconds / 60 );
+ SPIN_White_Moves->setValue( tmpTCP.Moves );
+ SPIN_White_Inc->setValue( tmpTCP.Increment );
+
+ tmpList = Param->time(BLACK);
+ tmpTCP = tmpList[0];
+
+ SPIN_Black_Base->setValue( tmpTCP.Seconds / 60 );
+ SPIN_Black_Moves->setValue( tmpTCP.Moves );
+ SPIN_Black_Inc->setValue( tmpTCP.Increment );
+}
+///////////////////////////////////////
+//
+// dlg_newmatch::setTypes
+//
+///////////////////////////////////////
+void dlg_newmatch::setTypes( void )
+{
+ switch( Param->type(WHITE) )
+ {
+ case PLAYERPC:
+ GROUP_White_Type->setButton( _TYPE_PC_ );
+ break;
+ case PLAYEREMAIL:
+ GROUP_White_Type->setButton( _TYPE_EMAIL_ );
+ break;
+ case PLAYERLOCAL:
+ default:
+ GROUP_White_Type->setButton( _TYPE_HUMAN_ );
+ slotWhiteType( _TYPE_HUMAN_ );
+ break;
+ }
+ if( GROUP_White_Type->selected() != _TYPE_HUMAN_ )
+ {
+ if( !GROUP_White_Type->selected()->isEnabled() )
+ {
+ GROUP_White_Type->setButton( _TYPE_HUMAN_ );
+ slotWhiteType( _TYPE_HUMAN_ );
+ }
+ }
+ else
+ {
+ Param->setType( WHITE, PLAYERLOCAL );
+ GROUP_White_Type->setButton( _TYPE_HUMAN_ );
+ }
+
+ switch( Param->type(BLACK) )
+ {
+ case PLAYERPC:
+ GROUP_Black_Type->setButton( _TYPE_PC_ );
+ break;
+ case PLAYEREMAIL:
+ GROUP_Black_Type->setButton( _TYPE_EMAIL_ );
+ break;
+ case PLAYERLOCAL:
+ default:
+ GROUP_Black_Type->setButton( _TYPE_HUMAN_ );
+ slotBlackType( _TYPE_HUMAN_ );
+ break;
+ }
+ if( GROUP_Black_Type->selected() != _TYPE_HUMAN_ )
+ {
+ if( !GROUP_Black_Type->selected()->isEnabled() )
+ {
+ GROUP_Black_Type->setButton( _TYPE_HUMAN_ );
+ slotBlackType( _TYPE_HUMAN_ );
+ }
+ }
+ else
+ {
+ Param->setType( BLACK, PLAYERLOCAL );
+ GROUP_Black_Type->setButton( _TYPE_HUMAN_ );
+ }
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::setImages
+//
+///////////////////////////////////////
+void dlg_newmatch::setImages( void )
+{
+ IMAGE_White->setPixmap( Param->image( WHITE ) );
+ IMAGE_Black->setPixmap( Param->image( BLACK ) );
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::setNames
+//
+///////////////////////////////////////
+void dlg_newmatch::setNames( void )
+{
+ LABEL_White_Name->setText( Param->name( WHITE ) );
+ LABEL_Black_Name->setText( Param->name( BLACK ) );
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotWhiteType
+//
+///////////////////////////////////////
+void dlg_newmatch::slotWhiteType( int type )
+{
+ if( type == _TYPE_PC_ )
+ {
+ EngineSelect = new dlg_selectengine( this, myResource, WHITE );
+ connect( EngineSelect, SIGNAL( valuesChanged() ), this, SLOT( slotReparse() ) );
+ EngineSelect->exec();
+ Param->setType( WHITE, PLAYERPC );
+ }
+ else if( type == _TYPE_EMAIL_ )
+ {
+ EmailSelect = new dlg_selectemail( this, myResource );
+ connect( EmailSelect, SIGNAL( valuesChanged() ), this, SLOT( slotReparse() ) );
+ EmailSelect->exec();
+ Param->setType( WHITE, PLAYEREMAIL );
+ }
+ else
+ {
+ Param->setType( WHITE, PLAYERLOCAL );
+ }
+ setNames();
+ setImages();
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotWhiteBase
+//
+///////////////////////////////////////
+void dlg_newmatch::slotWhiteBase( int time )
+{
+ TCPList tmpList( Param->time(WHITE) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Seconds = time * 60;
+ tmpList[0] = tmpTCP;
+ Param->setTime( WHITE, tmpList );
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotWhiteMoves
+//
+///////////////////////////////////////
+void dlg_newmatch::slotWhiteMoves( int time )
+{
+ TCPList tmpList( Param->time(WHITE) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Moves = time;
+ tmpList[0] = tmpTCP;
+ Param->setTime( WHITE, tmpList );
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotWhiteInc
+//
+///////////////////////////////////////
+void dlg_newmatch::slotWhiteInc( int time )
+{
+ TCPList tmpList( Param->time(WHITE) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Increment = time;
+ tmpList[0] = tmpTCP;
+ Param->setTime( WHITE, tmpList );
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotBlackType
+//
+///////////////////////////////////////
+void dlg_newmatch::slotBlackType( int type )
+{
+ if( type == _TYPE_PC_ )
+ {
+ EngineSelect = new dlg_selectengine( this, myResource, BLACK );
+ connect( EngineSelect, SIGNAL( valuesChanged() ), this, SLOT( slotReparse() ) );
+ EngineSelect->exec();
+ Param->setType( BLACK, PLAYERPC );
+ }
+ else if( type == _TYPE_EMAIL_ )
+ {
+ EmailSelect = new dlg_selectemail( this, myResource );
+ connect( EmailSelect, SIGNAL( valuesChanged() ), this, SLOT( slotReparse() ) );
+ EmailSelect->exec();
+ Param->setType( BLACK, PLAYEREMAIL );
+ }
+ else
+ {
+ Param->setType( BLACK, PLAYERLOCAL );
+ }
+ setNames();
+ setImages();
+}
+
+///////////////////////////////////////
+//
+// dlg_newmatch::slotBlackBase
+//
+///////////////////////////////////////
+void dlg_newmatch::slotBlackBase( int time )
+{
+ TCPList tmpList( Param->time(BLACK) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Seconds = time * 60;
+ tmpList[0] = tmpTCP;
+ Param->setTime( BLACK, tmpList );
+}
+///////////////////////////////////////
+//
+// dlg_newmatch::slotBlackMoves
+//
+///////////////////////////////////////
+void dlg_newmatch::slotBlackMoves( int time )
+{
+ TCPList tmpList( Param->time(BLACK) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Moves = time;
+ tmpList[0] = tmpTCP;
+ Param->setTime( BLACK, tmpList );
+}
+///////////////////////////////////////
+//
+// dlg_newmatch::slotBlackInc
+//
+///////////////////////////////////////
+void dlg_newmatch::slotBlackInc( int time )
+{
+ TCPList tmpList( Param->time(BLACK) );
+ TCP tmpTCP = tmpList[0];
+ tmpTCP.Increment = time;
+ tmpList[0] = tmpTCP;
+ Param->setTime( BLACK, tmpList );
+}
+///////////////////////////////////////
+//
+// dlg_newmatch::slotReparse
+//
+///////////////////////////////////////
+void dlg_newmatch::slotReparse( void )
+{
+ setNames();
+ setImages();
+ Param->setStrength( WHITE, myResource->Strength[WHITE] );
+ Param->setStrength( BLACK, myResource->Strength[BLACK] );
+}
diff --git a/knights/dlg_newmatch.h b/knights/dlg_newmatch.h
new file mode 100644
index 0000000..82b5e57
--- /dev/null
+++ b/knights/dlg_newmatch.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ dlg_newmatch.h - description
+ -------------------
+ begin : Tue Jun 25 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_NEWMATCH_H
+#define DLG_NEWMATCH_H
+
+#include <qwidget.h>
+#include <kdialogbase.h>
+
+#include "match_param.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_selectengine;
+class dlg_selectemail;
+class resource;
+class QLabel;
+class QSpinBox;
+class QRadioButton;
+class QCheckBox;
+class QVBox;
+class QHBox;
+class QGrid;
+class QButtonGroup;
+class QGroupBox;
+class KComboBox;
+
+class dlg_newmatch : public KDialogBase
+{
+ Q_OBJECT
+ private:
+ resource *myResource;
+ match_param *Param;
+ dlg_selectengine *EngineSelect;
+ dlg_selectemail *EmailSelect;
+
+ QHBox *BOX_Parent;
+ QVBox *BOX_Players;
+ QGroupBox *BOX_White;
+ QLabel *IMAGE_White;
+ QVBox *BOX_White_Detail;
+ QLabel *LABEL_White_Name;
+ QButtonGroup *GROUP_White_Type;
+ QRadioButton *RADIO_White_Human;
+ QRadioButton *RADIO_White_PC;
+ QRadioButton *RADIO_White_Email;
+ QGrid *GRID_White_Time;
+ QLabel *LABEL_White_Base;
+ QSpinBox *SPIN_White_Base;
+ QLabel *LABEL_White_Inc;
+ QSpinBox *SPIN_White_Inc;
+ QLabel *LABEL_White_Moves;
+ QSpinBox *SPIN_White_Moves;
+ QGroupBox *BOX_Black;
+ QLabel *IMAGE_Black;
+ QVBox *BOX_Black_Detail;
+ QLabel *LABEL_Black_Name;
+ QButtonGroup *GROUP_Black_Type;
+ QRadioButton *RADIO_Black_Human;
+ QRadioButton *RADIO_Black_PC;
+ QRadioButton *RADIO_Black_Email;
+ QGrid *GRID_Black_Time;
+ QLabel *LABEL_Black_Base;
+ QSpinBox *SPIN_Black_Base;
+ QLabel *LABEL_Black_Inc;
+ QSpinBox *SPIN_Black_Inc;
+ QLabel *LABEL_Black_Moves;
+ QSpinBox *SPIN_Black_Moves;
+
+ public:
+ dlg_newmatch(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~dlg_newmatch();
+ match_param* paramaters( void ) { return Param; }
+ protected slots:
+ void slotWhiteType( int );
+ void slotWhiteBase( int );
+ void slotWhiteMoves( int );
+ void slotWhiteInc( int );
+
+ void slotBlackType( int );
+ void slotBlackBase( int );
+ void slotBlackMoves( int );
+ void slotBlackInc( int );
+
+ void slotReparse( void );
+
+ protected:
+ void setTCP( void );
+ void setTypes( void );
+ void setImages( void );
+ void setNames( void );
+};
+
+#endif
diff --git a/knights/dlg_promote.cpp b/knights/dlg_promote.cpp
new file mode 100644
index 0000000..d98ad83
--- /dev/null
+++ b/knights/dlg_promote.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+ dlg_promote.cpp - description
+ -------------------
+ begin : Fri Jul 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "definitions.h"
+#include "dlg_promote.moc"
+#include "knightspixcache.h"
+#include <qimage.h>
+
+dlg_promote::dlg_promote(QWidget *parent, const char *name, resource *Rsrc ) :
+ QDialog( parent, name, TRUE, Qt::WStyle_Customize | Qt::WStyle_DialogBorder )
+{
+ Resource = Rsrc;
+ Queen = new QPushButton( this );
+ Bishop = new QPushButton( this );
+ Knight = new QPushButton( this );
+ Rook = new QPushButton( this );
+ Description = new QLabel( this );
+}
+
+dlg_promote::~dlg_promote()
+{
+ delete Queen;
+ delete Bishop;
+ delete Knight;
+ delete Rook;
+ delete Description;
+}
+
+void dlg_promote::Init( bool Army )
+{
+ KnightsPixCache *cache = Resource->pixCache;
+ QImage tempImage;
+ QPixmap buffer;
+ int margin;
+
+ margin = 2;
+ buffer.resize( Resource->ThemeSize, Resource->ThemeSize );
+ Description->setFixedSize( Resource->ThemeSize * 2 , 20 );
+ Queen->setFixedSize( Resource->ThemeSize, Resource->ThemeSize );
+ Bishop->setFixedSize( Resource->ThemeSize, Resource->ThemeSize );
+ Knight->setFixedSize( Resource->ThemeSize, Resource->ThemeSize );
+ Rook->setFixedSize( Resource->ThemeSize, Resource->ThemeSize );
+ setFixedSize( ( margin * 4 ) + ( Resource->ThemeSize * 2 ),
+ ( margin * 6 ) + ( Resource->ThemeSize * 2 ) + 20 );
+
+ Description->move( margin, margin );
+ Queen->move( margin, ( margin * 3 ) + 20 );
+ Bishop->move( ( margin * 3 ) + Resource->ThemeSize, ( margin * 3 ) + 20 );
+ Knight->move( margin, ( margin * 5 ) + 20 + Resource->ThemeSize );
+ Rook->move( ( margin * 3 ) + Resource->ThemeSize, ( margin * 5 ) + 20 + Resource->ThemeSize );
+
+ /* Queen */
+ buffer = cache->SquareLight;
+ if( Army == WHITE ) bitBlt( &buffer, 0, 0, &cache->WhiteQueen, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ else bitBlt( &buffer, 0, 0, &cache->BlackQueen, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ Queen->setPixmap( buffer );
+ Queen->show();
+
+ /* Bishop */
+ buffer = cache->SquareDark;
+ if( Army == WHITE ) bitBlt( &buffer, 0, 0, &cache->WhiteBishop, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ else bitBlt( &buffer, 0, 0, &cache->BlackBishop, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ Bishop->setPixmap( buffer );
+ Bishop->show();
+
+ /* Knight */
+ buffer = cache->SquareDark;
+ if( Army == WHITE ) bitBlt( &buffer, 0, 0, &cache->WhiteKnight, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ else bitBlt( &buffer, 0, 0, &cache->BlackKnight, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ Knight->setPixmap( buffer );
+ Knight->show();
+
+ /* Rook */
+ buffer = cache->SquareLight;
+ if( Army == WHITE ) bitBlt( &buffer, 0, 0, &cache->WhiteRook, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ else bitBlt( &buffer, 0, 0, &cache->BlackRook, 0, 0, -1, -1, Qt::CopyROP, FALSE);
+ Rook->setPixmap( buffer );
+ Rook->show();
+
+ Description->setText( i18n( "Promote your pawn to..." ) );
+ Description->show();
+ connect( Queen, SIGNAL( clicked() ), this, SLOT( queenClick() ) );
+ connect( Bishop, SIGNAL( clicked() ), this, SLOT( bishopClick() ) );
+ connect( Knight, SIGNAL( clicked() ), this, SLOT( knightClick() ) );
+ connect( Rook, SIGNAL( clicked() ), this, SLOT( rookClick() ) );
+ Queen->setFocus();
+ setCaption( i18n( "Pawn Promotion" ) );
+}
+
+void dlg_promote::queenClick( void )
+{
+ done( 'q' );
+}
+
+void dlg_promote::bishopClick( void )
+{
+ done( 'b' );
+}
+
+void dlg_promote::knightClick( void )
+{
+ done( 'n' );
+}
+
+void dlg_promote::rookClick( void )
+{
+ done( 'r' );
+}
+
diff --git a/knights/dlg_promote.h b/knights/dlg_promote.h
new file mode 100644
index 0000000..0eb117e
--- /dev/null
+++ b/knights/dlg_promote.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ dlg_promote.h - description
+ -------------------
+ begin : Fri Jul 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_PROMOTE_H
+#define DLG_PROMOTE_H
+
+#include <klocale.h>
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_promote : public QDialog
+{
+ Q_OBJECT
+ public:
+
+ dlg_promote(QWidget *parent=0, const char *name=0, resource *Rsrc=0 );
+ ~dlg_promote();
+
+ void Init( bool Army );
+
+ public slots:
+ void queenClick( void );
+ void bishopClick( void );
+ void knightClick( void );
+ void rookClick( void );
+
+ private:
+ resource *Resource;
+ QLabel *Description;
+ QPushButton *Queen;
+ QPushButton *Bishop;
+ QPushButton *Knight;
+ QPushButton *Rook;
+};
+
+#endif
diff --git a/knights/dlg_selectemail.cpp b/knights/dlg_selectemail.cpp
new file mode 100644
index 0000000..5c7b583
--- /dev/null
+++ b/knights/dlg_selectemail.cpp
@@ -0,0 +1,46 @@
+/***************************************************************************
+ dlg_selectemail.cpp - description
+ -------------------
+ begin : Sun Oct 27 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "dlg_selectemail.moc"
+#include <qvbox.h>
+#include <qlineedit.h>
+#include "resource.h"
+
+dlg_selectemail::dlg_selectemail(QWidget *parent, resource *Rsrc ) :
+ KDialogBase( parent,
+ 0,
+ TRUE,
+ i18n("Select Email Address"),
+ Help|Ok,
+ Ok,
+ TRUE )
+{
+ myResource = Rsrc;
+ BOX_Parent = makeVBoxMainWidget();
+
+ EDIT_Email = new QLineEdit( BOX_Parent );
+ EDIT_Email->setText( myResource->Email_Address );
+ connect( EDIT_Email, SIGNAL( returnPressed() ), this, SLOT( changeValue() ) );
+}
+dlg_selectemail::~dlg_selectemail()
+{
+}
+void dlg_selectemail::changeValue( void )
+{
+ myResource->Email_Address = EDIT_Email->text();
+ emit valuesChanged();
+}
diff --git a/knights/dlg_selectemail.h b/knights/dlg_selectemail.h
new file mode 100644
index 0000000..6abf799
--- /dev/null
+++ b/knights/dlg_selectemail.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ dlg_selectemail.h - description
+ -------------------
+ begin : Sun Oct 27 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_SELECTEMAIL_H
+#define DLG_SELECTEMAIL_H
+
+#include <qwidget.h>
+#include <kdialogbase.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class resource;
+class QVBox;
+class QLineEdit;
+
+class dlg_selectemail : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_selectemail(QWidget *parent, resource *Rsrc );
+ ~dlg_selectemail();
+
+ signals:
+ void valuesChanged( void );
+
+ protected slots:
+ void changeValue( void );
+
+ private:
+ resource *myResource;
+
+ QVBox *BOX_Parent;
+ QLineEdit *EDIT_Email;
+};
+
+#endif
diff --git a/knights/dlg_selectengine.cpp b/knights/dlg_selectengine.cpp
new file mode 100644
index 0000000..e827184
--- /dev/null
+++ b/knights/dlg_selectengine.cpp
@@ -0,0 +1,201 @@
+/***************************************************************************
+ dlg_selectengine.cpp - description
+ -------------------
+ begin : Wed Aug 28 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "dlg_selectengine.moc"
+#include <qvbox.h>
+#include <qgroupbox.h>
+#include <qslider.h>
+#include <qlabel.h>
+#include <kcombobox.h>
+#include "resource.h"
+
+dlg_selectengine::dlg_selectengine(QWidget *parent, resource *Rsrc, bool army ) :
+ KDialogBase( parent,
+ 0,
+ TRUE,
+ i18n("Select Computer Player"),
+ Help|Ok,
+ Ok,
+ TRUE )
+{
+ Resource = Rsrc;
+ Army = army;
+ BOX_Parent = makeVBoxMainWidget();
+
+ BOX_Engine = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Computer Players" ),
+ BOX_Parent );
+ COMBO_Engine = new KComboBox( BOX_Engine );
+ COMBO_Engine->setEditable( FALSE );
+
+// BOX_EngineHelper = new QGroupBox( 1,
+// Qt::Horizontal,
+// i18n( "Computer Players' Helper" ),
+// BOX_Parent );
+// COMBO_EngineHelper = new KComboBox( BOX_Engine );
+// COMBO_EngineHelper->setEditable( FALSE );
+
+ buildEngineData();
+
+ connect( COMBO_Engine, SIGNAL( activated(int) ), this, SLOT( slotCurrent(int) ) );
+// connect( COMBO_EngineHelper, SIGNAL( activated(int) ), this, SLOT( slotCurrentHelper(int) ) );
+
+
+ GROUP_Strength = new QGroupBox( 3,
+ Qt::Horizontal,
+ i18n( "Player Strength" ),
+ BOX_Parent );
+ LABEL_Str_Min = new QLabel( i18n( "Weak" ), GROUP_Strength );
+ SLIDER_Strength = new QSlider ( 1,
+ 7,
+ 1,
+ Resource->Strength[ 1 * ( Army == BLACK ) ],
+ QSlider::Horizontal,
+ GROUP_Strength );
+ LABEL_Str_Max = new QLabel( i18n( "Strong" ), GROUP_Strength );
+ SLIDER_Strength->setTickmarks( QSlider::Below );
+ connect( SLIDER_Strength, SIGNAL( valueChanged(int) ), this, SLOT( slotStrength(int) ) );
+}
+dlg_selectengine::~dlg_selectengine()
+{
+}
+///////////////////////////////////////
+//
+// dlg_selectengine::buildEngineData
+//
+///////////////////////////////////////
+void dlg_selectengine::buildEngineData( void )
+{
+ bool FLAG1(FALSE);
+// bool FLAG2(FALSE);
+ int Index(0);
+ QStringList EngineList;
+ engineList::Iterator enginesIT;
+
+ /* Clear Comboboxes */
+ COMBO_Engine->clear();
+// COMBO_EngineHelper->clear();
+
+ /* Handle status of Book-engine boxes */
+// White_Use_Book->setChecked( Resource->OPTION_Book_White );
+// Engines_White_Book->setEnabled( Resource->OPTION_Book_White );
+
+ if( Army == WHITE )
+ {
+ Engine1F = ENGINE_WHITE;
+ Engine2F = ENGINE_WHITE_BK;
+ }
+ else
+ {
+ Engine1F = ENGINE_BLACK;
+ Engine2F = ENGINE_BLACK_BK;
+ }
+
+ /* Read the engine list */
+ if( Resource->engines.isEmpty() ) return;
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ EngineList.append( (*enginesIT).Name );
+ }
+
+ /* Insert engines into comboboxes */
+ EngineList.sort();
+ COMBO_Engine->insertStringList( EngineList );
+// COMBO_EngineHelper->insertStringList( EngineList );
+
+ /* Now run the list again, setting the current engine for each combobox */
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & Engine1F )
+ for( Index = 0; Index < COMBO_Engine->count(); Index++ )
+ if( COMBO_Engine->text(Index) == (*enginesIT).Name )
+ {
+ COMBO_Engine->setCurrentItem(Index);
+ FLAG1 = TRUE;
+ }
+// if( (*enginesIT).CurrentRef & Engine2F )
+// for( Index = 0; Index < COMBO_Engine->count(); Index++ )
+// if( COMBO_EngineHelper->text(Index) == (*enginesIT).Name )
+// {
+// COMBO_EngineHelper->setCurrentItem(Index);
+// FLAG2 = TRUE;
+// }
+ }
+
+ /*
+ This prevents a bug where you had to modify the
+ current_engine_comboboxes before you could get any engines to run.
+ */
+ if( ( !FLAG1 ) && ( COMBO_Engine->count() ) ) slotCurrent( COMBO_Engine->currentItem() );
+// if( ( !FLAG2 ) && ( COMBO_EngineHelper->count() ) ) slotCurrentHelper( COMBO_EngineHelper->currentItem() );
+}
+///////////////////////////////////////
+//
+// dlg_selectengine::slotCurrent
+//
+///////////////////////////////////////
+void dlg_selectengine::slotCurrent( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = COMBO_Engine->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & Engine1F ) (*enginesIT).CurrentRef -= Engine1F;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= Engine1F;
+ }
+ emit valuesChanged();
+}
+///////////////////////////////////////
+//
+// dlg_selectengine::slotCurrentHelper
+//
+///////////////////////////////////////
+void dlg_selectengine::slotCurrentHelper( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = COMBO_EngineHelper->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & Engine2F ) (*enginesIT).CurrentRef -= Engine2F;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= Engine2F;
+ }
+ emit valuesChanged();
+}
+///////////////////////////////////////
+//
+// dlg_selectengine::strength
+//
+///////////////////////////////////////
+int dlg_selectengine::strength( void )
+{
+ return SLIDER_Strength->value();
+}
+///////////////////////////////////////
+//
+// dlg_selectengine::slotStrength
+//
+///////////////////////////////////////
+void dlg_selectengine::slotStrength( int value )
+{
+ Resource->Strength[Army] = value;
+ emit valuesChanged();
+}
diff --git a/knights/dlg_selectengine.h b/knights/dlg_selectengine.h
new file mode 100644
index 0000000..a9dffdb
--- /dev/null
+++ b/knights/dlg_selectengine.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ dlg_selectengine.h - description
+ -------------------
+ begin : Wed Aug 28 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_SELECTENGINE_H
+#define DLG_SELECTENGINE_H
+
+#include <qwidget.h>
+#include <kdialogbase.h>
+#include "definitions.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class QVBox;
+class QSlider;
+class QLabel;
+class KComboBox;
+class QGroupBox;
+class resource;
+
+class dlg_selectengine : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_selectengine(QWidget *parent, resource *Rsrc, bool army );
+ ~dlg_selectengine();
+ int strength( void );
+ bool Army;
+
+ protected:
+ void buildEngineData( void );
+
+ protected slots:
+ void slotCurrent( int Index );
+ void slotCurrentHelper( int Index );
+ void slotStrength( int );
+
+ signals:
+ void valuesChanged( void );
+
+ private:
+ resource *Resource;
+ int Engine1F;
+ int Engine2F;
+
+ QVBox *BOX_Parent;
+ QGroupBox *BOX_Engine;
+ KComboBox *COMBO_Engine;
+ QGroupBox *BOX_EngineHelper;
+ KComboBox *COMBO_EngineHelper;
+ QGroupBox *GROUP_Strength;
+ QLabel *LABEL_Str_Min;
+ QSlider *SLIDER_Strength;
+ QLabel *LABEL_Str_Max;
+};
+
+#endif
diff --git a/knights/dlg_server.cpp b/knights/dlg_server.cpp
new file mode 100644
index 0000000..89073cb
--- /dev/null
+++ b/knights/dlg_server.cpp
@@ -0,0 +1,240 @@
+/***************************************************************************
+ dlg_server.cpp - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kicontheme.h>
+#include "dlg_server.moc"
+
+dlg_server::dlg_server(QWidget *parent, const char *name, resource *Rsrc, QString ItemName ) :
+ KDialogBase( parent,
+ name,
+ TRUE,
+ i18n("Configure Server"),
+ Help|Ok|Apply|Cancel,
+ Ok,
+ TRUE )
+{
+ Resource = Rsrc;
+ Name = ItemName;
+
+ BOX_Parent = makeVBoxMainWidget();
+
+ BOX_Name = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Server Name" ),
+ BOX_Parent );
+ EDIT_Name = new KLineEdit( BOX_Name );
+
+ BOX_URLPort = new QHBox( BOX_Parent );
+ BOX_URL = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Server URL" ),
+ BOX_URLPort );
+ EDIT_URL = new KLineEdit( BOX_URL );
+ BOX_Port = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Server Port" ),
+ BOX_URLPort );
+ EDIT_Port = new KLineEdit( BOX_Port );
+
+ BOX_UNameStore = new QHBox( BOX_Parent );
+ BOX_UserName = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Username" ),
+ BOX_UNameStore );
+ EDIT_UserName = new KLineEdit( BOX_UserName );
+ CHECK_StorePass = new QCheckBox( i18n( "Remember My Password" ), BOX_UNameStore );
+
+ BOX_Pass = new QHBox( BOX_Parent );
+ BOX_Password = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Password" ),
+ BOX_Pass );
+ EDIT_Password = new KLineEdit( BOX_Password );
+ EDIT_Password->setEchoMode( QLineEdit::Password );
+
+ BOX_PasswordRetype = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Confirm Password" ),
+ BOX_Pass );
+ EDIT_PasswordRetype = new KLineEdit( BOX_PasswordRetype );
+ EDIT_PasswordRetype->setEchoMode( QLineEdit::Password );
+
+ /* Use Timeseal? */
+ GROUP_Timeseal = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Timeseal" ),
+ BOX_Parent );
+ EDIT_Timeseal = new KLineEdit( GROUP_Timeseal );
+ BUTTON_Timeseal = new QPushButton( GROUP_Timeseal );
+ BUTTON_Timeseal->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ connect( BUTTON_Timeseal, SIGNAL( clicked() ), this, SLOT( slot_Timeseal() ) );
+
+ BOX_LogFile = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Log File" ),
+ BOX_Parent );
+ EDIT_LogFile = new KLineEdit( BOX_LogFile );
+ BUTTON_LogFile = new QPushButton( BOX_LogFile );
+
+ setMainWidget( BOX_Parent );
+ BUTTON_LogFile->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ EDIT_Name->setMinimumWidth( 120 );
+ EDIT_URL->setMinimumWidth( 120 );
+ EDIT_UserName->setMinimumWidth( 120 );
+ EDIT_Password->setMinimumWidth( 120 );
+ EDIT_PasswordRetype->setMinimumWidth( 120 );
+ /* Load in data if this is a modification */
+ if( !Name.isEmpty() )
+ {
+ for ( serversIT = Resource->servers.begin(); serversIT != Resource->servers.end(); ++serversIT )
+ {
+ if( (*serversIT).Name == Name ) break;
+ }
+ EDIT_Name->setText( (*serversIT).Name );
+ EDIT_URL->setText( (*serversIT).URL );
+ EDIT_Port->setText( QString("").setNum( (*serversIT).Port ) );
+ EDIT_UserName->setText( (*serversIT).UserName );
+ CHECK_StorePass->setChecked( (*serversIT).StorePass );
+ EDIT_Password->setText( (*serversIT).Password );
+ EDIT_PasswordRetype->setText( (*serversIT).Password );
+ EDIT_LogFile->setText( (*serversIT).LogFile );
+ EDIT_Timeseal->setText( (*serversIT).Timeseal );
+ }
+ if( CHECK_StorePass->isChecked() )
+ {
+ EDIT_Password->setEnabled( TRUE );
+ EDIT_PasswordRetype->setEnabled( TRUE );
+ }
+ else
+ {
+ EDIT_Password->setEnabled( FALSE );
+ EDIT_PasswordRetype->setEnabled( FALSE );
+ }
+ /* Init the buttons */
+ showButtonCancel( TRUE );
+ showButtonOK( TRUE );
+ showButtonApply( TRUE );
+ showButton( Help, TRUE );
+
+ enableButtonCancel( TRUE );
+ enableButtonOK( TRUE );
+ enableButtonApply( FALSE );
+ enableButton( Help, TRUE );
+
+ setHelp( QString( "configure-servers" ) );
+ /* Make Connections */
+ connect( BUTTON_LogFile, SIGNAL( clicked() ), this, SLOT( slotLogFileDialog() ) );
+ connect( CHECK_StorePass, SIGNAL( toggled(bool) ), this, SLOT( slotStorePass(bool) ) );
+ connect( EDIT_Name, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ connect( EDIT_URL, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ connect( EDIT_Port, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ connect( EDIT_UserName, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ connect( EDIT_Password, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ connect( EDIT_Timeseal, SIGNAL( textChanged( const QString&) ), this, SLOT( slotEnableApply( const QString&) ) );
+ show();
+}
+dlg_server::~dlg_server()
+{
+}
+
+void dlg_server::slotOk( void )
+{
+ slotApply();
+ slotDelayedDestruct();
+}
+
+void dlg_server::slotApply( void )
+{
+ serverResource newServer;
+
+ if( ( EDIT_Password->text() != EDIT_PasswordRetype->text() ) && ( CHECK_StorePass->isChecked() ) )
+ {
+ return;
+ }
+ if( Name.isEmpty() )
+ {
+ serversIT = Resource->servers.append( newServer );
+ Name = "notemptyanymore";
+ (*serversIT).CurrentRef = 0;
+ }
+ (*serversIT).Name = EDIT_Name->text();
+ (*serversIT).URL = EDIT_URL->text();
+ (*serversIT).Port = QString( EDIT_Port->text() ).toInt();
+ (*serversIT).UserName = EDIT_UserName->text();
+ (*serversIT).Password = EDIT_Password->text();
+ (*serversIT).LogFile = EDIT_LogFile->text();
+ (*serversIT).StorePass = CHECK_StorePass->isChecked();
+ (*serversIT).Timeseal = EDIT_Timeseal->text();
+
+ enableButtonApply( FALSE );
+}
+
+void dlg_server::slotCancel( void )
+{
+ slotDelayedDestruct();
+}
+
+void dlg_server::slotLogFileDialog( void )
+{
+ QString temp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ this,
+ QString( "Find Log..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_LogFile->setText( temp );
+ enableButtonApply( TRUE );
+}
+
+void dlg_server::slotEnableApply( const QString& )
+{
+ enableButtonApply( TRUE );
+}
+
+void dlg_server::slotStorePass( bool )
+{
+ if( CHECK_StorePass->isChecked() )
+ {
+ EDIT_Password->setEnabled( TRUE );
+ EDIT_PasswordRetype->setEnabled( TRUE );
+ }
+ else
+ {
+ EDIT_Password->setEnabled( FALSE );
+ EDIT_PasswordRetype->setEnabled( FALSE );
+ }
+ enableButtonApply( TRUE );
+}
+///////////////////////////////////////
+//
+// dlg_server::slot_Timeseal
+//
+///////////////////////////////////////
+void dlg_server::slot_Timeseal( void )
+{
+ QString temp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ 0,
+ QString( "Find Timeseal..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_Timeseal->setText( temp );
+ enableButtonApply( TRUE );
+}
+
diff --git a/knights/dlg_server.h b/knights/dlg_server.h
new file mode 100644
index 0000000..5d9c316
--- /dev/null
+++ b/knights/dlg_server.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ dlg_server.h - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_SERVER_H
+#define DLG_SERVER_H
+
+#include <kdialogbase.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <kfiledialog.h>
+#include <qgroupbox.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <qstring.h>
+#include "definitions.h"
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_server : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_server(QWidget *parent=0, const char *name=0, resource *Rsrc=0, QString ItemName="" );
+ ~dlg_server();
+
+ public slots:
+ void slotOk( void );
+ void slotApply( void );
+ void slotCancel( void );
+ void slotLogFileDialog( void );
+ void slotEnableApply( const QString& );
+ void slotStorePass( bool state );
+ void slot_Timeseal( void );
+
+ private:
+ serverList::Iterator serversIT;
+ resource *Resource;
+ QString Name;
+
+ QVBox *BOX_Parent;
+ QHBox *BOX_URLPort;
+ QHBox *BOX_UNameStore;
+ QHBox *BOX_Pass;
+
+ QGroupBox *BOX_Name;
+ KLineEdit *EDIT_Name;
+
+ QGroupBox *BOX_URL;
+ KLineEdit *EDIT_URL;
+
+ QGroupBox *BOX_Port;
+ KLineEdit *EDIT_Port;
+
+ QGroupBox *BOX_UserName;
+ KLineEdit *EDIT_UserName;
+ QCheckBox *CHECK_StorePass;
+
+ QGroupBox *BOX_Password;
+ KLineEdit *EDIT_Password;
+
+ QGroupBox *BOX_PasswordRetype;
+ KLineEdit *EDIT_PasswordRetype;
+
+ QGroupBox *GROUP_Timeseal;
+ KLineEdit *EDIT_Timeseal;
+ QPushButton *BUTTON_Timeseal;
+
+ QGroupBox *BOX_LogFile;
+ KLineEdit *EDIT_LogFile;
+ QPushButton *BUTTON_LogFile;
+};
+
+#endif
diff --git a/knights/dlg_settings.cpp b/knights/dlg_settings.cpp
new file mode 100644
index 0000000..82fa117
--- /dev/null
+++ b/knights/dlg_settings.cpp
@@ -0,0 +1,201 @@
+/***************************************************************************
+ dlg_settings.cpp - description
+ -------------------
+ begin : Mon Jul 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kicontheme.h>
+#include <kstddirs.h>
+#include "definitions.h"
+#include "dlg_settings.moc"
+#include "setpagedisplay.h"
+#include "setpageaudio.h"
+#include "setpageengines.h"
+#include "setpageservers.h"
+#include "setpagegeneral.h"
+
+///////////////////////////////////////
+//
+// dlg_settings::Constructor
+//
+///////////////////////////////////////
+dlg_settings::dlg_settings(QWidget *parent, const char *name, resource *Rsrc ) :
+ KDialogBase( IconList,
+ i18n("Configure"),
+ Help|Ok|Apply|Cancel,
+ Ok,
+ parent,
+ name,
+ FALSE,
+ FALSE )
+{
+ QString buffer;
+ Resource = Rsrc;
+ Resource->ConfigWrite();
+
+ /* General Page */
+ FRAME_General = addPage( i18n( "General" ),
+ i18n( "Various aspects of Knights get configured here." ),
+ QPixmap( locate( "data", "knights/icon-general.png" ) ) );
+ PAGE_General = new setPageGeneral( FRAME_General, Resource );
+ connect( PAGE_General, SIGNAL( enableApply() ), this, SLOT( slotEnableApply() ) );
+
+ /* Display Page */
+ FRAME_Display = addPage( i18n( "Display" ),
+ i18n( "These settings determine how Knights displays itself to you." ),
+ QPixmap( locate( "data", "knights/icon-display.png" ) ) );
+ PAGE_Display = new setPageDisplay( FRAME_Display, Resource );
+ connect( PAGE_Display, SIGNAL( enableApply() ), this, SLOT( slotEnableApply() ) );
+
+ /* Audio Page */
+ FRAME_Audio = addPage( i18n( "Audio" ),
+ i18n( "These settings determine what Knights sounds like." ),
+ Resource->LoadIcon( QString("multimedia"), KIcon::Panel ) );
+ PAGE_Audio = new setPageAudio( FRAME_Audio, Resource );
+ connect( PAGE_Audio, SIGNAL( enableApply() ), this, SLOT( slotEnableApply() ) );
+
+ /* Engines Page */
+ FRAME_Engines = addPage( i18n( "Computer Opponents" ),
+ i18n( "Configure your chess engines here." ),
+ Resource->LoadIcon( QString("gear"), KIcon::Panel ) );
+ PAGE_Engines = new setPageEngines( FRAME_Engines, Resource );
+ connect( PAGE_Engines, SIGNAL( enableApply() ), this, SLOT( slotEnableApply() ) );
+
+ /* Servers Page */
+ FRAME_Servers = addPage( i18n( "Chess Servers" ),
+ i18n( "Configure your internet chess servers here." ),
+ Resource->LoadIcon( QString("network"), KIcon::Panel ) );
+ PAGE_Servers = new setPageServers( FRAME_Servers, Resource );
+ connect( PAGE_Servers, SIGNAL( enableApply() ), this, SLOT( slotEnableApply() ) );
+
+ connect( this, SIGNAL( aboutToShowPage( QWidget* ) ), this, SLOT( slotPageChanging( QWidget* ) ) );
+
+ /* Init the buttons */
+ showButtonCancel( TRUE );
+ showButtonOK( TRUE );
+ showButtonApply( TRUE );
+ showButton( Help, TRUE );
+
+ enableButtonCancel( TRUE );
+ enableButtonOK( TRUE );
+ enableButtonApply( FALSE );
+ enableButton( Help, TRUE );
+
+ setHelp( QString( "configure" ) );
+ show();
+}
+///////////////////////////////////////
+//
+// dlg_settings::Destructor
+//
+///////////////////////////////////////
+dlg_settings::~dlg_settings()
+{
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotOk
+//
+///////////////////////////////////////
+void dlg_settings::slotOk( void )
+{
+ slotApply();
+ slotDelayedDestruct();
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotApply
+//
+///////////////////////////////////////
+void dlg_settings::slotApply( void )
+{
+ if( PAGE_Display->changeTheme )
+ {
+ PAGE_Display->changeTheme = FALSE;
+ emit themeChanged( PAGE_Display->NewBoards, PAGE_Display->NewChessmen );
+ }
+ if( PAGE_Display->refreshBoard )
+ {
+ PAGE_Display->refreshBoard = FALSE;
+ emit redrawBoard();
+ }
+ if( PAGE_Display->rebuildConsole )
+ {
+ Resource->buildStyle();
+ PAGE_Display->rebuildConsole = FALSE;
+ emit rebuildConsole();
+ }
+ if( PAGE_Audio->changeTheme )
+ {
+ PAGE_Audio->changeTheme = FALSE;
+ Resource->setAudio( PAGE_Audio->NewSounds );
+ }
+ if( PAGE_Servers->resetServer )
+ {
+ PAGE_Servers->resetServer = FALSE;
+ emit resetServer();
+ }
+ Resource->ConfigWrite();
+ enableButtonApply( FALSE );
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotCancel
+//
+///////////////////////////////////////
+void dlg_settings::slotCancel( void )
+{
+ Resource->ConfigRead();
+ slotDelayedDestruct();
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotEnableApply
+//
+///////////////////////////////////////
+void dlg_settings::slotEnableApply( void )
+{
+ enableButtonApply( TRUE );
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotThemesAdded
+//
+///////////////////////////////////////
+void dlg_settings::slotThemesAdded( void )
+{
+ PAGE_Display->buildThemeList();
+ PAGE_Audio->buildThemeList();
+}
+///////////////////////////////////////
+//
+// dlg_settings::slotPageChanging
+//
+///////////////////////////////////////
+void dlg_settings::slotPageChanging( QWidget *page )
+{
+ if( page == FRAME_General )
+ setHelp( QString( "configure-general" ) );
+ else if( page == FRAME_Display )
+ setHelp( QString( "configure-display" ) );
+ else if( page == FRAME_Audio )
+ setHelp( QString( "configure-audio" ) );
+ else if( page == FRAME_Engines )
+ setHelp( QString( "configure-engines" ) );
+ else if( page == FRAME_Servers )
+ setHelp( QString( "configure-servers" ) );
+}
+
+
+
diff --git a/knights/dlg_settings.h b/knights/dlg_settings.h
new file mode 100644
index 0000000..997db07
--- /dev/null
+++ b/knights/dlg_settings.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ dlg_settings.h - description
+ -------------------
+ begin : Mon Jul 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DLG_SETTINGS_H
+#define DLG_SETTINGS_H
+
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qvbox.h>
+#include "definitions.h"
+#include "resource.h"
+
+class setPageDisplay;
+class setPageAudio;
+class setPageEngines;
+class setPageServers;
+class setPageGeneral;
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class dlg_settings : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ dlg_settings(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~dlg_settings();
+
+ public slots:
+ void slotOk( void );
+ void slotApply( void );
+ void slotCancel( void );
+ void slotEnableApply( void );
+ void slotThemesAdded( void );
+ void slotPageChanging( QWidget* );
+
+ signals:
+ void themeChanged( int, int );
+ void redrawBoard( void );
+ void rebuildConsole( void );
+ void resetServer( void );
+
+ private:
+ resource *Resource;
+
+ QFrame *FRAME_General;
+ setPageGeneral *PAGE_General;
+
+ QFrame *FRAME_Display;
+ setPageDisplay *PAGE_Display;
+
+ QFrame *FRAME_Audio;
+ setPageAudio *PAGE_Audio;
+
+ QFrame *FRAME_Engines;
+ setPageEngines *PAGE_Engines;
+
+ QFrame *FRAME_Servers;
+ setPageServers *PAGE_Servers;
+};
+
+#endif
diff --git a/knights/idmanager.cpp b/knights/idmanager.cpp
new file mode 100644
index 0000000..dd979c3
--- /dev/null
+++ b/knights/idmanager.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ idmanager.cpp - description
+ -------------------
+ begin : Wed Jun 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "idmanager.h"
+
+IDManager::IDManager()
+{
+ counter = 0;
+}
+
+
+IDManager::~IDManager()
+{
+ counter = 0;
+}
+
+unsigned int IDManager::getNewID()
+{
+ counter++;
+ return counter;
+ /* this might be a problem if there are more than MAX
+ unsigned int matches going on at the same time */
+}
diff --git a/knights/idmanager.h b/knights/idmanager.h
new file mode 100644
index 0000000..04be2c1
--- /dev/null
+++ b/knights/idmanager.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ idmanager.h - description
+ -------------------
+ begin : Wed Jun 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef IDMANAGER_H
+#define IDMANAGER_H
+
+#include <qobject.h>
+
+/**
+ *@author Alexander Wels
+ */
+
+/////////////////////////////////////////////////////
+// This class generates and manages ID's for matches
+// The ID's generated are unsigned integers
+/////////////////////////////////////////////////////
+
+class IDManager : public QObject
+{
+public:
+ IDManager();
+ ~IDManager();
+ unsigned int getNewID();
+private:
+ unsigned int counter;
+};
+
+#endif
diff --git a/knights/io_base.cpp b/knights/io_base.cpp
new file mode 100644
index 0000000..db62330
--- /dev/null
+++ b/knights/io_base.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+ io_base.cpp - description
+ -------------------
+ begin : Tue Jun 18 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "io_base.moc"
+
+io_base::io_base(resource *resc)
+{
+ this->myResource = resc;
+}
+
+io_base::io_base(resource *resc, int ID)
+{
+ this->myResource = resc;
+ this->myID = ID;
+}
+
+io_base::io_base(QWidget* parent, resource *rsrc)
+{
+ this->myParent = parent;
+ this->myResource = rsrc;
+}
+
+io_base::~io_base()
+{
+
+}
+
+void io_base::setID(const int ID)
+{
+ this->myID = ID;
+}
+
+int io_base::getID()
+{
+ return myID;
+}
+
+int io_base::getType()
+{
+ return myType;
+}
+
+
diff --git a/knights/io_base.h b/knights/io_base.h
new file mode 100644
index 0000000..7feeff0
--- /dev/null
+++ b/knights/io_base.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ io_base.h - description
+ -------------------
+ begin : Tue Jun 18 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef IO_BASE_H
+#define IO_BASE_H
+
+
+#include "definitions.h"
+#include "resource.h"
+#include "command.h"
+#include "match_param.h"
+
+#include <qobject.h>
+#include <qwidget.h>
+/**
+ *@author Alexander Wels.
+ */
+
+class io_base : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum ioType
+ {
+ INTERNET = 0,
+ LOCAL = 1
+ };
+
+ io_base(QWidget *parent=NULL, resource *rsrc=NULL);
+ io_base(resource *rsrc);
+ io_base(resource *rsrc, int ID);
+ virtual ~io_base();
+ int getID( void );
+ void setID( const int ID );
+ int getType( void );
+
+public slots:
+ virtual void recvCMD(const Command& command) = 0; // sub classes have to implement this
+
+signals:
+ virtual void sendCMD(const Command& command) = 0; // sub classes have to implement this
+
+
+protected:
+ // The knightio object needs to know its ID
+ QWidget *myParent;
+ int myID;
+ resource *myResource;
+ ioType myType;
+};
+
+#endif
diff --git a/knights/io_engine.cpp b/knights/io_engine.cpp
new file mode 100644
index 0000000..d9a15a7
--- /dev/null
+++ b/knights/io_engine.cpp
@@ -0,0 +1,312 @@
+/***************************************************************************
+ io_engine.cpp - description
+ -------------------
+ begin : Sat Jun 30 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kprocess.h>
+#include <kicontheme.h>
+
+#include <qregexp.h>
+#include <qfile.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "io_engine.moc"
+#include "definitions.h"
+#include "proto_base.h"
+#include "proto_xboard.h"
+#include "proto_uci.h"
+
+io_engine::io_engine( QWidget *parent, resource *Rsrc ) : io_base( parent, Rsrc )
+{
+ myType = io_base::LOCAL;
+ engine = NULL;
+ Log = NULL;
+ proto = NULL;
+ SafeToSend = TRUE;
+ CleanBuffer = TRUE;
+ SendSIGINT = FALSE;
+ Forced = TRUE;
+ Protocol = XBoard;
+ FIFO_In = "";
+ FIFO_Out = "";
+}
+//
+io_engine::~io_engine()
+{
+ if( engine )
+ {
+ Kill();
+ }
+ if( Log )
+ {
+ Log->close();
+ delete Log;
+ }
+ if( proto )
+ {
+ delete proto;
+ }
+}
+///////////////////////////////////////
+//
+// io_engine::Start
+//
+///////////////////////////////////////
+void io_engine::Start( const int side )
+{
+ QStringList args;
+ unsigned int tmp;
+ int ID;
+ bool Army;
+
+ /* Stop accidents */
+ if( engine != NULL )
+ return;
+ engine = new KProcess();
+
+ /* Convert 'side' to 'ID' */
+ if( side == WHITE )
+ {
+ ID = ENGINE_WHITE;
+ Army = WHITE;
+ }
+ else if( side == BLACK )
+ {
+ ID = ENGINE_BLACK;
+ Army = BLACK;
+ }
+ else if( side == WHITE_HELPER )
+ {
+ ID = ENGINE_WHITE_BK;
+ Army = WHITE;
+ }
+ else
+ {
+ ID = ENGINE_BLACK_BK;
+ Army = BLACK;
+ }
+
+ /* Get and parse engine config from resource */
+ for( IT = myResource->engines.begin(); IT != myResource->engines.end(); ++IT )
+ {
+ if( (*IT).CurrentRef & ID )
+ break;
+ }
+ if( IT == myResource->engines.end() )
+ {
+ kdError() << "io_engine::Start: Can not find engine resource ID " << ID << endl;
+ return;
+ }
+
+ /* ...protocol */
+ Protocol = (*IT).Protocol;
+ switch( Protocol )
+ {
+ case UCI:
+ proto = new proto_uci( myID );
+ break;
+ case XBoard:
+ default:
+ proto = new proto_xboard( myID );
+ break;
+ }
+ connect( proto, SIGNAL( output( const QString& ) ), this, SLOT( WriteFIFO( const QString& ) ) );
+ connect( proto, SIGNAL( output( const Command& ) ), this, SLOT( recvProtoCMD( const Command& ) ) );
+
+ /* ...engine's display name */
+ proto->parse( Command( myID, CMD_Set_Name, (*IT).Name ) );
+
+ /* ...engine file name */
+ (*engine) << (*IT).Filename;
+
+ /* ...command line arguments */
+ args = QStringList::split( QString(" "), (*IT).Arguments, FALSE );
+ for( tmp = 0; tmp < args.count(); tmp++ )
+ {
+ (*engine) << args[tmp];
+ }
+
+ /* ...log file */
+ if( !(*IT).LogFile.isEmpty() )
+ {
+ Log = new QFile( (*IT).LogFile );
+ if( !Log->open( IO_WriteOnly | IO_Append ) )
+ if( !Log->open( IO_WriteOnly ) )
+ kdError() << "io_engine::Start: Can not open " << (*IT).LogFile << " for writing." << endl;
+ }
+
+ /* Showtime */
+ if( !engine->start( KProcess::NotifyOnExit, KProcess::All ) )
+ {
+ kdError() << "io_engine::Start: Can not run the engine: " << (*IT).Filename << endl;
+ return;
+ }
+ connect( engine, SIGNAL( wroteStdin( KProcess* ) ), this, SLOT( SendClear( KProcess* ) ) );
+ connect( engine, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( Recv( KProcess*, char*, int ) ) );
+ connect( engine, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( Recv( KProcess*, char*, int ) ) );
+
+ proto->parse( Command( myID, CMD_Init ) );
+
+ if( myResource->OPTION_Ponder )
+ proto->parse( Command( myID, CMD_Ponder ) );
+ else
+ proto->parse( Command( myID, CMD_No_Pondering ) );
+
+ proto->parse( Command( myID, CMD_NewGame ) );
+
+ if( Army == WHITE )
+ proto->parse( Command( myID, CMD_Play_White ) );
+ else
+ proto->parse( Command( myID, CMD_Play_Black ) );
+ return;
+}
+///////////////////////////////////////
+//
+// io_engine::Kill
+//
+///////////////////////////////////////
+void io_engine::Kill( void )
+{
+ proto->parse( Command( myID, CMD_Exit ) );
+ if( engine != NULL )
+ delete engine;
+}
+///////////////////////////////////////
+//
+// io_engine::sendToChild
+//
+///////////////////////////////////////
+void io_engine::sendToChild( void )
+{
+ if( !SafeToSend || FIFO_Out.isEmpty() || !engine->isRunning() )
+ return;
+
+ /* Interrupt those engines that want or need it */
+ if( SendSIGINT )
+ {
+ engine->kill( SIGINT );
+ SendSIGINT = FALSE;
+ }
+
+ /* Write it */
+ SafeToSend = FALSE;
+ if( engine->writeStdin( FIFO_Out.latin1(), FIFO_Out.length() ) )
+ {
+ /* Print the output to the log file */
+ if( Log )
+ {
+ FIFO_Out.prepend( "<- " );
+ Log->writeBlock( FIFO_Out.latin1(), FIFO_Out.length() );
+ }
+ FIFO_Out = "";
+ }
+ else
+ kdError() << "io_engine::sendToChild: Could not write to engine." << endl;
+}
+///////////////////////////////////////
+//
+// io_engine::Recv
+//
+///////////////////////////////////////
+void io_engine::Recv( KProcess*, char *buffer, int bufLen )
+{
+ char *newBuff = new char[bufLen + 1];
+ strncpy( newBuff, buffer, bufLen );
+ newBuff[bufLen] = 0;
+ FIFO_In += newBuff;
+ delete newBuff;
+
+ if( FIFO_In.contains( QChar('\n') ) )
+ {
+ QString proc = FIFO_In.left( FIFO_In.findRev( QChar('\n') ) );
+ FIFO_In = FIFO_In.right( FIFO_In.length() - proc.length() );
+
+ /* Split and Parse Full Lines of Input */
+ QStringList strList = QStringList::split( "\n", proc );
+ for( unsigned int loop = 0; loop < strList.count(); loop++ )
+ {
+ /* Print the input to the log file */
+ if( Log )
+ {
+ QString data = "-> " + strList[loop] + "\n";
+ Log->writeBlock( data.latin1(), data.length() );
+ }
+ proto->parse( strList[loop] );
+ }
+ }
+ return;
+}
+///////////////////////////////////////
+//
+// io_engine::WriteFIFO
+//
+///////////////////////////////////////
+void io_engine::WriteFIFO( const QString &Data )
+{
+ QString data = Data;
+ if( data.isEmpty() )
+ return;
+ if( data.right(1) != "\n" )
+ data += "\n";
+ FIFO_Out += data;
+ sendToChild();
+ return;
+}
+///////////////////////////////////////
+//
+// io_engine::recvCMD
+//
+///////////////////////////////////////
+void io_engine::recvCMD( const Command &command )
+{
+ proto->parse( command );
+}
+
+///////////////////////////////////////
+//
+// io_engine::recvProtoCMD
+//
+///////////////////////////////////////
+void io_engine::recvProtoCMD( const Command &command )
+{
+ Command cmd = command;
+
+ switch( cmd.getCommand() )
+ {
+ /* Command: Send_SIGTERM */
+ case CMD_Send_SIGTERM:
+ engine->kill();
+ break;
+ /* Command: Send_SIGINT */
+ case CMD_Send_SIGINT:
+ SendSIGINT = TRUE;
+ break;
+ /* Command to Core */
+ default:
+ emit sendCMD( command );
+ break;
+ }
+}
+
+void io_engine::SendClear( KProcess* )
+{
+ SafeToSend = TRUE;
+ if( !FIFO_Out.isEmpty() )
+ sendToChild();
+}
+
diff --git a/knights/io_engine.h b/knights/io_engine.h
new file mode 100644
index 0000000..3952d60
--- /dev/null
+++ b/knights/io_engine.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ io_engine.h - description
+ -------------------
+ begin : Sat Jun 30 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef IO_ENGINE_H
+#define IO_ENGINE_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+#include "io_base.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class QFile;
+class KProcess;
+class resource;
+class proto_base;
+
+class io_engine : public io_base
+{
+ Q_OBJECT
+ public:
+ io_engine( QWidget *parent=NULL, resource *Rsrc=0 );
+ ~io_engine();
+
+ void Start( const int side );
+
+ public slots:
+ virtual void recvCMD( const Command& command );
+ void recvProtoCMD( const Command& command );
+ void SendClear( KProcess* );
+ void Recv( KProcess*, char*, int );
+
+ signals:
+ virtual void sendCMD(const Command& command);
+
+ protected slots:
+ void sendToChild( void );
+ void WriteFIFO( const QString &Data );
+
+ protected:
+ void Kill( void );
+
+ private:
+
+ engineList::Iterator IT;
+ proto_base *proto;
+
+ /* States */
+ bool SafeToSend;
+ bool SendSIGINT;
+ bool CleanBuffer;
+ bool Forced;
+
+ /* References */
+ QFile *Log;
+ int Protocol;
+ ChessMove Move;
+
+ /* Data */
+ KProcess *engine;
+ QString FIFO_In;
+ QString FIFO_Out;
+};
+
+#endif
diff --git a/knights/io_internet.cpp b/knights/io_internet.cpp
new file mode 100644
index 0000000..e5325cd
--- /dev/null
+++ b/knights/io_internet.cpp
@@ -0,0 +1,1138 @@
+/***************************************************************************
+ io_internet.cpp - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/* KDE */
+#include <ksock.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+
+/* Qt */
+#include <qobject.h>
+#include <qwidget.h>
+#include <qregexp.h>
+#include <qdns.h>
+#include <qsocket.h>
+#include <qptrlist.h>
+
+/* Local */
+#include "io_internet.moc"
+#include "resource.h"
+#include "dlg_login.h"
+#include "dlg_challenge.h"
+#include "match.h"
+#include "core.h"
+#include "audio.h"
+#include "../config.h"
+
+static const int TXT_Std = 0;
+static const int TXT_Pvt = 1;
+static const int TXT_Ch = 2;
+static const int TXT_Sht = 3;
+static const int TXT_Wsp = 4;
+static const int TXT_Not = 5;
+
+io_internet::io_internet( QWidget *parent, resource *rsrc )
+{
+ myResource = rsrc;
+ challenge = NULL;
+ myTimeseal = NULL;
+ socket = NULL;
+ loginStage = LOGIN_STAGE_NAME;
+ lineBuffer = "";
+ Log = NULL;
+
+ /* set type */
+ this->myType = io_base::INTERNET;
+
+ /* initialize various variables */
+ this->waiting_for_move_list = false;
+ this->myParent = parent;
+ connected = false; /* we are not connected to a server */
+
+ /* create the login dialog and show it to the user */
+ loginDlg = new dlg_login( myParent, "LoginDialog", myResource);
+ connect(loginDlg, SIGNAL( okClicked() ), this, SLOT( connectToServer() ) );
+ connect(loginDlg, SIGNAL( cancelClicked() ), this, SLOT( selfDestruct() ) );
+ connect(loginDlg, SIGNAL( login(QString, QString) ), this, SLOT( setUserInfo(QString, QString) ) );
+}
+
+///////////////////////////////////////////////////////////
+// Destructor
+///////////////////////////////////////////////////////////
+io_internet::~io_internet()
+{
+ TabMap::Iterator i;
+
+ /* Close and remove socket */
+ if( socket != NULL )
+ {
+ if(socket->socket() != -1)
+ {
+ send("quit");
+ }
+ delete socket;
+ }
+ /* Close and remove logfile */
+ if( Log )
+ {
+ Log->close();
+ delete Log;
+ Log = NULL;
+ }
+ /* Remove Timeseal */
+ if( myTimeseal != NULL )
+ {
+ myTimeseal->kill();
+ delete myTimeseal;
+ }
+ /* Close and remove Tabs */
+
+ for(i = myTabList.begin(); i != myTabList.end(); i++)
+ {
+ if(myResource->tabManager->isTab(*i))
+ {
+ myResource->tabManager->removeTab(*i);
+ }
+ }
+}
+
+void io_internet::connectToServer()
+{
+ serverList::iterator i;
+ QWidget *tempTab;
+ QWidget *consoleTab;
+ QValueList<Command>::iterator j;
+
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Thinking );
+ /* Get and parse server config from resource */
+ myServer = NULL;
+ for( i = myResource->servers.begin(); i != myResource->servers.end(); i++ )
+ {
+ if( (*i).CurrentRef )
+ {
+ myServer = &(*i);
+ }
+ }
+ if(myServer == NULL)
+ {
+ /* No server configured. Notify User and die gracefully */
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+ kdError() << "internetio::internetio: Can not find server resource CurrentRef " << endl;
+ KMessageBox::sorry( (QWidget*)myParent, i18n( "There are no servers configured.\nPlease make sure you have at least one server configured." ), i18n( "Cannot find a server."));
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+ return;
+ }
+
+ if(myServer->Port == 0)
+ {
+ myServer->Port = 5000;
+ }
+
+ if(!myServer->Timeseal.isEmpty())
+ {
+ myTimeseal = new KProcess();
+ (*myTimeseal) << myServer->Timeseal << myServer->URL << QString().setNum( myServer->Port )
+ << QString( "-p" ) << QString().setNum(myServer->Port + 1);
+ if(!myTimeseal->start())
+ {
+ /* Couldn't start Timeseal. Notify User and die gracefully */
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+ KMessageBox::sorry( (QWidget*)myParent, i18n( "Knights can not start Timeseal.\nPlease make sure you have the correct path and filename configured." ), i18n( "Cannot find Timeseal."));
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+ return;
+ }
+ socket = new KSocket("127.0.0.1", myServer->Port + 1, 30);
+ if(socket->socket() == -1)
+ {
+ /* try again on a different port, somehow the port hasn't been freed yet */
+ delete socket;
+ myTimeseal->kill();
+
+ myTimeseal = new KProcess();
+ (*myTimeseal) << myServer->Timeseal << myServer->URL << QString().setNum( myServer->Port )
+ << QString( "-p" ) << QString().setNum(myServer->Port + 2);
+ if(!myTimeseal->start())
+ {
+ /* Couldn't start Timeseal. Notify User and die gracefully */
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+ KMessageBox::sorry( (QWidget*)myParent, i18n( "Knights can not start Timeseal.\nPlease make sure you have the correct path and filename configured." ), i18n( "Cannot find Timeseal."));
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+ return;
+ }
+ socket = new KSocket("127.0.0.1", myServer->Port + 2, 30);
+ if(socket->socket() == -1)
+ {
+ /* if we can't do it the second time, give up */
+ /* Couldn't connect to server through Timeseal. Notify User and die gracefully */
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+ KMessageBox::sorry( (QWidget*)myParent, i18n( "Knights is unable to connect to the server.\n Please make sure your internet connection is working and try again."), i18n( "Cannot connect to server(timeseal)."));
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+ return;
+ }
+ }
+ }
+ else
+ {
+ socket = new KSocket(myServer->URL, myServer->Port, 30);
+ if(socket->socket() == -1)
+ {
+ /* Couldn't connect to server. Notify User and die gracefully */
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+ KMessageBox::sorry( (QWidget*)myParent, i18n( "Knights is unable to connect to the server.\n Please make sure your internet connection is working and try again."), i18n( "Cannot connect to server."));
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+ return;
+ }
+ }
+ socket->enableRead(true);
+ socket->enableWrite(true);
+
+ /* connect a signal to readReady */
+ connect(socket, SIGNAL(readEvent(KSocket *)), this, SLOT(readCommand(KSocket *)));
+
+ /* setup the seekTimer and turn it off by default */
+ seekTimer = new QTimer(this);
+ connect(seekTimer, SIGNAL(timeout()), this, SLOT(processSeekTimer()));
+
+ /* succesfully connected to the server, turn connected on and flush the command buffer */
+ connected = true;
+ for(j = myCommandBuffer.begin(); j != myCommandBuffer.end(); j++)
+ {
+ recvCMD(*j);
+ }
+
+ /*
+ Create ICS Related Tabs
+
+ These will need to be moved into thier own functions because we want to be able to open
+ and close these tabs at will, or have multiple open at once. ALL communication to our tabs
+ needs to be done with SIGNALS & SLOTS to facilitate this.
+ */
+ consoleTab = new Console( 0, myServer->Name, myResource );
+ myTabList[consoleTab] = consoleTab;
+ myResource->tabManager->addTab( myTabList[consoleTab], i18n( "%1 Console" ).arg( myServer->Name ) );
+ connect( myTabList[consoleTab], SIGNAL( sendCMD( const Command& ) ), this, SLOT( recvCMD( const Command& ) ) );
+ connect( this, SIGNAL( sendCMD( const Command& ) ), myTabList[consoleTab], SLOT( recvCMD( const Command& ) ) );
+
+ tempTab = new tab_SeekList( 0, "seekList", myResource );
+ myTabList[tempTab] = tempTab;
+ myResource->tabManager->addTab( myTabList[tempTab], i18n( "Sought Matches List" ) );
+ connect( myTabList[tempTab], SIGNAL( sendCMD( const Command& ) ), this, SLOT( recvCMD( const Command& ) ) );
+ connect( this, SIGNAL( sendCMD( const Command& ) ), myTabList[tempTab], SLOT( recvCMD( const Command& ) ) );
+
+ tempTab = new Challenge_Graph( 0, "seekGraph", myResource );
+ myTabList[tempTab] = tempTab;
+ myResource->tabManager->addTab( myTabList[tempTab], i18n( "Sought Matches Graph" ) );
+ connect( myTabList[tempTab], SIGNAL( sendCMD( const Command& ) ), this, SLOT( recvCMD( const Command& ) ) );
+ connect( this, SIGNAL( sendCMD( const Command& ) ), myTabList[tempTab], SLOT( recvCMD( const Command& ) ) );
+
+ myResource->tabManager->showTab(consoleTab);
+
+ /* ...log file */
+ if( !myServer->LogFile.isEmpty() )
+ {
+ Log = new QFile( myServer->LogFile );
+ if( !Log->open( IO_WriteOnly | IO_Append ) )
+ {
+ if( !Log->open( IO_WriteOnly ) )
+ {
+ kdError() << "Can not open " << myServer->LogFile << " for writing." << endl;
+ }
+ }
+ }
+ qApp->mainWidget()->setCursor( myResource->CURSOR_Standard );
+}
+
+void io_internet::recvCMD(const Command& command)
+{
+ QString error_message;
+
+ if(!connected)
+ {
+ myCommandBuffer.push_back(command);
+ return;
+ }
+
+ switch(((Command)command).getCommand())
+ {
+ case CMD_Move:
+ send(((Command)command).getMove().SAN);
+ break;
+ case CMD_Reset_Server:
+ sendUserSettings();
+ break;
+ case CMD_Toggle_Seek:
+ if(seekTimer->isActive())
+ {
+ /* timer running stop it */
+ seekTimer->stop();
+ emit sendCMD( Command( 0, CMD_Hide_Sought_List ) );
+ }
+ else
+ {
+ /* timer not running start it */
+ seekTimer->start(myResource->Seek_Timer * 100);
+ /* send a sought now */
+ processSeekTimer();
+ }
+ break;
+ case CMD_Player_Finger:
+ send("$finger " + ((Command)command).getData());
+ break;
+ case CMD_Add_Friend:
+ send("$+notify " + ((Command)command).getData());
+ break;
+ case CMD_Ignore_Player:
+ send("$+censor " + ((Command)command).getData());
+ break;
+ case CMD_Player_History:
+ send("$history " + ((Command)command).getData());
+ break;
+ case CMD_Start_Match:
+ send("$play " + ((Command)command).getData());
+ break;
+ case CMD_Assess:
+ send("$assess " + ((Command)command).getData());
+ break;
+ case CMD_Set_Input:
+ sendCMD( command );
+ break;
+ case CMD_Send_To_ICS:
+ if(((Command)command).getData().contains(QRegExp("^(?:\\.|tell)")))
+ {
+ writeToConsole(((Command)command).getData(), "K_PVT");
+ }
+ send(((Command)command).getData());
+ break;
+ case CMD_Examine_Forward:
+ send("$forward 1");
+ break;
+ case CMD_Examine_Backward:
+ send("$backward 1");
+ break;
+ case CMD_White_Resign:
+ case CMD_Black_Resign:
+ send("$resign");
+ break;
+ case CMD_Offer_Draw:
+ send("$draw");
+ break;
+ case CMD_Reject_Draw:
+ send("$decline t draw");
+ break;
+ default:
+ /* do nothing unknown command */
+ kdWarning() << "InternetIO::sendCMD received an unknown command: " << ((Command)command).getCommand() << endl;
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::send
+//
+///////////////////////////////////////
+void io_internet::send(const QString& msg)
+{
+ QString tmp(msg);
+ ssize_t len;
+
+ /* Attach events to specific outgoing text */
+ if( ( tmp == "accept" ) ||
+ ( tmp == "decline" ) ||
+ ( tmp.left(6) == "match " ) )
+ {
+ if( challenge != NULL )
+ {
+ delete challenge;
+ nullifyChallenge();
+ }
+ }
+ if( tmp.right(1) != "\n" )
+ {
+ tmp += "\n";
+ }
+
+ len = write(socket->socket(), tmp.latin1(), tmp.length() );
+
+ if( Log )
+ {
+ Log->writeBlock( QString("<< ").latin1(), 3 );
+ Log->writeBlock( tmp.latin1(), tmp.length() );
+ }
+ if( len < (signed)tmp.length() )
+ {
+ kdWarning() << "io_internet::Send: Failed to write full block of data to socket." << endl;
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::readCommand
+//
+///////////////////////////////////////
+void io_internet::readCommand(KSocket* socket)
+{
+ char buffer[READ_BUFFER_SIZE];
+ QString tmp;
+ QStringList lines;
+
+ memset(buffer, 0, READ_BUFFER_SIZE);
+ read(socket->socket(), buffer, READ_BUFFER_SIZE);
+ tmp = buffer;
+
+ tmp = lineBuffer + tmp;
+ if( Log )
+ {
+ Log->writeBlock( tmp.latin1(), tmp.length() );
+ }
+ if(loginStage != LOGIN_STAGE_LOGGED_IN)
+ {
+ // route all the data to the login parser
+ parseLoginData(tmp);
+ this->parseMode = NORMAL_MODE;
+ }
+ else
+ {
+ lines = QStringList::split( QRegExp("\n\r?"), tmp, FALSE );
+ if(!(tmp.endsWith("\n\r") || tmp.endsWith("\n")))
+ {
+ lineBuffer = (*(--lines.end()));
+ }
+ else
+ {
+ lineBuffer = "";
+ }
+ for(QStringList::iterator i = lines.begin(); i != lines.end(); i++)
+ {
+ if(lineBuffer == "" || i != --lines.end())
+ {
+ (*i).replace( QRegExp( "\\a" ), "" );
+ parseLine(*i);
+ }
+ }
+ }
+}
+///////////////////////////////////////
+//
+// io_internet::sendUserName
+//
+///////////////////////////////////////
+void io_internet::sendUserName()
+{
+ loginStage = LOGIN_STAGE_PASSWORD;
+ send(userName);
+}
+///////////////////////////////////////
+//
+// io_internet::sendPassword
+//
+///////////////////////////////////////
+void io_internet::sendPassword()
+{
+ send(passWord);
+}
+
+///////////////////////////////////////
+//
+// io_internet::parseLoginData
+//
+///////////////////////////////////////
+void io_internet::parseLoginData( QString data )
+{
+ QStringList lines;
+
+ if(loginStage == LOGIN_STAGE_NAME)
+ {
+ if(data.contains( "login:" ))
+ {
+ sendUserName();
+ }
+ lines = QStringList::split( QRegExp("\n\r?"), data, FALSE );
+ for(QStringList::iterator i = lines.begin(); i != lines.end(); i++)
+ {
+ writeToConsole((*i), "K_STD");
+ }
+ }
+ else if(loginStage == LOGIN_STAGE_PASSWORD)
+ {
+ if(data.contains("**** Invalid password! ****") ||
+ data.contains("Sorry, names can only consist of lower and upper case letters. Try again.") ||
+ data.contains("If you are not a registered player, enter guest or a unique ID."))
+ {
+ loginDlg = new dlg_login( myParent, "LoginDialog", myResource);
+ loginDlg->disableServerSelect();
+ connect(loginDlg, SIGNAL( okClicked() ), this, SLOT( sendUserName() ) );
+ connect(loginDlg, SIGNAL( cancelClicked() ), this, SLOT( selfDestruct() ) );
+ connect(loginDlg, SIGNAL( login(QString, QString) ), this, SLOT( setUserInfo(QString, QString) ) );
+ }
+ else if(data.contains("Press return to enter the server as"))
+ {
+ QRegExp guestName("Logging you in as \"(\\w*)\"");
+ int pos = guestName.search(data);
+ if(pos > -1)
+ {
+ userName = guestName.cap(1);
+ }
+ send("\n");
+ }
+ else if(data.contains("password:"))
+ {
+ sendPassword();
+ }
+ else
+ {
+ loginStage = LOGIN_STAGE_LOGGED_IN;
+ sendUserSettings();
+ }
+ lines = QStringList::split( QRegExp("\n\r?"), data, FALSE );
+ for(QStringList::iterator i = lines.begin(); i != lines.end(); i++)
+ {
+ writeToConsole((*i), "K_STD");
+ }
+ }
+ else
+ {
+ lines = QStringList::split( QRegExp("\n\r?"), data, FALSE );
+ for(QStringList::iterator i = lines.begin(); i != lines.end(); i++)
+ {
+ writeToConsole((*i), "K_STD");
+ }
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::ParseLine
+//
+///////////////////////////////////////
+void io_internet::parseLine( QString line )
+{
+ int i, j;
+ QString tmp;
+
+ switch(parseMode)
+ {
+ case NORMAL_MODE: /* determine which mode we should go into */
+ if(line.contains(QRegExp("^\\s*\\d{1,3}\\s+(?:\\d{1,4}|\\+\\+\\+\\+|\\-\\-\\-\\-)\\s+\\w{3,17}(\\(C\\))?\\s+\\d{1,3}\\s+\\d{1,3}")))
+ {
+ updateSoughtList(line);
+ parseMode = UPDATE_SOUGHT_MODE;
+ }
+ /* CHALLENGE */
+ else if( line.contains(QRegExp("^\\s*Challenge: ")))
+ {
+ myResource->play( SND_CHALLENGE );
+ if( challenge != NULL )
+ {
+ delete challenge;
+ }
+ challenge = new dlg_challenge( 0, "Challenge", myResource );
+ connect( challenge, SIGNAL( destroyed() ), this, SLOT( nullifyChallenge() ) );
+ connect( challenge, SIGNAL( user1Clicked() ), this, SLOT( acceptChallenge() ) );
+ connect( challenge, SIGNAL( user2Clicked() ), this, SLOT( declineChallenge() ) );
+ line.replace(QRegExp("^\\s*Challenge: "), "");
+ challenge->setValues( line, userName );
+ parseMode = CHALLENGE_MODE;
+ }
+ else if( ( line.left(15) == "Challenge from " ) && ( line.right(9) == " removed." ) )
+ {
+ if( challenge != NULL )
+ {
+ delete challenge;
+ }
+ }
+ /* SOUGHT GAME */
+ else if(line.contains("seeking"))
+ {
+ // writeToConsole("seeking", "K_CH");
+ }
+ /* PRIVATE TELL */
+ else if(line.contains(QRegExp(".+ tells you: .*")))
+ {
+ /* First grab the user name so we can auto-respond later */
+ emit sendCMD( Command( 0, CMD_Set_Src_Tell, line.section(' ', 0, 0) ) );
+ myResource->play( SND_TELL );
+ writeToConsole(line, "K_PVT");
+ }
+ /* SAY */
+ else if(line.contains( QRegExp(".+ says: .*")))
+ {
+ myResource->play(SND_SAY);
+ writeToConsole(line, "K_PVT");
+ return;
+ }
+ /* WHISPER & KIBITZ */
+ else if(line.contains(QRegExp(".+ whispers: .*")) || line.contains(QRegExp(".+ kibitzes: .*")))
+ {
+ writeToConsole(line, "K_WSP");
+ }
+ /* Important System Messages: Use Whisper Color */
+ else if(line.contains(QRegExp("declines the draw request\\.$" )))
+ {
+ writeToConsole(line, "K_WSP");
+ }
+ /* DRAW OFFER */
+ else if(line.right(19) == " offers you a draw.")
+ {
+ writeToConsole(line, "K_WSP");
+ }
+ else if( line.contains( QRegExp(".+rating adjustment:.+" ) ) )
+ {
+ writeToConsole(line, "K_WSP");
+ }
+ /* SHOUTS */
+ else if( line.contains( QRegExp("^c?t?s?-?shouts: ") ) )
+ {
+ writeToConsole(line, "K_SHT");
+ }
+ /* NOTIFY */
+ else if((line.contains(QRegExp("\\s*Notification:"))) ||
+ (line.contains(QRegExp("\\s*Present company includes:"))) ||
+ (line.contains(QRegExp("\\s*Your arrival was noted by:"))))
+ {
+ writeToConsole(line, "K_NOT");
+ myResource->play( SND_NOTIFICATION );
+ }
+ /* CHANNEL TELLS */
+ else if(line.contains(QRegExp( ".\\(\\d+\\):" )))
+ {
+ /* First grab the channel # so we can auto-respond later */
+ j = line.find(QString("):"));
+ i = line.findRev(QString("("), j) + 1;
+ emit sendCMD( Command( 0, CMD_Set_Src_Channel, line.mid(i, j - i) ) );
+ writeToConsole(line, "K_CH");
+ }
+ else if(line.contains(QRegExp("^<12>\\s")))
+ {
+ /* a game move */
+ parseStyle12(line, PARSE12_MODE_MOVE);
+ }
+ else if(line.contains(QRegExp("^<b1>\\s")))
+ {
+ /* a bughouse piece has been passed or a piece has been captured in crazyhouse */
+ writeToConsole(line, "K_CH");
+ }
+ else if(line.contains(QRegExp("^\\\\")))
+ {
+ writeToConsole(line, lastTag);
+ }
+ else if(line.contains(QRegExp("^\\{?Game \\d+")) && line.contains("Creating", TRUE))
+ {
+ parseMode = NEW_GAME_MODE;
+ }
+ else if(line.contains("You are now observing game"))
+ {
+ parseMode = OBSERVE_GAME_MODE;
+ }
+ else if(line.startsWith("Movelist for game"))
+ {
+ QRegExp gameNumber("\\d+");
+ int pos = gameNumber.search(line);
+ if(pos > -1)
+ {
+ ficsMoveListNumber = gameNumber.cap(0).toInt();
+ }
+ parseMode = PARSE_MOVE_LIST_MODE;
+ }
+ else if((line.contains(QRegExp("^\\{?Game \\d+")) || line.contains(QRegExp("Game \\d+"))) &&
+ (
+ line.contains(" forfeits by disconnection", TRUE) ||
+ line.contains(" forfeits by disconnection}", TRUE) ||
+ line.contains(" forfeits on time} ", TRUE) ||
+ line.contains(" forfeits on time ", TRUE) ||
+ line.contains(" resigns} ", TRUE) ||
+ line.contains(" resigns ", TRUE) ||
+ line.contains(" Game drawn by mutual agreement ", TRUE) ||
+ line.contains(" Game drawn by mutual agreement} ", TRUE) ||
+ line.contains(", has lost contact or quit.", TRUE) ||
+ line.contains(" checkmated ", TRUE) ||
+ line.contains(" checkmated} ", TRUE) ||
+ line.contains("lost connection", TRUE) ||
+ line.contains("has no material to mate", TRUE)
+ )
+ )
+ {
+ sendEndOfGameCommand(line);
+ }
+ else
+ {
+ /* don't know what to do with it, just send it to the console */
+ /* don't write the prompt to the console */
+ if( line.contains( QRegExp( "^a?d?f?g?s?z?ics% " ) ) ||
+ line.contains( QRegExp( "^cex% " ) ) ||
+ line.contains( QRegExp( "^chess% " ) ) )
+ break;
+ writeToConsole(line, "K_STD");
+ }
+ break;
+ case UPDATE_SOUGHT_MODE:
+ if(line.contains(QRegExp("\\d+\\s+ads? displayed.")))
+ {
+ updateSoughtList(line);
+ parseMode = NORMAL_MODE;
+ }
+ else
+ {
+ updateSoughtList(line);
+ }
+ break;
+ case NEW_GAME_MODE:
+ if(line.contains(QRegExp("<12>\\s")))
+ {
+ /* a game move */
+ parseStyle12(line, PARSE12_MODE_NEW);
+ }
+ else if((line.startsWith("fics%") && line.length() == 6))
+ {
+ parseMode = NORMAL_MODE;
+ }
+ break;
+ case OBSERVE_GAME_MODE:
+ if(line.contains(QRegExp("<12>\\s")))
+ {
+ /* a game move */
+ parseStyle12(line, PARSE12_MODE_NEW);
+ send("moves");
+ parseMode = NORMAL_MODE;
+ }
+ break;
+ case CHALLENGE_MODE:
+ if(line.startsWith("You can \"accept\" or \"decline\", or propose"))
+ {
+ parseMode = NORMAL_MODE;
+ }
+ break;
+ case PARSE_MOVE_LIST_MODE:
+ if(!line.contains("{Still in progress}"))
+ {
+ if(line.contains(QRegExp("\\d\\.")))
+ {
+ parseMoveList(line);
+ }
+ }
+ else
+ {
+ parseMode = NORMAL_MODE;
+ }
+ break;
+ default: /* do nothing */
+ break;
+ };
+}
+
+///////////////////////////////////////
+//
+// io_internet::ParseStyle12
+//
+///////////////////////////////////////
+void io_internet::parseStyle12(QString line, const unsigned int Mode)
+{
+// kdWarning() << line << endl;
+
+ struct ChessMove move;
+ QStringList fields;
+ QString position_line = "";
+ match_param *param = NULL;
+ Command::clearMove(&move);
+ switch(Mode)
+ {
+ case PARSE12_MODE_NEW:
+ {
+ /* a new game that we are playing, or observing */
+ param = new match_param(this->myResource);
+ fields = QStringList::split( QChar(' '), line, FALSE );
+
+ /* set white time control */
+ TCPList tmpListWhite(param->time(WHITE));
+ TCP tmpTCPWhite = tmpListWhite[0];
+ tmpTCPWhite.Seconds = fields[20].toInt() * 60;
+ tmpTCPWhite.Increment = fields[21].toInt();
+ tmpListWhite[0] = tmpTCPWhite;
+ param->setTime(WHITE, tmpListWhite);
+
+ /* set black time control */
+ TCPList tmpListBlack(param->time(BLACK));
+ TCP tmpTCPBlack = tmpListBlack[0];
+ tmpTCPBlack.Seconds = fields[20].toInt() * 60;
+ tmpTCPBlack.Increment = fields[21].toInt();
+ tmpListBlack[0] = tmpTCPBlack;
+ param->setTime(BLACK, tmpListBlack);
+
+ if((userName.upper() == fields[17].upper()) &&
+ ((fields[19].toInt() == -1) || (fields[19].toInt() == 1)))
+ {
+ /* I am playing white */
+ param->setType(WHITE, PLAYERLOCAL);
+ }
+ else if(fields[19].toInt() != 2)
+ {
+ /* I am not playing white */
+ param->setType(WHITE, PLAYERTCP);
+ }
+
+ if((userName.upper() == fields[18].upper()) &&
+ ((fields[19].toInt() == -1) || (fields[19].toInt() == 1)))
+ {
+ /* I am playing black */
+ param->setType(BLACK, PLAYERLOCAL);
+ }
+ else if(fields[19].toInt() != 2)
+ {
+ /* I am not playing black */
+ param->setType(BLACK, PLAYERTCP);
+ }
+
+ if(fields[19].toInt() == 2)
+ {
+ param->setType(WHITE, PLAYEREXAMINE);
+ param->setType(BLACK, PLAYEREXAMINE);
+ }
+ //param->setVariation(something); figure out how to get the variation
+ param->setName(WHITE, fields[17]);
+ param->setName(BLACK, fields[18]);
+ /* tell core to connect us to a new match */
+ fics_to_knights[fields[16].toInt()] = ((core*)myParent)->newMatch(param)->getID();
+ }
+ case PARSE12_MODE_MOVE:
+ {
+ fields = QStringList::split( QChar(' '), line, FALSE );
+
+ /* various ICS stuff for ChessMove */
+ move.ICS_ClockTicking = fields[31].toInt();
+ move.ICS_PawnPushFile = fields[10].toShort();
+ move.ICS_MoveCounter = fields[15].toInt();
+ if(fields[9] == "W")
+ {
+ move.ICS_OnMove = BLACK;
+ }
+ else if( fields[9] == "B" )
+ {
+ move.ICS_OnMove = WHITE;
+ }
+
+ switch( fields[19].toInt() )
+ {
+ /* Examining a game */
+ case 2:
+ move.ICS_Mode = ICS_Examine;
+ if(fics_to_knights[fields[16].toInt()] == 0)
+ {
+ /* no new game started yet, call parsestyle 12 with a different mode */
+ parseStyle12(line, PARSE12_MODE_NEW);
+ return;
+ }
+ break;
+ /* Observing a game */
+ case -2:
+ case 0:
+ move.ICS_Mode = ICS_Observe;
+ break;
+ /* Playing a game */
+ default:
+ move.ICS_Mode = ICS_Normal;
+ break;
+ }
+
+ /* Verbose Coordinate Notation of previous move ( USE AS CAN ) */
+ strcpy(move.CAN, fields[27].right(fields[27].length() - 2).replace(QRegExp("-"), ""));
+ /* SAN */
+ strcpy(move.SAN, fields[29].replace(QRegExp("\\+"), "").replace(QRegExp("#"), ""));
+
+ /* fill the line for the command */
+ position_line += fields[1]; /* Internal Rank #7 */
+ position_line += fields[2]; /* Internal Rank #6 */
+ position_line += fields[3]; /* Internal Rank #5 */
+ position_line += fields[4]; /* Internal Rank #4 */
+ position_line += fields[5]; /* Internal Rank #3 */
+ position_line += fields[6]; /* Internal Rank #2 */
+ position_line += fields[7]; /* Internal Rank #1 */
+ position_line += fields[8]; /* Internal Rank #0 */
+ /* Can White Castle Short (boolean) */
+ position_line += fields[11];
+ /* Can White Castle Long (boolean) */
+ position_line += fields[12];
+ /* Can Black Castle Short (boolean) */
+ position_line += fields[13];
+ /* Can Black Castle Long (boolean) */
+ position_line += fields[14];
+
+ Command command(fics_to_knights[fields[16].toInt()], CMD_Move, fields[24].toInt() * 100,
+ fields[25].toInt() * 100, move);
+ command.setData(position_line);
+ emit sendCMD(command);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::ParsePlayer
+//
+///////////////////////////////////////
+//void io_internet::ParsePlayer( QString Handle )
+//{
+// player.Raw = Handle;
+ /* SysAdmin */
+// if( Handle.contains( QRegExp("\\(\\*\\)") ) )
+// {
+// player.SysAdmin = TRUE;
+// Handle.replace( QRegExp("\\(\\*\\)"), QString("") );
+// }
+// else player.SysAdmin = FALSE;
+ /* ServiceRep */
+// if( Handle.contains( QRegExp("\\(SR\\)") ) )
+// {
+// player.ServiceRep = TRUE;
+// Handle.replace( QRegExp("\\(SR\\)"), QString("") );
+// }
+// else player.ServiceRep = FALSE;
+ /* Computer */
+// if( Handle.contains( QRegExp("\\(C\\)") ) )
+// {
+// player.Computer = TRUE;
+// Handle.replace( QRegExp("\\(C\\)"), QString("") );
+// }
+// else player.Computer = FALSE;
+ /* Unregistered */
+// if( Handle.contains( QRegExp("\\(U\\)") ) )
+// {
+// player.Unregistered = TRUE;
+// Handle.replace( QRegExp("\\(U\\)"), QString("") );
+// }
+// else player.Unregistered = FALSE;
+// return;
+//}
+///////////////////////////////////////
+//
+// io_internet::nullifyChallenge
+//
+///////////////////////////////////////
+void io_internet::nullifyChallenge( void )
+{
+ challenge = NULL;
+}
+
+///////////////////////////////////////
+//
+// io_internet::declineChallenge
+//
+///////////////////////////////////////
+void io_internet::declineChallenge( void )
+{
+ send( "decline" );
+ delete challenge;
+ challenge = NULL;
+}
+///////////////////////////////////////
+//
+// io_internet::acceptChallenge
+//
+///////////////////////////////////////
+void io_internet::acceptChallenge( void )
+{
+ send( challenge->values() );
+ delete challenge;
+ challenge = NULL;
+}
+
+///////////////////////////////////////
+//
+// io_internet::writeToConsole
+//
+///////////////////////////////////////
+void io_internet::writeToConsole(QString text, QString tag)
+{
+ lastTag = tag;
+ /* Remove Bells */
+ text.replace( QRegExp("\\x0007") , "" );
+ /* Replace misc characters with rich-text friendly counterparts */
+ text.replace( QRegExp("\\x003c"), "&#60;" );
+ text.replace( QRegExp("\\x007c"), "&#124;" );
+ text.replace( QRegExp( "\\f"), "");
+ text.replace( QRegExp( "\\n"), "");
+ text.replace( QRegExp( "\\r*" ), "" );
+ emit sendCMD( Command( 0, CMD_Append_To_Console, "<" + tag + ">" + text + "</" + tag + ">" ) );
+}
+
+///////////////////////////////////////
+//
+// io_internet::updateSoughtList
+//
+///////////////////////////////////////
+void io_internet::updateSoughtList(QString soughtLine)
+{
+ /* "ADS DISPLAYED" MESSAGE */
+ if(soughtLine.contains(QRegExp("\\d+\\s+ads? displayed.")))
+ {
+ emit sendCMD( Command( 0, CMD_Show_Sought_List ) );
+ }
+ else
+ {
+ emit sendCMD( Command( 0, CMD_Add_Sought_Match, soughtLine ) );
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::sendUserSettings()
+//
+///////////////////////////////////////
+void io_internet::sendUserSettings()
+{
+ send("set style 12");
+ send(QString("set interface Knights %1").arg(_VERSION_));
+ send(QString("set private %1").arg(myResource->OPTION_Private));
+ send(QString("set kibitz %1").arg(myResource->OPTION_Kibitz));
+ send(QString("set tell %1").arg(myResource->OPTION_Tell));
+ send(QString("set shout %1").arg(myResource->OPTION_Shout));
+ send(QString("set seek %1").arg(myResource->OPTION_Seek));
+ send(QString("set tolerance %1").arg(myResource->OPTION_Profanity));
+}
+
+///////////////////////////////////////
+//
+// io_internet::parseMoveList(QString data)
+//
+///////////////////////////////////////
+void io_internet::parseMoveList(QString line)
+{
+ QStringList two_plys;
+ struct ChessMove move;
+ Command command;
+ int move_counter = 0;
+
+ /* white */
+ two_plys = QStringList::split(QRegExp("\\s+"), line, FALSE);
+ Command::clearMove(&move);
+ move_counter = two_plys[0].left(two_plys[0].length() - 1).length(); /* remove the . */
+ move.ICS_MoveCounter = move_counter;
+ move.ICS_Mode = ICS_Movelist;
+ move.ICS_OnMove = WHITE;
+ strcpy(move.SAN, two_plys[1]);
+ command.setCommand((int&)CMD_Move);
+ command.setID(fics_to_knights[ficsMoveListNumber]);
+ command.setMove(move);
+ emit sendCMD(command);
+
+ /* black */
+ if(two_plys.size() > 3)
+ {
+ Command::clearMove(&move);
+ move.ICS_MoveCounter = move_counter;
+ move.ICS_Mode = ICS_Movelist;
+ move.ICS_OnMove = BLACK;
+ strcpy(move.SAN, two_plys[3]);
+ command.setCommand((int&)CMD_Move);
+ command.setID(fics_to_knights[ficsMoveListNumber]);
+ command.setMove(move);
+ emit sendCMD(command);
+ }
+}
+
+///////////////////////////////////////
+//
+// io_internet::sendEndOfGameCommand(QString line)
+//
+///////////////////////////////////////
+void io_internet::sendEndOfGameCommand(QString line)
+{
+ QStringList fields;
+ Command command;
+
+ fields = QStringList::split( QChar(' '), line, FALSE );
+ if(fields[1].endsWith(":"))
+ {
+ fields[1] = fields[1].left(fields[1].length() - 1);
+ }
+ command.setID(fics_to_knights[fields[1].toInt()]);
+ fields[fields.count() - 1] = fields[fields.count() - 1].stripWhiteSpace();
+ if(fields[fields.count() - 1] == "1-0" )
+ {
+ if(fields[fields.count() - 2].contains("resigns"))
+ {
+ command.setCommand((int&)CMD_Black_Resign);
+ }
+ else if(fields[fields.count() - 2].contains("time"))
+ {
+ command.setCommand((int&)CMD_White_Called_Flag);
+ }
+ else
+ {
+ command.setCommand((int&)CMD_Result_White);
+ }
+ }
+ else if(fields[fields.count() - 1] == "0-1")
+ {
+ if(fields[fields.count() - 2].contains("resigns"))
+ {
+ command.setCommand((int&)CMD_White_Resign);
+ }
+ else if(fields[fields.count() - 2].contains("time"))
+ {
+ command.setCommand((int&)CMD_Black_Called_Flag);
+ }
+ else
+ {
+ command.setCommand((int&)CMD_Result_Black);
+ }
+ }
+ else if(fields[fields.count() - 1] == "1/2-1/2")
+ {
+ command.setCommand((int&)CMD_Result_Draw);
+ }
+ else
+ {
+ command.setCommand((int&)CMD_Lost_Contact);
+ }
+ emit sendCMD(command);
+}
+
+///////////////////////////////////////
+//
+// io_internet::processSeekTimer()
+//
+///////////////////////////////////////
+void io_internet::processSeekTimer()
+{
+ /* timer timed out, send out a sought */
+ send("sought");
+}
+
+///////////////////////////////////////
+//
+// io_internet::selfDestruct()
+//
+///////////////////////////////////////
+void io_internet::selfDestruct()
+{
+ /* cause the io_internet to delete itself */
+ QApplication::postEvent( qApp->mainWidget(), new QCustomEvent( EVENT_Del_IO_Net ) );
+}
+
+///////////////////////////////////////
+//
+// io_internet::setUserInfo()
+//
+///////////////////////////////////////
+void io_internet::setUserInfo(QString userName, QString passWord)
+{
+ this->userName = userName;
+ this->passWord = passWord;
+}
+
diff --git a/knights/io_internet.h b/knights/io_internet.h
new file mode 100644
index 0000000..cf56379
--- /dev/null
+++ b/knights/io_internet.h
@@ -0,0 +1,138 @@
+/***************************************************************************
+ io_internet.h - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef IO_INTERNET_H
+#define IO_INTERNET_H
+
+/* Local */
+#include "definitions.h"
+#include "io_base.h"
+#include "match_param.h"
+#include "command.h"
+
+/* Tabs */
+#include "tabmanager.h"
+#include "console.h"
+#include "challenge_graph.h"
+#include "tab_seeklist.h"
+
+class KSocket;
+class KProcess;
+class resource;
+class core;
+class dlg_login;
+class dlg_challenge;
+
+#include <qfile.h>
+
+/**
+ *@author Troy Corbin Jr / Alexander Wels.
+ */
+
+struct MatchRecord
+{
+ int knightsID;
+ int serverID;
+ bool observing;
+ bool examining;
+ bool finished;
+};
+
+const int READ_BUFFER_SIZE = 64 * 1024; /* 64k is max ip packet size */
+
+const int LOGIN_STAGE_NAME = 1;
+const int LOGIN_STAGE_PASSWORD = 2;
+const int LOGIN_STAGE_LOGGED_IN = 3;
+
+const unsigned int NORMAL_MODE = 1;
+const unsigned int UPDATE_SOUGHT_MODE = 2;
+const unsigned int NEW_GAME_MODE = 3;
+const unsigned int OBSERVE_GAME_MODE = 4;
+const unsigned int CHALLENGE_MODE = 5;
+const unsigned int PARSE_MOVE_LIST_MODE = 6;
+
+const unsigned int PARSE12_MODE_NEW = 1;
+const unsigned int PARSE12_MODE_MOVE = 2;
+
+typedef QMap<QWidget *, QWidget *> TabMap;
+
+class io_internet : public io_base
+{
+ Q_OBJECT
+ public:
+ io_internet(QWidget *parent = NULL, resource *Rsrc = NULL);
+ ~io_internet();
+
+ public slots:
+ virtual void recvCMD(const Command& command);
+ void readCommand(KSocket *);
+ void sendUserName(void);
+ void sendPassword(void);
+ void send(const QString&);
+ void nullifyChallenge( void );
+ void acceptChallenge( void );
+ void declineChallenge( void );
+ void processSeekTimer( void );
+ void connectToServer( void );
+ void selfDestruct( void );
+ void setUserInfo(QString userName, QString passWord);
+ signals:
+ virtual void sendCMD(const Command& command);
+ void setLastPrivateSource( const QString& );
+ void setLastChannelSource( const QString& );
+
+ protected:
+ void parseLine(QString command);
+ void parseLoginData(QString command);
+ void writeToConsole(QString text, QString tag);
+ void updateSoughtList(QString text);
+ void parseStyle12(QString line, const unsigned int mode);
+ void sendUserSettings(void);
+ void parseMoveList(QString data);
+ void sendEndOfGameCommand(QString line);
+ private:
+
+ dlg_login *loginDlg;
+ dlg_challenge *challenge;
+
+ /* These are used to handle the automagic seek command */
+ QTimer *seekTimer;
+
+ /* These are used for the connection & logon */
+ QFile *Log;
+ KSocket *socket;
+ KProcess *myTimeseal;
+ struct serverResource *myServer;
+ int loginStage;
+ unsigned int parseMode;
+ QString lastTag;
+ int ficsMoveListNumber;
+ QString lineBuffer;
+ bool connected;
+ QString userName;
+ QString passWord;
+
+ /* communication with the server */
+ QStringList command_list; /* this is a temp buffer while waiting for the movelist */
+ bool waiting_for_move_list;
+ QMap<match_param *, int> fics_ids;
+ QMap<int, int> fics_to_knights; /* maps fics id's to knights id's */
+ TabMap myTabList; /* maintains the list of the tabs currently owned by this io_internet */
+ QValueList<Command> myCommandBuffer; /* this is a buffer for all the commands io_internet received while not connected to a server */
+};
+
+#endif
diff --git a/knights/knights.cpp b/knights/knights.cpp
new file mode 100644
index 0000000..ae68539
--- /dev/null
+++ b/knights/knights.cpp
@@ -0,0 +1,1024 @@
+/***************************************************************************
+ knights.cpp - description
+ -------------------
+ begin : Thu Mar 1 10:43:51 CST 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/* Local */
+#include "knights.moc"
+#include "core.h"
+#include "wiz_setup.h"
+#include "pgn.h"
+#include "splash.h"
+#include "dlg_settings.h"
+#include "dlg_newmatch.h"
+/* KDE */
+#include <kmenubar.h>
+#include <kmessagebox.h>
+#include <kicontheme.h>
+#include <kkeydialog.h>
+#include <kcombobox.h>
+#include <kpopupmenu.h>
+#include <klocale.h>
+/* KFile */
+#include <kfiledialog.h>
+/* Qt */
+#include <qpalette.h>
+#include <qiconset.h>
+#include <qlabel.h>
+#include <qframe.h>
+#include <qstyle.h>
+
+Knights::Knights(KCmdLineArgs *Args, QWidget *parent, const char *name) : KMainWindow(parent, name)
+{
+ InitAll = TRUE;
+ ResizeFlag = TRUE;
+ Minimized = FALSE;
+ args = Args;
+ SplashScreen = NULL;
+ setFocusPolicy( ClickFocus );
+}
+Knights::~Knights()
+{
+ if( !InitAll )
+ KillAll();
+}
+///////////////////////////////////////
+//
+// Knights::BirthAll
+//
+///////////////////////////////////////
+void Knights::BirthAll(void)
+{
+ SettingsDialog = NULL;
+ Resource = new resource(args);
+
+ if( Resource->OPTION_Show_Splash )
+ SplashScreen = new splash();
+
+ aboutData = new KAboutData( "knights", I18N_NOOP("Knights"), _VERSION_ );
+ topMenu = menuBar();
+ myAccel = new Accel( this, Resource->myAccel );
+ help = helpMenu();
+ fileMenu = new KPopupMenu( this , "fileMenu");
+ settingsMenu = new KPopupMenu( this, "settingsMenu");
+ matchMenu = new KPopupMenu( this, "matchMenu");
+ drawMenu = new KPopupMenu( this, "drawMenu");
+ tutorialMenu = new KPopupMenu( this, "tutorialMenu");
+ MainFrame = new QFrame( this, "MainFrame" );
+ Core = new core( MainFrame, "Core", Resource );
+ Message = new QLabel( MainFrame, "Message");
+ whiteTimeLabel = new QLabel( MainFrame, "whiteTimeLabel");
+ blackTimeLabel = new QLabel( MainFrame, "blackTimeLabel");
+ notationBar = new KComboBox( MainFrame, "notationBar");
+
+ /* Connect all Signals & Slots */
+ connect( Core, SIGNAL( requestResize() ), this, SLOT( resizeMainFrame() ) );
+ connect( Core, SIGNAL( setStatusBar(const int&, const QString& ) ), this, SLOT( setStatusBar(const int&, const QString& ) ) );
+ connect( Core, SIGNAL( setNotation() ), this, SLOT( setNotation() ) );
+ connect( Core, SIGNAL( initMatch() ), this, SLOT( initMatch() ) );
+ connect( Core, SIGNAL( setClocks() ), this, SLOT( setClocks() ) );
+ connect( Core, SIGNAL( serverDestroyed() ), this, SLOT( netConnect() ) );
+ connect( notationBar, SIGNAL( activated(int) ), Core, SLOT( review(int) ) );
+}
+///////////////////////////////////////
+//
+// Knights::menuClose
+//
+///////////////////////////////////////
+void Knights::menuClose(void)
+{
+ if( !queryClose() )
+ return;
+ qApp->quit();
+}
+///////////////////////////////////////
+//
+// Knights::queryClose
+//
+///////////////////////////////////////
+bool Knights::queryClose(void)
+{
+ return Core->clearAll();
+}
+///////////////////////////////////////
+//
+// Knights::KillAll
+//
+///////////////////////////////////////
+void Knights::KillAll(void)
+{
+ delete Core;
+ delete fileMenu;
+ delete matchMenu;
+ delete drawMenu;
+ delete tutorialMenu;
+ delete settingsMenu;
+ delete whiteTimeLabel;
+ delete blackTimeLabel;
+ delete notationBar;
+ delete Message;
+ delete aboutData;
+ delete MainFrame;
+ delete myAccel;
+ delete Resource;
+ InitAll = TRUE;
+}
+///////////////////////////////////////
+//
+// Knights::init
+//
+///////////////////////////////////////
+bool Knights::init( void )
+{
+ wiz_setup *Wizard;
+ QColorGroup GroupWhite;
+ QColorGroup GroupBlack;
+
+ BirthAll();
+ SelectTheme(-1,-1);
+ Resource->setAudio();
+ ResizeFlag = FALSE;
+
+ /*
+ Connect Accelerators
+ */
+ connect( Resource->myAccel, SIGNAL( board_up() ), this, SLOT( boardBigger() ) );
+ connect( Resource->myAccel, SIGNAL( board_down() ), this, SLOT( boardSmaller() ) );
+ connect( Resource->myAccel, SIGNAL( move_prev() ), this, SLOT( PrevNotation() ) );
+ connect( Resource->myAccel, SIGNAL( move_next() ), this, SLOT( NextNotation() ) );
+ connect( this, SIGNAL( focus( const QChar& ) ), Resource->myAccel, SIGNAL( focus( const QChar& ) ) );
+
+ initMenus();
+
+ /* Init Message */
+ Message->setAlignment( Qt::AlignAuto | Qt::AlignVCenter | Qt::SingleLine );
+
+ /* Init White Time Label */
+ GroupWhite.setColor( QColorGroup::Background, Resource->COLOR_White );
+ GroupWhite.setColor( QColorGroup::Foreground, Resource->COLOR_Black );
+ whiteTimeLabel->setPalette( QPalette( GroupWhite, GroupWhite, GroupWhite ) );
+ whiteTimeLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ whiteTimeLabel->setAlignment( Qt::AlignCenter | Qt::SingleLine );
+
+ /* Init Black Time Label */
+ GroupBlack.setColor( QColorGroup::Background, Resource->COLOR_Black );
+ GroupBlack.setColor( QColorGroup::Foreground, Resource->COLOR_White );
+ blackTimeLabel->setPalette( QPalette( GroupBlack, GroupBlack, GroupBlack ) );
+ blackTimeLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ blackTimeLabel->setAlignment( Qt::AlignCenter | Qt::SingleLine );
+
+ /* Configure self */
+ setCentralWidget( MainFrame );
+ InitAll = FALSE;
+ resizeMainFrame();
+ show();
+ setStatusBar( READY );
+
+ /* Remove the Splash Screen */
+ if( SplashScreen != NULL )
+ {
+ delete SplashScreen;
+ }
+
+ /* Run the Setup Wizard if needed */
+ if( Resource->Config_Version < CONFIG_VERSION )
+ {
+ Wizard = new wiz_setup( this, "wiz_setup", Resource );
+ Wizard->exec();
+ delete Wizard;
+ resizeMainFrame();
+ /* if( !Resource->Accepted_License )
+ return FALSE;*/
+ Resource->Config_Version = CONFIG_VERSION;
+ }
+
+ /* Begin loading file from command line */
+ if( args->count() )
+ {
+ Core->load( QString( args->arg( 0 ) ) );
+ }
+ else
+ {
+ /* Bring up a match or pgn file */
+ switch( Resource->OPTION_On_Init )
+ {
+ case MENU_SOLITARE:
+ Core->newMatch( new match_param( Resource, PLAYERLOCAL, PLAYERLOCAL ) );
+ break;
+ case MENU_VS_PC:
+ if( Resource->engines.count() )
+ {
+ Core->newMatch( new match_param( Resource, PLAYERLOCAL, PLAYERPC ) );
+ }
+ break;
+ case MENU_CONNECT:
+ netConnect();
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// Knights::initMenus
+//
+///////////////////////////////////////
+void Knights::initMenus( void )
+{
+ /*
+ matchMenu menu
+ */
+ matchMenu->setCheckable(TRUE);
+ // MENU_DRAW
+ matchMenu->insertItem( i18n( "&Draw" ), drawMenu, MENU_DRAW );
+ matchMenu->setItemEnabled( MENU_DRAW, FALSE );
+ // MENU_RETRACT
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("undo"), KIcon::Small ) ),
+ i18n( "&Retract Move" ), Core, SLOT(matchMenu(int)), 0, MENU_RETRACT );
+ matchMenu->setItemEnabled( MENU_RETRACT, FALSE );
+ matchMenu->setWhatsThis( MENU_RETRACT, i18n( "Select this to retract your last move." ) );
+ // MENU_RESIGN
+ matchMenu->insertItem( i18n( "Resign" ), Core, SLOT(matchMenu(int)), 0, MENU_RESIGN );
+ matchMenu->setItemEnabled( MENU_RESIGN, FALSE );
+ matchMenu->setWhatsThis( MENU_RESIGN, i18n( "Use this to concede the match to your opponent." ) );
+ // MENU_CALL_FLAG
+ matchMenu->insertItem( i18n( "&Call Flag" ), Core, SLOT(matchMenu(int)), 0, MENU_CALL_FLAG );
+ matchMenu->setItemEnabled( MENU_CALL_FLAG, FALSE );
+ matchMenu->setWhatsThis( MENU_CALL_FLAG, i18n( "Use this to declare the match over, due to your opponent being out of time." ) );
+ // MENU_HINT
+ matchMenu->insertItem( i18n( "&Hint" ), Core, SLOT(matchMenu(int)), 0, MENU_HINT );
+ matchMenu->setItemEnabled( MENU_HINT, FALSE );
+ matchMenu->setWhatsThis( MENU_HINT, i18n( "This will ask your opponent for a hint." ) );
+ // MENU_MOVE_NOW
+ matchMenu->insertItem( i18n( "Move &Now" ), Core, SLOT(matchMenu(int)), 0, MENU_MOVE_NOW );
+ matchMenu->setItemEnabled( MENU_MOVE_NOW, FALSE );
+ matchMenu->setWhatsThis( MENU_MOVE_NOW, i18n( "Clicking this option will force your opponent to move immediately." ) );
+ // MENU_ORIENTATION
+ matchMenu->insertItem( i18n( "&Flip View" ), Core, SLOT(matchMenu(int)), Key_F2, MENU_ORIENTATION );
+ matchMenu->setItemEnabled( MENU_ORIENTATION, FALSE );
+ matchMenu->setWhatsThis( MENU_ORIENTATION, i18n( "This will reverse the chessboard's orientation by 180 degrees." ) );
+ // MENU_PONDER
+ matchMenu->insertItem( i18n( "&Ponder" ), this, SLOT(Settings(int)), 0, MENU_PONDER );
+ matchMenu->setItemChecked( MENU_PONDER, Resource->OPTION_Ponder );
+ matchMenu->setItemEnabled( MENU_PONDER, FALSE );
+ matchMenu->setWhatsThis( MENU_PONDER, i18n( "This toggles your opponent's ability to think while it's your turn." ) );
+ matchMenu->insertSeparator();
+ // MENU_PAUSE
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("player_pause"), KIcon::Small ) ),
+ i18n( "Pause" ), this, SLOT( Settings(int) ), Key_F12, MENU_PAUSE );
+ matchMenu->setItemEnabled( MENU_PAUSE, FALSE );
+ matchMenu->setWhatsThis( MENU_PAUSE, i18n( "Select this to pause the clock for this match." ) );
+ /*
+ drawMenu menu
+ */
+ // MENU_OFFER_DRAW
+ drawMenu->insertItem( i18n( "&Offer Draw" ), Core, SLOT(matchMenu(int)), 0, MENU_OFFER_DRAW );
+ drawMenu->setWhatsThis( MENU_OFFER_DRAW, i18n( "Clicking this will inform your opponent that you are willing draw the match." ) );
+ // MENU_ACCEPT_DRAW
+ drawMenu->insertItem( i18n( "&Accept Draw" ), Core, SLOT(matchMenu(int)), 0, MENU_ACCEPT_DRAW );
+ drawMenu->setWhatsThis( MENU_ACCEPT_DRAW, i18n( "Clicking this will accept a draw offered by your opponent." ) );
+ // MENU_REJECT_DRAW
+ drawMenu->insertItem( i18n( "&Reject Draw" ), Core, SLOT(matchMenu(int)), 0, MENU_REJECT_DRAW );
+ drawMenu->setWhatsThis( MENU_REJECT_DRAW, i18n( "Clicking this will reject a draw offered by your opponent." ) );
+ // MENU_IGNORE_DRAW
+ drawMenu->insertItem( i18n( "&Ignore Draw" ), Core, SLOT(matchMenu(int)), 0, MENU_IGNORE_DRAW );
+ drawMenu->setWhatsThis( MENU_IGNORE_DRAW, i18n( "Clicking this will ignore future draw offers from your opponent." ) );
+ /*
+ fileMenu menu
+ */
+ // MENU_NEWGAME
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("filenew"), KIcon::Small ) ),
+ i18n( "&New Match..." ), this, SLOT( openNewMatchDialog() ), CTRL+Key_N, MENU_NEWGAME );
+ fileMenu->setWhatsThis( MENU_NEWGAME, i18n( "This allows you to begin a new match." ) );
+ // MENU_LOAD
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("fileopen"), KIcon::Small ) ),
+ i18n( "&Load Match..." ), Core, SLOT( load() ), CTRL+Key_L, MENU_LOAD );
+ fileMenu->setWhatsThis( MENU_LOAD, i18n( "The Load command will allow you to select a previously saved match and play it again." ) );
+ fileMenu->insertSeparator();
+ // MENU_SAVE
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("filesave"), KIcon::Small ) ),
+ i18n( "&Save Match" ), this, SLOT( SaveGame() ), CTRL+Key_S, MENU_SAVE );
+ fileMenu->setItemEnabled( MENU_SAVE, FALSE );
+ fileMenu->setWhatsThis( MENU_SAVE, i18n( "The Save command will allow you to store a copy of your current match for later use." ) );
+ // MENU_SAVEAS
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("filesave"), KIcon::Small ) ),
+ i18n( "Save Match &As..." ), this, SLOT( SaveGameAs() ), CTRL+Key_A, MENU_SAVEAS );
+ fileMenu->setItemEnabled( MENU_SAVEAS, FALSE );
+ fileMenu->setWhatsThis( MENU_SAVEAS, i18n( "The Save command will allow you to store a copy of your current match for later use." ) );
+ fileMenu->insertSeparator();
+ // MENU_CONNECT
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("connect_creating"), KIcon::Small ) ),
+ i18n( "Connect to Server" ), this, SLOT( netConnect() ), CTRL+Key_C, MENU_CONNECT );
+ fileMenu->setWhatsThis( MENU_CONNECT, i18n( "Clicking this will connect Knights with an internet chess server." ) );
+ fileMenu->insertSeparator();
+ // MENU_PRINT
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("fileprint"), KIcon::Small ) ),
+ i18n( "&Print Notation..." ), Core, SLOT( print() ), CTRL+Key_P, MENU_PRINT );
+ fileMenu->setItemEnabled( MENU_PRINT, FALSE );
+ fileMenu->setWhatsThis( MENU_PRINT, i18n( "The Print command will allow you to print this game's notation on your printer." ) );
+ fileMenu->insertSeparator();
+ // MENU_CLOSE
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("fileclose"), KIcon::Small ) ),
+ i18n( "&Close Match" ), Core, SLOT( clearMatch() ), CTRL+Key_W, MENU_CLOSE );
+ fileMenu->setItemEnabled( MENU_CLOSE, FALSE );
+ fileMenu->setWhatsThis( MENU_CLOSE, i18n( "This command removes the current match." ) );
+ // MENU_CLOSEALL
+ fileMenu->insertItem( i18n( "Close All" ), Core, SLOT( clearAll() ), 0, MENU_CLOSEALL );
+ fileMenu->setItemEnabled( MENU_CLOSEALL, FALSE );
+ fileMenu->setWhatsThis( MENU_CLOSEALL, i18n( "This command will remove all matches that are currently loaded." ) );
+ fileMenu->insertSeparator();
+ // MENU_QUIT
+ fileMenu->insertItem( QIconSet( Resource->LoadIcon( QString("exit"), KIcon::Small ) ),
+ i18n( "&Quit" ), this, SLOT(menuClose()), CTRL+Key_Q, MENU_QUIT );
+ fileMenu->setWhatsThis( MENU_QUIT, i18n( "The Quit command will stop all matches and exit Knights." ) );
+ /*
+ settingsMenu menu
+ */
+ // MENU_INSTALL_THEMES
+ settingsMenu->insertItem( i18n( "&Install Themes" ), this, SLOT(installThemes()), 0, MENU_INSTALL_THEMES );
+ settingsMenu->setWhatsThis( MENU_INSTALL_THEMES, i18n( "This lets you install downloaded themes into Knights." ) );
+ // MENU_BINDINGS_DIALOG
+ settingsMenu->insertItem( QIconSet( Resource->LoadIcon( QString("key_bindings"), KIcon::Small ) ),
+ i18n( "Configure &Key Bindings..." ), this, SLOT(openKeyBindingDialog()), 0, MENU_BINDINGS_DIALOG );
+ settingsMenu->setWhatsThis( MENU_BINDINGS_DIALOG, i18n( "Click this if you want to change the keyboard shortcuts that Knights uses." ) );
+ // MENU_SETTINGS_DIALOG
+ settingsMenu->insertItem( QIconSet( Resource->LoadIcon( QString("configure"), KIcon::Small ) ),
+ i18n( "&Configure Knights..." ), this, SLOT(openSettingsDialog()), 0, MENU_SETTINGS_DIALOG );
+ settingsMenu->setWhatsThis( MENU_SETTINGS_DIALOG, i18n( "This opens a new window which allows you to customize Knights to your particular tastes." ) );
+ /*
+ tutorialMenu menu
+ */
+ tutorialMenu->setCheckable(TRUE);
+ // MENU_OPEN_TUTORIAL
+ tutorialMenu->insertItem( i18n( "Begin a Tutorial" ), this, SLOT(Settings(int)), 0, MENU_OPEN_TUTORIAL );
+// tutorialMenu->setWhatsThis( MENU_OPEN_TUTORIAL, i18n( "" ) );
+ /*
+ topMenu menu
+ */
+ topMenu->insertItem( i18n( "&File" ), fileMenu );
+ topMenu->insertItem( i18n( "&Match" ), matchMenu );
+ topMenu->insertItem( i18n( "&Settings" ), settingsMenu );
+// topMenu->insertItem( i18n( "&Tutorials" ), tutorialMenu );
+ topMenu->insertSeparator();
+ topMenu->insertItem( i18n( "&Help" ), help );
+}
+///////////////////////////////////////
+//
+// Knights::resizeMainFrame
+//
+///////////////////////////////////////
+void Knights::resizeMainFrame(void)
+{
+ QStyle& Style = QApplication::style();
+ QSize S_Message;
+ QSize S_Menu;
+
+ int statusY(0);
+ int statusX(0);
+ int statusHeight(0);
+
+ /* Get some numbers */
+ margin = Style.defaultFrameWidth();
+ /* Take care of the Core first */
+ Core->move( 0, 0 );
+ Core->resize();
+ /* Get our size hints */
+ S_Message = Message->sizeHint();
+ S_Menu = topMenu->sizeHint();
+ statusHeight = S_Message.height() + ( margin << 1 );
+ statusY += Core->height() + margin + statusHeight + margin;
+ statusX = Core->width();
+
+ MainFrame->setFixedSize( statusX, statusY );
+ setFixedSize( statusX, statusY + S_Menu.height() );
+
+ /* enable or disable games in the menu */
+ if( Resource->servers.count() )
+ {
+ fileMenu->setItemEnabled( MENU_CONNECT, TRUE );
+ }
+ else
+ {
+ fileMenu->setItemEnabled( MENU_CONNECT, FALSE );
+ }
+}
+///////////////////////////////////////
+//
+// Knights::event
+//
+///////////////////////////////////////
+bool Knights::event( QEvent *e )
+{
+ if( e->type() == EVENT_Del_IO_Net )
+ {
+ netConnect();
+ return TRUE;
+ }
+ return KMainWindow::event( e );
+}
+///////////////////////////////////////
+//
+// Knights::resizeEvent
+//
+///////////////////////////////////////
+void Knights::resizeEvent( QResizeEvent * )
+{
+ QSize S_Message;
+ int tmp(0);
+ int statusHeight(0);
+ int statusY(0);
+ int statusX(0);
+ int gridX(0);
+
+ if( ResizeFlag ) return;
+ /* Get the height & Y of the status bar */
+ gridX = Core->width() >> 3;
+ S_Message = Message->sizeHint() + QSize( 2, 2 );
+ statusHeight = S_Message.height() + ( margin << 1 );
+ Resource->Widget_Height = statusHeight;
+ statusY += Core->height() + margin;
+
+ if( InitAll ) return;
+ /* Do the Message box */
+ tmp = gridX * 3;
+ Message->setFixedSize( tmp - ( margin << 1 ), statusHeight );
+ Message->move( margin, statusY );
+ statusX = tmp;
+ /* Do the White Time */
+ tmp = gridX + ( gridX >> 1 );
+ whiteTimeLabel->setFixedSize( tmp - margin, statusHeight );
+ whiteTimeLabel->move( statusX, statusY );
+ statusX += tmp;
+ /* Do the Black Time */
+ tmp = gridX + ( gridX >> 1 );
+ blackTimeLabel->setFixedSize( tmp - margin, statusHeight );
+ blackTimeLabel->move( statusX, statusY );
+ statusX += tmp;
+ /* Do the Notation Bar */
+ tmp = gridX << 1;
+ notationBar->setFixedSize( tmp - margin, statusHeight );
+ notationBar->move( statusX, statusY );
+ statusX += tmp;
+}
+///////////////////////////////////////
+//
+// Knights::keyPressEvent
+//
+///////////////////////////////////////
+void Knights::keyPressEvent( QKeyEvent *e )
+{
+ QChar input;
+
+ if( ( e->state() | Qt::ShiftButton ) == Qt::ShiftButton )
+ {
+ input = e->text().at(0);
+ if( input.isLetterOrNumber() )
+ {
+ emit focus( input );
+ e->accept();
+ return;
+ }
+ }
+ e->ignore();
+}
+///////////////////////////////////////
+//
+// Knights::hideEvent
+//
+///////////////////////////////////////
+void Knights::hideEvent( QHideEvent* )
+{
+ if( !Resource->OPTION_Pause_On_Minimize )
+ return;
+ Core->matchMenu( MENU_PAUSEALL );
+ Minimized = TRUE;
+}
+///////////////////////////////////////
+//
+// Knights::showEvent
+//
+///////////////////////////////////////
+void Knights::showEvent( QShowEvent* )
+{
+ if( !Minimized )
+ return;
+ Core->matchMenu( MENU_PAUSEALL );
+ Minimized = FALSE;
+}
+///////////////////////////////////////
+//
+// Knights::wheelEvent
+//
+///////////////////////////////////////
+void Knights::wheelEvent( QWheelEvent *event )
+{
+ event->accept();
+ if( event->delta() > 0 ) PrevNotation();
+ if( event->delta() < 0 ) NextNotation();
+}
+///////////////////////////////////////
+//
+// Knights::SelectTheme
+//
+///////////////////////////////////////
+void Knights::SelectTheme( int boardIndex, int chessmenIndex )
+{
+ Resource->setTheme( boardIndex, chessmenIndex );
+ resizeMainFrame();
+}
+///////////////////////////////////////
+//
+// Knights::setStatusBar
+//
+///////////////////////////////////////
+void Knights::setStatusBar( const int &ID, const QString &MSG )
+{
+ /* Game comments as specified in http://www.schachprobleme.de/chessml/faq/pgn/
+ Section 10: Numeric Annotation Glyphs */
+ if( ( ID & COMMENT ) == COMMENT )
+ {
+ Message->setText( pgn::getNAG( ID - COMMENT ) );
+ return;
+ }
+ /* Knights specific messages */
+ switch( ID )
+ {
+ /* Error Codes */
+ case BOOK_ERROR_1:
+ Message->setText( i18n( "Error with white engine" ) );
+ KMessageBox::sorry( this,
+ i18n("You selected %1 to play white,\nbut it can only be used as a book engine.\nPlease select another engine to play white.").arg( MSG ),
+ i18n("White Engine Problem") );
+ break;
+ case BOOK_ERROR_2:
+ Message->setText( i18n( "Error with white book engine" ) );
+ KMessageBox::sorry( this,
+ i18n("You selected %1 to play white's book,\nbut it can only be used as a regular engine.\nPlease select another engine to play white's book.").arg( MSG ),
+ i18n("White Book Engine Problem") );
+ break;
+ case BOOK_ERROR_3:
+ Message->setText( i18n( "Error with black engine" ) );
+ KMessageBox::sorry( this,
+ i18n("You selected %1 to play black,\nbut it can only be used as a book engine.\nPlease select another engine to play black.").arg( MSG ),
+ i18n("Black Engine Problem") );
+ break;
+ case BOOK_ERROR_4:
+ Message->setText( i18n( "Error with black book engine" ) );
+ KMessageBox::sorry( this,
+ i18n("You selected %1 to play black's book,\nbut it can only be used as a regular engine.\nPlease select another engine to play black's book.").arg( MSG ),
+ i18n("Black Book Engine Problem") );
+ break;
+ case ENGINE_DIED_ERROR:
+ Message->setText( i18n( "The computer opponent assigned to play %1 has crashed" ).arg( MSG ) );
+ break;
+ case LOAD_ERROR:
+ Message->setText( i18n( "There was an error while loading the file" ) );
+ break;
+ case SAVE_ERROR:
+ Message->setText( i18n( "There was an error while saving the file" ) );
+ break;
+ /* Standard Codes */
+ case LOAD_OK:
+ Message->setText( i18n( "Loading complete" ) );
+ break;
+ case SAVE_OK:
+ Message->setText( i18n( "Saving complete" ) );
+ break;
+ case READING_FILE:
+ Message->setText( i18n( "Reading File" ) );
+ break;
+ case NO_MOVE_WHILE_REVIEW:
+ Message->setText( i18n( "Can not move a chessman while reviewing the match" ) );
+ break;
+ case ILLEGAL_MOVE:
+ Message->setText( i18n( "Illegal Move" ) );
+ break;
+ case WHITE_TURN:
+ Message->setText( i18n( "White's turn" ) );
+ break;
+ case BLACK_TURN:
+ Message->setText( i18n( "Black's turn" ) );
+ break;
+ case WHITE_WIN:
+ Message->setText( i18n( "White wins" ) );
+ break;
+ case BLACK_WIN:
+ Message->setText( i18n( "Black wins" ) );
+ break;
+ case WHITE_CHECKMATE:
+ Message->setText( i18n( "Checkmate, White wins" ) );
+ break;
+ case BLACK_CHECKMATE:
+ Message->setText( i18n( "Checkmate, Black wins" ) );
+ break;
+ case WHITE_RESIGN:
+ Message->setText( i18n( "White resigns" ) );
+ break;
+ case BLACK_RESIGN:
+ Message->setText( i18n( "Black resigns" ) );
+ break;
+ case WHITE_FLAG:
+ Message->setText( i18n( "White's flag fell" ) );
+ break;
+ case BLACK_FLAG:
+ Message->setText( i18n( "Black's flag fell" ) );
+ break;
+ case WHITE_CALL_FLAG:
+ Message->setText( i18n( "Black's flag was called, White wins" ) );
+ break;
+ case BLACK_CALL_FLAG:
+ Message->setText( i18n( "White's flag was called, Black wins" ) );
+ break;
+ case GAME_DRAW:
+ Message->setText( i18n( "Draw match" ) );
+ break;
+ case GAME_50_MOVES:
+ Message->setText( i18n( "50 moves rule, draw match" ) );
+ break;
+ case WAITING:
+ Message->setText( i18n( "Starting computer players, please wait" ) );
+ break;
+ case PAUSED:
+ Message->setText( i18n( "Match paused" ) );
+ break;
+ case WHITE_DRAW_OFFER:
+ Message->setText( i18n( "White has offered a draw" ) );
+ break;
+ case BLACK_DRAW_OFFER:
+ Message->setText( i18n( "Black has offered a draw" ) );
+ break;
+ case LOST_CONTACT:
+ Message->setText( i18n( "Lost contact with opponent" ) );
+ case READY:
+ default:
+ Message->setText( i18n( "Ready" ) );
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// Knights::setClocks
+//
+///////////////////////////////////////
+void Knights::setClocks( void )
+{
+ whiteTimeLabel->setText( Core->clock( WHITE ) );
+ blackTimeLabel->setText( Core->clock( BLACK ) );
+ if( Core->flag( WHITE ) )
+ if( Core->blackInput() == PLAYERLOCAL )
+ matchMenu->setItemEnabled( MENU_CALL_FLAG, TRUE );
+ else
+ matchMenu->setItemEnabled( MENU_CALL_FLAG, FALSE );
+ if( Core->flag( BLACK ) )
+ if( Core->whiteInput() == PLAYERLOCAL )
+ matchMenu->setItemEnabled( MENU_CALL_FLAG, TRUE );
+ else
+ matchMenu->setItemEnabled( MENU_CALL_FLAG, FALSE );
+}
+///////////////////////////////////////
+//
+// Knights::setNotation
+//
+///////////////////////////////////////
+void Knights::setNotation( void )
+{
+ QStringList *list;
+ QStringList::Iterator IT;
+ int count(0);
+
+ setCaption( Core->caption() );
+ notationBar->clear();
+ list = Core->notation();
+ /*
+ Several menu items' status changes based upon the availability
+ of notation data. Therefore, we'll enable & disable those here
+ since we've gathered the notation data anyway.
+ */
+ if( list == NULL )
+ {
+ /* Disable Save & Print Functions */
+ fileMenu->setItemEnabled( MENU_SAVE, FALSE );
+ fileMenu->setItemEnabled( MENU_SAVEAS, FALSE );
+ fileMenu->setItemEnabled( MENU_PRINT, FALSE );
+ matchMenu->setItemEnabled( MENU_RETRACT, FALSE );
+ return;
+ }
+ if( Core->modified() )
+ fileMenu->setItemEnabled( MENU_SAVE, TRUE );
+ else
+ fileMenu->setItemEnabled( MENU_SAVE, FALSE );
+ /* Core->onMove is called before it is updated by Match->slot_Move. Because of this, the following
+ if statement checks for the wrong player's turn. On purpose */
+ if( ( Core->inputOnMove() == PLAYERLOCAL ) && ( Core->inputOnMove(TRUE) == PLAYERPC ) && list->count() )
+ matchMenu->setItemEnabled( MENU_RETRACT, TRUE );
+ else
+ matchMenu->setItemEnabled( MENU_RETRACT, FALSE );
+ fileMenu->setItemEnabled( MENU_SAVEAS, TRUE );
+ fileMenu->setItemEnabled( MENU_PRINT, TRUE );
+
+ /* Create the List */
+ for( IT = list->begin(); IT != list->end(); ++IT )
+ {
+ notationBar->insertItem( (*IT), count++ );
+ }
+ notationBar->setCurrentItem( --count );
+ delete list;
+}
+///////////////////////////////////////
+//
+// Knights::PrevNotation
+//
+///////////////////////////////////////
+void Knights::PrevNotation( void )
+{
+ int tmp( notationBar->currentItem() - 1 );
+ Core->review( tmp ); // Do this before the bounds checking in case this is examine mode
+ if( tmp < 0 )
+ return;
+ notationBar->setCurrentItem( tmp );
+}
+///////////////////////////////////////
+//
+// Knights::NextNotation
+//
+///////////////////////////////////////
+void Knights::NextNotation( void )
+{
+ int tmp( notationBar->currentItem() + 1 );
+ Core->review( tmp ); // Do this before the bounds checking in case this is examine mode
+ if( tmp > ( notationBar->count() - 1 ) )
+ return;
+ notationBar->setCurrentItem( tmp );
+}
+///////////////////////////////////////
+//
+// Knights::initMatch
+//
+///////////////////////////////////////
+void Knights::initMatch( void )
+{
+ setNotation();
+
+ /* Are there any players? ( ie - is this a match or a null? */
+ if( ( Core->whiteInput() == Null ) || ( Core->blackInput() == Null ) )
+ {
+ fileMenu->setItemEnabled( MENU_CLOSE, FALSE );
+ fileMenu->setItemEnabled( MENU_CLOSEALL, FALSE );
+ matchMenu->setItemEnabled( MENU_ORIENTATION, FALSE );
+ whiteTimeLabel->setText( "" );
+ blackTimeLabel->setText( "" );
+ setStatusBar( READY );
+ }
+ else
+ {
+ fileMenu->setItemEnabled( MENU_CLOSE, TRUE );
+ fileMenu->setItemEnabled( MENU_CLOSEALL, TRUE );
+ matchMenu->setItemEnabled( MENU_ORIENTATION, TRUE );
+ }
+
+ /* Is there a local player? */
+ if( ( Core->whiteInput() == PLAYERLOCAL ) || ( Core->blackInput() == PLAYERLOCAL ) )
+ {
+ matchMenu->setItemEnabled( MENU_DRAW, TRUE );
+ matchMenu->setItemEnabled( MENU_RESIGN, TRUE );
+ /* Is there also a PC player? */
+ if( ( Core->whiteInput() == PLAYERPC ) || ( Core->blackInput() == PLAYERPC ) )
+ {
+ }
+ }
+ else
+ {
+ matchMenu->setItemEnabled( MENU_DRAW, FALSE );
+ matchMenu->setItemEnabled( MENU_RESIGN, FALSE );
+ }
+ /* Is there a PC player? */
+ if( ( Core->whiteInput() == PLAYERPC ) || ( Core->blackInput() == PLAYERPC ) )
+ {
+ matchMenu->setItemEnabled( MENU_MOVE_NOW, TRUE );
+ matchMenu->setItemEnabled( MENU_HINT, TRUE );
+ matchMenu->setItemEnabled( MENU_PONDER, TRUE );
+ matchMenu->setItemEnabled( MENU_PAUSE, TRUE );
+ }
+ else
+ {
+ matchMenu->setItemEnabled( MENU_MOVE_NOW, FALSE );
+ matchMenu->setItemEnabled( MENU_HINT, FALSE );
+ matchMenu->setItemEnabled( MENU_PONDER, FALSE );
+ matchMenu->setItemEnabled( MENU_PAUSE, FALSE );
+ }
+ /* Is there a TCP player? */
+// if( ( Core->whiteInput() == PLAYERTCP ) || ( Core->blackInput() == PLAYERTCP ) )
+// {
+// }
+// else
+// {
+// }
+}
+///////////////////////////////////////
+//
+// Knights::netConnect
+//
+///////////////////////////////////////
+void Knights::netConnect( void )
+{
+ if(Core->isOnline())
+ {
+ fileMenu->changeItem( MENU_CONNECT, QIconSet( Resource->LoadIcon( QString("connect_creating"),
+ KIcon::Small ) ), i18n( "Connect to Server" ));
+ Core->goOffline();
+ setCursor( Resource->CURSOR_Standard );
+ }
+ else
+ {
+ fileMenu->changeItem( MENU_CONNECT, QIconSet( Resource->LoadIcon( QString("connect_no"),
+ KIcon::Small ) ), i18n( "Disconnect from Server" ) );
+ /*
+ By passing Null as the ID, we're telling core that we're
+ creating a new internetio, not reusing an exsisting one.
+ */
+ Core->createNewIO( PLAYERTCP, Null);
+ }
+}
+///////////////////////////////////////
+//
+// Knights::openSettingsDialog
+//
+///////////////////////////////////////
+void Knights::openSettingsDialog( void )
+{
+ SettingsDialog = new dlg_settings( this, "settings", Resource );
+ connect( SettingsDialog, SIGNAL( themeChanged(int,int) ), this, SLOT( SelectTheme(int,int) ) );
+ connect( SettingsDialog, SIGNAL( redrawBoard() ), Core, SLOT( resize() ) );
+ connect( SettingsDialog, SIGNAL( resetServer() ), Core, SLOT( resetServer() ) );
+ connect( this, SIGNAL( themesAdded() ), SettingsDialog, SLOT( slotThemesAdded() ) );
+ SettingsDialog->show();
+}
+///////////////////////////////////////
+//
+// Knights::openNewMatchDialog
+//
+///////////////////////////////////////
+void Knights::openNewMatchDialog( void )
+{
+ NewMatch = new dlg_newmatch( this, "NewMatch", Resource );
+ connect( NewMatch, SIGNAL( okClicked() ), this, SLOT( newMatch() ) );
+ NewMatch->show();
+}
+///////////////////////////////////////
+//
+// Knights::newMatch
+//
+///////////////////////////////////////
+void Knights::newMatch( void )
+{
+ Core->newMatch( NewMatch->paramaters() );
+}
+///////////////////////////////////////
+//
+// Knights::openKeyBindingDialog
+//
+///////////////////////////////////////
+void Knights::openKeyBindingDialog( void )
+{
+ KKeyDialog::configureKeys( myAccel, TRUE, this );
+}
+///////////////////////////////////////
+//
+// Knights::Settings
+//
+///////////////////////////////////////
+void Knights::Settings(int opt)
+{
+ switch(opt)
+ {
+ case MENU_PONDER:
+ Resource->OPTION_Ponder = 1 - Resource->OPTION_Ponder;
+ matchMenu->setItemChecked(MENU_PONDER, Resource->OPTION_Ponder );
+ Core->matchMenu( MENU_PONDER );
+ break;
+ case MENU_PAUSE:
+ if( Core->paused() )
+ {
+ matchMenu->changeItem( MENU_PAUSE,
+ QIconSet( Resource->LoadIcon( QString("player_pause"), KIcon::Small ) ),
+ i18n( "Pause" ) );
+ }
+ else
+ {
+ matchMenu->changeItem( MENU_PAUSE,
+ QIconSet( Resource->LoadIcon( QString("1rightarrow"), KIcon::Small ) ),
+ i18n( "Resume" ) );
+ }
+ Core->matchMenu( MENU_PAUSE );
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// Knights::SaveGame & Variants
+//
+///////////////////////////////////////
+bool Knights::SaveGame( void )
+{
+ /* We use 'Null' to indicate the current match */
+ return Core->save( Null, FALSE, FALSE );
+}
+bool Knights::SaveGamePrompt( void )
+{
+ return Core->save( Null, TRUE, FALSE );
+}
+bool Knights::SaveGameAs( void )
+{
+ return Core->save( Null, FALSE, TRUE );
+}
+///////////////////////////////////////
+//
+// Knights::boardBigger
+//
+///////////////////////////////////////
+void Knights::boardBigger( void )
+{
+ Resource->resizeTheme( Resource->ThemeSize + 8 );
+ resizeMainFrame();
+}
+///////////////////////////////////////
+//
+// Knights::boardSmaller
+//
+///////////////////////////////////////
+void Knights::boardSmaller( void )
+{
+ Resource->resizeTheme( Resource->ThemeSize - 8 );
+ resizeMainFrame();
+}
+
+///////////////////////////////////////
+//
+// Knights::installThemes
+//
+///////////////////////////////////////
+void Knights::installThemes( void )
+{
+ bool localFlag(FALSE);
+ bool installError(FALSE);
+ unsigned int loop;
+ QString allerror;
+ QString fileFilter( "KB* KC* KS*|" );
+ fileFilter += i18n( "Knights Themes" );
+ KURL::List files = KFileDialog::getOpenURLs( QString::null, fileFilter, this, i18n( "Install Theme..." ) );
+ for( loop = 0; loop < files.count(); loop++ )
+ {
+ /* Try writing to the global theme dir */
+ if( !KIO::NetAccess::copy( files[loop], KURL( QString( Resource->themeDir() + files[loop].filename() ) ) ) )
+ {
+ /* Nope... Try a local .knights dir */
+ allerror += "\n\n" + QString( Resource->themeDir() + files[loop].filename() )
+ + " - " + KIO::NetAccess::lastErrorString();
+ if( !KIO::NetAccess::exists( KURL( QString( QDir::homeDirPath() + "/.knights" ) ) ) )
+ {
+ /* Create local .knights dir */
+ KIO::NetAccess::mkdir( KURL( QString( QDir::homeDirPath() + "/.knights" ) ) );
+ }
+ if( !KIO::NetAccess::copy( files[loop], KURL( QString( QDir::homeDirPath() + "/.knights/" + files[loop].filename() ) ) ) )
+ {
+ /* Nope, can't copy it anywhere */
+ installError = TRUE;
+ allerror += "\n\n" + QString( QDir::homeDirPath() + "/.knights/"
+ + files[loop].filename() ) + " - " + KIO::NetAccess::lastErrorString();
+ }
+ else
+ {
+ localFlag = TRUE;
+ }
+ }
+ }
+ if( localFlag )
+ {
+ KMessageBox::sorry( this,
+ i18n("You do not have permission to install this theme systemwide, so Knights installed it locally."),
+ i18n("Installed theme locally") );
+ }
+ if( installError )
+ {
+ KMessageBox::sorry( this,
+ i18n("The theme could not be installed:\n%1").arg( allerror ),
+ i18n("Can not install theme") );
+ }
+ return;
+}
diff --git a/knights/knights.desktop b/knights/knights.desktop
new file mode 100644
index 0000000..603108c
--- /dev/null
+++ b/knights/knights.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Type=Application
+Exec=knights
+Icon=knights.png
+MiniIcon=knights.png
+Name=Knights
+Name[de]=Knights
+Comment=A graphical chess interface
+Comment[de]=A graphical chess interface
+InitialPreference=1
+MimeType=application/x-chess-pgn,Application
+ServiceTypes=
+DocPath=knights/index.html
+Terminal=false
+
+
diff --git a/knights/knights.h b/knights/knights.h
new file mode 100644
index 0000000..a17aaa6
--- /dev/null
+++ b/knights/knights.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+ knights.h - description
+ -------------------
+ begin : Thu Mar 1 10:43:51 CST 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KNIGHTS_H
+#define KNIGHTS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* KDEBase */
+#include <kapp.h>
+#include <kmainwindow.h>
+#include <khelpmenu.h>
+#include <kaboutdata.h>
+#include <kstatusbar.h>
+#include <kcmdlineargs.h>
+/* QT */
+#include <qlayout.h>
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qstring.h>
+/* Local */
+#include "definitions.h"
+#include "resource.h"
+#include "accel.h"
+
+class KMenuBar;
+class KPopupMenu;
+class KComboBox;
+class QLabel;
+class QFrame;
+class dlg_settings;
+class dlg_newmatch;
+class core;
+class splash;
+
+/**
+ Knights is the top-level widget of the project.
+ It is responsable for creating the menu bar and it's contents,
+ as well as creating an instance of the game itself ( class Grid )
+**/
+class Knights : public KMainWindow
+{
+ Q_OBJECT
+ public:
+ KAboutData *aboutData;
+ resource *Resource;
+
+ Knights( KCmdLineArgs *Args, QWidget* parent=0, const char *name=0 );
+ ~Knights();
+ bool init( void );
+ void initMenus( void );
+ void BirthAll( void );
+ void keyPressEvent( QKeyEvent* );
+
+ public slots:
+ void KillAll( void );
+ void menuClose( void );
+ /** Yeah, they're sloppy, but I need my own geometry managment routines
+ because I don't like the "default" look my statusbar was getting
+ ( double-height ). Plus, I want the console to appear only when needed. */
+ void resizeMainFrame( void );
+
+ bool event( QEvent* );
+ void resizeEvent( QResizeEvent* );
+ void hideEvent( QHideEvent* );
+ void showEvent( QShowEvent* );
+ void wheelEvent( QWheelEvent* );
+
+ void setStatusBar( const int &ID, const QString& MSG=QString::null );
+
+ void setClocks( void );
+ void initMatch( void );
+
+ void setNotation( void );
+ void PrevNotation( void );
+ void NextNotation( void );
+
+ void SelectTheme( int boardIndex, int chessmenIndex );
+ void Settings( int opt );
+ void openSettingsDialog( void );
+ void openNewMatchDialog( void );
+ void openKeyBindingDialog( void );
+ bool SaveGame( void );
+ bool SaveGamePrompt( void );
+ bool SaveGameAs( void );
+
+ void netConnect( void );
+
+ signals:
+ void themesAdded( void );
+ void focus( const QChar& );
+
+ protected:
+ bool queryClose( void );
+
+ protected slots:
+ void boardSmaller( void );
+ void boardBigger( void );
+ void installThemes( void );
+ void newMatch( void );
+
+ private:
+ KCmdLineArgs *args;
+ KMenuBar *topMenu;
+ KPopupMenu *help;
+ KPopupMenu *fileMenu;
+ KPopupMenu *settingsMenu;
+ KPopupMenu *matchMenu;
+ KPopupMenu *drawMenu;
+ KPopupMenu *tutorialMenu;
+ KComboBox *notationBar;
+ QFrame *MainFrame;
+ QLabel *whiteTimeLabel;
+ QLabel *blackTimeLabel;
+ QLabel *Message;
+ dlg_settings *SettingsDialog;
+ dlg_newmatch *NewMatch;
+ core *Core;
+ splash *SplashScreen;
+ Accel *myAccel;
+
+ int NotationIndex;
+ bool InitAll;
+ bool Minimized;
+ bool ResizeFlag;
+ int margin;
+};
+
+#endif
diff --git a/knights/knightsmap.h b/knights/knightsmap.h
new file mode 100644
index 0000000..a3b1d3d
--- /dev/null
+++ b/knights/knightsmap.h
@@ -0,0 +1,178 @@
+/***************************************************************************
+ knightsmap.h - description
+ -------------------
+ begin : Sun Aug 25 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qvaluelist.h>
+
+#ifndef KNIGHTSMAP_H
+#define KNIGHTSMAP_H
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+template<class Key, class T>
+class KnightsMap
+{
+public:
+ typedef Key KeyType;
+ typedef T DataType;
+ typedef struct Pair
+ {
+ KeyType key;
+ DataType data;
+ };
+
+private:
+ QValueList<Pair> pairList;
+
+ Key searchKey;
+ unsigned int searchIndex;
+ T nullValue;
+ T tempValue;
+
+public:
+ /*
+ Constructor
+ */
+ KnightsMap()
+ {
+ nullValue = 0;
+ clear();
+ }
+
+ /*
+ Destructor
+ */
+ ~KnightsMap()
+ { clear(); }
+
+ /*
+ Returns the number of items in the map
+ */
+unsigned int count( void )
+ { return pairList.count(); }
+
+ /*
+ Clears the map
+ */
+void clear( void )
+ {
+ searchIndex = 0;
+ pairList.clear();
+ }
+
+ /*
+ Add a Key/Value pair to the map
+ */
+void add( KeyType key, DataType data )
+ {
+ Pair newPair;
+ newPair.key = key;
+ newPair.data = data;
+ pairList.append( newPair );
+ }
+
+ /*
+ Return the next Value associated with the Key given
+ in the last call to 'find'. If there are none, then
+ NULL is returned.
+ */
+T& findNext( void )
+ {
+ unsigned int maxIndex( pairList.count() );
+ for( ; searchIndex < maxIndex ; searchIndex++ )
+ {
+ if( searchKey != pairList[searchIndex].key )
+ {
+ continue;
+ }
+ return pairList[searchIndex++].data;
+ }
+ return nullValue;
+ }
+
+ /*
+ Lookup a Value by it's key. This will always return
+ the first Value that's associated with the given Key.
+ If no Value has the given Key, NULL is returned.
+ */
+T& find( KeyType key )
+ {
+ searchKey = key;
+ searchIndex = 0;
+ return findNext();
+ }
+
+ /* Removes all Values that are associated with Key */
+T& remove( KeyType key )
+ {
+ QValueListIterator<Pair> IT( pairList.begin() );
+ while( IT != pairList.end() )
+ {
+ if( (*IT).key == key )
+ {
+ tempValue = (*IT).data;
+ IT = pairList.remove( IT );
+ return tempValue;
+ }
+ IT++;
+ }
+ return nullValue;
+ }
+
+ /* Return the Value stored at Index i */
+T& operator[]( unsigned int i )
+ { return pairList[i].data; }
+
+ /* Return the Key stored at Index i */
+Key& keyAt( unsigned int i )
+ { return pairList[i].key; }
+
+ /*
+ Return the Value stored one Index position previous
+ to the last returned search Value. If already at the
+ begining of the Map, then NULL is returned.
+ */
+T& operator--( void )
+ {
+ if( searchIndex > 1 )
+ {
+ searchIndex -= 2;
+ }
+ else
+ {
+ return nullValue;
+ }
+ return pairList[searchIndex++].data;
+ }
+
+ /*
+ Return the Value stored one Index position after
+ the last returned search Value. If already at the
+ end of the Map, then NULL is returned.
+ */
+T& operator++( void )
+ {
+ if( searchIndex >= count() )
+ {
+ return nullValue;
+ }
+ return pairList[searchIndex++].data;
+ }
+};
+
+#endif
diff --git a/knights/knightspixcache.cpp b/knights/knightspixcache.cpp
new file mode 100644
index 0000000..5f7a26e
--- /dev/null
+++ b/knights/knightspixcache.cpp
@@ -0,0 +1,156 @@
+/***************************************************************************
+ knightspixcache.cpp - description
+ -------------------
+ begin : Mon Aug 20 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "knightspixcache.h"
+#include "definitions.h"
+
+KnightsPixCache::KnightsPixCache()
+{
+ bytesTotal = 1024 * 1024;
+ bytesUsed = 0;
+}
+KnightsPixCache::~KnightsPixCache()
+{
+ clear();
+ bytesUsed = 0;
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::cacheLimit
+//
+///////////////////////////////////////
+unsigned int KnightsPixCache::cacheLimit( void )
+{
+ return ( bytesTotal / 1024 );
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::setCacheLimit
+//
+///////////////////////////////////////
+void KnightsPixCache::setCacheLimit( const unsigned int &limit )
+{
+ bytesTotal = limit * 1024;
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::clear
+//
+///////////////////////////////////////
+void KnightsPixCache::clear( void )
+{
+ list.clear();
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::cleanCache
+//
+///////////////////////////////////////
+void KnightsPixCache::cleanCache( const unsigned int &space )
+{
+ pixmapList::Iterator tmpIT;
+ register unsigned int age;
+
+ while( bytesUsed + space > bytesTotal )
+ {
+ if( list.count() == 0 ) return;
+ age = 0;
+ for( IT = list.begin(); IT != list.end(); ++IT )
+ {
+ if( (*IT).age > age )
+ {
+ age = (*IT).age;
+ tmpIT = IT;
+ }
+ }
+ bytesUsed -= (*tmpIT).bytes;
+ list.remove( tmpIT );
+ }
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::add
+//
+///////////////////////////////////////
+void KnightsPixCache::add( const QString &label, const QPixmap &pixmap )
+{
+ unsigned int tmp;
+ cacheItem newItem;
+
+ if( pixmap.isNull() )
+ return;
+ tmp = ( pixmap.width() * pixmap.height() * pixmap.depth() ) >> 3;
+ if( ( bytesUsed + tmp ) > bytesTotal )
+ cleanCache(tmp);
+
+ newItem.label = label;
+ newItem.bytes = tmp;
+ newItem.item = pixmap;
+ newItem.age = 0;
+ list.append( newItem );
+ bytesUsed += tmp;
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::find
+//
+///////////////////////////////////////
+bool KnightsPixCache::find( const QString &label, QPixmap &pixmap )
+{
+ bool status(FALSE);
+ for( IT = list.begin(); IT != list.end(); ++IT )
+ {
+ if( (*IT).label == label )
+ {
+ pixmap = (*IT).item;
+ (*IT).age = 0;
+ status = TRUE;
+ }
+ else
+ (*IT).age++;
+ }
+ return status;
+}
+///////////////////////////////////////
+//
+// KnightsPixCache::resize
+//
+///////////////////////////////////////
+void KnightsPixCache::resize( const int &size )
+{
+ SquareLight.convertFromImage( Orig_SquareLight.smoothScale( size, size ) );
+ SquareDark.convertFromImage( Orig_SquareDark.smoothScale( size, size ) );
+ HighlightSelect.convertFromImage( Orig_HighlightSelect.smoothScale( size, size ) );
+ HighlightMove.convertFromImage( Orig_HighlightMove.smoothScale( size, size ) );
+ HighlightAttack.convertFromImage( Orig_HighlightAttack.smoothScale( size, size ) );
+ BlackKing.convertFromImage( Orig_BlackKing.smoothScale( size, size ) );
+ BlackQueen.convertFromImage( Orig_BlackQueen.smoothScale( size, size ) );
+ BlackBishop.convertFromImage( Orig_BlackBishop.smoothScale( size, size ) );
+ BlackKnight.convertFromImage( Orig_BlackKnight.smoothScale( size, size ) );
+ BlackRook.convertFromImage( Orig_BlackRook.smoothScale( size, size ) );
+ BlackPawn.convertFromImage( Orig_BlackPawn.smoothScale( size, size ) );
+ WhiteKing.convertFromImage( Orig_WhiteKing.smoothScale( size, size ) );
+ WhiteQueen.convertFromImage( Orig_WhiteQueen.smoothScale( size, size ) );
+ WhiteBishop.convertFromImage( Orig_WhiteBishop.smoothScale( size, size ) );
+ WhiteKnight.convertFromImage( Orig_WhiteKnight.smoothScale( size, size ) );
+ WhiteRook.convertFromImage( Orig_WhiteRook.smoothScale( size, size ) );
+ WhitePawn.convertFromImage( Orig_WhitePawn.smoothScale( size, size ) );
+ Border.convertFromImage( Orig_Border.smoothScale( size * 9, size * 9) );
+ BorderLightOn.convertFromImage( Orig_BorderLightOn.smoothScale( size / 2, size / 2) );
+ BorderLightOff.convertFromImage( Orig_BorderLightOff.smoothScale( size / 2, size / 2) );
+ return;
+}
diff --git a/knights/knightspixcache.h b/knights/knightspixcache.h
new file mode 100644
index 0000000..75b9cc7
--- /dev/null
+++ b/knights/knightspixcache.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ knightspixcache.h - description
+ -------------------
+ begin : Mon Aug 20 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KNIGHTSPIXCACHE_H
+#define KNIGHTSPIXCACHE_H
+
+#include <qvaluelist.h>
+#include <qpixmap.h>
+#include <qimage.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+typedef struct cacheItem
+{
+ QString label;
+ QPixmap item;
+ unsigned int bytes;
+ unsigned int age;
+};
+
+typedef QValueList<cacheItem> pixmapList;
+
+class KnightsPixCache
+{
+ public:
+ QPixmap SquareLight;
+ QPixmap SquareDark;
+ QPixmap HighlightSelect;
+ QPixmap HighlightMove;
+ QPixmap HighlightAttack;
+ QPixmap BlackKing;
+ QPixmap BlackQueen;
+ QPixmap BlackBishop;
+ QPixmap BlackKnight;
+ QPixmap BlackRook;
+ QPixmap BlackPawn;
+ QPixmap WhiteKing;
+ QPixmap WhiteQueen;
+ QPixmap WhiteBishop;
+ QPixmap WhiteKnight;
+ QPixmap WhiteRook;
+ QPixmap WhitePawn;
+ QPixmap Border;
+ QPixmap BorderLightOn;
+ QPixmap BorderLightOff;
+
+ QImage Orig_SquareLight;
+ QImage Orig_SquareDark;
+ QImage Orig_HighlightSelect;
+ QImage Orig_HighlightMove;
+ QImage Orig_HighlightAttack;
+ QImage Orig_BlackKing;
+ QImage Orig_BlackQueen;
+ QImage Orig_BlackBishop;
+ QImage Orig_BlackKnight;
+ QImage Orig_BlackRook;
+ QImage Orig_BlackPawn;
+ QImage Orig_WhiteKing;
+ QImage Orig_WhiteQueen;
+ QImage Orig_WhiteBishop;
+ QImage Orig_WhiteKnight;
+ QImage Orig_WhiteRook;
+ QImage Orig_WhitePawn;
+ QImage Orig_Border;
+ QImage Orig_BorderLightOn;
+ QImage Orig_BorderLightOff;
+
+ KnightsPixCache();
+ ~KnightsPixCache();
+ void clear( void );
+ void setCacheLimit( const unsigned int &limit );
+ unsigned int cacheLimit( void );
+ void add( const QString &label, const QPixmap &pixmap );
+ bool find( const QString &label, QPixmap &pixmap);
+ void resize( const int &size );
+
+ private:
+
+ pixmapList list;
+ pixmapList::Iterator IT;
+
+ unsigned int bytesUsed;
+ unsigned int bytesTotal;
+
+ void cleanCache( const unsigned int &space );
+};
+
+#endif
diff --git a/knights/knightstextview.cpp b/knights/knightstextview.cpp
new file mode 100644
index 0000000..dc14936
--- /dev/null
+++ b/knights/knightstextview.cpp
@@ -0,0 +1,238 @@
+/***************************************************************************
+ knightstextview.cpp - description
+ -------------------
+ begin : Sun Dec 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "knightstextview.moc"
+#include "definitions.h"
+#include "resource.h"
+#include <kdebug.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kurl.h>
+#include <krun.h>
+
+// Used for printing functionality
+#include <qpaintdevicemetrics.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include <kprinter.h>
+#include <qsimplerichtext.h>
+
+KnightsTextView::KnightsTextView(QWidget *parent, resource *Rsrc ) : QTextBrowser(parent)
+{
+ myResource = Rsrc;
+ setReadOnly( TRUE );
+ setTextFormat( Qt::RichText );
+ menuView = new KPopupMenu( this );
+ /*
+ Configure functions in the View right click menu
+ */
+ menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("editcopy"), KIcon::Small ) ),
+ i18n( "&Copy" ), this, SLOT( menuFunct(int) ), CTRL+Key_C, MENU_COPY );
+ menuView->insertItem( i18n("Select &All"), this, SLOT( menuFunct(int) ), CTRL+Key_A, MENU_SELECT_ALL );
+ menuView->insertSeparator();
+ menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("fileprint"), KIcon::Small ) ),
+ i18n( "&Print" ), this, SLOT( menuFunct(int) ), CTRL+Key_P, MENU_PRINT );
+// menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("find"), KIcon::Small ) ),
+// i18n( "&Find" ), this, SLOT( menuFunct(int) ), CTRL+Key_F, MENU_FIND );
+// menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("next"), KIcon::Small ) ),
+// i18n( "Find &Next" ), this, SLOT( menuFunct(int) ), Key_F3, MENU_FIND_NEXT );
+// menuView->insertSeparator();
+ menuView->insertSeparator();
+ menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("viewmag+"), KIcon::Small ) ),
+ i18n( "Zoom &In" ), this, SLOT( menuFunct(int) ), 0, MENU_ZOOM_IN );
+ menuView->insertItem( QIconSet( Rsrc->LoadIcon( QString("viewmag-"), KIcon::Small ) ),
+ i18n( "Zoom &Out" ), this, SLOT( menuFunct(int) ), 0, MENU_ZOOM_OUT );
+
+ /* disconnect the linkClicked signal so we can replace it with our own */
+ disconnect(this, SIGNAL(linkClicked(const QString&)),this ,0);
+ /* connect the linkClicked signal to displayLink slot */
+ connect(this, SIGNAL(linkClicked(const QString&)), this, SLOT(displayLink(const QString&)));
+
+ show();
+}
+
+KnightsTextView::~KnightsTextView()
+{
+ delete menuView;
+}
+
+///////////////////////////////////////
+//
+// KnightsTextView::viewportMousePressEvent
+//
+///////////////////////////////////////
+void KnightsTextView::viewportMousePressEvent( QMouseEvent *e )
+{
+ if( e->button() == RightButton )
+ {
+ emit rightButtonClicked( e->globalPos() );
+ display_menuView( e->globalPos() );
+ }
+ QTextEdit::viewportMousePressEvent( e );
+}
+///////////////////////////////////////
+//
+// KnightsTextView::display_menuView
+//
+///////////////////////////////////////
+void KnightsTextView::display_menuView( const QPoint &Pos )
+{
+ if( hasSelectedText() )
+ {
+ menuView->setItemEnabled( MENU_COPY, TRUE );
+ }
+ else
+ {
+ menuView->setItemEnabled( MENU_COPY, FALSE );
+ }
+ menuView->popup( Pos );
+}
+///////////////////////////////////////
+//
+// KnightsTextView::menuFunct
+//
+///////////////////////////////////////
+void KnightsTextView::menuFunct( int funct )
+{
+ switch( funct )
+ {
+ case MENU_COPY:
+ copy();
+ break;
+ case MENU_SELECT_ALL:
+ selectAll();
+ break;
+ case MENU_ZOOM_IN:
+ zoomIn();
+ break;
+ case MENU_ZOOM_OUT:
+ zoomOut();
+ break;
+ case MENU_PRINT:
+ print();
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// KnightsTextView::pageMove
+//
+///////////////////////////////////////
+void KnightsTextView::pageMove( Qt::Key key )
+{
+ int NewY;
+ if( key == Key_PageUp )
+ {
+ NewY = contentsY() - visibleHeight();
+ if( NewY < 0 )
+ NewY = 0;
+ }
+ else
+ {
+ NewY = contentsY() + visibleHeight();
+ if( NewY > ( contentsHeight() - visibleHeight() ) )
+ NewY = contentsHeight() - visibleHeight();
+ }
+ setContentsPos( 0, NewY );
+ updateContents( 0, NewY, visibleWidth(), visibleHeight() );
+}
+
+///////////////////////////////////////
+//
+// KnightsTextView::displayLink(QString url)
+//
+///////////////////////////////////////
+void KnightsTextView::displayLink(const QString& urlString)
+{
+ KURL url(urlString);
+ new KRun(url);
+}
+
+///////////////////////////////////////
+//
+// KnightsTextView::print
+//
+///////////////////////////////////////
+void KnightsTextView::print( void )
+{
+ KPrinter printer( true, QPrinter::ScreenResolution );
+ viewport()->setCursor( waitCursor );
+
+ /* Make sure we want to print */
+ if( printer.setup() )
+ {
+ QPainter paint( &printer );
+ QPaintDeviceMetrics pageMetrics( paint.device() );
+
+ /* Setup sizes */
+ int dpix = pageMetrics.logicalDpiX();
+ int dpiy = pageMetrics.logicalDpiY();
+ const int margin = 36; // pt
+ QRect body( margin * dpix / 72, margin * dpiy / 72,
+ pageMetrics.width() - margin * dpix / 72 * 2,
+ pageMetrics.height() - margin * dpiy / 72 * 2 );
+ QRect view( body );
+
+ printer.setFullPage( true );
+ printer.setCreator( "Knights" );
+ QSimpleRichText simpText( this->text(), this->font() );
+ simpText.setWidth( view.width() );
+
+ /* Count Pages */
+ int currentPage = 1;
+ int totalPages = simpText.height() / view.height();
+ if( view.height() * totalPages < simpText.height() )
+ {
+ totalPages++;
+ }
+
+ /* Print */
+ while( 1 )
+ {
+ /* Print the Contents */
+ paint.setClipRect( body );
+ simpText.draw( &paint, body.left(), body.top(), view, colorGroup() );
+ paint.setClipping( false );
+ view.moveBy( 0, body.height() );
+ paint.translate( 0, -body.height() );
+
+ /* Print the Page Number */
+ paint.setFont( myResource->FONT_Standard );
+ paint.setPen( myResource->COLOR_Black );
+ QString pageCount = i18n( "Page %1 of %2" ).arg( currentPage ).arg( totalPages );
+ paint.drawText( view.width() - paint.fontMetrics().width( pageCount ),
+ view.bottom() + paint.fontMetrics().ascent() + 5, pageCount );
+ if( view.top() >= simpText.height() )
+ {
+ break;
+ }
+ printer.newPage();
+ currentPage++;
+ }
+ }
+
+ /* Restore Playground */
+ viewport()->unsetCursor();
+}
+
+void QTextBrowser::setSource(const QString&)
+{
+ /* overwrote this to stop clicked links from clearing the
+ console */
+}
diff --git a/knights/knightstextview.h b/knights/knightstextview.h
new file mode 100644
index 0000000..f76db25
--- /dev/null
+++ b/knights/knightstextview.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ knightstextview.h - description
+ -------------------
+ begin : Sun Dec 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KNIGHTSTEXTVIEW_H
+#define KNIGHTSTEXTVIEW_H
+
+#include <qwidget.h>
+#include <qtextbrowser.h>
+
+/**
+ *@author Troy Corbin Jr./Alexander Wels
+ */
+
+class KPopupMenu;
+class resource;
+
+class KnightsTextView : public QTextBrowser
+{
+ Q_OBJECT
+ public:
+ KnightsTextView(QWidget *parent, resource *Rsrc );
+ ~KnightsTextView();
+ void pageMove( Qt::Key key=Key_PageUp );
+
+ public slots:
+ void display_menuView( const QPoint& );
+ void menuFunct( int );
+ void displayLink(const QString& urlString);
+ void print( void );
+
+ signals:
+ void rightButtonClicked( const QPoint& );
+
+ protected:
+ void viewportMousePressEvent( QMouseEvent *e );
+ resource *myResource;
+ KPopupMenu *menuView;
+};
+
+#endif
diff --git a/knights/list_pgn.cpp b/knights/list_pgn.cpp
new file mode 100644
index 0000000..57be536
--- /dev/null
+++ b/knights/list_pgn.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ list_pgn.cpp - description
+ -------------------
+ begin : Thu Dec 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "list_pgn.moc"
+#include <klistview.h>
+#include <kstatusbar.h>
+#include <kprogress.h>
+#include <qhbox.h>
+#include "resource.h"
+#include "match_param.h"
+
+list_pgn::list_pgn(QWidget *parent, const char *name) : QVBox(parent,name)
+{
+ listView = new KListView( this, "listView" );
+ listView->addColumn( i18n( "Result" ) );
+ listView->addColumn( i18n( "White" ) );
+ listView->addColumn( i18n( "Black" ) );
+ listView->addColumn( i18n( "Round" ) );
+ listView->addColumn( i18n( "Site" ) );
+ listView->addColumn( i18n( "Date" ) );
+ listView->setSorting( 1 );
+ listView->setAllColumnsShowFocus( TRUE );
+ listView->setMultiSelection( FALSE );
+ listView->setShowSortIndicator( TRUE );
+ listView->restoreLayout( kapp->config(), "PGN_ListView" );
+ listView->show();
+ connect( listView, SIGNAL( executed( QListViewItem* ) ), this, SLOT( slot_selected( QListViewItem* ) ) );
+
+ /*
+ Showing listView while scanning can mean the difference between
+ a 12 second load time and a 40 second load time. dummyView is
+ just a placeholder for listView while scanning.
+ */
+ dummyView = new KListView( this, "dummyView" );
+ dummyView->addColumn( i18n( "Result" ) );
+ dummyView->addColumn( i18n( "White" ) );
+ dummyView->addColumn( i18n( "Black" ) );
+ dummyView->addColumn( i18n( "Round" ) );
+ dummyView->addColumn( i18n( "Site" ) );
+ dummyView->addColumn( i18n( "Date" ) );
+ dummyView->restoreLayout( kapp->config(), "PGN_ListView" );
+ dummyView->hide();
+
+ statusBox = new QHBox( this, "statusBox" );
+ status = new KStatusBar( statusBox, "status" );
+
+ progress = new KProgress( statusBox, "progress" );
+ progress->setValue( 0 );
+
+ show();
+}
+list_pgn::~list_pgn()
+{
+ listView->saveLayout( kapp->config(), "PGN_ListView" );
+}
+///////////////////////////////////////
+//
+// list_pgn::setURL
+//
+///////////////////////////////////////
+void list_pgn::setURL( QString URL )
+{
+ myURL = URL;
+ listView->clear();
+ setCaption( URL );
+
+ if( tmpPGN.open( URL ) == FALSE )
+ {
+ status->message( i18n( "Can not open %1" ).arg( URL ) );
+ return;
+ }
+ listView->hide();
+ dummyView->show();
+ startTimer( 0 );
+}
+///////////////////////////////////////
+//
+// list_pgn::setProgress
+//
+///////////////////////////////////////
+void list_pgn::setProgress( const int num )
+{
+ progress->setValue( num );
+ if( num == 100 )
+ progress->setEnabled( FALSE );
+ else
+ progress->setEnabled( TRUE );
+}
+///////////////////////////////////////
+//
+// list_pgn::slot_selected
+//
+///////////////////////////////////////
+void list_pgn::slot_selected( QListViewItem *item )
+{
+ emit selected( myURL, item->text(6).toInt() );
+}
+///////////////////////////////////////
+//
+// list_pgn::timerEvent
+//
+///////////////////////////////////////
+void list_pgn::timerEvent( QTimerEvent* )
+{
+ int fileProgress;
+
+ fileProgress = tmpPGN.scan();
+ setProgress( fileProgress );
+ if( tmpPGN.TAG_White.isEmpty() )
+ {
+ if( listView->childCount() == 1 )
+ {
+ emit selected( myURL, 0 );
+ }
+ killTimers();
+ listView->show();
+ dummyView->hide();
+ }
+ else
+ {
+ (void) new KListViewItem( listView,
+ tmpPGN.TAG_Result,
+ tmpPGN.TAG_White,
+ tmpPGN.TAG_Black,
+ tmpPGN.TAG_Round,
+ tmpPGN.TAG_Site,
+ tmpPGN.TAG_Date,
+ QString::number(tmpPGN.File_Position) );
+ status->message( i18n( QString( "%1 matches found." ).arg( listView->childCount() ) ) );
+ }
+}
diff --git a/knights/list_pgn.h b/knights/list_pgn.h
new file mode 100644
index 0000000..f8712b5
--- /dev/null
+++ b/knights/list_pgn.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ list_pgn.h - description
+ -------------------
+ begin : Thu Dec 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LIST_PGN_H
+#define LIST_PGN_H
+
+#include <qvbox.h>
+#include <qstring.h>
+#include "pgn.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class match_param;
+class KStatusBar;
+class KProgress;
+class KListView;
+class QHBox;
+
+class list_pgn : public QVBox
+{
+ Q_OBJECT
+ public:
+ list_pgn(QWidget *parent=0, const char *name=0);
+ void setURL( QString URL );
+ void setProgress( const int );
+ QString URL( void )
+ { return myURL; }
+ ~list_pgn();
+
+
+ signals:
+ void selected( const QString&, const int& );
+
+ protected slots:
+ void slot_selected( QListViewItem *item );
+
+ protected:
+ void timerEvent( QTimerEvent * );
+
+ private:
+ QString myURL;
+ QHBox *statusBox;
+ KListView *listView;
+ KListView *dummyView;
+ KStatusBar *status;
+ KProgress *progress;
+ pgn tmpPGN;
+};
+
+#endif
diff --git a/knights/logic.cpp b/knights/logic.cpp
new file mode 100644
index 0000000..9d889d4
--- /dev/null
+++ b/knights/logic.cpp
@@ -0,0 +1,1495 @@
+/***************************************************************************
+ logic.cpp - description
+ -------------------
+ begin : Sat Sep 29 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "logic.h"
+#include "dlg_promote.h"
+#include "command.h"
+#include <stdlib.h>
+
+///////////////////////////////////////
+//
+// logic::logic
+//
+///////////////////////////////////////
+logic::logic( resource *Rsrc, match_param *param )
+{
+ Resource = Rsrc;
+ Param = param;
+ int tmp;
+
+ GameType = Type_Standard;
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ current[tmp].File = ( tmp % 8 );
+ current[tmp].Rank = ( tmp >> 3 );
+ }
+ clearBoard();
+}
+///////////////////////////////////////
+//
+// logic::~logic
+//
+///////////////////////////////////////
+logic::~logic()
+{
+}
+///////////////////////////////////////
+//
+// logic::Pointer
+//
+///////////////////////////////////////
+int logic::Pointer( const char File, const char Rank )
+{
+ if( ( File < 0 ) || ( File > 7 ) ) return Null;
+ if( ( Rank < 0 ) || ( Rank > 7 ) ) return Null;
+ return ( ( Rank << 3 ) + File );
+}
+///////////////////////////////////////
+//
+// logic::CalcPointer
+//
+///////////////////////////////////////
+int logic::CalcPointer( const char File, const char Rank )
+{
+ char tmpFile, tmpRank;
+
+ tmpFile = chessman[ManPtr].File + File;
+ tmpRank = chessman[ManPtr].Rank + Rank;
+ return Pointer( tmpFile, tmpRank );
+}
+///////////////////////////////////////
+//
+// logic::isChessman
+//
+///////////////////////////////////////
+bool logic::isChessman( const char ChessmanPtr )
+{
+ char BoardPtr = Pointer( chessman[ChessmanPtr].File, chessman[ChessmanPtr].Rank );
+ if( ( BoardPtr < 0 ) || ( BoardPtr > 63 ) ) return FALSE;
+ if( current[BoardPtr].ManPtr != ChessmanPtr ) return FALSE;
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// logic::clearBoard
+//
+///////////////////////////////////////
+void logic::clearBoard( void )
+{
+ for( register int tmp = 0; tmp < 64; tmp++ )
+ {
+ chessman[tmp].Type = Null;
+ current[tmp].ManPtr = Null;
+ current[tmp].Note = NOTE_NONE;
+ }
+}
+///////////////////////////////////////
+//
+// logic::Init
+//
+///////////////////////////////////////
+void logic::Init( const int Var )
+{
+ GameType = Var;
+ switch( GameType )
+ {
+ case Type_Standard: // Fall Through
+ default:
+ Init_Standard();
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// logic::Init_Standard
+//
+///////////////////////////////////////
+void logic::Init_Standard( void )
+{
+ register int tmp;
+
+ clearBoard();
+ for( tmp = 0; tmp < 32; tmp++ )
+ {
+ if( tmp < 16 )
+ {
+ chessman[tmp].Army = WHITE;
+ chessman[tmp].Rank = 0;
+ }
+ else
+ {
+ chessman[tmp].Army = BLACK;
+ chessman[tmp].Rank = 7;
+ }
+ switch( tmp % 16 )
+ {
+ case 0:
+ chessman[tmp].Type = King;
+ chessman[tmp].File = 4;
+ break;
+ case 1:
+ chessman[tmp].Type = Queen;
+ chessman[tmp].File = 3;
+ break;
+ case 2:
+ chessman[tmp].Type = Bishop;
+ chessman[tmp].File = 2;
+ break;
+ case 3:
+ chessman[tmp].Type = Bishop;
+ chessman[tmp].File = 5;
+ break;
+ case 4:
+ chessman[tmp].Type = Knight;
+ chessman[tmp].File = 1;
+ break;
+ case 5:
+ chessman[tmp].Type = Knight;
+ chessman[tmp].File = 6;
+ break;
+ case 6:
+ chessman[tmp].Type = Rook;
+ chessman[tmp].File = 0;
+ break;
+ case 7:
+ chessman[tmp].Type = Rook;
+ chessman[tmp].File = 7;
+ break;
+ default:
+ chessman[tmp].Type = Pawn;
+ chessman[tmp].File = ( tmp % 16 ) - 8;
+ if( chessman[tmp].Army == WHITE ) chessman[tmp].Rank = 1;
+ else chessman[tmp].Rank = 6;
+ break;
+ }
+ current[ Pointer( chessman[tmp].File, chessman[tmp].Rank ) ].ManPtr = tmp;
+ CastleFlag[0] = CF_King + CF_RookQ + CF_RookK;
+ CastleFlag[1] = CF_King + CF_RookQ + CF_RookK;
+ OnMove = WHITE;
+ }
+}
+///////////////////////////////////////
+//
+// logic::parseCAN
+//
+///////////////////////////////////////
+bool logic::parseCAN( const bool Army )
+{
+ if( chessMove.CAN == NULL ) return FALSE;
+ if( ( chessMove.CAN[0] != 'o' ) && ( chessMove.CAN[0] != 'O' ) )
+ {
+ if( ( chessMove.CAN[0] < 'a' ) || ( chessMove.CAN[0] > 'h' ) ) return FALSE;
+ chessMove.fromFile = chessMove.CAN[0] - 97;
+ if( ( chessMove.CAN[1] < '1' ) || ( chessMove.CAN[1] > '8' ) ) return FALSE;
+ chessMove.fromRank = chessMove.CAN[1] - 49;
+ if( ( chessMove.CAN[2] < 'a' ) || ( chessMove.CAN[2] > 'h' ) ) return FALSE;
+ chessMove.toFile = chessMove.CAN[2] - 97;
+ if( ( chessMove.CAN[3] < '1' ) || ( chessMove.CAN[3] > '8' ) ) return FALSE;
+ chessMove.toRank = chessMove.CAN[3] - 49;
+ if( strlen( chessMove.CAN ) == 5 ) chessMove.Promote = chessMove.CAN[4];
+ else chessMove.Promote = Null;
+ }
+ /*
+ For some reason some engines w/ CAN output
+ express castling using SAN, not to name names GNUChess v4
+ */
+ else
+ {
+ chessMove.fromFile = 4;
+ if( QString( chessMove.CAN ).lower() == "o-o" ) chessMove.toFile = 6;
+ else chessMove.toFile = 2;
+ if( Army == WHITE )
+ {
+ chessMove.fromRank = 0;
+ chessMove.toRank = 0;
+ }
+ else
+ {
+ chessMove.fromRank = 7;
+ chessMove.toRank = 7;
+ }
+ }
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// logic::parseSAN
+//
+///////////////////////////////////////
+bool logic::parseSAN( void )
+{
+ bool Army(OnMove);
+ char Type(Pawn);
+ char SANPtr(0), tmp(0);
+
+ chessMove.fromFile = Null;
+ chessMove.fromRank = Null;
+ chessMove.toFile = Null;
+ chessMove.toRank = Null;
+ chessMove.Promote = Null;
+ chessMove.ManTaken = Null;
+ chessMove.NAG = 0;
+ while( SANPtr < (signed)QString( chessMove.SAN ).length() )
+ {
+ /* Parse a character */
+ switch( chessMove.SAN[SANPtr] )
+ {
+ case 'K':
+ if( SANPtr == 0 )
+ Type = King;
+ else
+ chessMove.Promote = 'k';
+ break;
+ case 'Q':
+ if( SANPtr == 0 )
+ Type = Queen;
+ else
+ chessMove.Promote = 'q';
+ break;
+ case 'B':
+ if( SANPtr == 0 )
+ Type = Bishop;
+ else
+ chessMove.Promote = 'b';
+ break;
+ case 'N':
+ if( SANPtr == 0 )
+ Type = Knight;
+ else
+ chessMove.Promote = 'n';
+ break;
+ case 'R':
+ if( SANPtr == 0 )
+ Type = Rook;
+ else
+ chessMove.Promote = 'r';
+ break;
+ /* Parse castle */
+ case 'o':
+ case 'O':
+ if( SANPtr != 0 )
+ break;
+ Type = King;
+ if( Army == WHITE )
+ chessMove.toRank = 0;
+ else
+ chessMove.toRank = 7;
+ if( QString( chessMove.SAN ).lower() == "o-o-o" )
+ chessMove.toFile = 2;
+ if( QString( chessMove.SAN ).lower() == "o-o" )
+ chessMove.toFile = 6;
+ break;
+ /* Ignore some symbols... these fall through */
+ case 'x':
+ case '=':
+ case '#':
+ case '+':
+ case '-':
+ case 'P':
+ break;
+ /* Handle annotations */
+ case '!':
+ chessMove.NAG = 1;
+ if( chessMove.SAN[SANPtr - 1] == '!' )
+ chessMove.NAG = 3;
+ if( chessMove.SAN[SANPtr - 1] == '?' )
+ chessMove.NAG = 6;
+ break;
+ case '?':
+ chessMove.NAG = 2;
+ if( chessMove.SAN[SANPtr - 1] == '!' )
+ chessMove.NAG = 5;
+ if( chessMove.SAN[SANPtr - 1] == '?' )
+ chessMove.NAG = 4;
+ break;
+ default:
+ if( ( chessMove.SAN[SANPtr] >= '1' ) && ( chessMove.SAN[SANPtr] <= '8' ) )
+ {
+ if( chessMove.toRank != Null )
+ chessMove.fromRank = chessMove.toRank;
+ chessMove.toRank = chessMove.SAN[SANPtr] - 49;
+ break;
+ }
+ if( ( chessMove.SAN[SANPtr] >= 'a' ) && ( chessMove.SAN[SANPtr] <= 'h' ) )
+ {
+ if( chessMove.toFile != Null )
+ chessMove.fromFile = chessMove.toFile;
+ chessMove.toFile = chessMove.SAN[SANPtr] - 97;
+ break;
+ }
+ /* Unknown symbol... Can not process this chessMove */
+// kdDebug() << "logic::ParseSAN: Unknown Symbol: " << chessMove.SAN[SANPtr] << "\n";
+ return FALSE;
+ break;
+ }
+ SANPtr++;
+ }
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( chessman[tmp].Type != Type )
+ continue;
+ if( chessman[tmp].Army != Army )
+ continue;
+ if( ( chessMove.fromFile != Null ) && ( chessman[tmp].File != chessMove.fromFile ) )
+ continue;
+ if( ( chessMove.fromRank != Null ) && ( chessman[tmp].Rank != chessMove.fromRank ) )
+ continue;
+ if( !isChessman( tmp ) )
+ continue;
+ HashLegal( tmp );
+ if( current[ ( chessMove.toRank << 3 ) + chessMove.toFile ].Note < NOTE_MOVE )
+ continue;
+ chessMove.fromFile = chessman[tmp].File;
+ chessMove.fromRank = chessman[tmp].Rank;
+ break;
+ }
+ if( tmp == 64 )
+ {
+// kdWarning() << "logic::ParseSAN could not make a legal chessMove out of " << QString( chessMove.SAN ) << endl;
+// kdWarning() << (int)Army << " " << (int)Type << " " << (int)chessMove.fromFile << " " << (int)chessMove.fromRank
+// << " " << (int)chessMove.toFile << " " << (int)chessMove.toRank << endl;
+ return FALSE;
+ }
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// logic::writeCAN
+//
+///////////////////////////////////////
+void logic::writeCAN( void )
+{
+ chessMove.CAN[0] = chessMove.fromFile + 97;
+ chessMove.CAN[1] = chessMove.fromRank + 49;
+ chessMove.CAN[2] = chessMove.toFile + 97;
+ chessMove.CAN[3] = chessMove.toRank + 49;
+ if( chessMove.Promote == Null ) chessMove.CAN[4] = 0;
+ else
+ {
+ chessMove.CAN[4] = chessMove.Promote;
+ chessMove.CAN[5] = 0;
+ }
+}
+///////////////////////////////////////
+//
+// logic::writeSAN
+//
+///////////////////////////////////////
+void logic::writeSAN( void )
+{
+ Position backup[64];
+ bool SANambig(FALSE);
+ bool SANambig2(FALSE);
+ register char tmp, manPtr, toPtr, fromPtr;
+ QString SAN;
+
+ /*
+ writeSAN calls HashLegal(), which writes on current[],
+ which we need intact for Move()... so we need a backup
+ copy of current[]. Removing this breaks en passant moves
+ */
+ copyPositions( current, backup );
+ fromPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
+ toPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
+ if( ( fromPtr > 63 ) || ( toPtr > 63 ) ) return;
+ if( ( fromPtr < 0 ) || ( toPtr < 0 ) ) return;
+ manPtr = current[fromPtr].ManPtr;
+ if( manPtr == Null ) return;
+
+ /* Check ambiguity for SAN notation */
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( tmp == manPtr ) continue;
+ if( !isChessman( tmp ) ) continue;
+ if( chessman[tmp].Army == chessman[manPtr].Army )
+ {
+ if( chessman[tmp].Type == chessman[manPtr].Type )
+ {
+ HashLegal( tmp );
+ if( current[toPtr].Note >= NOTE_MOVE )
+ {
+ SANambig = TRUE;
+ if( chessman[tmp].File == chessman[manPtr].File )
+ SANambig2 = TRUE;
+ }
+ }
+ /*
+ This IF was added to fix an ambiguity that occurs when a pawn
+ on B file and a Bishop can attack the same spot
+ */
+ else
+ if( ( ( chessman[manPtr].Type == Bishop ) && ( chessman[tmp].Type == Pawn ) ) ||
+ ( ( chessman[manPtr].Type == Pawn ) && ( chessman[tmp].Type == Bishop ) ) )
+ {
+ if( ( chessman[manPtr].File == 1 ) || ( chessman[tmp].File == 1 ) )
+ {
+ HashLegal( tmp );
+ if( current[toPtr].Note >= NOTE_MOVE )
+ {
+ SANambig = TRUE;
+ SANambig2 = TRUE;
+ }
+ }
+ }
+ }
+ }
+ /* Go ahead and restore the backup. */
+ copyPositions( backup, current );
+ if( ( ( current[toPtr].Note == NOTE_ATTACK ) ||
+ ( current[toPtr].Note == NOTE_ENPASSANT ) ) &&
+ ( chessman[manPtr].Type == Pawn ) )
+ {
+ SANambig = TRUE;
+ }
+ /* Write SAN Notation */
+ if( current[toPtr].Note == NOTE_CASTLE )
+ {
+ if( chessMove.toFile == 6 ) SAN = "O-O";
+ if( chessMove.toFile == 2 ) SAN = "O-O-O";
+ }
+ else
+ {
+ switch( chessman[manPtr].Type )
+ {
+ case King:
+ SAN += 'K';
+ break;
+ case Queen:
+ SAN += 'Q';
+ break;
+ case Bishop:
+ SAN += 'B';
+ break;
+ case Knight:
+ SAN += 'N';
+ break;
+ case Rook:
+ SAN += 'R';
+ break;
+ case Pawn:
+// if( SANambig2 ) SAN += 'P';
+ break;
+ default:
+ break;
+ }
+ if( SANambig == TRUE )
+ {
+ SAN += char( chessMove.fromFile + 97 );
+ if( SANambig2 ) SAN += char( chessMove.fromRank + 49 );
+ }
+ if( ( current[toPtr].Note == NOTE_ATTACK ) ||
+ ( current[toPtr].Note == NOTE_ENPASSANT ) )
+ SAN += 'x';
+ SAN += char( chessMove.toFile + 97 );
+ SAN += char( chessMove.toRank + 49 );
+ switch( chessMove.Promote )
+ {
+ case 'q':
+ chessman[manPtr].Type = Queen;
+ SAN += "=Q";
+ break;
+ case 'b':
+ chessman[manPtr].Type = Bishop;
+ SAN += "=B";
+ break;
+ case 'n':
+ chessman[manPtr].Type = Knight;
+ SAN += "=N";
+ break;
+ case 'r':
+ chessman[manPtr].Type = Rook;
+ SAN += "=R";
+ break;
+ default:
+ break;
+ }
+ }
+ strcpy( chessMove.SAN, SAN.latin1() );
+}
+///////////////////////////////////////
+//
+// logic::board
+//
+///////////////////////////////////////
+QString logic::board( void )
+{
+ QString output;
+ register int tmp(0), tmpMan(0), cR(7), cF(0);
+
+ while( tmp != 64 )
+ {
+ tmpMan = current[ Pointer( cF, cR ) ].ManPtr;
+ if( tmpMan == Null )
+ output += '-';
+ else
+ {
+ switch( chessman[ tmpMan ].Type )
+ {
+ case King:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'K';
+ else
+ output += 'k';
+ break;
+ case Queen:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'Q';
+ else
+ output += 'q';
+ break;
+ case Bishop:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'B';
+ else
+ output += 'b';
+ break;
+ case Knight:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'N';
+ else
+ output += 'n';
+ break;
+ case Rook:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'R';
+ else
+ output += 'r';
+ break;
+ case Pawn: // Fall through
+ default:
+ if( chessman[ tmpMan ].Army == WHITE )
+ output += 'P';
+ else
+ output += 'p';
+ break;
+ }
+ }
+ cF++;
+ tmp++;
+ if( cF == 8 )
+ {
+ cF = 0;
+ cR--;
+ }
+ }
+
+ if( CastleFlag[WHITE] & ( CF_King | CF_RookK ) )
+ output += '1';
+ else
+ output += '0';
+ if( CastleFlag[WHITE] & ( CF_King | CF_RookQ ) )
+ output += '1';
+ else
+ output += '0';
+ if( CastleFlag[BLACK] & ( CF_King | CF_RookK ) )
+ output += '1';
+ else
+ output += '0';
+ if( CastleFlag[BLACK] & ( CF_King | CF_RookQ ) )
+ output += '1';
+ else
+ output += '0';
+
+ return output;
+}
+///////////////////////////////////////
+//
+// logic::setBoard
+//
+///////////////////////////////////////
+void logic::setBoard( const QString &board, const short ppf )
+{
+ QChar piece;
+ int tmp(0), tmp2(0), cR(7), cF(0);
+
+ clearBoard();
+ if( board.length() < 64 )
+ {
+ kdWarning() << "logic::setBoard: Was passed a string that is less than 64 bytes long." << endl;
+ return;
+ }
+ while( tmp != 64 )
+ {
+ piece = board.at(tmp++);
+ switch( piece.lower() )
+ {
+ case 'k':
+ if( piece == 'K' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = King;
+ break;
+ case 'q':
+ if( piece == 'Q' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = Queen;
+ break;
+ case 'b':
+ if( piece == 'B' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = Bishop;
+ break;
+ case 'n':
+ if( piece == 'N' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = Knight;
+ break;
+ case 'r':
+ if( piece == 'R' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = Rook;
+ break;
+ case 'p':
+ if( piece == 'P' ) chessman[tmp2].Army = WHITE;
+ else chessman[tmp2].Army = BLACK;
+ chessman[tmp2].Type = Pawn;
+ break;
+ default:
+ break;
+ }
+ if( piece != '-' )
+ {
+ chessman[tmp2].Rank = cR;
+ chessman[tmp2].File = cF;
+ current[ Pointer( cF, cR ) ].ManPtr = tmp2;
+ tmp2++;
+ }
+ cF++;
+ if( cF == 8 )
+ {
+ cF = 0;
+ cR--;
+ }
+ }
+ CastleFlag[WHITE] = 0;
+ CastleFlag[BLACK] = 0;
+ if( board.at(64) == '1' ) CastleFlag[WHITE] += CF_RookK;
+ if( board.at(65) == '1' ) CastleFlag[WHITE] += CF_RookQ;
+ if( board.at(66) == '1' ) CastleFlag[BLACK] += CF_RookK;
+ if( board.at(67) == '1' ) CastleFlag[BLACK] += CF_RookQ;
+ if( CastleFlag[WHITE] ) CastleFlag[WHITE] += CF_King;
+ if( CastleFlag[BLACK] ) CastleFlag[BLACK] += CF_King;
+ /* Update enpassant record */
+ if( ppf != -2 )
+ {
+ enPassant[ !OnMove ] = Null;
+ if( ppf != -1 )
+ enPassant[ OnMove ] = ppf + 24 + ( ( OnMove == BLACK ) << 3 );
+ }
+}
+///////////////////////////////////////
+//
+// logic::getKing
+//
+///////////////////////////////////////
+int logic::getKing( const bool Army )
+{
+ register int tmp;
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( ( chessman[tmp].Army == Army ) && ( chessman[tmp].Type == King ) )
+ if( isChessman( tmp ) )
+ {
+ return Pointer( chessman[tmp].File, chessman[tmp].Rank );
+ }
+ }
+ return Null;
+}
+///////////////////////////////////////
+//
+// logic::isCheck
+//
+///////////////////////////////////////
+bool logic::isCheck( const bool Army )
+{
+ register char tmp(0), currentKing( getKing(Army) );
+
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( chessman[tmp].Army != Army )
+ if( isChessman( tmp ) )
+ {
+ HashLegal( tmp );
+ if( current[ currentKing ].Note == NOTE_ATTACK ) return TRUE;
+ }
+ }
+ return FALSE;
+}
+///////////////////////////////////////
+//
+// logic::isLegal
+//
+///////////////////////////////////////
+bool logic::isLegal( const bool Army )
+{
+ register int tmp(0), tmp2(0), count(0);
+
+ for( tmp2 = 0; tmp2 < 64; tmp2++ )
+ {
+ if( chessman[tmp2].Army == Army )
+ if( isChessman( tmp2 ) )
+ {
+ ManPtr = tmp2;
+ _HashLegal();
+ count = 0;
+ tmp = 0;
+ while( tmp < 64 ) count += ( current[tmp++].Note >= NOTE_MOVE );
+ if( count ) return TRUE;
+ }
+ }
+ return FALSE;
+}
+///////////////////////////////////////
+//
+// logic::isDraw
+//
+///////////////////////////////////////
+bool logic::isDraw( const bool Army )
+{
+ bool haveBishop(FALSE);
+ bool haveBishopDiag(FALSE);
+ bool haveKnight(FALSE);
+ bool EnemyBishop(FALSE);
+ bool EnemyBishopDiag(TRUE);
+ bool EnemyKnight(FALSE);
+ int tmp(0);
+
+ if( !isLegal( Army ) ) return TRUE;
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( !isChessman( tmp ) ) continue;
+ if( chessman[tmp].Type == Queen ) return FALSE;
+ if( chessman[tmp].Type == Pawn ) return FALSE;
+ if( chessman[tmp].Type == Rook ) return FALSE;
+ /* Enemy guys */
+ if( chessman[tmp].Army != Army )
+ {
+ if( chessman[tmp].Type == Bishop )
+ {
+ if( EnemyBishop == TRUE ) return FALSE;
+ EnemyBishopDiag = abs( ( current[tmp].Rank % 2 ) - ( current[tmp].File % 2 ) );
+ EnemyBishop = TRUE;
+ }
+ if( chessman[tmp].Type == Knight )
+ {
+ if( EnemyKnight == TRUE ) return FALSE;
+ EnemyKnight = TRUE;
+ }
+ continue;
+ }
+ /* Our guys */
+ if( chessman[tmp].Type == Bishop )
+ {
+ if( haveBishop == TRUE ) return FALSE;
+ haveBishopDiag = abs( ( current[tmp].Rank % 2 ) - ( current[tmp].File % 2 ) );
+ haveBishop = TRUE;
+ }
+ if( chessman[tmp].Type == Knight )
+ {
+ if( haveKnight == TRUE ) return FALSE;
+ haveKnight = TRUE;
+ }
+ }
+ if( haveKnight && EnemyKnight ) return FALSE;
+ if( haveBishop && EnemyKnight ) return FALSE;
+ if( haveKnight && EnemyBishop ) return FALSE;
+ if( haveKnight && haveBishop ) return FALSE;
+ if( EnemyKnight && EnemyBishop ) return FALSE;
+ if( ( haveBishop && EnemyBishop ) && ( haveBishopDiag != EnemyBishopDiag ) ) return FALSE;
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// logic::setBoardFromFen
+//
+///////////////////////////////////////
+void logic::setBoardFromFen(const QString &fen)
+{
+ clearBoard();
+ int j = 0; //position in string
+ int r = 7; //rank
+ int f = 0; //file
+ int p = 63; //chessman number
+ QChar c; //current letter
+
+ for (j=0;j<120 && p>=0 ;j++) {
+ c = fen[j];
+
+ if (c.isLetter()) {
+ //describing a piece
+ if (c == 'r') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = Rook;
+
+ }
+ if (c=='q') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = Queen;
+ }
+ if (c=='k') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = King;
+ }
+ if (c=='p') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = Pawn;
+ }
+ if (c=='n') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = Knight;
+ }
+ if (c=='b') {
+ chessman[p].Army = BLACK;
+ chessman[p].Type = Bishop;
+ }
+ //black pieces
+ if (c == 'R') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = Rook;
+
+ }
+ if (c=='Q') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = Queen;
+ }
+ if (c=='K') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = King;
+ }
+ if (c=='P') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = Pawn;
+ }
+ if (c=='N') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = Knight;
+ }
+ if (c=='B') {
+ chessman[p].Army = WHITE;
+ chessman[p].Type = Bishop;
+ }
+ chessman[p].Rank = r;
+ chessman[p].File = f;
+ current[ Pointer( chessman[p].File, chessman[p].Rank ) ].ManPtr = p;
+ p--;
+ f++;
+ }
+ if (c.isNumber()) {
+ //describing blank squares
+
+ p = p - c.digitValue();
+ f = f + c.digitValue();
+ }
+
+ if (c == '/') {
+ //describing new rank
+ r--;
+ f=0;
+ }
+
+ }
+
+ do {
+ j++;
+ c = fen[j];
+ } while (c == '/' || c == ' ');
+ if (c=='w')
+ OnMove = WHITE;
+ if (c=='b')
+ OnMove = BLACK;
+
+}
+///////////////////////////////////////
+//
+// logic::Move
+//
+///////////////////////////////////////
+bool logic::Move( void )
+{
+ dlg_promote *ProDlg;
+ int tmp;
+ int fromPtr, toPtr, manPtr;
+
+ fromPtr = Pointer( chessMove.fromFile, chessMove.fromRank );
+ toPtr = Pointer( chessMove.toFile, chessMove.toRank );
+ if( ( fromPtr == Null ) || ( toPtr == Null ) )
+ return FALSE;
+ manPtr = current[fromPtr].ManPtr;
+ if( manPtr == Null )
+ return FALSE;
+
+ HashLegal( manPtr );
+ /* Only proceed if this is a move */
+ if( current[toPtr].Note < NOTE_MOVE )
+ return FALSE; // This depends on all moves being higher value than NOTE_MOVE,
+ // while all non-moves are less.
+
+ /* Take care of moving the rook in a caste */
+ if( current[toPtr].Note == NOTE_CASTLE )
+ {
+ if( chessMove.toFile == 6 )
+ {
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( ( chessman[tmp].Army == chessman[manPtr].Army ) &&
+ ( chessman[tmp].Type == Rook ) &&
+ ( chessman[tmp].File == 7 ) )
+ {
+ chessman[tmp].File = 5;
+ current[ Pointer( 7, ( 7 * ( chessman[tmp].Army == BLACK ) ) ) ].ManPtr = Null;
+ current[ Pointer( 5, ( 7 * ( chessman[tmp].Army == BLACK ) ) ) ].ManPtr = tmp;
+ break;
+ }
+ }
+ }
+ if( chessMove.toFile == 2 )
+ {
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( ( chessman[tmp].Army == chessman[manPtr].Army ) &&
+ ( chessman[tmp].Type == Rook ) &&
+ ( chessman[tmp].File == 0 ) )
+ {
+ chessman[tmp].File = 3;
+ current[ Pointer( 0, ( 7 * ( chessman[tmp].Army == BLACK ) ) ) ].ManPtr = Null;
+ current[ Pointer( 3, ( 7 * ( chessman[tmp].Army == BLACK ) ) ) ].ManPtr = tmp;
+ break;
+ }
+ }
+ }
+ }
+ /* Handle the 50 Move Rule */
+ MoveCounter++;
+ if( chessman[manPtr].Type == Pawn ) MoveCounter = 0;
+ if( current[ toPtr ].ManPtr != Null )
+ {
+ MoveCounter = 0;
+ chessMove.ManTaken = current[ toPtr ].ManPtr;
+ }
+ /* Check for Pawn Promotion */
+ if( ( chessMove.toRank == ( 7 * ( chessman[manPtr].Army == WHITE ) ) ) &&
+ ( chessman[manPtr].Type == Pawn ) )
+ {
+ if( ( ( OnMove == WHITE ) && ( Param->type(WHITE) == PLAYERLOCAL ) ) ||
+ ( ( OnMove == BLACK ) && ( Param->type(BLACK) == PLAYERLOCAL ) ) )
+ {
+ if( Resource->OPTION_Auto_Queen == TRUE ) chessMove.Promote = 'q';
+ else
+ {
+ /* Prompt user for promotion */
+ ProDlg = new dlg_promote( 0, "promotedialog", Resource );
+ ProDlg->Init( OnMove );
+ chessMove.Promote = ProDlg->exec();
+ delete ProDlg;
+ /* Default to Queen if the user quit the dialog without choosing */
+ if( ( chessMove.Promote != 'q' ) &&
+ ( chessMove.Promote != 'b' ) &&
+ ( chessMove.Promote != 'n' ) &&
+ ( chessMove.Promote != 'r' ) ) chessMove.Promote = 'q';
+ }
+ }
+ }
+ /* Write CAN & SAN Notation for this move */
+ writeCAN();
+ writeSAN();
+ /* Make the move */
+ chessman[manPtr].File = chessMove.toFile;
+ chessman[manPtr].Rank = chessMove.toRank;
+ current[fromPtr].ManPtr = Null;
+ current[toPtr].ManPtr = manPtr;
+ /* Remove pawns taken en passant */
+ if( current[toPtr].Note == NOTE_ENPASSANT )
+ {
+ MoveCounter = 0;
+ chessMove.ManTaken = current[ enPassant[ 1 - chessman[manPtr].Army ] ].ManPtr;
+ current[ enPassant[ 1 - chessman[manPtr].Army ] ].ManPtr = Null;
+ }
+ /* Take care of en passant data */
+ if( current[toPtr].Note == NOTE_PAWN_DOUBLE )
+ enPassant[ chessman[manPtr].Army ] = toPtr;
+ enPassant[ 1 - chessman[manPtr].Army ] = Null;
+ /* Handle castle flags */
+ if( chessman[manPtr].Type == King )
+ CastleFlag[ chessman[manPtr].Army ] = 0;
+ if( ( chessman[manPtr].Type == Rook ) && ( chessMove.fromFile == 0 ) )
+ CastleFlag[ chessman[manPtr].Army ] -= CF_RookQ;
+ if( ( chessman[manPtr].Type == Rook ) && ( chessMove.fromFile == 7 ) )
+ CastleFlag[ chessman[manPtr].Army ] -= CF_RookK;
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// logic::HashLegal
+//
+///////////////////////////////////////
+void logic::HashLegal( const char Man, const bool Recursion )
+{
+ char tmp;
+ tmp = ManPtr;
+ ManPtr = Man;
+ _HashLegal( Recursion );
+ ManPtr = tmp;
+}
+void logic::_HashLegal( const bool Recursion )
+{
+ /* Used for loops and positions */
+ register int Ptr(0), tmp(0), tmp2(0);
+
+ /* Used to calculate a position relative to a given position */
+ int dirF(0), dirR(0);
+
+ /* Used to monitor the King inside the Monster */
+ int currentKing(0), _castleFlag(0);
+
+ if( !isChessman(ManPtr) )
+ return;
+
+ copyPositions( current, hash );
+
+ while( tmp < 64 )
+ hash[tmp++].Note = NOTE_NONE;
+
+ switch( chessman[ManPtr].Type )
+ {
+ /* ROOK & QUEEN */
+ case Rook:
+ case Queen:
+ /* Positive Rank Movement */
+ for( tmp = 1; tmp < 8; tmp++ )
+ {
+ Ptr = CalcPointer( 0, tmp );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* Negitive Rank Movement */
+ for( tmp = -1; tmp > -8; tmp-- )
+ {
+ Ptr = CalcPointer( 0, tmp );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* Positive File Movement */
+ for( tmp = 1; tmp < 8; tmp++ )
+ {
+ Ptr = CalcPointer( tmp, 0 );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* Negative File Movement */
+ for( tmp = -1; tmp > -8; tmp-- )
+ {
+ Ptr = CalcPointer( tmp, 0 );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( chessman[ManPtr].Type == Rook ) break;
+ /* Bishop & Queen */
+ case Bishop:
+ /* NE Movement */
+ for( tmp = 1; tmp < 8; tmp++ )
+ {
+ Ptr = CalcPointer( tmp, tmp );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* NW Movement */
+ for( tmp = -1; tmp > -8; tmp-- )
+ {
+ Ptr = CalcPointer( tmp, abs(tmp) );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* SW Movement */
+ for( tmp = -1; tmp > -8; tmp-- )
+ {
+ Ptr = CalcPointer( tmp, tmp );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ /* SE Movement */
+ for( tmp = -1; tmp > -8; tmp-- )
+ {
+ Ptr = CalcPointer( abs(tmp), tmp );
+ if( Ptr == Null ) break;
+ if( hash[Ptr].ManPtr == Null )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ continue;
+ }
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ {
+ hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ break;
+ }
+ break;
+ /* Knight */
+ case Knight:
+ for( tmp = 0; tmp < 8; tmp++ )
+ {
+ switch( tmp )
+ {
+ case 0:
+ Ptr = CalcPointer( -1, 2 );
+ break;
+ case 1:
+ Ptr = CalcPointer( 1, 2 );
+ break;
+ case 2:
+ Ptr = CalcPointer( 2, 1 );
+ break;
+ case 3:
+ Ptr = CalcPointer( 2, -1 );
+ break;
+ case 4:
+ Ptr = CalcPointer( 1, -2 );
+ break;
+ case 5:
+ Ptr = CalcPointer( -1, -2 );
+ break;
+ case 6:
+ Ptr = CalcPointer( -2, -1 );
+ break;
+ case 7:
+ Ptr = CalcPointer( -2, 1 );
+ break;
+ default:
+ break;
+ }
+ if( Ptr != Null )
+ {
+ if( hash[Ptr].ManPtr == Null )
+ hash[Ptr].Note = NOTE_MOVE;
+ else
+ {
+ if( Recursion == TRUE )
+ hash[Ptr].Note = NOTE_ATTACK;
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army )
+ hash[Ptr].Note = NOTE_ATTACK;
+ }
+ }
+ }
+ break;
+ /* King */
+ case King:
+ dirF = -1;
+ dirR = 1;
+ while(1)
+ {
+ Ptr = CalcPointer( dirF, dirR );
+ if( Ptr != Null )
+ {
+ if( hash[Ptr].ManPtr == Null ) hash[Ptr].Note = NOTE_MOVE;
+ else
+ {
+ if( Recursion == TRUE ) hash[Ptr].Note = NOTE_ATTACK;
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army ) hash[Ptr].Note = NOTE_ATTACK;
+ }
+ }
+ dirF++;
+ if( dirF == 2 )
+ {
+ dirF = -1;
+ dirR--;
+ }
+ if( dirR == -2 ) break;
+ if( ( dirR == 0 ) && ( dirF == 0 ) ) dirF++;
+ }
+ /* Check for castles */
+ if( Recursion == FALSE )
+ {
+ /* Can the King castle at all? */
+ if( CastleFlag[ chessman[ ManPtr ].Army ] & CF_King )
+ {
+ dirR = 0;
+ /* How about with the Queen's Rook? */
+ if( CastleFlag[ chessman[ ManPtr ].Army ] & CF_RookQ )
+ {
+ if( hash[ CalcPointer( -1, dirR ) ].ManPtr == Null )
+ {
+ if( hash[ CalcPointer( -2, dirR ) ].ManPtr == Null )
+ {
+ if( hash[ CalcPointer( -3, dirR ) ].ManPtr == Null )
+ {
+ hash[ CalcPointer( -2, dirR ) ].Note = NOTE_CASTLE;
+ _castleFlag |= CF_RookQ;
+ }
+ }
+ }
+ }
+ /* King's Rook? */
+ if( CastleFlag[ chessman[ ManPtr ].Army ] & CF_RookK )
+ {
+ if( hash[ CalcPointer( 1, dirR ) ].ManPtr == Null )
+ {
+ if( hash[ CalcPointer( 2, dirR ) ].ManPtr == Null )
+ {
+ hash[ CalcPointer( 2, dirR ) ].Note = NOTE_CASTLE;
+ _castleFlag |= CF_RookK;
+ }
+ }
+ }
+ }
+ }
+ break;
+ /* PAWN */
+ default:
+ /* Get direction of movement */
+ if( chessman[ManPtr].Army == WHITE ) dirR = 1;
+ else dirR = -1;
+ if( Recursion == FALSE )
+ {
+ /* Forward 1 square */
+ Ptr = CalcPointer( 0, dirR );
+ if( ( Ptr != Null ) && ( hash[Ptr].ManPtr == Null ) )
+ {
+ hash[Ptr].Note = NOTE_MOVE;
+ tmp = 1 + ( 5 * ( chessman[ManPtr].Army == BLACK ) );
+ if( chessman[ManPtr].Rank == tmp )
+ {
+ /* Forward 2 squares */
+ dirR = dirR << 1;
+ Ptr = CalcPointer( 0, dirR );
+ if( ( Ptr != Null ) && ( hash[Ptr].ManPtr == Null ) ) hash[Ptr].Note = NOTE_PAWN_DOUBLE;
+ dirR = dirR >> 1;
+ }
+ }
+ }
+ if( Recursion == TRUE )
+ {
+ /* Attack Left */
+ Ptr = CalcPointer( -1, dirR );
+ if( Ptr != Null ) hash[Ptr].Note = NOTE_ATTACK;
+ /* Attack Right */
+ Ptr = CalcPointer( 1, dirR );
+ if( Ptr != Null ) hash[Ptr].Note = NOTE_ATTACK;
+ }
+ else
+ {
+ /* Attack Left */
+ Ptr = CalcPointer( -1, dirR );
+ if( ( Ptr != Null ) && ( hash[Ptr].ManPtr != Null ) )
+ {
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army ) hash[Ptr].Note = NOTE_ATTACK;
+ }
+ /* Attack Right */
+ Ptr = CalcPointer( 1, dirR );
+ if( ( Ptr != Null ) && ( hash[Ptr].ManPtr != Null ) )
+ {
+ if( chessman[hash[Ptr].ManPtr].Army != chessman[ManPtr].Army ) hash[Ptr].Note = NOTE_ATTACK;
+ }
+ /* Attack en Passant Left */
+ Ptr = CalcPointer( -1, 0 );
+ if( ( Ptr != Null ) && ( enPassant[ 1 - chessman[ManPtr].Army ] == Ptr ) )
+ {
+ Ptr = CalcPointer( -1, dirR );
+ hash[Ptr].Note = NOTE_ENPASSANT;
+ }
+ /* Attack en Passant Right */
+ Ptr = CalcPointer( 1, 0 );
+ if( ( Ptr != Null ) && ( enPassant[ 1 - chessman[ManPtr].Army ] == Ptr ) )
+ {
+ Ptr = CalcPointer( 1, dirR );
+ hash[Ptr].Note = NOTE_ENPASSANT;
+ }
+ }
+ break;
+ }
+ /* THE MONSTER */
+ /* Remove all possible moves that would either put your */
+ /* king into check or wouldn't stop a check in progress */
+ if( Recursion == FALSE )
+ {
+ /* Make Backups */
+ copyPositions( hash, hashBackup );
+ copyChessmen( chessman, chessmanBackup );
+
+ /* Find the King's Position */
+ currentKing = getKing( chessman[ManPtr].Army );
+
+ /* Remove castles under specific conditions */
+ if( _castleFlag )
+ {
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( !isChessman( tmp ) ) continue;
+ if( ( chessman[tmp].Army != chessman[ManPtr].Army ) && ( chessman[tmp].Type != Null ) )
+ {
+ HashLegal( tmp, TRUE );
+ /* Is a check in progress? */
+ if( hash[ currentKing ].Note == NOTE_ATTACK )
+ {
+ for( tmp2 = 0; tmp2 < 64; tmp2++ )
+ if( hashBackup[tmp2].Note == NOTE_CASTLE ) hashBackup[tmp2].Note = NOTE_NONE;
+ break;
+ }
+ else
+ {
+ /* Store ManPtr in dirF so we can use ManPtr */
+ dirF = ManPtr;
+ ManPtr = hashBackup[ currentKing ].ManPtr;
+ /* Is the path to Queenside in check? */
+ if( _castleFlag & CF_RookQ )
+ {
+ if( ( hash[ CalcPointer( -1, 0 ) ].Note == NOTE_MOVE ) ||
+ ( hash[ CalcPointer( -2, 0 ) ].Note == NOTE_MOVE ) )
+ {
+ hashBackup[ CalcPointer( -2, 0 ) ].Note = NOTE_NONE;
+ _castleFlag -= CF_RookQ;
+ }
+ }
+ /* Is the path to Kingside in check? */
+ if( _castleFlag & CF_RookK )
+ {
+ if( ( hash[ CalcPointer( 1, 0 ) ].Note == NOTE_MOVE ) ||
+ ( hash[ CalcPointer( 2, 0 ) ].Note == NOTE_MOVE ) )
+ {
+ hashBackup[ CalcPointer( 2, 0 ) ].Note = NOTE_NONE;
+ _castleFlag -= CF_RookK;
+ }
+ }
+ /* Restore ManPtr */
+ ManPtr = dirF;
+ }
+ }
+ }
+ } // <- End Castle Checks
+
+ /* Check all possible moves */
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ /* Only proceed if this is a move */
+ if( hashBackup[tmp].Note < NOTE_MOVE )
+ continue; // This depends on all moves being higher value than NOTE_MOVE,
+ // while all non-moves are less.
+
+ /* Pretend we moved here... what would happen? */
+ current[ Pointer( chessman[ManPtr].File, chessman[ManPtr].Rank ) ].ManPtr = Null;
+ chessman[ManPtr].File = hashBackup[tmp].File;
+ chessman[ManPtr].Rank = hashBackup[tmp].Rank;
+ current[tmp].ManPtr = ManPtr;
+ if( current[tmp].Note == NOTE_ENPASSANT )
+ {
+ current[ enPassant[ 1 - chessman[ManPtr].Army ] ].ManPtr = Null;
+ }
+
+ /* Recalc King pos, as we may have just moved him */
+ currentKing = getKing( chessman[ManPtr].Army );
+
+ /* Rehash in new position. If King is now under check, then */
+ /* we can't use this move and it's removed from contention */
+ for( tmp2 = 0; tmp2 < 64; tmp2++ )
+ {
+ if( chessman[tmp2].Army != chessman[ManPtr].Army )
+ if( isChessman( tmp2 ) )
+ {
+ HashLegal( tmp2, TRUE );
+ if( hash[ currentKing ].Note == NOTE_ATTACK )
+ {
+ hashBackup[tmp].Note = NOTE_NONE;
+ }
+ }
+ }
+
+ /* Restore the playground */
+ copyPositions( hashBackup, current );
+ copyChessmen( chessmanBackup, chessman );
+ } // <- End of 'Check All Moves' loop
+
+ copyPositions( hashBackup, current );
+ copyPositions( hashBackup, hash );
+ copyChessmen( chessmanBackup, chessman );
+ }
+}
diff --git a/knights/logic.h b/knights/logic.h
new file mode 100644
index 0000000..d57a553
--- /dev/null
+++ b/knights/logic.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ logic.h - description
+ -------------------
+ begin : Sat Sep 29 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LOGIC_H
+#define LOGIC_H
+
+#include <qstring.h>
+#include "definitions.h"
+#include "resource.h"
+#include "match_param.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+const char CF_King = 0x01;
+const char CF_RookQ = 0x02;
+const char CF_RookK = 0x04;
+
+class logic
+{
+
+ public:
+ char OnMove;
+ Position current[64];
+ Chessman chessman[64];
+ ChessMove chessMove;
+
+ /* This is used for the 50 move rule */
+ char MoveCounter;
+
+ logic( resource *Rsrc=0, match_param *param=0 );
+ ~logic();
+ void Init( const int Var=Type_Standard );
+ void setBoard( const QString &board=QString::null, const short ppf=-2 );
+ void setBoardFromFen( const QString &fen );
+ QString board( void );
+ bool isChessman( const char ChessmanPtr );
+ bool isCheck( const bool Army );
+ bool isLegal( const bool Army );
+ bool isDraw( const bool Army );
+ bool Move( void );
+ void HashLegal( const char Man, const bool Recursion=FALSE );
+ int Pointer( const char File, const char Rank );
+
+ bool parseCAN( const bool Army );
+ bool parseSAN( void );
+ void writeCAN( void );
+ void writeSAN( void );
+
+ protected:
+ int CalcPointer( const char File, const char Rank );
+ void _HashLegal( const bool Recursion=FALSE );
+ void clearBoard( void );
+ int getKing( const bool Army );
+ void Init_Standard( void );
+ inline void copyPositions( Position *Src, Position *Dst )
+ { memcpy( Dst, Src, sizeof(Position) << 6 ); }
+ inline void copyChessmen( Chessman *Src, Chessman *Dst )
+ { memcpy( Dst, Src, sizeof(Chessman) << 6 ); }
+
+ private:
+ resource *Resource;
+ match_param *Param;
+ int GameType;
+ Position hash[64];
+ Position hashBackup[64];
+ Chessman chessmanBackup[64];
+ char CastleFlag[2];
+ char enPassant[2];
+ char ManPtr;
+};
+
+#endif
diff --git a/knights/main.cpp b/knights/main.cpp
new file mode 100644
index 0000000..f5f508e
--- /dev/null
+++ b/knights/main.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Thu Mar 1 10:43:51 CST 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+
+#include "knights.h"
+
+static KCmdLineOptions options[] =
+{
+ { "d <path>", I18N_NOOP("Specify the location of your Knights data directory."), 0 },
+ { "+[filename]", I18N_NOOP("A .pgn file to be loaded."), 0 },
+ { 0, 0, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData( "knights",
+ I18N_NOOP("Knights"),
+ _VERSION_,
+ I18N_NOOP("The Knights Chess Interface\n\nKnights is a chess interface\nfor the K Desktop Environment."),
+ KAboutData::License_GPL_V2,
+ "(c) 2003, Troy Corbin Jr.",
+ 0,
+ "http://knights-chess.com",
+ "troy@knights-chess.com");
+
+ aboutData.addAuthor("Troy Corbin Jr.",
+ I18N_NOOP("Project Manager and Programmer"),
+ "tcorbin@users.sourceforge.net",
+ "http://knights.sourceforge.net");
+ aboutData.addAuthor("Alexander Wels",
+ I18N_NOOP("Communications Programmer"),
+ "agpwels@adelphia.net",
+ "");
+ aboutData.addCredit("Mark Westcott",
+ I18N_NOOP("Qtopia port and patches"),
+ "mark@houseoffish.org",
+ "");
+ aboutData.addCredit("Kunnar Klauks",
+ I18N_NOOP("Patches and suggestions"),
+ "kunnk@yahoo.com",
+ "");
+ aboutData.addCredit("Harald Fernengel",
+ I18N_NOOP("KDE3 Compatability Patch"),
+ "harry@kdevelop.org",
+ "");
+ aboutData.addCredit("Tim Mann",
+ I18N_NOOP("XBoard protocol"),
+ "tim.mann@compaq.com",
+ "http://www.tim-mann.org/chess.html");
+ aboutData.setTranslator(I18N_NOOP("_: NAME OF TRANSLATORS\nYour names"),
+ I18N_NOOP("_: EMAIL OF TRANSLATORS\nYour emails"));
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KApplication a;
+ Knights *knights = new Knights(args);
+ a.setMainWidget(knights);
+ if( !knights->init() ) // Did we init ok?
+ {
+ return 0;
+ }
+ /* Without this connection, the destructors are not called, and some
+ housecleaning ( like destroying child processes ) isn't done */
+ a.connect( &a, SIGNAL( shutDown () ), knights, SLOT( KillAll() ) );
+ return a.exec();
+}
diff --git a/knights/match.cpp b/knights/match.cpp
new file mode 100644
index 0000000..21957e4
--- /dev/null
+++ b/knights/match.cpp
@@ -0,0 +1,1120 @@
+/***************************************************************************
+ match.cpp - description
+ -------------------
+ begin : Mon Jul 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qregexp.h>
+#include <kmessagebox.h>
+#include "match.moc"
+#include "board_base.h"
+#include "board_2d.h"
+#include "audio.h"
+
+#define WHITE_INPUT Record->Param->type(WHITE)
+#define BLACK_INPUT Record->Param->type(BLACK)
+
+///////////////////////////////////////
+//
+// match::match
+//
+///////////////////////////////////////
+match::match( QWidget *parent, match_param *param, resource *Rsrc ) : QWidget(parent)
+{
+ Resource = Rsrc;
+
+ /* Init Children */
+ Record = new pgn( Resource, param );
+ Logic = new logic( Resource, param );
+ Board = new board_2d( parent, "Board", Resource, Logic );
+ Board->show();
+ connect( Board, SIGNAL( leftClick(int) ), this, SLOT( slot_Select(int) ) );
+ connect( Board, SIGNAL( rightClick(int) ), this, SLOT( slot_Preview(int) ) );
+ Clock = new chessclock( this, "Clock", Resource );
+ Record->init();
+ Logic->Init();
+ Clock->Reset();
+ clearSelections();
+
+ /* Init Variables */
+ Draw_Offered[WHITE] = FALSE;
+ Draw_Offered[BLACK] = FALSE;
+ Modified = FALSE;
+ Loading = FALSE;
+ Paused = FALSE;
+ JustMoved = FALSE;
+ preMoved = FALSE;
+ Current = FALSE;
+ loadTimer = 0;
+ StatusCode = READY;
+ StatusMessage = QString::null;
+ ICSGameMode = Null;
+ parseMatchParam();
+
+ /* Connect Signals and Slots */
+ connect( param, SIGNAL( valuesChanged() ), this, SLOT( parseMatchParam() ) );
+ connect( Record, SIGNAL( processMove(ChessMove) ), this, SLOT( move(ChessMove) ) );
+ connect( Record, SIGNAL( processSpecial() ), this, SLOT( loadSpecial() ) );
+ connect( Clock, SIGNAL( flagFell(const bool) ), this, SLOT( slot_flagFell(const bool) ) );
+ connect( this, SIGNAL( setStatusBar( const int&, const QString& ) ), this, SLOT( saveStatusBar( const int&, const QString& ) ) );
+
+}
+///////////////////////////////////////
+//
+// match::~match
+//
+///////////////////////////////////////
+match::~match()
+{
+ delete Clock;
+ if( Board != NULL ) delete Board;
+ delete Record;
+ delete Logic;
+}
+///////////////////////////////////////
+//
+// match::setVisibility
+//
+///////////////////////////////////////
+void match::setVisibility( const bool vis )
+{
+ if( vis == TRUE )
+ {
+ show();
+ Board->show();
+ setEnabled( TRUE );
+ }
+ else
+ {
+ hide();
+ Board->hide();
+ setEnabled( FALSE );
+ }
+}
+///////////////////////////////////////
+//
+// match::parseMatchParam
+//
+///////////////////////////////////////
+void match::parseMatchParam( void )
+{
+ switch( BLACK_INPUT )
+ {
+ case PLAYERLOCAL:
+ Board->setLocalArmy( BLACK );
+ break;
+ }
+ switch( WHITE_INPUT )
+ {
+ case PLAYERLOCAL:
+ Board->setLocalArmy( WHITE );
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// match::tick
+//
+///////////////////////////////////////
+void match::tick(void)
+{
+ Clock->Tick();
+ emit setClocks();
+ if( Loading )
+ {
+ if( loadTimer )
+ loadTimer--;
+ else
+ {
+ /*
+ All this is for a match we just finished loading
+ */
+ if( !Record->loadNext() )
+ {
+ Loading = FALSE;
+ emit sendCMD( Command( myID, CMD_Play ) );
+ if( Record->TAG_Result == "*" )
+ {
+ /* Unfinished Game */
+ Clock->Set( Record->whiteTime, Record->blackTime, onMove() );
+ }
+ else
+ {
+ /* Finished Match */
+ Clock->Pause();
+ if( Record->TAG_Result == "1/2-1/2" )
+ emit setStatusBar( GAME_DRAW );
+ if( Record->TAG_Result == "1-0" )
+ emit setStatusBar( WHITE_WIN );
+ if( Record->TAG_Result == "0-1" )
+ emit setStatusBar( BLACK_WIN );
+ }
+ }
+ }
+ }
+}
+///////////////////////////////////////
+//
+// match::clearSelections
+//
+///////////////////////////////////////
+void match::clearSelections( void )
+{
+ bool commitFlag( FALSE );
+ register char tmp;
+
+ if( ICSGameMode == Null )
+ {
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ if( Logic->current[tmp].Note != NOTE_NONE )
+ {
+ Logic->current[tmp].Note = NOTE_NONE;
+ Board->drawPosition( tmp );
+ commitFlag = TRUE;
+ }
+ }
+ }
+ else
+ {
+ for( tmp = 0; tmp < 64; tmp++ )
+ {
+ Logic->current[tmp].Note = NOTE_NONE;
+ Board->drawPosition( tmp );
+ commitFlag = TRUE;
+ }
+ }
+ if( commitFlag )
+ {
+ Board->commit();
+ }
+}
+///////////////////////////////////////
+//
+// match::flip
+//
+///////////////////////////////////////
+void match::flip(void)
+{
+ Board->flipBoard();
+}
+///////////////////////////////////////
+//
+// match::resize
+//
+///////////////////////////////////////
+void match::resize(void)
+{
+ Board->resizeBoard();
+ setFixedSize( Board->width(), Board->height() );
+}
+///////////////////////////////////////
+//
+// match::redraw
+//
+///////////////////////////////////////
+void match::redraw(void)
+{
+ Board->redrawAll();
+}
+///////////////////////////////////////
+//
+// match::slot_flagFell
+//
+///////////////////////////////////////
+void match::slot_flagFell( const bool Army )
+{
+ if( Army == WHITE )
+ {
+ emit setStatusBar( WHITE_FLAG );
+ if( ( Resource->OPTION_Auto_Call_Flag ) && ( WHITE_INPUT != PLAYERLOCAL ) && ( BLACK_INPUT == PLAYERLOCAL ) )
+ {
+ emit sendCMD( Command( myID, CMD_Black_Called_Flag ) );
+ recvCMD( Command( myID, CMD_Black_Called_Flag ) );
+ }
+ }
+ else
+ {
+ emit setStatusBar( BLACK_FLAG );
+ if( ( Resource->OPTION_Auto_Call_Flag ) && ( BLACK_INPUT != PLAYERLOCAL ) && ( WHITE_INPUT == PLAYERLOCAL ) )
+ {
+ emit sendCMD( Command( myID, CMD_White_Called_Flag ) );
+ recvCMD( Command( myID, CMD_White_Called_Flag ) );
+ }
+ }
+}
+///////////////////////////////////////
+//
+// match::setPaused
+//
+///////////////////////////////////////
+void match::setPaused( const bool State )
+{
+ Paused = State;
+ Board->setPaused( State );
+ if( Paused )
+ {
+ Clock->Pause();
+ emit setStatusBar( PAUSED );
+ }
+ else
+ {
+ Clock->Resume();
+ if( onMove() == WHITE ) emit setStatusBar( WHITE_TURN );
+ else emit setStatusBar( BLACK_TURN );
+ }
+}
+///////////////////////////////////////
+//
+// match::inputOnMove
+//
+///////////////////////////////////////
+char match::inputOnMove( bool reverse )
+{
+ if( reverse )
+ {
+ if( Logic->OnMove == BLACK )
+ return WHITE_INPUT;
+ if( Logic->OnMove == WHITE )
+ return BLACK_INPUT;
+ }
+ else
+ {
+ if( Logic->OnMove == WHITE )
+ return WHITE_INPUT;
+ if( Logic->OnMove == BLACK )
+ return BLACK_INPUT;
+ }
+ return Null;
+}
+///////////////////////////////////////
+//
+// match::input
+//
+///////////////////////////////////////
+char match::input( char army )
+{
+ return Record->Param->type(army);
+}
+///////////////////////////////////////
+//
+// match::save
+//
+///////////////////////////////////////
+bool match::save( QString URL )
+{
+ Record->whiteTime = Clock->getCentiseconds(WHITE);
+ Record->blackTime = Clock->getCentiseconds(BLACK);
+ return Record->save( URL );
+}
+///////////////////////////////////////
+//
+// match::load
+//
+///////////////////////////////////////
+bool match::load( const QString URL, const int pos )
+{
+ bool Result;
+ Loading = TRUE;
+ loadTimer = 20;
+ if( !Record->open( URL ) )
+ {
+ return FALSE;
+ }
+ Result = Record->load( pos );
+ if( !Record->TAG_FEN.isEmpty() )
+ {
+ // We must set up the FEN position
+ Logic->setBoardFromFen( Record->TAG_FEN );
+ sendCMD( Command( myID, CMD_Set_Board, Record->TAG_FEN ) );
+ }
+ return Result;
+}
+///////////////////////////////////////
+//
+// match::loadSpecial
+//
+///////////////////////////////////////
+void match::loadSpecial( void )
+{
+ /*
+ As pointless as this function may seem ( in light of these variables and more
+ being setup in tick(), it is required to initialize a Chess Engine and feed it
+ the moves from a saved game so you can play it again later.
+ */
+ emit sendCMD( Command( myID, CMD_New_Players ) );
+}
+///////////////////////////////////////
+//
+// match::url
+//
+///////////////////////////////////////
+QString match::url( void )
+{
+ if( !Record->CurrentURL.isEmpty() )
+ return Record->CurrentURL;
+ if( Resource->OPTION_Reuse_PGN )
+ return Resource->PGN_Filename;
+ return QString::null;
+}
+///////////////////////////////////////
+//
+// match::clock
+//
+///////////////////////////////////////
+QString match::clock( const bool Army )
+{
+ if( Army == WHITE ) return Clock->whiteClock;
+ return Clock->blackClock;
+}
+///////////////////////////////////////
+//
+// match::slot_Select
+//
+///////////////////////////////////////
+void match::slot_Select( int position )
+{
+ bool preMoving(FALSE);
+ register char tmp, army, selected(Null);
+
+ if( Paused ) return;
+ /* Clear all non-SELECT notes */
+ for( tmp = 0;tmp < 64;tmp++ )
+ {
+ if( Logic->current[tmp].Note != NOTE_NONE )
+ {
+ if( Logic->current[tmp].Note != NOTE_SELECT )
+ {
+ Logic->current[tmp].Note = NOTE_NONE;
+ Board->drawPosition( tmp );
+ }
+ else
+ {
+ selected = tmp;
+ }
+ }
+ }
+ Board->commit();
+
+ /* Check to make sure it's our turn to select. */
+ if( !( inputOnMove() & PLAYERLOCAL ) )
+ {
+ if( ( inputOnMove(TRUE) == PLAYERLOCAL ) && ( Resource->OPTION_Premove ) )
+ {
+ preMoving = TRUE;
+ }
+ else
+ {
+ return;
+ }
+ }
+ /* If you left click on a selected square, it becomes unselected. */
+ if( Logic->current[position].Note == NOTE_SELECT )
+ {
+ Logic->current[position].Note = NOTE_NONE;
+ drawPosition( position );
+ playSound( SND_SELECT );
+ return;
+ }
+ if( preMoved )
+ {
+ preMoved = FALSE;
+ playSound( SND_SELECT );
+ Board->setPremovePositions( Null, Null );
+ Board->drawPosition( Logic->Pointer( preMove.fromFile, preMove.fromRank ) );
+ Board->drawPosition( Logic->Pointer( preMove.toFile, preMove.toRank ) );
+ Board->commit();
+ }
+ /* Check to see if there is already a selected square. */
+ if( selected != Null )
+ {
+ /*
+ If there is already a selected square, and you just clicked on another of your men,
+ we'll change your selection.
+ */
+ if( Logic->current[position].ManPtr != Null )
+ {
+ if( Logic->chessman[ Logic->current[selected].ManPtr ].Army == Logic->chessman[ Logic->current[position].ManPtr ].Army )
+ {
+ Logic->current[selected].Note = NOTE_NONE;
+ Logic->current[position].Note = NOTE_SELECT;
+ Board->drawPosition( selected );
+ drawPosition( position );
+ if( Resource->OPTION_Auto_Preview == TRUE )
+ slot_Preview( position );
+ else
+ playSound( SND_SELECT );
+ return;
+ }
+ }
+ /*
+ If there is already a selected square, but this one you just clicked
+ isn't one of your chessmen, you must want to move a piece.
+ */
+ if( ( Record->currentIndex != ( Record->Positions.count() - 1 ) ) && ( Record->currentIndex ) )
+ {
+ emit setStatusBar( NO_MOVE_WHILE_REVIEW );
+ return;
+ }
+ if( preMoving )
+ {
+ Command::clearMove( &preMove );
+ preMove.fromRank = Logic->current[selected].Rank;
+ preMove.fromFile = Logic->current[selected].File;
+ preMove.toRank = Logic->current[position].Rank;
+ preMove.toFile = Logic->current[position].File;
+ preMoved = TRUE;
+ playSound( SND_SELECT );
+ Board->setPremovePositions( selected, position );
+ }
+ else
+ {
+ Command::clearMove( &chessMove );
+ chessMove.fromRank = Logic->current[selected].Rank;
+ chessMove.fromFile = Logic->current[selected].File;
+ chessMove.toRank = Logic->current[position].Rank;
+ chessMove.toFile = Logic->current[position].File;
+ JustMoved = TRUE;
+ if( move() == FALSE )
+ {
+ Logic->current[selected].Note = NOTE_SELECT;
+ drawPosition( selected );
+ }
+ }
+ return;
+ }
+ tmp = Logic->current[position].ManPtr;
+
+ /* You can't select an empty square. */
+ if( tmp == Null )
+ {
+ return;
+ }
+ army = Logic->chessman[ tmp ].Army;
+
+ /* You can't select your enemy */
+ if( ( army != onMove() ) && ( preMoving == FALSE ) )
+ {
+ return;
+ }
+
+ /* If your clicking on one of your chessmen, you can select it. */
+ clearSelections();
+ if( ( army == WHITE ) && ( WHITE_INPUT & PLAYERLOCAL ) )
+ {
+ Logic->current[position].Note = NOTE_SELECT;
+ }
+ if( ( army == BLACK ) && ( BLACK_INPUT & PLAYERLOCAL ) )
+ {
+ Logic->current[position].Note = NOTE_SELECT;
+ }
+ drawPosition( position );
+ if( Resource->OPTION_Auto_Preview == TRUE )
+ {
+ slot_Preview( position );
+ }
+ else
+ {
+ /* Play the select sound if you selected a square & you didn't preview */
+ if( Logic->current[position].Note == NOTE_SELECT )
+ {
+ playSound( SND_SELECT );
+ }
+ }
+}
+///////////////////////////////////////
+//
+// match::slot_Preview
+//
+///////////////////////////////////////
+void match::slot_Preview( int position )
+{
+ char tmp;
+
+ if( Paused )
+ {
+ return;
+ }
+ clearSelections();
+ tmp = Logic->current[position].ManPtr;
+ if( tmp == Null ) return;
+
+ Logic->HashLegal( tmp );
+
+ /* If your clicking on one of your chessmen, you can select it. */
+ if( ( Logic->chessman[tmp].Army == Logic->OnMove ) && ( Record->Param->type( Logic->OnMove ) & PLAYERLOCAL ) )
+ Logic->current[position].Note = NOTE_SELECT;
+ for( tmp = 0;tmp < 64;tmp++ )
+ {
+ if( Logic->current[tmp].Note != NOTE_NONE )
+ {
+ Board->drawPosition( tmp );
+ }
+ }
+ drawPosition( 0 );
+ playSound( SND_SELECT );
+}
+///////////////////////////////////////
+//
+// match::recvCMD
+//
+///////////////////////////////////////
+void match::recvCMD( const Command &constCommand )
+{
+ Command cmd( constCommand );
+
+ if( cmd.getID() != myID )
+ return;
+ ChessMove newMove = cmd.getMove();
+
+ switch( cmd.getCommand() )
+ {
+ /* CMD_Move */
+ case CMD_Move:
+ if( newMove.ICS_Mode == Null )
+ {
+ /* Not an ICS Move */
+ move( newMove );
+ }
+ else
+ {
+ /* Do NOT accept a setBoard on a concluded match */
+ if( ( Logic->OnMove == -1 ) && ( newMove.ICS_Mode < ICS_Examine ) )
+ return;
+ ICSGameMode = newMove.ICS_Mode;
+ Logic->OnMove = newMove.ICS_OnMove;
+
+ if( ICSGameMode == ICS_Movelist )
+ {
+ /* Recieving Movelist */
+ Logic->chessMove = newMove;
+ Logic->parseSAN();
+ JustMoved = FALSE;
+ }
+ else
+ {
+ /* Recieving Standard Move */
+ Logic->setBoard( cmd.getData(), newMove.ICS_PawnPushFile );
+ Logic->MoveCounter = newMove.ICS_MoveCounter;
+ Logic->chessMove = newMove;
+ Logic->parseCAN( Logic->OnMove );
+ }
+ chessMove = Logic->chessMove;
+ /* Run through the Move function */
+ if( !JustMoved )
+ move();
+ else
+ {
+ JustMoved = FALSE;
+ Logic->OnMove = !Logic->OnMove;
+ }
+
+ Clock->Set( cmd.getWhiteTime(), cmd.getBlackTime(), !newMove.ICS_OnMove );
+ if( newMove.ICS_ClockTicking )
+ {
+ Clock->Resume();
+ }
+ else
+ {
+ Clock->Pause();
+ }
+ }
+ break;
+
+ /* CMD_Offer_Draw */
+ case CMD_Offer_Draw:
+ if( cmd.getData() == "W" )
+ {
+ Draw_Offered[WHITE] = 2;
+ emit setStatusBar( WHITE_DRAW_OFFER );
+ }
+ else
+ {
+ Draw_Offered[BLACK] = 2;
+ emit setStatusBar( BLACK_DRAW_OFFER );
+ }
+ break;
+
+ /* CMD_Illegal */
+ case CMD_Illegal:
+ retract();
+ emit setNotation();
+ break;
+
+ /* Lost Contact */
+ case CMD_Lost_Contact:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( LOST_CONTACT );
+ Record->TAG_Result = "*";
+ Record->TAG_Termination = "Lost Contact with Opponent";
+ break;
+
+ /* Result White */
+ case CMD_Result_White:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( WHITE_CHECKMATE );
+ Record->TAG_Result = "1-0";
+ Record->TAG_Termination = "Normal";
+ break;
+
+ /* Result Black */
+ case CMD_Result_Black:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( BLACK_CHECKMATE );
+ Record->TAG_Result = "0-1";
+ Record->TAG_Termination = "Normal";
+ break;
+
+ /* Result Draw */
+ case CMD_Result_Draw:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ if( Logic->MoveCounter == 50 )
+ {
+ emit setStatusBar( GAME_50_MOVES );
+ }
+ else
+ {
+ emit setStatusBar( GAME_DRAW );
+ }
+ Record->TAG_Result = "1/2-1/2";
+ break;
+
+ /* White Resign */
+ case CMD_White_Resign:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( WHITE_RESIGN );
+ Record->TAG_Result = "0-1";
+ Record->TAG_Termination = "White resigned";
+ break;
+
+ /* Black Resign */
+ case CMD_Black_Resign:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( BLACK_RESIGN );
+ Record->TAG_Result = "1-0";
+ Record->TAG_Termination = "Black resigned";
+ break;
+
+ /* White Called Flag */
+ case CMD_White_Called_Flag:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( WHITE_CALL_FLAG );
+ Record->TAG_Result = "1-0";
+ Record->TAG_Termination = "Black's flag was called";
+ break;
+
+ /* Black Called Flag */
+ case CMD_Black_Called_Flag:
+ Clock->Pause();
+ Logic->OnMove = -1;
+ emit setStatusBar( BLACK_CALL_FLAG );
+ Record->TAG_Result = "0-1";
+ Record->TAG_Termination = "White's flag was called";
+ break;
+
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// match::move
+//
+///////////////////////////////////////
+bool match::move( ChessMove newMove )
+{
+ /* Clear selections from the board */
+ clearSelections();
+
+ Logic->chessMove = newMove;
+ if( Logic->parseCAN( onMove() ) != TRUE )
+ {
+ if( Logic->parseSAN() != TRUE )
+ {
+ kdDebug() << "#" << myID << ": Recieved bad data: " << newMove.CAN << endl;
+ return FALSE;
+ }
+ }
+ chessMove = Logic->chessMove;
+ JustMoved = TRUE;
+ return move();
+}
+bool match::move( void )
+{
+ int soundType( SND_MOVE );
+ int result(Null);
+ char manPtr(Null);
+ QString SAN;
+
+ /* Bring the display up to the latest move before we proceed */
+ if( ICSGameMode == Null )
+ {
+ if( Record->currentIndex != ( Record->Positions.count() - 1 ) )
+ {
+ review( Record->Moves.count() - 1 );
+ }
+ }
+
+ /* Clear selections from the board */
+ clearSelections();
+
+ /* Build Pointers */
+ char fromPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
+ char toPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
+
+ /* Skip all this if we're being called due to normal server moves */
+ if( ( JustMoved == TRUE ) || ( ICSGameMode == ICS_Movelist ) )
+ {
+ if( ( fromPtr > 63 ) || ( toPtr > 63 ) )
+ return FALSE;
+ if( ( fromPtr < 0 ) || ( toPtr < 0 ) )
+ return FALSE;
+ manPtr = Logic->current[fromPtr].ManPtr;
+ if( manPtr == Null )
+ return FALSE;
+ /* Make the move */
+ Logic->chessMove = chessMove;
+ if( Logic->Move() == FALSE )
+ return FALSE;
+ chessMove = Logic->chessMove;
+ }
+
+ /* Play sound for Promotion */
+ if( QString( chessMove.SAN ).contains( QChar( '=' ) ) )
+ {
+ soundType = SND_PROMOTE;
+ }
+
+ /* Check to see if the game is ended */
+ /* 50 Move Rule? */
+ if( Logic->MoveCounter == 50 )
+ {
+ result = CMD_Result_Draw;
+ }
+ /*
+ A Draw via 3 move repeat
+
+ if( Record->isThreeMoveDraw() )
+ {
+ result = CMD_Result_Draw;
+ Record->TAG_Result = "1/2-1/2";
+ emit setStatusBar( GAME_DRAW );
+ } */
+ /*
+ A Draw?
+
+ Condition 1 = White Material Draw
+ Condition 2 = Black Material Draw
+ Condition 3 = Both sides agree to a draw
+ */
+ if( ( Logic->OnMove == BLACK && Logic->isDraw( WHITE ) ) ||
+ ( Logic->OnMove == WHITE && Logic->isDraw( BLACK ) ) ||
+ ( Draw_Offered[WHITE] && Draw_Offered[BLACK] ) )
+ {
+ result = CMD_Result_Draw;
+ }
+
+ /* Is White under check? */
+ if( Logic->isCheck( WHITE ) )
+ {
+ if( !Logic->isLegal( WHITE ) )
+ {
+ SAN += '#';
+ result = CMD_Result_Black;
+ }
+ else
+ {
+ SAN += '+';
+ soundType = SND_CHECK;
+ }
+ }
+
+ /* Is Black under check? */
+ if( Logic->isCheck( BLACK ) )
+ {
+ if( !Logic->isLegal( BLACK ) )
+ {
+ SAN += '#';
+ result = CMD_Result_White;
+ }
+ else
+ {
+ SAN += '+';
+ soundType = SND_CHECK;
+ }
+ }
+
+ /* Check to make sure this isn't the starting position in an ICS match */
+ if( QString( chessMove.SAN ) != "none" )
+ {
+ if( !SAN.isEmpty() )
+ {
+ strcat( chessMove.SAN, SAN.latin1() );
+ }
+ Record->Positions << Logic->board();
+ Record->Moves << chessMove;
+ Record->currentIndex = Record->Moves.count() - 1;
+ if( JustMoved == TRUE )
+ {
+ /* Send this move to engines and servers */
+ emit sendCMD( Command( myID, CMD_Move, centiseconds( WHITE ), centiseconds( BLACK ),
+ chessMove, Record->notation(FALSE)->join(QString(" ")) ) );
+ }
+ /* Draw The Move */
+ if( ICSGameMode != ICS_Movelist )
+ Board->drawMove( chessMove );
+ }
+
+ /* Take care of changing turns, status messages, etc. */
+ if( result == Null )
+ {
+ Clock->Moved();
+ if( Paused )
+ Clock->Pause();
+
+ Logic->OnMove = !Logic->OnMove;
+ /* Set Status Bar */
+ if( Logic->OnMove == WHITE )
+ {
+ emit setStatusBar( WHITE_TURN );
+ }
+ if( Logic->OnMove == BLACK )
+ {
+ emit setStatusBar( BLACK_TURN );
+ }
+
+ /* Set Cursor */
+ if( ( inputOnMove(TRUE) == PLAYERLOCAL ) && ( inputOnMove() != PLAYERLOCAL ) )
+ {
+ Board->setCursor( Resource->CURSOR_Thinking );
+ }
+ else
+ {
+ Board->setCursor( Resource->CURSOR_Standard );
+ }
+
+ /* Deprecieate Draw Offers */
+ if( Draw_Offered[WHITE] )
+ {
+ Draw_Offered[WHITE]--;
+ }
+ if( Draw_Offered[BLACK] )
+ {
+ Draw_Offered[BLACK]--;
+ }
+
+ /* Display NAG Anotation */
+ if( chessMove.NAG != 0 )
+ {
+ emit setStatusBar( COMMENT + chessMove.NAG );
+ }
+ }
+ else
+ {
+ /* End of Match */
+ Board->setCursor( Resource->CURSOR_Standard );
+ recvCMD( Command( myID, result ) );
+ emit sendCMD( Command( myID, result ) );
+ soundType = SND_MATCH_OVER;
+ }
+ emit setNotation();
+
+ if( ICSGameMode != ICS_Movelist )
+ {
+ Board->redrawLights();
+ Board->commit();
+ }
+ /* Play the Sound */
+ playSound( soundType );
+
+ /* Handle special cases */
+ if( loading() )
+ {
+ loadTimer = 10; // Loading...
+ }
+ else
+ {
+ Modified = TRUE;
+ }
+ if( preMoved )
+ {
+ preMoved = FALSE;
+ Board->setPremovePositions( Null, Null );
+ chessMove = preMove;
+ JustMoved = TRUE;
+ move();
+ }
+/* if( inputOnMove() == PLAYEREMAIL )
+ {
+ Clock->Pause(); // Email
+ KMessageBox::questionYesNo( this,
+ i18n("Would you like to email this move?"),
+ i18n("Send Email?") );
+ }
+*/
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// match::retract
+//
+///////////////////////////////////////
+void match::retract( void )
+{
+ emit setStatusBar(ILLEGAL_MOVE);
+ review( Record->Moves.count() - 2 );
+ _retract();
+}
+void match::_retract( void )
+{
+ if( Record->Moves.count() )
+ {
+ Record->Moves.remove( Record->Moves.at( Record->Moves.count() - 1 ) );
+ Record->Positions.remove( Record->Positions.at( Record->Positions.count() - 1 ) );
+ Record->currentIndex = Record->Moves.count() - 1;
+ }
+}
+///////////////////////////////////////
+//
+// match::review
+//
+///////////////////////////////////////
+void match::review( const int Index )
+{
+ int tmp(0), step;
+ QString tmpS;
+ if( ICSGameMode == ICS_Examine )
+ {
+ /* Examined Game: Use Examine Semantics */
+ if( Index < (signed)Record->currentIndex )
+ step = -1;
+ else
+ step = 1;
+ if( ( Record->currentIndex == 0 ) && ( Index == 0 ) && ( step == 1 ) )
+ {
+ emit sendCMD( Command( myID, CMD_Examine_Forward ) );
+ }
+ if( step == 1 )
+ {
+ for( tmp = Record->currentIndex; tmp != Index; tmp += step )
+ {
+ emit sendCMD( Command( myID, CMD_Examine_Forward ) );
+ }
+ }
+ else
+ {
+ for( tmp = Record->currentIndex; tmp != Index; tmp += step )
+ {
+ _retract();
+ _retract();
+ emit sendCMD( Command( myID, CMD_Examine_Backward ) );
+ }
+ }
+ }
+ else
+ {
+ /* Regular Game: Use Standard Review Semantics */
+ if( Record->Positions.count() == 0 )
+ return;
+ if( Index < 0 )
+ return;
+ if( Index > ( (signed int)Record->Positions.count() - 1 ) )
+ return;
+
+ /* Review differently depending on our Animation Option */
+ if( Resource->OPTION_Animate_Moves )
+ {
+ if( (unsigned)Index > Record->currentIndex )
+ {
+ /* Forward */
+ Logic->setBoard( Record->Positions[Index - 1] );
+ while( tmp < 64 )
+ Board->drawPosition( tmp++ );
+ Logic->setBoard( Record->Positions[Index] );
+ Board->drawMove( Record->Moves[Index] );
+ }
+ else if( (unsigned)Index < Record->currentIndex )
+ {
+ /* Reverse */
+ Logic->setBoard( Record->Positions[Index + 1] );
+ while( tmp < 64 )
+ Board->drawPosition( tmp++ );
+ Board->drawMove( Record->Moves[Index + 1], TRUE );
+ Logic->setBoard( Record->Positions[Index] );
+ }
+ }
+ else
+ {
+ /* No Animation */
+ Logic->setBoard( Record->Positions[Index] );
+ while( tmp < 64 )
+ Board->drawPosition( tmp++ );
+ Board->drawMove( Record->Moves[Index] );
+ }
+ Board->commit();
+
+ /* Statusbar shows NAG if available, otherwise Army to move */
+ if( Record->Moves[Index].NAG )
+ {
+ tmp = StatusCode;
+ tmpS = StatusMessage;
+ emit setStatusBar( COMMENT + Record->Moves[Index].NAG );
+ StatusCode = tmp;
+ StatusMessage = tmpS;
+ }
+ else
+ emit setStatusBar( StatusCode, StatusMessage );
+ Record->currentIndex = Index;
+ }
+}
+///////////////////////////////////////
+//
+// match::playSound
+//
+///////////////////////////////////////
+void match::playSound( const int snd )
+{
+ if( Resource->OPTION_Audio_Current_Only && !Current )
+ {
+ return;
+ }
+ Resource->play( snd );
+}
+///////////////////////////////////////
+//
+// match::drawPosition
+//
+///////////////////////////////////////
+void match::drawPosition( const int position )
+{
+ Board->drawPosition( position );
+ Board->commit();
+}
+///////////////////////////////////////
+//
+// match::requestHint
+//
+///////////////////////////////////////
+void match::requestHint( void )
+{
+ emit sendCMD( Command( myID, CMD_Hint ) );
+ emit sendCMD( Command( myID, CMD_UCI_Hint, centiseconds( WHITE ), centiseconds( BLACK ), Record->notation(FALSE)->join(QString(" ")) ) );
+}
diff --git a/knights/match.h b/knights/match.h
new file mode 100644
index 0000000..22db6a9
--- /dev/null
+++ b/knights/match.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ match.h - description
+ -------------------
+ begin : Mon Jul 2 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef MATCH_H
+#define MATCH_H
+
+#include <qwidget.h>
+#include "resource.h"
+#include "match_param.h"
+#include "command.h"
+#include "chessclock.h"
+#include "logic.h"
+#include "pgn.h"
+
+class board_base;
+
+class match : public QWidget
+{
+ Q_OBJECT
+
+ private:
+ resource *Resource;
+ board_base *Board;
+ pgn *Record;
+ logic *Logic;
+ chessclock *Clock;
+ ChessMove chessMove;
+ ChessMove preMove;
+ bool preMoved;
+ bool Modified;
+ bool Paused;
+ bool Loading;
+ bool JustMoved;
+ bool Current;
+ int myID;
+ int StatusCode;
+ int loadTimer;
+ QString StatusMessage;
+ char ICSGameMode;
+ char Draw_Offered[2];
+
+ public:
+ match(QWidget *parent, match_param *param, resource *Rsrc);
+ ~match();
+ char inputOnMove( bool reverse=FALSE );
+ char input( char army );
+ QString url( void );
+ void flip( void );
+ void retract( void );
+ void requestHint( void );
+ void recvCMD( const Command &cmd );
+ void setVisibility( const bool vis );
+ void setPaused( const bool State );
+ /* Inline Function */
+ int getID( void )
+ { return myID; }
+ void setID( const int &ID )
+ { myID = ID; }
+ QString caption( void )
+ { return Record->caption(); }
+ char onMove( void )
+ { return Logic->OnMove; }
+ bool modified( void )
+ { return Modified; }
+ bool paused( void )
+ { return Paused; }
+ bool flag( const bool &Army )
+ { return Clock->Flag[Army]; }
+ void setCurrent( const bool &State )
+ { Current = State; }
+ void print( void )
+ { Record->print(); }
+ bool loading( void )
+ { return Loading; }
+ int centiseconds( const bool &Army )
+ { return Clock->getCentiseconds( Army ); }
+ QStringList* notation( void )
+ { return Record->notation(); }
+ void setModified( const bool &state )
+ { Modified = state; }
+ void resendStatusBar( void )
+ { emit setStatusBar( StatusCode, StatusMessage ); }
+ match_param* getParam( void )
+ { return Record->Param; }
+
+ public slots:
+ void tick( void );
+ void resize( void );
+ void redraw( void );
+ QString clock( bool );
+ bool save( QString );
+ bool load( const QString URL, const int pos=0 );
+ void loadSpecial( void );
+ void slot_Select( int );
+ void slot_Preview( int );
+ void slot_flagFell( const bool );
+ void review( const int );
+ void parseMatchParam( void );
+ void saveStatusBar( const int &ID, const QString &MSG )
+ { StatusCode = ID; StatusMessage = MSG; }
+
+ protected slots:
+ bool move( ChessMove );
+
+ signals:
+ void setNotation( void );
+ void setClocks( void );
+ void setStatusBar( const int &ID, const QString &MSG=QString::null );
+ void sendCMD( const Command& );
+
+ protected:
+ bool move( void );
+ void clearSelections( void );
+ void drawPosition( const int );
+ void playSound( const int );
+ void _retract( void );
+};
+
+#endif
diff --git a/knights/match_param.cpp b/knights/match_param.cpp
new file mode 100644
index 0000000..3b356a4
--- /dev/null
+++ b/knights/match_param.cpp
@@ -0,0 +1,243 @@
+/***************************************************************************
+ match_param.cpp - description
+ -------------------
+ begin : Tue Jun 25 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kstddirs.h>
+#include <qcstring.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <string.h>
+#include "match_param.moc"
+
+match_param::match_param(resource *Rsrc) : QObject()
+{
+ myResource = Rsrc;
+ initialize();
+}
+match_param::match_param(resource *Rsrc, const int &whiteType, const int &blackType) : QObject()
+{
+ myResource = Rsrc;
+ initialize();
+
+ myResource->Type[WHITE] = Type[WHITE] = whiteType;
+ myResource->Type[BLACK] = Type[BLACK] = blackType;
+ lookupNames();
+ lookupImages();
+}
+match_param::~match_param()
+{
+}
+///////////////////////////////////////
+//
+// match_param::initialize
+//
+///////////////////////////////////////
+void match_param::initialize( void )
+{
+ PlayerNames << "" << "" << "" << "";
+ PlayerImages << QPixmap() << QPixmap() << QPixmap() << QPixmap();
+ Type[WHITE] = myResource->Type[WHITE];
+ Type[WHITE_HELPER] = myResource->Type[WHITE_HELPER];
+ Type[BLACK] = myResource->Type[BLACK];
+ Type[BLACK_HELPER] = myResource->Type[BLACK_HELPER];
+
+ Strength[WHITE] = myResource->Strength[WHITE];
+ Strength[WHITE_HELPER] = myResource->Strength[WHITE_HELPER];
+ Strength[BLACK] = myResource->Strength[BLACK];
+ Strength[BLACK_HELPER] = myResource->Strength[BLACK_HELPER];
+
+ Variation = myResource->MatchRules;
+
+ lookupTCP();
+ lookupNames();
+ lookupImages();
+}
+///////////////////////////////////////
+//
+// match_param::lookupNames
+//
+///////////////////////////////////////
+void match_param::lookupNames( void )
+{
+ engineList::Iterator IT;
+ char ID = 0;
+ for( int loop=0; loop < 4; loop++)
+ {
+ switch( Type[loop] )
+ {
+ case PLAYERLOCAL:
+ PlayerNames[loop] = myResource->Local_Player;
+ break;
+ case PLAYERPC:
+ /* Convert standard player numbers into engine Reference IDs */
+ switch( loop )
+ {
+ case WHITE:
+ ID = ENGINE_WHITE;
+ break;
+ case BLACK:
+ ID = ENGINE_BLACK;
+ break;
+ case WHITE_HELPER:
+ ID = ENGINE_WHITE_BK;
+ break;
+ case BLACK_HELPER:
+ ID = ENGINE_BLACK_BK;
+ break;
+ }
+ /* Search for Engine. I'm starting to like the idea of maps. =) */
+ for( IT = myResource->engines.begin(); IT != myResource->engines.end(); ++IT )
+ {
+ if( (*IT).CurrentRef & ID ) break;
+ }
+ if( IT == myResource->engines.end() )
+ {
+ PlayerNames[loop] = i18n("Unknown");
+ }
+ else
+ {
+ PlayerNames[loop] = (*IT).Name;
+ }
+ break;
+ case PLAYEREMAIL:
+ PlayerNames[loop] = myResource->Email_Address;
+ break;
+ }
+ }
+}
+///////////////////////////////////////
+//
+// match_param::lookupTCP
+//
+///////////////////////////////////////
+void match_param::lookupTCP( void )
+{
+ Time_White = myResource->TCPWhite;
+ Time_Black = myResource->TCPBlack;
+}
+///////////////////////////////////////
+//
+// match_param::lookupImages
+//
+///////////////////////////////////////
+void match_param::lookupImages( void )
+{
+ for( int loop=0; loop < 4; loop++)
+ {
+ switch( Type[loop] )
+ {
+ case PLAYERLOCAL:
+ PlayerImages[loop] = myResource->loadSCIDImage( PlayerNames[loop] );
+ if( PlayerImages[loop].isNull() )
+ PlayerImages[loop].load( locate("data", "knights/default-portrait.jpg" ) );
+ break;
+ case PLAYERPC:
+ PlayerImages[loop] = myResource->loadSCIDImage( PlayerNames[loop] );
+ if( PlayerImages[loop].isNull() )
+ PlayerImages[loop].load( locate("data", "knights/default-engine-portrait.jpg" ) );
+ break;
+ case PLAYEREMAIL:
+ PlayerImages[loop] = myResource->loadSCIDImage( PlayerNames[loop] );
+ if( PlayerImages[loop].isNull() )
+ PlayerImages[loop].load( locate("data", "knights/default-portrait.jpg" ) );
+ break;
+ }
+ }
+}
+///////////////////////////////////////
+//
+// match_param::time
+//
+///////////////////////////////////////
+TCPList match_param::time( const char &player )
+{
+ if( player == BLACK )
+ return Time_Black;
+ return Time_White;
+}
+
+///////////////////////////////////////
+//
+// match_param::setTime
+//
+///////////////////////////////////////
+void match_param::setTime( const char &player, const TCPList &tcp )
+{
+ if( player == BLACK )
+ myResource->TCPBlack = Time_Black = tcp;
+ else
+ myResource->TCPWhite = Time_White = tcp;
+ setTimer();
+}
+
+///////////////////////////////////////
+//
+// match_param::getVariation
+//
+///////////////////////////////////////
+
+int match_param::getVariation(void)
+{
+ return Variation;
+}
+
+///////////////////////////////////////
+//
+// match_param::setVariation
+//
+///////////////////////////////////////
+void match_param::setVariation(const int variation)
+{
+ Variation = variation;
+ setTimer();
+}
+
+///////////////////////////////////////
+//
+// match_param::setTimer
+//
+///////////////////////////////////////
+void match_param::setTimer( void )
+{
+ if( TimerFlag ) return;
+ QTimer::singleShot( 0, this, SLOT( slot_Timer() ) );
+ TimerFlag = TRUE;
+}
+
+///////////////////////////////////////
+//
+// match_param::slot_Timer
+//
+///////////////////////////////////////
+void match_param::slot_Timer( void )
+{
+ emit valuesChanged();
+ TimerFlag = FALSE;
+}
+
+///////////////////////////////////////
+//
+// match_param::setType
+//
+///////////////////////////////////////
+void match_param::setType( const int &player, const char &type )
+{
+ myResource->Type[player] = Type[player] = type;
+ lookupNames();
+ lookupImages();
+ setTimer();
+}
+
diff --git a/knights/match_param.h b/knights/match_param.h
new file mode 100644
index 0000000..ff48227
--- /dev/null
+++ b/knights/match_param.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ match_param.h - description
+ -------------------
+ begin : Tue Jun 25 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef MATCH_PARAM_H
+#define MATCH_PARAM_H
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qvaluelist.h>
+#include <qtimer.h>
+#include "definitions.h"
+#include "resource.h"
+
+class match_param : public QObject
+{
+ Q_OBJECT
+
+ private:
+ resource *myResource;
+ QStringList PlayerNames;
+ QValueList<QPixmap> PlayerImages;
+
+ /*
+ This is used to keep the signal valuesChanged
+ from triggering multiple times in a row.
+ */
+ bool TimerFlag;
+
+ char Type[4];
+ TCPList Time_White;
+ TCPList Time_Black;
+ char Strength[4];
+ int Variation;
+
+ protected:
+ void initialize( void );
+ void lookupTCP( void );
+ void lookupNames( void );
+ void lookupImages( void );
+ void setTimer( void );
+
+ public:
+ match_param( resource *Rsrc=0 );
+ match_param( resource*, const int &whiteType, const int &blackType );
+ ~match_param();
+
+ char type( const int &player )
+ { return Type[player]; }
+
+ char strength( const int &player )
+ { return Strength[player]; }
+
+ QPixmap image( const char &player )
+ { return PlayerImages[player]; }
+
+ QString name( const char &player )
+ { return PlayerNames[player]; }
+
+ TCPList time( const char &player );
+
+ void setType( const int &player, const char &type );
+
+ void setStrength( const int &player, const char &str )
+ { setTimer(); myResource->Strength[player] = Strength[player] = str; }
+
+ void setTime( const char &player, const TCPList &tcp );
+
+ void setName( const int &player, const QString &name )
+ { PlayerNames[player] = name; }
+
+ void setVariation( const int variation );
+ int getVariation( void );
+
+ public slots:
+ void slot_Timer( void );
+
+ signals:
+ void valuesChanged( void );
+};
+
+#endif
diff --git a/knights/pgn.cpp b/knights/pgn.cpp
new file mode 100644
index 0000000..a4de0a6
--- /dev/null
+++ b/knights/pgn.cpp
@@ -0,0 +1,1464 @@
+/***************************************************************************
+ pgn.cpp - description
+ -------------------
+ begin : Mon Jul 30 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <qdatetime.h>
+#include <qregexp.h>
+#include <kprinter.h>
+#include <qfontmetrics.h>
+#include <qpaintdevicemetrics.h>
+#include "pgn.moc"
+#include "tabmanager.h"
+#include "tab_pgnview.h"
+
+pgn::pgn( resource *Rsrc, match_param *param )
+{
+ Resource = Rsrc;
+ Param = param;
+ pgnView = NULL;
+
+ if( Param != NULL )
+ {
+ connect( Param, SIGNAL( valuesChanged() ), this, SLOT( parseMatchParam() ) );
+ }
+}
+pgn::~pgn()
+{
+ if( Param )
+ delete Param;
+ if( pgnView )
+ {
+ if( Resource->tabManager->isTab( pgnView ) )
+ {
+ Resource->tabManager->removeTab( pgnView );
+ }
+ }
+}
+///////////////////////////////////////
+//
+// pgn::parseMatchParam
+//
+///////////////////////////////////////
+void pgn::parseMatchParam( void )
+{
+ if( Param == NULL )
+ return;
+ TAG_White = Param->name( WHITE );
+ TAG_Black = Param->name( BLACK );
+ switch( Param->type( BLACK ) )
+ {
+ case PLAYERLOCAL:
+ TAG_BlackType = "human";
+ break;
+ case PLAYERPC:
+ TAG_BlackType = "program";
+ break;
+ case PLAYERTCP:
+ TAG_BlackType = "unknown";
+ TAG_Mode = "ICS";
+ break;
+ case PLAYEREMAIL:
+ TAG_BlackType = "unknown";
+ TAG_Mode = "EM";
+ break;
+ default:
+ TAG_BlackType = "unknown";
+ break;
+ }
+ switch( Param->type( WHITE ) )
+ {
+ case PLAYERLOCAL:
+ TAG_WhiteType = "human";
+ break;
+ case PLAYERPC:
+ TAG_WhiteType = "program";
+ break;
+ case PLAYERTCP:
+ TAG_WhiteType = "unknown";
+ TAG_Mode = "ICS";
+ break;
+ case PLAYEREMAIL:
+ TAG_WhiteType = "unknown";
+ TAG_Mode = "EM";
+ break;
+ default:
+ TAG_WhiteType = "unknown";
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// pgn::notation
+//
+///////////////////////////////////////
+QStringList* pgn::notation( const int format )
+{
+ QStringList *list;
+ QString notation;
+ MoveList::Iterator IT;
+ Annotation *annon;
+ int tmp(0), Line(0);
+ bool showLineNumber( false );
+
+ list = new QStringList;
+
+ switch( format )
+ {
+ case 0:
+ /* CAN Raw move data ( ie. for UCI engines ) */
+ for( IT = Moves.begin(); IT != Moves.end(); ++IT )
+ {
+ list->append( QString( (*IT).CAN ) );
+ }
+ break;
+
+ case 1:
+ /* SAN For display to the user */
+ for( IT = Moves.begin(); IT != Moves.end(); ++IT )
+ {
+ Line = ( tmp + 2 ) >> 1;
+ if( ( tmp % 2 ) == 0 )
+ {
+ notation = QString( "%1. %2" ).arg( Line ).arg( (*IT).SAN );
+ }
+ else
+ {
+ notation = QString( "%1... %2" ).arg( Line ).arg( (*IT).SAN );
+ }
+ list->append( notation );
+ tmp++;
+ }
+ break;
+
+ case 2:
+ /* SAN For PGN */
+ for( IT = Moves.begin(); IT != Moves.end(); ++IT )
+ {
+ Line = ( tmp + 2 ) >> 1;
+ if( ( tmp % 2 ) == 0 )
+ {
+ notation = QString( "%1. %2" ).arg( Line ).arg( (*IT).SAN );
+ }
+ else
+ {
+ if( showLineNumber )
+ {
+ notation = QString( "%1... %2" ).arg( Line ).arg( (*IT).SAN );
+ }
+ else
+ {
+ notation = QString( (*IT).SAN );
+ }
+ }
+ showLineNumber = false;
+ /* Insert NAGs */
+ if( (*IT).NAG != 0 )
+ {
+ notation += QString( " $%1" ).arg( QString::number( (*IT).NAG ) );
+ }
+ /* Insert RAVs */
+ annon = RAV.find( tmp );
+ if( annon != NULL )
+ {
+ notation += QString( " (%1)" ).arg( annon->text );
+ showLineNumber = true;
+ }
+ /* Insert Annotations */
+ annon = annotations.find( tmp );
+ if( annon != NULL )
+ {
+ notation += QString( " {%1}" ).arg( annon->text );
+ showLineNumber = true;
+ }
+ list->append( notation );
+ tmp++;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return list;
+}
+///////////////////////////////////////
+//
+// pgn::caption
+//
+///////////////////////////////////////
+QString pgn::caption( void )
+{
+ QString caption;
+
+ caption = i18n( "%1 vs. %2").arg( TAG_White ).arg( TAG_Black );
+ return caption;
+}
+///////////////////////////////////////
+//
+// pgn::clear
+//
+///////////////////////////////////////
+void pgn::clear( void )
+{
+ Moves.clear();
+ RAV.clear();
+ annotations.clear();
+ Positions.clear();
+ currentIndex = 0;
+ whiteTCP.clear();
+ blackTCP.clear();
+ whiteTime = 300;
+ blackTime = 300;
+ CurrentURL = "";
+ Move_Data.clear();
+ clearTags();
+}
+///////////////////////////////////////
+//
+// pgn::clearTags
+//
+///////////////////////////////////////
+void pgn::clearTags( void )
+{
+ TAG_Site = "";
+ TAG_Date = "";
+ TAG_Round = "";
+ TAG_Result = "";
+ TAG_White = "";
+ TAG_WhiteTitle = "";
+ TAG_WhiteElo = "";
+ TAG_WhiteUSCF = "";
+ TAG_WhiteNA = "";
+ TAG_WhiteType = "";
+ TAG_Black = "";
+ TAG_BlackTitle = "";
+ TAG_BlackElo = "";
+ TAG_BlackUSCF = "";
+ TAG_BlackNA = "";
+ TAG_BlackType = "";
+ TAG_Time = "";
+ TAG_UTCTime = "";
+ TAG_UTCDate = "";
+ TAG_Event = "";
+ TAG_EventDate = "";
+ TAG_EventSponsor = "";
+ TAG_Section = "";
+ TAG_Stage = "";
+ TAG_Board = "";
+ TAG_Opening = "";
+ TAG_Variation = "";
+ TAG_SubVariation = "";
+ TAG_ECO = "";
+ TAG_NIC = "";
+ TAG_TimeControl = "";
+ TAG_Termination = "";
+ TAG_SetUp = "";
+ TAG_FEN = "";
+ TAG_Annotator = "";
+ TAG_Mode = "";
+ TAG_PlyCount = "";
+}
+///////////////////////////////////////
+//
+// pgn::init
+//
+///////////////////////////////////////
+void pgn::init( void )
+{
+ QString temp;
+ struct utsname unamePtr;
+ QDateTime qdt;
+
+ clear();
+ parseMatchParam();
+ uname( &unamePtr );
+
+ /* Build Date */
+ qdt = QDateTime::currentDateTime();
+ TAG_Date = QString("%1.%2.%3").arg(qdt.date().year(),4).arg(qdt.date().month(),2).arg(qdt.date().day(),2);
+ TAG_Date = TAG_Date.replace( QRegExp("\\s"), QString("0") );
+ TAG_Time = qdt.time().toString();
+
+ TAG_Site = unamePtr.nodename;
+ TAG_Event = "Knights Computer Chess Game";
+ TAG_Round = "-";
+ TAG_Result = "*";
+}
+///////////////////////////////////////
+//
+// pgn::scan
+//
+///////////////////////////////////////
+int pgn::scan( void )
+{
+ register int Section(0);
+ QChar c;
+
+ clearTags();
+ File_Position = File.at();
+
+ /* Toplevel parsing loop */
+ while( 1 )
+ {
+ /* Is this the end of the .pgn file? */
+ if( Input.atEnd() )
+ {
+ close();
+ return 100; // 100% Complete
+ }
+ currentLine = Input.readLine();
+ if( currentLine.isEmpty() )
+ {
+ if( Section == 1 )
+ return (int)( ( (float)File.at() / (float)File.size() ) * 100.0 );
+ }
+ c = getch();
+ while( c != QChar::null )
+ {
+ switch( c )
+ {
+ /* Tag Pair */
+ case '[':
+ parseTag();
+ break;
+ case '%': /* Fall through */
+ case ';':
+ c = QChar::null;
+ continue;
+ break;
+ default:
+ Section = 1;
+ c = QChar::null;
+ continue;
+ break;
+ }
+ c = getch();
+ }
+ }
+ /* We should NEVER reach this point */
+ close();
+ return -1;
+}
+///////////////////////////////////////
+//
+// pgn::load
+//
+///////////////////////////////////////
+bool pgn::load( const int pos )
+{
+ QString Token,
+ Value;
+ QChar c;
+
+ File.at(pos);
+ clear();
+
+ /* Toplevel parsing loop */
+ while( 1 )
+ {
+ if( Input.atEnd() )
+ break;
+ currentLine = Input.readLine();
+ if( currentLine.isEmpty() )
+ {
+ /* Finished with TAGs... now grab the move data for display */
+ File_Position = File.at();
+ while( 1 )
+ {
+ currentLine = Input.readLine();
+ if( ( currentLine.at(0) == '[' ) || Input.atEnd() )
+ break;
+ Move_Data << currentLine;
+ }
+ /* Allocate the Tab_PGNView */
+ pgnView = new tab_pgnView( this, Resource );
+ connect( pgnView, SIGNAL( destroyed() ), this, SLOT( childViewDestroyed() ) );
+ Resource->tabManager->addTab( pgnView, i18n( "%1 vs. %2" ).arg( TAG_White ).arg( TAG_Black ) );
+ pgnView->init();
+ File.at( File_Position );
+ currentLine = "";
+ return TRUE;
+ }
+ c = getch();
+ while( c != QChar::null )
+ {
+ Token = "";
+ Value = "";
+ switch( c )
+ {
+ /* Special break... look for the Knights tag */
+ case '%':
+ Value = getword();
+ if( Value == "KNIGHTS_CMD" ) parseKnightsData();
+ /* Fall through */
+ case ';':
+ c = QChar::null;
+ continue;
+ break;
+ /* Tag Pair */
+ case '[':
+ parseTag();
+ break;
+ default:
+ c = QChar::null;
+ break;
+ }
+ c = getch();
+ }
+ }
+ close();
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// pgn::loadNext
+//
+///////////////////////////////////////
+bool pgn::loadNext( void )
+{
+ QChar c;
+ QString Value;
+ ChessMove Move;
+ bool postMove( FALSE );
+
+ /* Toplevel parsing loop */
+ while( 1 )
+ {
+ if( currentLine.isEmpty() )
+ {
+ if( Input.atEnd() ) break;
+ currentLine = Input.readLine();
+ }
+ c = getch();
+ while( c != QChar::null )
+ {
+ Value = "";
+ switch( c )
+ {
+ /* Special break... look for the Knights tag */
+ case '%':
+ Value = getword();
+ if( Value == "KNIGHTS_CMD" ) parseKnightsData();
+ /* Fall through */
+ case ';':
+ c = QChar::null;
+ continue;
+ /* Tag Pair...next game, so we're done. */
+ case '[':
+ return FALSE;
+ /* Numeric Annotation Glyph */
+ case '$':
+ c = getch();
+ while( ( c >= '0' ) && ( c <= '9' ) )
+ {
+ Value += c;
+ c = getch();
+ }
+ Moves[ Moves.count() - 1 ].NAG = Value.toInt();
+ break;
+ /* Recursive Annotation Variations */
+ case '(':
+ parseRAV();
+ break;
+ /* Textual Annotation */
+ case '{':
+ parseAnnotation();
+ break;
+ /* Reserved for future expansion by the PGN */
+ case '<':
+ while( c != '>' ) c = getch();
+ break;
+ /* Everything from '0' to '*' is null to us and falls through */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case ' ':
+ case '/':
+ case '-':
+ case '.':
+ case '*':
+ break;
+ default:
+ if( postMove )
+ {
+ currentLine.prepend( c );
+ return TRUE;
+ }
+ /* Catch Standard Algebraic Notation */
+ while( ( c != QChar::null ) &&
+ ( c != ' ' ) &&
+ ( c != ';' ) &&
+ ( c != '%' ) )
+ {
+ Value += c;
+ c = getch();
+ }
+ strcpy( Move.SAN, Value.latin1() );
+ emit processMove( Move );
+ postMove = TRUE;
+ }
+ c = getch();
+ }
+ }
+ return FALSE;
+}
+///////////////////////////////////////
+//
+// pgn::save
+//
+///////////////////////////////////////
+bool pgn::save( QString URL )
+{
+ QFile Save( URL );
+ QTextStream *Output;
+ QString Token,
+ Value;
+
+ close();
+ CurrentURL = URL;
+ if( Resource->OPTION_Reuse_PGN && ( URL == Resource->PGN_Filename ) )
+ {
+ Save.open( IO_WriteOnly | IO_Append );
+ }
+ else
+ {
+ Save.open( IO_WriteOnly );
+ }
+ Output = new QTextStream( &Save );
+ (*Output) << "[Event \"" << TAG_Event << "\"]\n";
+ (*Output) << "[Site \"" << TAG_Site << "\"]\n";
+ (*Output) << "[Date \"" << TAG_Date << "\"]\n";
+ (*Output) << "[Round \"" << TAG_Round << "\"]\n";
+ (*Output) << "[White \"" << TAG_White << "\"]\n";
+ (*Output) << "[Black \"" << TAG_Black << "\"]\n";
+ (*Output) << "[Result \"" << TAG_Result << "\"]\n";
+ if( !TAG_TimeControl.isEmpty() )
+ (*Output) << "[TimeControl \"" << TAG_TimeControl << "\"]\n";
+ if( !TAG_WhiteTitle.isEmpty() )
+ (*Output) << "[WhiteTitle \"" << TAG_WhiteTitle << "\"]\n";
+ if( !TAG_WhiteElo.isEmpty() )
+ (*Output) << "[WhiteElo \"" << TAG_WhiteElo << "\"]\n";
+ if( !TAG_WhiteUSCF.isEmpty() )
+ (*Output) << "[WhiteUSCF \"" << TAG_WhiteUSCF << "\"]\n";
+ if( !TAG_WhiteNA.isEmpty() )
+ (*Output) << "[WhiteNA \"" << TAG_WhiteNA << "\"]\n";
+ if( !TAG_WhiteType.isEmpty() )
+ (*Output) << "[WhiteType \"" << TAG_WhiteType << "\"]\n";
+ if( !TAG_BlackTitle.isEmpty() )
+ (*Output) << "[BlackTitle \"" << TAG_BlackTitle << "\"]\n";
+ if( !TAG_BlackElo.isEmpty() )
+ (*Output) << "[BlackElo \"" << TAG_BlackElo << "\"]\n";
+ if( !TAG_BlackUSCF.isEmpty() )
+ (*Output) << "[BlackUSCF \"" << TAG_BlackUSCF << "\"]\n";
+ if( !TAG_BlackNA.isEmpty() )
+ (*Output) << "[BlackNA \"" << TAG_BlackNA << "\"]\n";
+ if( !TAG_BlackType.isEmpty() )
+ (*Output) << "[BlackType \"" << TAG_BlackType << "\"]\n";
+ if( !TAG_Time.isEmpty() )
+ (*Output) << "[Time \"" << TAG_Time << "\"]\n";
+ if( !TAG_UTCTime.isEmpty() )
+ (*Output) << "[UTCTime \"" << TAG_UTCTime << "\"]\n";
+ if( !TAG_UTCDate.isEmpty() )
+ (*Output) << "[UTCDate \"" << TAG_UTCDate << "\"]\n";
+ if( !TAG_EventDate.isEmpty() )
+ (*Output) << "[EventDate \"" << TAG_EventDate << "\"]\n";
+ if( !TAG_EventSponsor.isEmpty() )
+ (*Output) << "[EventSponsor \"" << TAG_EventSponsor << "\"]\n";
+ if( !TAG_Section.isEmpty() )
+ (*Output) << "[Section \"" << TAG_Section << "\"]\n";
+ if( !TAG_Stage.isEmpty() )
+ (*Output) << "[Stage \"" << TAG_Stage << "\"]\n";
+ if( !TAG_Board.isEmpty() )
+ (*Output) << "[Board \"" << TAG_Board << "\"]\n";
+ if( !TAG_Opening.isEmpty() )
+ (*Output) << "[Opening \"" << TAG_Opening << "\"]\n";
+ if( !TAG_Variation.isEmpty() )
+ (*Output) << "[Variation \"" << TAG_Variation << "\"]\n";
+ if( !TAG_SubVariation.isEmpty() )
+ (*Output) << "[SubVariation \"" << TAG_SubVariation << "\"]\n";
+ if( !TAG_ECO.isEmpty() )
+ (*Output) << "[ECO \"" << TAG_ECO << "\"]\n";
+ if( !TAG_NIC.isEmpty() )
+ (*Output) << "[NIC \"" << TAG_NIC << "\"]\n";
+ if( !TAG_Termination.isEmpty() )
+ (*Output) << "[Termination \"" << TAG_Termination << "\"]\n";
+ if( !TAG_SetUp.isEmpty() )
+ (*Output) << "[SetUp \"" << TAG_SetUp << "\"]\n";
+ if( !TAG_FEN.isEmpty() )
+ (*Output) << "[FEN \"" << TAG_FEN << "\"]\n";
+ if( !TAG_Annotator.isEmpty() )
+ (*Output) << "[Annotator \"" << TAG_Annotator << "\"]\n";
+ if( !TAG_Mode.isEmpty() )
+ (*Output) << "[Mode \"" << TAG_Mode << "\"]\n";
+ TAG_PlyCount = QString().setNum( Moves.count() );
+ (*Output) << "[PlyCount \"" << TAG_PlyCount << "\"]\n";
+
+ /* Save internal data if this game is unfinished */
+ if( TAG_Result == "*" )
+ {
+ (*Output) << "% KNIGHTS_CMD WhiteType ";
+ switch( Param->type(WHITE) )
+ {
+ case PLAYERPC:
+ (*Output) << "PC\n";
+ break;
+ case PLAYERTCP:
+ (*Output) << "TCP\n";
+ break;
+ case PLAYEREMAIL:
+ (*Output) << "Email\n";
+ break;
+ case PLAYERLOCAL:
+ default:
+ (*Output) << "Local\n";
+ break;
+ }
+ (*Output) << "% KNIGHTS_CMD BlackType ";
+ switch( Param->type(BLACK) )
+ {
+ case PLAYERPC:
+ (*Output) << "PC\n";
+ break;
+ case PLAYERTCP:
+ (*Output) << "TCP\n";
+ break;
+ case PLAYEREMAIL:
+ (*Output) << "Email\n";
+ break;
+ case PLAYERLOCAL:
+ default:
+ (*Output) << "Local\n";
+ break;
+ }
+ (*Output) << "% KNIGHTS_CMD WhiteTime " << whiteTime << "\n";
+ (*Output) << "% KNIGHTS_CMD BlackTime " << blackTime << "\n";
+ (*Output) << "% KNIGHTS_CMD DONE\n";
+ }
+ /* End of internal data save */
+
+ (*Output) << "\n";
+ QStringList *list = notation(2);
+ QString SAN = list->join( " " );
+ delete list;
+
+ kdWarning() << SAN.right( 20 ) << endl;
+
+ unsigned int pos = 80;
+ unsigned int lastPos = 0;
+ while( pos < SAN.length() )
+ {
+ while( SAN.at( pos ) != ' ' )
+ pos--;
+ SAN = SAN.replace( pos, 1, QString("\n") );
+ lastPos = pos;
+ pos = lastPos + 80;
+ }
+ kdWarning() << SAN.right( 20 ) << endl;
+
+ (*Output) << SAN << " " << TAG_Result << "\n\n";
+ Save.close();
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// pgn::getch
+//
+///////////////////////////////////////
+QChar pgn::getch( void )
+{
+ QChar c;
+
+ c = currentLine.at(0);
+ currentLine.remove( 0, 1 );
+ return c;
+}
+///////////////////////////////////////
+//
+// pgn::getword
+//
+///////////////////////////////////////
+QString pgn::getword( void )
+{
+ QChar c;
+ QString word;
+
+ do
+ {
+ c = getch();
+ } while( c == ' ' );
+
+ while( ( c != ' ' ) && ( c != QChar::null ) )
+ {
+ word += c;
+ c = getch();
+ }
+ return word;
+}
+///////////////////////////////////////
+//
+// pgn::open
+//
+///////////////////////////////////////
+bool pgn::open( const QString &URL )
+{
+ close();
+ if( !KIO::NetAccess::download( URL, tempFile ) )
+ return FALSE;
+
+ File.setName( tempFile );
+ if( !File.open( IO_ReadOnly ) )
+ {
+ close();
+ return FALSE;
+ }
+ Input.setDevice( &File );
+ CurrentURL = URL;
+ File.at(0);
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// pgn::close
+//
+///////////////////////////////////////
+void pgn::close( void )
+{
+ if( !File.isOpen() )
+ {
+ File.close();
+ }
+ if( !tempFile.isEmpty() )
+ {
+ KIO::NetAccess::removeTempFile( tempFile );
+ tempFile = "";
+ }
+}
+///////////////////////////////////////
+//
+// pgn::parseTag
+//
+///////////////////////////////////////
+void pgn::parseTag( void )
+{
+ QChar c;
+ QString Token;
+ QString Value;
+
+ c = getch();
+ while( c == ' ' ) c = getch();
+ while( c != '\"' )
+ {
+ if( c == ' ' )
+ {
+ c = getch();
+ continue;
+ }
+ Token += c;
+ c = getch();
+ }
+ c = getch();
+ while( c != '\"' )
+ {
+ Value += c;
+ c = getch();
+ }
+ c = getch();
+ while( c != ']' ) c = getch();
+ /* Now Apply the Token/Value that we got */
+ if( Token == "Site" ) TAG_Site = Value;
+ else if( Token == "Date" ) TAG_Date = Value;
+ else if( Token == "Round" ) TAG_Round = Value;
+ else if( Token == "Result" ) TAG_Result = Value;
+
+ else if( Token == "White" ) TAG_White = Value;
+ else if( Token == "WhiteTitle" ) TAG_WhiteTitle = Value;
+ else if( Token == "WhiteElo" ) TAG_WhiteElo = Value;
+ else if( Token == "WhiteUSCF" ) TAG_WhiteUSCF = Value;
+ else if( Token == "WhiteNA" ) TAG_WhiteNA = Value;
+ else if( Token == "WhiteType" ) TAG_WhiteType = Value;
+
+ else if( Token == "Black" ) TAG_Black = Value;
+ else if( Token == "BlackTitle" ) TAG_BlackTitle = Value;
+ else if( Token == "BlackElo" ) TAG_BlackElo = Value;
+ else if( Token == "BlackUSCF" ) TAG_BlackUSCF = Value;
+ else if( Token == "BlackNA" ) TAG_BlackNA = Value;
+ else if( Token == "BlackType" ) TAG_BlackType = Value;
+
+ else if( Token == "Time" ) TAG_Time = Value;
+ else if( Token == "UTCTime" ) TAG_UTCTime = Value;
+ else if( Token == "UTCDate" ) TAG_UTCDate = Value;
+
+ else if( Token == "Event" ) TAG_Event = Value;
+ else if( Token == "EventDate" ) TAG_EventDate = Value;
+ else if( Token == "EventSponsor") TAG_EventSponsor = Value;
+ else if( Token == "Section" ) TAG_Section = Value;
+ else if( Token == "Stage" ) TAG_Stage = Value;
+ else if( Token == "Board" ) TAG_Board = Value;
+
+ else if( Token == "Opening" ) TAG_Opening = Value;
+ else if( Token == "Variation" ) TAG_Variation = Value;
+ else if( Token == "SubVariation" ) TAG_SubVariation = Value;
+ else if( Token == "ECO" ) TAG_ECO = Value;
+ else if( Token == "NIC" ) TAG_NIC = Value;
+
+ else if( Token == "TimeControl" ) TAG_TimeControl = Value;
+ else if( Token == "Termination" ) TAG_Termination = Value;
+ else if( Token == "SetUp" ) TAG_SetUp = Value;
+ else if( Token == "FEN" ) TAG_FEN = Value;
+ else if( Token == "Annotator" ) TAG_Annotator = Value;
+ else if( Token == "Mode" ) TAG_Mode = Value;
+ else if( Token == "PlyCount" ) TAG_PlyCount = Value;
+}
+///////////////////////////////////////
+//
+// pgn::Parse_Annotation
+//
+///////////////////////////////////////
+void pgn::parseAnnotation( const int fromRAVnum )
+{
+ Annotation *annon = new Annotation;
+ QChar c;
+
+ c = getch();
+ while( c != '}' )
+ {
+ if( c == QChar::null )
+ {
+ if( Input.eof() ) break;
+ currentLine = Input.readLine();
+ c = ' ';
+ }
+ annon->text += c;
+ c = getch();
+ }
+ annon->RAV = fromRAVnum;
+ annotations.add( Moves.count() - 1, annon );
+// kdWarning() << "# " << annon.pos << " : " << annon.text << endl;
+}
+///////////////////////////////////////
+//
+// pgn::Parse_RAV
+//
+///////////////////////////////////////
+void pgn::parseRAV( void )
+{
+ int RAVLevel(1);
+ Annotation *annon = new Annotation;
+ QChar c;
+
+ while( RAVLevel )
+ {
+ c = getch();
+ if( c == QChar::null )
+ {
+ if( Input.eof() )
+ break;
+ currentLine = Input.readLine();
+ c = ' ';
+ }
+ if( c == ')' )
+ {
+ RAVLevel--;
+ if( !RAVLevel )
+ break;
+ }
+ if( c == '(' )
+ {
+ RAVLevel++;
+ }
+ annon->text += c;
+ }
+ RAV.add( Moves.count() - 1, annon );
+// kdWarning() << "# " << annon.pos << " : " << annon.text << endl;
+}
+///////////////////////////////////////
+//
+// pgn::parseKnightsData
+//
+///////////////////////////////////////
+void pgn::parseKnightsData( void )
+{
+ QString Key;
+ QString Value;
+
+ Key = getword();
+ if( Key == "DONE" )
+ {
+ emit processSpecial();
+ return;
+ }
+ if( Key == "WhiteType" )
+ {
+ Value = getword();
+ if( Value == "Local" ) Param->setType(WHITE, PLAYERLOCAL);
+ if( Value == "PC" ) Param->setType(WHITE, PLAYERPC);
+ if( Value == "TCP" ) Param->setType(WHITE, PLAYERTCP);
+ if( Value == "Email" ) Param->setType(WHITE, PLAYEREMAIL);
+ return;
+ }
+ if( Key == "BlackType" )
+ {
+ Value = getword();
+ if( Value == "Local" ) Param->setType(BLACK, PLAYERLOCAL);
+ if( Value == "PC" ) Param->setType(BLACK, PLAYERPC);
+ if( Value == "TCP" ) Param->setType(BLACK, PLAYERTCP);
+ if( Value == "Email" ) Param->setType(BLACK, PLAYEREMAIL);
+ return;
+ }
+ if( Key == "WhiteTime" )
+ {
+ Value = getword();
+ whiteTime = Value.toInt();
+ return;
+ }
+ if( Key == "BlackTime" )
+ {
+ Value = getword();
+ blackTime = Value.toInt();
+ return;
+ }
+}
+///////////////////////////////////////
+//
+// pgn::print
+//
+///////////////////////////////////////
+void pgn::print( void )
+{
+ if( !pgnView )
+ {
+ /* Allocate the Tab_PGNView */
+ pgnView = new tab_pgnView( this, Resource );
+ Resource->tabManager->addTab( pgnView, i18n( "%1 vs. %2" ).arg( TAG_White ).arg( TAG_Black ) );
+ connect( pgnView, SIGNAL( destroyed() ), this, SLOT( childViewDestroyed() ) );
+ pgnView->init();
+ }
+ pgnView->print();
+}
+///////////////////////////////////////
+//
+// pgn::childViewDestroyed
+//
+///////////////////////////////////////
+void pgn::childViewDestroyed( void )
+{
+ pgnView = NULL;
+}
+///////////////////////////////////////
+//
+// pgn::getNAG
+//
+///////////////////////////////////////
+QString pgn::getNAG( int num )
+{
+ QString Line;
+
+ switch( num )
+ {
+ case 1:
+ Line = i18n( "Good move" );
+ break;
+ case 2:
+ Line = i18n( "Poor move" );
+ break;
+ case 3:
+ Line = i18n( "Very good move" );
+ break;
+ case 4:
+ Line = i18n( "Very poor move" );
+ break;
+ case 5:
+ Line = i18n( "Speculative move" );
+ break;
+ case 6:
+ Line = i18n( "Questionable move" );
+ break;
+ case 7:
+ Line = i18n( "Forced move" );
+ break;
+ case 8:
+ Line = i18n( "Singular move" );
+ break;
+ case 9:
+ Line = i18n( "Worst move" );
+ break;
+ case 10:
+ Line = i18n( "Drawish position" );
+ break;
+ case 11:
+ Line = i18n( "Equal chances, quiet position" );
+ break;
+ case 12:
+ Line = i18n( "Equal chances, active position" );
+ break;
+ case 13:
+ Line = i18n( "Unclear position" );
+ break;
+ case 14:
+ Line = i18n( "White has a slight advantage" );
+ break;
+ case 15:
+ Line = i18n( "Black has a slight advantage" );
+ break;
+ case 16:
+ Line = i18n( "White has a moderate advantage" );
+ break;
+ case 17:
+ Line = i18n( "Black has a moderate advantage" );
+ break;
+ case 18:
+ Line = i18n( "White has a decisive advantage" );
+ break;
+ case 19:
+ Line = i18n( "Black has a decisive advantage" );
+ break;
+ case 20:
+ Line = i18n( "White has a crushing advantage ( Black should resign )" );
+ break;
+ case 21:
+ Line = i18n( "Black has a crushing advantage ( White should resign )" );
+ break;
+ case 22:
+ Line = i18n( "White is in zugzwang" );
+ break;
+ case 23:
+ Line = i18n( "Black is in zugzwang" );
+ break;
+ case 24:
+ Line = i18n( "White has a slight space advantage" );
+ break;
+ case 25:
+ Line = i18n( "Black has a slight space advantage" );
+ break;
+ case 26:
+ Line = i18n( "White has a moderate space advantage" );
+ break;
+ case 27:
+ Line = i18n( "Black has a moderate space advantage" );
+ break;
+ case 28:
+ Line = i18n( "White has a decisive space advantage" );
+ break;
+ case 29:
+ Line = i18n( "Black has a decisive space advantage" );
+ break;
+ case 30:
+ Line = i18n( "White has a slight time ( development ) advantage" );
+ break;
+ case 31:
+ Line = i18n( "Black has a slight time ( development ) advantage" );
+ break;
+ case 32:
+ Line = i18n( "White has a moderate time ( development ) advantage" );
+ break;
+ case 33:
+ Line = i18n( "Black has a moderate time ( development ) advantage" );
+ break;
+ case 34:
+ Line = i18n( "White has a decisive time ( development ) advantage" );
+ break;
+ case 35:
+ Line = i18n( "Black has a decisive time ( development ) advantage" );
+ break;
+ case 36:
+ Line = i18n( "White has the initiative" );
+ break;
+ case 37:
+ Line = i18n( "Black has the initiative" );
+ break;
+ case 38:
+ Line = i18n( "White has a lasting initiative" );
+ break;
+ case 39:
+ Line = i18n( "Black has a lasting initiative" );
+ break;
+ case 40:
+ Line = i18n( "White has the attack" );
+ break;
+ case 41:
+ Line = i18n( "Black has the attack" );
+ break;
+ case 42:
+ Line = i18n( "White has insufficient compensation for material deficit" );
+ break;
+ case 43:
+ Line = i18n( "Black has insufficient compensation for material deficit" );
+ break;
+ case 44:
+ Line = i18n( "White has sufficient compensation for material deficit" );
+ break;
+ case 45:
+ Line = i18n( "Black has sufficient compensation for material deficit" );
+ break;
+ case 46:
+ Line = i18n( "White has more than adequate compensation for material deficit" );
+ break;
+ case 47:
+ Line = i18n( "Black has more than adequate compensation for material deficit" );
+ break;
+ case 48:
+ Line = i18n( "White has a slight center control advantage" );
+ break;
+ case 49:
+ Line = i18n( "Black has a slight center control advantage" );
+ break;
+ case 50:
+ Line = i18n( "White has a moderate center control advantage" );
+ break;
+ case 51:
+ Line = i18n( "Black has a moderate center control advantage" );
+ break;
+ case 52:
+ Line = i18n( "White has a decisive center control advantage" );
+ break;
+ case 53:
+ Line = i18n( "Black has a decisive center control advantage" );
+ break;
+ case 54:
+ Line = i18n( "White has a slight kingside control advantage" );
+ break;
+ case 55:
+ Line = i18n( "Black has a slight kingside control advantage" );
+ break;
+ case 56:
+ Line = i18n( "White has a moderate kingside control advantage" );
+ break;
+ case 57:
+ Line = i18n( "Black has a moderate kingside control advantage" );
+ break;
+ case 58:
+ Line = i18n( "White has a decisive kingside control advantage" );
+ break;
+ case 59:
+ Line = i18n( "Black has a decisive kingside control advantage" );
+ break;
+ case 60:
+ Line = i18n( "White has a slight queenside control advantage" );
+ break;
+ case 61:
+ Line = i18n( "Black has a slight queenside control advantage" );
+ break;
+ case 62:
+ Line = i18n( "White has a moderate queenside control advantage" );
+ break;
+ case 63:
+ Line = i18n( "Black has a moderate queenside control advantage" );
+ break;
+ case 64:
+ Line = i18n( "White has a decisive queenside control advantage" );
+ break;
+ case 65:
+ Line = i18n( "Black has a decisive queenside control advantage" );
+ break;
+ case 66:
+ Line = i18n( "White has a vulnerable first rank" );
+ break;
+ case 67:
+ Line = i18n( "Black has a vulnerable first rank" );
+ break;
+ case 68:
+ Line = i18n( "White has a well protected first rank" );
+ break;
+ case 69:
+ Line = i18n( "Black has a well protected first rank" );
+ break;
+ case 70:
+ Line = i18n( "White has a poorly protected king" );
+ break;
+ case 71:
+ Line = i18n( "Black has a poorly protected king" );
+ break;
+ case 72:
+ Line = i18n( "White has a well protected king" );
+ break;
+ case 73:
+ Line = i18n( "Black has a well protected king" );
+ break;
+ case 74:
+ Line = i18n( "White has a poorly placed king" );
+ break;
+ case 75:
+ Line = i18n( "Black has a poorly placed king" );
+ break;
+ case 76:
+ Line = i18n( "White has a well placed king" );
+ break;
+ case 77:
+ Line = i18n( "Black has a well placed king" );
+ break;
+ case 78:
+ Line = i18n( "White has a very weak pawn structure" );
+ break;
+ case 79:
+ Line = i18n( "Black has a very weak pawn structure" );
+ break;
+ case 80:
+ Line = i18n( "White has a moderately weak pawn structure" );
+ break;
+ case 81:
+ Line = i18n( "Black has a moderately weak pawn structure" );
+ break;
+ case 82:
+ Line = i18n( "White has a moderately strong pawn structure" );
+ break;
+ case 83:
+ Line = i18n( "Black has a moderately strong pawn structure" );
+ break;
+ case 84:
+ Line = i18n( "White has a very strong pawn structure" );
+ break;
+ case 85:
+ Line = i18n( "Black has a very strong pawn structure" );
+ break;
+ case 86:
+ Line = i18n( "White has poor knight placement" );
+ break;
+ case 87:
+ Line = i18n( "Black has poor knight placement" );
+ break;
+ case 88:
+ Line = i18n( "White has good knight placement" );
+ break;
+ case 89:
+ Line = i18n( "Black has good knight placement" );
+ break;
+ case 90:
+ Line = i18n( "White has poor bishop placement" );
+ break;
+ case 91:
+ Line = i18n( "Black has poor bishop placement" );
+ break;
+ case 92:
+ Line = i18n( "White has good bishop placement" );
+ break;
+ case 93:
+ Line = i18n( "Black has good bishop placement" );
+ break;
+ case 94:
+ Line = i18n( "White has poor rook placement" );
+ break;
+ case 95:
+ Line = i18n( "Black has poor rook placement" );
+ break;
+ case 96:
+ Line = i18n( "White has good rook placement" );
+ break;
+ case 97:
+ Line = i18n( "Black has good rook placement" );
+ break;
+ case 98:
+ Line = i18n( "White has poor queen placement" );
+ break;
+ case 99:
+ Line = i18n( "Black has poor queen placement" );
+ break;
+ case 100:
+ Line = i18n( "White has good queen placement" );
+ break;
+ case 101:
+ Line = i18n( "Black has good queen placement" );
+ break;
+ case 102:
+ Line = i18n( "White has poor piece coordination" );
+ break;
+ case 103:
+ Line = i18n( "Black has poor piece coordination" );
+ break;
+ case 104:
+ Line = i18n( "White has good piece coordination" );
+ break;
+ case 105:
+ Line = i18n( "Black has good piece coordination" );
+ break;
+ case 106:
+ Line = i18n( "White has played the opening very poorly" );
+ break;
+ case 107:
+ Line = i18n( "Black has played the opening very poorly" );
+ break;
+ case 108:
+ Line = i18n( "White has played the opening poorly" );
+ break;
+ case 109:
+ Line = i18n( "Black has played the opening poorly" );
+ break;
+ case 110:
+ Line = i18n( "White has played the opening well" );
+ break;
+ case 111:
+ Line = i18n( "Black has played the opening well" );
+ break;
+ case 112:
+ Line = i18n( "White has played the opening very well" );
+ break;
+ case 113:
+ Line = i18n( "Black has played the opening very well" );
+ break;
+ case 114:
+ Line = i18n( "White has played the middlegame very poorly" );
+ break;
+ case 115:
+ Line = i18n( "Black has played the middlegame very poorly" );
+ break;
+ case 116:
+ Line = i18n( "White has played the middlegame poorly" );
+ break;
+ case 117:
+ Line = i18n( "Black has played the middlegame poorly" );
+ break;
+ case 118:
+ Line = i18n( "White has played the middlegame well" );
+ break;
+ case 119:
+ Line = i18n( "Black has played the middlegame well" );
+ break;
+ case 120:
+ Line = i18n( "White has played the middlegame very well" );
+ break;
+ case 121:
+ Line = i18n( "Black has played the middlegame very well" );
+ break;
+ case 122:
+ Line = i18n( "White has played the ending very poorly" );
+ break;
+ case 123:
+ Line = i18n( "Black has played the ending very poorly" );
+ break;
+ case 124:
+ Line = i18n( "White has played the ending poorly" );
+ break;
+ case 125:
+ Line = i18n( "Black has played the ending poorly" );
+ break;
+ case 126:
+ Line = i18n( "White has played the ending well" );
+ break;
+ case 127:
+ Line = i18n( "Black has played the ending well" );
+ break;
+ case 128:
+ Line = i18n( "White has played the ending very well" );
+ break;
+ case 129:
+ Line = i18n( "Black has played the ending very well" );
+ break;
+ case 130:
+ Line = i18n( "White has slight counterplay" );
+ break;
+ case 131:
+ Line = i18n( "Black has slight counterplay" );
+ break;
+ case 132:
+ Line = i18n( "White has moderate counterplay" );
+ break;
+ case 133:
+ Line = i18n( "Black has moderate counterplay" );
+ break;
+ case 134:
+ Line = i18n( "White has decisive counterplay" );
+ break;
+ case 135:
+ Line = i18n( "Black has decisive counterplay" );
+ break;
+ case 136:
+ Line = i18n( "White has moderate time control pressure" );
+ break;
+ case 137:
+ Line = i18n( "Black has moderate time control pressure" );
+ break;
+ case 138:
+ Line = i18n( "White has severe time control pressure" );
+ break;
+ case 139:
+ Line = i18n( "Black has severe time control pressure" );
+ case 140:
+ Line = i18n( "With the idea..." );
+ break;
+ case 141:
+ Line = i18n( "Aimed against..." );
+ break;
+ case 142:
+ Line = i18n( "Better Move" );
+ break;
+ case 143:
+ Line = i18n( "Worse Move" );
+ break;
+ case 144:
+ Line = i18n( "Equivalent move" );
+ break;
+ case 145:
+ Line = i18n( "Editor's Remark" );
+ break;
+ case 146:
+ Line = i18n( "Novelty" );
+ break;
+ case 147:
+ Line = i18n( "Weak point" );
+ break;
+ case 148:
+ Line = i18n( "Endgame" );
+ break;
+ case 149:
+ Line = i18n( "Line" );
+ break;
+ case 150:
+ Line = i18n( "Diagonal" );
+ break;
+ case 151:
+ Line = i18n( "White has a pair of Bishops" );
+ break;
+ case 152:
+ Line = i18n( "Black has a pair of Bishops" );
+ break;
+ case 153:
+ Line = i18n( "Bishops of opposite color" );
+ break;
+ case 154:
+ Line = i18n( "Bishops of same color" );
+ break;
+ case 190:
+ Line = i18n( "Etc." );
+ break;
+ case 191:
+ Line = i18n( "Doubled pawns" );
+ break;
+ case 192:
+ Line = i18n( "Isolated pawn" );
+ break;
+ case 193:
+ Line = i18n( "Connected pawns" );
+ break;
+ case 194:
+ Line = i18n( "Hanging pawns" );
+ break;
+ case 195:
+ Line = i18n( "Backwards pawn" );
+ break;
+ default:
+ Line = "";
+ break;
+ }
+ return Line;
+}
+
diff --git a/knights/pgn.desktop b/knights/pgn.desktop
new file mode 100644
index 0000000..5ccbce1
--- /dev/null
+++ b/knights/pgn.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Type=MimeType
+MimeType=application/x-chess-pgn
+Icon=pgn.png
+Comment=Portable Game Notation
+X-KDE-AutoEmbed=false
+Patterns=*.pgn *.PGN
+Name=Chess Match
+
+
+
diff --git a/knights/pgn.h b/knights/pgn.h
new file mode 100644
index 0000000..eeff9d8
--- /dev/null
+++ b/knights/pgn.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ pgn.h - description
+ -------------------
+ begin : Mon Jul 30 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PGN_H
+#define PGN_H
+
+#include <klocale.h>
+#include <ktempfile.h>
+#include <kio/netaccess.h>
+#include <qobject.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qpainter.h>
+#include "definitions.h"
+#include "resource.h"
+#include "knightsmap.h"
+#include "match_param.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+typedef struct Annotation
+{
+ int RAV;
+ QString text;
+};
+
+typedef QValueList<ChessMove> MoveList;
+typedef KnightsMap<int, Annotation*> Annotations;
+
+class tab_pgnView;
+
+class pgn : public QObject
+{
+ Q_OBJECT
+ public:
+ /* Standard PGN Tags */
+ QString TAG_Event;
+ QString TAG_Site;
+ QString TAG_Date;
+ QString TAG_Round;
+ QString TAG_White;
+ QString TAG_Black;
+ QString TAG_Result;
+ QString TAG_EventDate;
+ QString TAG_EventSponsor;
+ QString TAG_Section;
+ QString TAG_Stage;
+ QString TAG_Board;
+ QString TAG_WhiteTitle;
+ QString TAG_WhiteElo;
+ QString TAG_WhiteUSCF;
+ QString TAG_WhiteNA;
+ QString TAG_WhiteType;
+ QString TAG_BlackTitle;
+ QString TAG_BlackElo;
+ QString TAG_BlackUSCF;
+ QString TAG_BlackNA;
+ QString TAG_BlackType;
+ QString TAG_Opening;
+ QString TAG_Variation;
+ QString TAG_SubVariation;
+ QString TAG_ECO;
+ QString TAG_NIC;
+ QString TAG_Time;
+ QString TAG_UTCTime;
+ QString TAG_UTCDate;
+ QString TAG_TimeControl;
+ QString TAG_SetUp;
+ QString TAG_FEN;
+ QString TAG_Termination;
+ QString TAG_Annotator;
+ QString TAG_Mode;
+ QString TAG_PlyCount;
+
+ int File_Position; // Used to scan PGN file
+ QStringList Move_Data;
+
+ /* The match_param */
+ match_param *Param;
+
+ /* These are used in unfinished save games */
+ int whiteTime;
+ int blackTime;
+ TCPList whiteTCP;
+ TCPList blackTCP;
+
+ QString CurrentURL;
+ MoveList Moves;
+ Annotations RAV;
+ Annotations annotations;
+ QStringList Positions;
+ unsigned int currentIndex;
+
+ pgn( resource *Rsrc=0, match_param *param=NULL );
+ ~pgn();
+ void clear( void );
+ void init( void );
+ int scan( void );
+ bool load( const int pos=0 );
+ bool save( QString URL );
+ bool open( const QString& URL );
+ void print( void );
+ QStringList* notation( const int format=1 );
+ void close( void );
+ static QString getNAG( int num );
+ QString caption( void );
+
+ signals:
+ void processMove( ChessMove );
+ void processSpecial( void );
+
+ public slots:
+ bool loadNext( void );
+ void parseMatchParam( void );
+ void childViewDestroyed( void );
+
+ private:
+ resource *Resource;
+ tab_pgnView *pgnView;
+ QString tempFile;
+ QString currentLine;
+ QFile File;
+ QTextStream Input;
+
+ QChar getch( void );
+ QString getword( void );
+ void clearTags( void );
+ void parseTag( void );
+ void parseAnnotation( const int fromRAVnum=0 );
+ void parseRAV( void );
+ void parseKnightsData( void );
+};
+
+#endif
diff --git a/knights/proto_base.cpp b/knights/proto_base.cpp
new file mode 100644
index 0000000..c7e64fc
--- /dev/null
+++ b/knights/proto_base.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ proto_base.cpp - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "proto_base.moc"
+
+proto_base::proto_base( const int ID ) : QObject()
+{
+ myID = ID;
+}
+proto_base::~proto_base()
+{
+}
+void proto_base::setID( const int ID )
+{
+ myID = ID;
+}
+int proto_base::getID()
+{
+ return myID;
+}
diff --git a/knights/proto_base.h b/knights/proto_base.h
new file mode 100644
index 0000000..43113c6
--- /dev/null
+++ b/knights/proto_base.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ proto_base.h - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROTO_BASE_H
+#define PROTO_BASE_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+#include "command.h"
+#include "definitions.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+typedef QValueList<Command> CommandList;
+
+class proto_base : public QObject
+{
+ Q_OBJECT
+ public:
+ proto_base( const int ID );
+ virtual ~proto_base();
+ int getID( void );
+ void setID( const int ID );
+
+ public slots:
+ virtual void parse( const Command& ) = 0;
+ virtual void parse( const QString& ) = 0;
+
+ signals:
+ void output( const QString& );
+ void output( const Command& );
+
+ protected:
+ int myID;
+ ChessMove myMove;
+};
+
+#endif
diff --git a/knights/proto_uci.cpp b/knights/proto_uci.cpp
new file mode 100644
index 0000000..d277326
--- /dev/null
+++ b/knights/proto_uci.cpp
@@ -0,0 +1,218 @@
+/***************************************************************************
+ proto_uci.cpp - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qstringlist.h>
+#include <qregexp.h>
+
+#include "proto_uci.moc"
+#include "definitions.h"
+
+proto_uci::proto_uci( const int ID ) : proto_base( ID )
+{
+ hintMode = FALSE;
+ initMode = FALSE;
+ JustMoved = FALSE;
+ myArmy = BLACK;
+ Turn = WHITE;
+ CMDList = new CommandList;
+}
+proto_uci::~proto_uci()
+{
+ delete CMDList;
+}
+///////////////////////////////////////
+//
+// proto_uci::parse( const Command &command )
+//
+///////////////////////////////////////
+void proto_uci::parse( const Command &command )
+{
+ Command cmd = command;
+
+ if( initMode )
+ {
+ CMDList->append( command );
+ return;
+ }
+
+ switch( cmd.getCommand() )
+ {
+ /* Command: Init */
+ case CMD_Init:
+ emit output( "uci" );
+ initMode = TRUE;
+ break;
+
+ /* Command: New Game */
+ case CMD_NewGame:
+ emit output( "isready" );
+ break;
+
+ /* Command: Exit */
+ case CMD_Exit:
+ emit output( "quit" );
+ break;
+
+ /* Command: Move */
+ case CMD_Move:
+ if( JustMoved )
+ {
+ JustMoved = FALSE;
+ break;
+ }
+ if( FEN.isEmpty() )
+ {
+ emit output( QString("position startpos moves %1").arg( cmd.getData() ) );
+ }
+ else
+ {
+ emit output( QString("position fen %1 moves %2").arg( FEN ).arg( cmd.getData() ) );
+ }
+ emit output( QString("go wtime %1 btime %2 depth %3").arg( cmd.getWhiteTime() ).arg( cmd.getBlackTime() ).arg( difficulty ) );
+ break;
+
+ /* Command: Set Difficulty */
+ case CMD_Set_Difficulty:
+ difficulty = cmd.getData();
+ break;
+
+ /* Command: Set Board */
+ case CMD_Set_Board:
+ FEN = cmd.getData();
+ break;
+
+ /* Command: Move Now */
+ case CMD_MoveNow:
+ emit output( "stop" );
+ break;
+
+ /* Command: UCI Hint */
+ case CMD_UCI_Hint:
+ hintMode = TRUE;
+ if( FEN.isEmpty() )
+ {
+ emit output( QString("position startpos moves %1").arg( cmd.getData() ) );
+ }
+ else
+ {
+ emit output( QString("position fen %1 moves %2").arg( FEN ).arg( cmd.getData() ) );
+ }
+ emit output( QString("go wtime %1 btime %2 depth %3").arg( cmd.getWhiteTime() ).arg( cmd.getBlackTime() ).arg( difficulty ) );
+ break;
+
+ /* Command: Play White */
+ case CMD_Play_White:
+ myArmy = WHITE;
+ break;
+
+ /* Command: Play Black */
+ case CMD_Play_Black:
+ myArmy = BLACK;
+ break;
+
+ /* Command: Set Name */
+ case CMD_Set_Name:
+ engineName = cmd.getData();
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// proto_uci::parse( const QString &string )
+//
+///////////////////////////////////////
+void proto_uci::parse( const QString &string )
+{
+ QString strIn = string;
+ QStringList strList( QStringList::split( ' ', strIn ) );
+
+ /* Bestmove */
+ if( strList[0] == "bestmove" )
+ {
+ if( strList.count() < 2 )
+ {
+ kdWarning() << "proto_uci::parse: Incomplete Bestmove command" << endl;
+ return;
+ }
+ Command::clearMove( &myMove );
+ strcpy( myMove.CAN, strList[1].latin1() );
+ if( hintMode )
+ {
+ /* The Engine Gives a Hint */
+ hintMode = FALSE;
+// emit output( Command( myID, CMD_Hint, i18n( "%1 suggests this move:\n%2" ).arg( engineName ).arg( strList[1] ) ) );
+ emit output( Command( myID, CMD_Hint, QString( "%1 suggests this move:\n%2" ).arg( engineName ).arg( strList[1] ) ) );
+ }
+ else
+ {
+ /* The Engine Moves */
+ JustMoved = TRUE;
+ emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
+ }
+ }
+
+ /* UCIOK */
+ if( strList[0] == "uciok" )
+ {
+ initMode = FALSE;
+ releaseBuffer();
+ }
+
+ /* READYOK */
+ if( strList[0] == "readyok" )
+ {
+ initMode = FALSE;
+ releaseBuffer();
+ }
+
+ /* ID */
+ if( strList[0] == "id" )
+ {
+ if( strList[1] == "name" )
+ {
+ engineName = strIn.right( strIn.length() - 8 );
+ }
+ if( strList[1] == "author" )
+ {
+ engineAuthor = strIn.right( strIn.length() - 10 );
+ }
+ }
+
+ /* COPYPROTECTION */
+ if( strList[0] == "copyprotection" )
+ {
+ if( strList[1] == "error" )
+ {
+// emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 did not pass it's copy protection check." ).arg( engineName ) ) );
+ emit output( Command( myID, CMD_Tell_User_Error, QString( "%1 did not pass it's copy protection check." ).arg( engineName ) ) );
+ }
+ }
+}
+///////////////////////////////////////
+//
+// proto_uci::releaseBuffer
+//
+///////////////////////////////////////
+void proto_uci::releaseBuffer( void )
+{
+ CommandList::Iterator it;
+ for( it = CMDList->begin(); it != CMDList->end(); it++ )
+ {
+ parse( *it );
+ }
+ CMDList->clear();
+}
diff --git a/knights/proto_uci.h b/knights/proto_uci.h
new file mode 100644
index 0000000..23a27b3
--- /dev/null
+++ b/knights/proto_uci.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ proto_uci.h - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROTO_UCI_H
+#define PROTO_UCI_H
+
+#include <qvaluelist.h>
+#include "proto_base.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class proto_uci : public proto_base
+{
+ Q_OBJECT
+ public:
+ proto_uci( const int ID );
+ ~proto_uci();
+
+ virtual void parse( const Command& );
+ virtual void parse( const QString& );
+
+ protected slots:
+ void releaseBuffer( void );
+
+ private:
+ QString engineName;
+ QString engineAuthor;
+ QString difficulty;
+ QString FEN;
+
+ CommandList *CMDList;
+ bool hintMode;
+ bool initMode;
+ bool JustMoved;
+ bool myArmy;
+ bool Turn;
+};
+
+#endif
diff --git a/knights/proto_xboard.cpp b/knights/proto_xboard.cpp
new file mode 100644
index 0000000..8b68bb0
--- /dev/null
+++ b/knights/proto_xboard.cpp
@@ -0,0 +1,687 @@
+/***************************************************************************
+ proto_xboard.cpp - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <klocale.h>
+#include <qtimer.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+
+#include "proto_xboard.moc"
+#include "definitions.h"
+
+proto_xboard::proto_xboard( const int ID ) : proto_base( ID )
+{
+ FEATURE_Analyze = TRUE;
+ FEATURE_Colors = TRUE;
+ FEATURE_Draw = TRUE;
+ FEATURE_ICS = FALSE;
+ FEATURE_Name = TRUE;
+ FEATURE_Pause = FALSE;
+ FEATURE_Ping = FALSE;
+ FEATURE_PlayOther = FALSE;
+ FEATURE_Reuse = TRUE;
+ FEATURE_SetBoard = FALSE;
+ FEATURE_SAN = FALSE;
+ FEATURE_SIGINT = TRUE;
+ FEATURE_SIGTERM = TRUE;
+ FEATURE_Time = TRUE;
+ FEATURE_UserMove = FALSE;
+ FEATURE_Variants = 0;
+ FEATURE_Level = 1;
+ FEATURE_BookEngine = 0;
+
+ CMDList = new CommandList;
+ InitTimer = new QTimer( this );
+ connect( InitTimer, SIGNAL( timeout() ), this, SLOT( releaseBuffer() ) );
+
+ Check = TRUE;
+ Team = FALSE;
+ JustMoved = FALSE;
+ AcceptIllegal = FALSE;
+ DelayedGo = FALSE;
+ Forced = TRUE;
+ Turn = WHITE;
+}
+proto_xboard::~proto_xboard()
+{
+ delete InitTimer;
+ delete CMDList;
+}
+///////////////////////////////////////
+//
+// proto_xboard::parse( const Command &command )
+//
+///////////////////////////////////////
+void proto_xboard::parse( const Command &command )
+{
+ QString temp;
+ Command cmd = command;
+
+ if( InitTimer->isActive() )
+ {
+ /*
+ Store Command for later use..
+ we're still waiting for the engine to finish
+ */
+ CMDList->append( command );
+ return;
+ }
+
+ switch( cmd.getCommand() )
+ {
+ /* Command: Init */
+ case CMD_Init:
+ emit output( "xboard\nprotover 3" );
+ InitTimer->start( 2000, TRUE );
+ break;
+
+ /* Command: New Game */
+ case CMD_NewGame:
+ emit output( "new\nrandom" );
+ break;
+
+ /* Command: Exit */
+ case CMD_Exit:
+ emit output( "quit" );
+ if( FEATURE_SIGTERM )
+ emit output( Command( myID, CMD_Send_SIGTERM ) );
+ break;
+
+ /* Command: Move Now */
+ case CMD_MoveNow:
+ emit output( "?" );
+ break;
+
+ /* Command: Move */
+ case CMD_Move:
+ if( JustMoved )
+ {
+ JustMoved = FALSE;
+ break;
+ }
+ AcceptIllegal = TRUE;
+ myMove = cmd.getMove();
+ /* Send Time */
+ if( FEATURE_Time )
+ {
+ if( Army == WHITE )
+ {
+ emit output( QString( "time %1" ).arg( cmd.getWhiteTime() ) );
+ emit output( QString( "otim %1" ).arg( cmd.getBlackTime() ) );
+ }
+ else
+ {
+ emit output( QString( "time %1" ).arg( cmd.getBlackTime() ) );
+ emit output( QString( "otim %1" ).arg( cmd.getWhiteTime() ) );
+ }
+ }
+ if( FEATURE_UserMove )
+ temp = "usermove ";
+ if( FEATURE_SAN )
+ temp += myMove.SAN;
+ else
+ temp += myMove.CAN;
+ if( DelayedGo )
+ {
+ DelayedGo = FALSE;
+ temp += "\ngo";
+ Forced = FALSE;
+ }
+ emit output( temp );
+ break;
+
+ /* Command: Pause */
+ case CMD_Pause:
+ if( FEATURE_Pause )
+ emit output( "pause" );
+ else
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ }
+ break;
+
+ /* Command: Resume */
+ case CMD_Resume:
+ if( FEATURE_Pause )
+ emit output( "resume" );
+ else
+ {
+ if( Turn == Army )
+ {
+ emit output( "go" );
+ Forced = FALSE;
+ }
+ else
+ DelayedGo = TRUE;
+ }
+ break;
+
+ /* Command: Play White */
+ case CMD_Play_White:
+ Army = WHITE;
+ if( Turn == BLACK )
+ {
+ if( FEATURE_PlayOther )
+ {
+ emit output( "playother" );
+ }
+ else if( FEATURE_Colors )
+ {
+ emit output( "black" );
+ }
+ else
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ DelayedGo = TRUE;
+ }
+ break;
+ }
+ else
+ {
+ temp = "force";
+ if( FEATURE_Colors )
+ temp += "\nwhite";
+ temp += "\ngo";
+ emit output( temp );
+ break;
+ }
+ break;
+
+ /* Command: Play Black */
+ case CMD_Play_Black:
+ Army = BLACK;
+ if( Turn == WHITE )
+ {
+ if( FEATURE_PlayOther )
+ {
+ emit output( "playother" );
+ }
+ else if( FEATURE_Colors )
+ {
+ emit output( "white" );
+ }
+ else
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ DelayedGo = TRUE;
+ }
+ break;
+ }
+ else
+ {
+ temp = "force";
+ if( FEATURE_Colors )
+ temp += "\nblack";
+ temp += "\ngo";
+ emit output( temp );
+ break;
+ }
+ break;
+
+ /* Command: Result White */
+ case CMD_Result_White:
+ emit output( "result 1-0 {White Mates}" );
+ AcceptIllegal = FALSE;
+// if( Army == WHITE )
+// (*IT).Wins++;
+// else
+// (*IT).Losses++;
+ break;
+
+ /* Command: Result Black */
+ case CMD_Result_Black:
+ emit output( "result 0-1 {Black Mates}" );
+ AcceptIllegal = FALSE;
+// if( Army == BLACK )
+// (*IT).Wins++;
+// else
+// (*IT).Losses++;
+ break;
+
+ /* Command: Result Draw */
+ case CMD_Result_Draw:
+ emit output( "result 1/2-1/2 {Draw Game}" );
+ AcceptIllegal = FALSE;
+// (*IT).Draws++;
+ break;
+
+ /* Command: Your Time */
+ case CMD_Your_Time:
+ if( FEATURE_Time )
+ {
+ if( Army == WHITE )
+ emit output( QString( "time %1" ).arg( cmd.getWhiteTime() ) );
+ else
+ emit output( QString( "time %1" ).arg( cmd.getBlackTime() ) );
+ }
+ break;
+
+ /* Command: Enemy Time */
+ case CMD_Enemy_Time:
+ if( FEATURE_Time )
+ {
+ if( Army == WHITE )
+ emit output( QString( "otim %1" ).arg( cmd.getBlackTime() ) );
+ else
+ emit output( QString( "otim %1" ).arg( cmd.getWhiteTime() ) );
+ }
+ break;
+
+ /* Command: Offer Draw */
+ case CMD_Offer_Draw:
+ if( FEATURE_Draw )
+ emit output( "draw" );
+ break;
+
+ /* Command: Book Mode */
+ case CMD_Book_Mode:
+ if( FEATURE_BookEngine != 0 )
+ emit output( "bookengine" );
+ break;
+
+ /* Command: Check Book */
+ case CMD_Check_Book:
+ emit output( "go" );
+ Forced = FALSE;
+ break;
+
+ /* Command: Ponder */
+ case CMD_Ponder:
+ emit output( "hard" );
+ break;
+
+ /* Command: No Pondering */
+ case CMD_No_Pondering:
+ emit output( "hard\neasy" );
+ break;
+
+ /* Command: Retract Move */
+ case CMD_Retract_Move:
+ emit output( "remove" );
+ break;
+
+ /* Command: Hint */
+ case CMD_Hint:
+ emit output( "hint" );
+ break;
+
+ /* Command: Listen */
+ case CMD_Listen:
+ emit output( "force" );
+ Forced = TRUE;
+ DelayedGo = FALSE;
+ break;
+
+ /* Command: Play */
+ case CMD_Play:
+ if( Army == Turn )
+ {
+ emit output( "go" );
+ Forced = FALSE;
+ }
+ else
+ DelayedGo = TRUE;
+ break;
+
+ /* Command: White Resign */
+ case CMD_White_Resign:
+ parse( Command( 0, CMD_Result_White ) );
+ break;
+
+ /* Command: Black Resign */
+ case CMD_Black_Resign:
+ parse( Command( 0, CMD_Result_Black ) );
+ break;
+
+ /* Command: Set Board */
+ case CMD_Set_Board:
+ if( FEATURE_SetBoard == TRUE )
+ {
+ emit output( QString( "setboard %1" ).arg( cmd.getData() ) );
+ }
+ else
+ {
+ // Convert FEN to edit commands here and feed them to engine
+ }
+ break;
+
+ /* Command: Set Difficulty */
+ case CMD_Set_Difficulty:
+ emit output( "sd " + cmd.getData() );
+ // emit output( "st " + QString::number( cmd.getData().toInt() >> 1 ) );
+ break;
+
+ /* Command: Set Name */
+ case CMD_Set_Name:
+ FEATURE_MyName = cmd.getData();
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// proto_xboard::parse( const QString &string )
+//
+///////////////////////////////////////
+void proto_xboard::parse( const QString &string )
+{
+ QString strIn = string;
+ QStringList strList( QStringList::split( ' ', strIn ) );
+
+ if( ( FEATURE_SIGINT ) && ( !Forced ) )
+ emit output( Command( myID, CMD_Send_SIGINT ) );
+
+ /* Illegal */
+ if( strList[0].contains( "illegal", FALSE ) )
+ {
+ if( AcceptIllegal )
+ {
+ if( strIn.contains("(no matching move)board") )
+ return;
+ if( strIn.contains("(no matching move)protover") )
+ return;
+ if( strIn.contains("(no matching move)sd") )
+ return;
+ AcceptIllegal = FALSE;
+ emit output( Command( myID, CMD_Illegal ) );
+ }
+ return;
+ }
+
+ /* A Move */
+ if( strList[0] == "move" )
+ {
+ if( strList.count() < 2 )
+ {
+ kdWarning() << "proto_xboard::parse: Incomplete Move command" << endl;
+ return;
+ }
+ Command::clearMove( &myMove );
+ strcpy( myMove.SAN, strList[1].latin1() );
+ strcpy( myMove.CAN, strList[1].latin1() );
+ if( Team )
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ }
+ JustMoved = TRUE;
+ emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
+ return;
+ }
+
+ /* A Move ( Old Variation ) */
+ if( ( strList[0].contains( QRegExp("\\d+\\.") ) ) && ( strList[1] == "..." ) )
+ {
+ Command::clearMove( &myMove );
+ strcpy( myMove.SAN, strList[2].latin1() );
+ strcpy( myMove.CAN, strList[2].latin1() );
+ if( Team )
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ }
+ JustMoved = TRUE;
+ emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
+ return;
+ }
+
+ /* Hint */
+ if( strList[0] == "Hint:" )
+ {
+ emit output( Command( myID, CMD_Hint, i18n( "%1 suggests this move:\n%2" ).arg( FEATURE_MyName ).arg( strList[1] ) ) );
+ return;
+ }
+
+ /* Offer Draw */
+ if( ( strList[0] == "offer" ) && ( strList[1] == "draw" ) )
+ {
+ emit output( Command( myID, CMD_Offer_Draw ) );
+ }
+
+ /* Out of Book */
+ if( strList[0] == "outofbook" )
+ {
+ emit output( "force" );
+ Forced = TRUE;
+ emit output( Command( myID, CMD_Out_Of_Book ) );
+ return;
+ }
+
+ /* Tell User */
+ if( strList[0] == "telluser" )
+ {
+ emit output( Command( myID, CMD_Tell_User, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() - 9 ) ) ) );
+ return;
+ }
+
+ /* Tell User Error */
+ if( strList[0] == "tellusererror" )
+ {
+ emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() - 14 ) ) ) );
+ return;
+ }
+
+ /* Error */
+ if( strList[0] == "Error" )
+ {
+ emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() ) ) ) );
+ return;
+ }
+
+ /* Tell Opponent */
+ if( strList[0] == "tellopponent" )
+ {
+ emit output( Command( myID, CMD_Tell_Opponent, QString( "%1" ).arg( strIn.right( strIn.length() - 13 ) ) ) );
+ return;
+ }
+
+ /* Tell Others */
+ if( strList[0] == "tellothers" )
+ {
+ emit output( Command( myID, CMD_Tell_Others, QString( "%1" ).arg( strIn.right( strIn.length() - 11 ) ) ) );
+ return;
+ }
+
+ /* Tell All */
+ if( strList[0] == "tellall" )
+ {
+ emit output( Command( myID, CMD_Tell_All, QString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
+ return;
+ }
+
+ /* Tell ICS */
+ if( strList[0] == "tellics" )
+ {
+ emit output( Command( myID, CMD_Tell_ICS, QString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
+ return;
+ }
+
+ /* Tell ICS No Alias */
+ if( strList[0] == "tellicsnoalias" )
+ {
+ emit output( Command( myID, CMD_Tell_ICS, QString( "%1" ).arg( strIn.right( strIn.length() - 15 ) ) ) );
+ return;
+ }
+
+ /* Resign */
+ if( strIn.contains( "resign", FALSE ) )
+ {
+ if( Army == WHITE )
+ emit output( Command( myID, CMD_White_Resign ) );
+ else
+ emit output( Command( myID, CMD_Black_Resign ) );
+ return;
+ }
+
+ /*
+ Parse Features
+ */
+ if( !InitTimer->isActive() )
+ return;
+ for( unsigned int loop = 0; loop < strList.count(); loop++ )
+ {
+ if( strList[loop] == "done=1" )
+ {
+ InitTimer->stop();
+ releaseBuffer();
+ continue;
+ }
+ /* This buys you 10 minutes */
+ if( strList[loop] == "done=0" )
+ {
+ InitTimer->changeInterval( 600000 );
+ continue;
+ }
+ if( strList[loop] == "feature" )
+ {
+ continue;
+ }
+ if( strList[loop].left(3) == "ics" )
+ {
+ FEATURE_ICS = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted ics" );
+ continue;
+ }
+ if( strList[loop].left(3) == "san" )
+ {
+ FEATURE_SAN = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted san" );
+ continue;
+ }
+ if( strList[loop].left(4) == "draw" )
+ {
+ FEATURE_Draw = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted draw" );
+ continue;
+ }
+ if( strList[loop].left(4) == "name" )
+ {
+ FEATURE_Name = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted name" );
+ continue;
+ }
+ if( strList[loop].left(4) == "ping" )
+ {
+ FEATURE_Ping = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted ping" );
+ continue;
+ }
+ if( strList[loop].left(4) == "time" )
+ {
+ FEATURE_Time = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted time" );
+ continue;
+ }
+ if( strList[loop].left(5) == "level" )
+ {
+ FEATURE_Level = QString( strList[loop].right( strList[loop].length() - 6 ) ).toInt();
+ emit output( "accepted level" );
+ continue;
+ }
+ if( strList[loop].left(5) == "pause" )
+ {
+ FEATURE_Pause = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted pause" );
+ continue;
+ }
+ if( strList[loop].left(5) == "reuse" )
+ {
+ FEATURE_Reuse = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted reuse" );
+ continue;
+ }
+ if( strList[loop].left(6) == "colors" )
+ {
+ FEATURE_Colors = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted colors" );
+ continue;
+ }
+ if( strList[loop].left(6) == "myname" )
+ {
+ FEATURE_MyName = QString( strList[loop].right( strList[loop].length() - 8 ) );
+ emit output( "accepted myname" );
+ continue;
+ }
+ if( strList[loop].left(6) == "sigint" )
+ {
+ FEATURE_SIGINT = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted sigint" );
+ continue;
+ }
+ if( strList[loop].left(7) == "analyze" )
+ {
+ FEATURE_Analyze = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted analyze" );
+ continue;
+ }
+ if( strList[loop].left(7) == "sigterm" )
+ {
+ FEATURE_SIGTERM = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted sigterm" );
+ continue;
+ }
+ if( strList[loop].left(8) == "setboard" )
+ {
+ FEATURE_SetBoard = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted setboard" );
+ continue;
+ }
+ if( strList[loop].left(8) == "usermove" )
+ {
+ FEATURE_UserMove = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted usermove" );
+ continue;
+ }
+ if( strList[loop].left(8) == "variants" )
+ {
+// FIFO_Tmp = strList[loop].right( strList[loop].length() - 10 );
+ // This must be finished
+ emit output( "accepted variants" );
+ continue;
+ }
+ if( strList[loop].left(9) == "playother" )
+ {
+ FEATURE_PlayOther = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted playother" );
+ continue;
+ }
+ if( strList[loop].left(10) == "bookengine" )
+ {
+ FEATURE_BookEngine = QString( strList[loop].right( strList[loop].length() - 11 ) ).toInt();
+ emit output( "accepted bookengine" );
+ continue;
+ }
+ }
+}
+///////////////////////////////////////
+//
+// proto_xboard::releaseBuffer
+//
+///////////////////////////////////////
+void proto_xboard::releaseBuffer( void )
+{
+ CommandList::Iterator it;
+ for( it = CMDList->begin(); it != CMDList->end(); it++ )
+ {
+ parse( *it );
+ }
+ CMDList->clear();
+}
diff --git a/knights/proto_xboard.h b/knights/proto_xboard.h
new file mode 100644
index 0000000..0b07109
--- /dev/null
+++ b/knights/proto_xboard.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ proto_xboard.h - description
+ -------------------
+ begin : Sat Oct 26 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROTO_XBOARD_H
+#define PROTO_XBOARD_H
+
+#include "proto_base.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class QTimer;
+
+class proto_xboard : public proto_base
+{
+ Q_OBJECT
+ public:
+ proto_xboard( const int ID );
+ ~proto_xboard();
+
+ virtual void parse( const Command& );
+ virtual void parse( const QString& );
+
+ protected slots:
+ void releaseBuffer( void );
+
+ private:
+
+ /* XBoard protover 2 */
+ bool FEATURE_Analyze;
+ bool FEATURE_Colors;
+ bool FEATURE_Draw;
+ bool FEATURE_ICS;
+ bool FEATURE_Name;
+ bool FEATURE_Pause;
+ bool FEATURE_Ping;
+ bool FEATURE_PlayOther;
+ bool FEATURE_Reuse;
+ bool FEATURE_SetBoard;
+ bool FEATURE_SAN;
+ bool FEATURE_SIGINT;
+ bool FEATURE_SIGTERM;
+ bool FEATURE_Time;
+ bool FEATURE_UserMove;
+ int FEATURE_Variants;
+ QString FEATURE_MyName;
+ /* XBoard protover 3 */
+ int FEATURE_Level;
+ int FEATURE_BookEngine;
+
+ bool Check;
+ bool Turn;
+ bool Team;
+ bool Army;
+ bool JustMoved;
+ bool AcceptIllegal;
+ bool DelayedGo;
+ bool Forced;
+ QTimer *InitTimer;
+ CommandList *CMDList;
+};
+
+#endif
diff --git a/knights/resource.cpp b/knights/resource.cpp
new file mode 100644
index 0000000..ba172b9
--- /dev/null
+++ b/knights/resource.cpp
@@ -0,0 +1,1048 @@
+/***************************************************************************
+ resource.cpp - description
+ -------------------
+ begin : Tue Jul 17 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/* KDE */
+#include <kstddirs.h>
+#include <kglobalsettings.h>
+#include <ksimpleconfig.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kmdcodec.h>
+#include <kio/netaccess.h>
+/* Qt */
+#include <qdir.h>
+#include <qimage.h>
+/* Local */
+#include "resource.h"
+#include "audio.h"
+#include "knightspixcache.h"
+#include "tabmanager.h"
+#include "accel.h"
+/* C & C++ */
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <time.h>
+
+#define CFG kapp->config()
+///////////////////////////////////////
+//
+// resource::resource
+//
+///////////////////////////////////////
+resource::resource(KCmdLineArgs *args)
+{
+ GlobalDataDir = "";
+ Widget_Height = 20; // prevents max_size error for thinbuttons on init
+ Icons = new KIconLoader( QString( "knights" ) );
+ Audio = new audio();
+
+ /* Define ConsoleStyle, our RichText */
+ ConsoleStyle = new QStyleSheet( 0, "ConsoleStyle" );
+ SSI_Default = new QStyleSheetItem( ConsoleStyle, "K_STD" );
+ SSI_PrivateTell = new QStyleSheetItem( ConsoleStyle, "K_PVT" );
+ SSI_ChannelTell = new QStyleSheetItem( ConsoleStyle, "K_CH" );
+ SSI_Shout = new QStyleSheetItem( ConsoleStyle, "K_SHT" );
+ SSI_Whisper = new QStyleSheetItem( ConsoleStyle, "K_WSP" );
+ SSI_Notification = new QStyleSheetItem( ConsoleStyle, "K_NOT" );
+ QStyleSheet::setDefaultSheet( ConsoleStyle );
+
+ /* Define GlobalDataDir... This is very important! */
+ GlobalDataDir = args->getOption( "d" );
+ if( GlobalDataDir.isEmpty() )
+ GlobalDataDir = KGlobal::dirs()->findResourceDir("data", "knights/splash.png") + "knights/";
+ if( GlobalDataDir.isEmpty() )
+ {
+ kdWarning() << "resource::resource: Can not read GlobalDataDir from environment." << endl;
+ GlobalDataDir = "/usr/local/kde/";
+ }
+ if( GlobalDataDir.right(1) != "/" ) GlobalDataDir += '/';
+
+ /* Allocate Accel */
+ myAccel = new Accel( qApp->mainWidget() );
+
+ /* Allocate TabManager */
+ tabManager = new TabManager( this );
+
+ ConfigRead();
+ pixCache = new KnightsPixCache();
+ pixCache->setCacheLimit( 2048 ); // 2meg
+}
+///////////////////////////////////////
+//
+// resource::~resource
+//
+///////////////////////////////////////
+resource::~resource()
+{
+ ConfigWrite();
+ delete Icons;
+ delete pixCache;
+ delete Audio;
+ delete tabManager;
+ delete myAccel;
+
+ /* Remove temp files that we missed
+ QStringList temps = KGlobal::dirs()->findAllResources("tmp","knights*");
+ for( int a=0; a < temps.count(); a++)
+ {
+ KIO::NetAccess::del( "file://" + temps[a] );
+ } */
+}
+///////////////////////////////////////
+//
+// resource::ConfigRead
+//
+///////////////////////////////////////
+void resource::ConfigRead( void )
+{
+ struct passwd *passwd;
+ QString sysName;
+ QString buffer;
+ QDesktopWidget *desktop = QApplication::desktop();
+
+ /* Get Initial Board Size In Case This Install Is New */
+ int initSize = ( desktop->height() >> 3 ) - 32;
+ if( initSize > IMAGE_MAX )
+ initSize = IMAGE_MAX;
+ if( initSize < IMAGE_MIN )
+ initSize = IMAGE_MIN;
+
+ /* Get user name from environment in case it's needed */
+ passwd = getpwuid( getuid() );
+ sysName = passwd->pw_gecos;
+ if( sysName.isEmpty() )
+ sysName = QStringList::split( ",", QString(passwd->pw_name) ).first();
+
+ /* Cursors */
+ CURSOR_Standard = KCursor::arrowCursor();
+ CURSOR_Thinking = KCursor::waitCursor();
+ CURSOR_Text = KCursor::ibeamCursor();
+
+ /* Themes */
+ readThemeDir();
+ CFG->setGroup( "Themes" );
+ CurrentBoard = CFG->readEntry( "CurrentBoard", "KBDefault.tar.gz" );
+ CurrentChessmen = CFG->readEntry( "CurrentChessmen", "KCDefault.tar.gz" );
+ OPTION_3DBoard = CFG->readBoolEntry( "Use3DBoard", FALSE );
+ ThemeSize = CFG->readNumEntry( "Size", initSize );
+ if( ThemeSize > ( initSize + 16 ) )
+ ThemeSize = initSize;
+
+ /* General */
+ ReadEngines();
+ ReadServers();
+ ReadMatchParam();
+ ReadColors();
+ ReadFonts();
+ buildStyle();
+ CFG->setGroup( "General" );
+ Local_Player = CFG->readEntry( "UserName", sysName );
+ Config_Version = CFG->readNumEntry( "ConfigVersion", 0 );
+ OPTION_On_Init = CFG->readNumEntry( "OnInit", MENU_VS_PC );
+ OPTION_Auto_Queen = CFG->readBoolEntry( "AlwaysQueen", FALSE );
+ OPTION_Ponder = CFG->readBoolEntry( "Ponder", TRUE );
+ OPTION_Book_White = CFG->readBoolEntry( "BookWhite", FALSE );
+ OPTION_Book_Black = CFG->readBoolEntry( "BookBlack", FALSE );
+ OPTION_Pause_On_Minimize = CFG->readBoolEntry( "PauseOnMinimize", TRUE );
+ OPTION_Reuse_PGN = CFG->readBoolEntry( "ReusePGN", FALSE );
+ PGN_Filename = CFG->readEntry( "PGNFilename", QString::null );
+ SCID_Image_Path = CFG->readEntry( "SCIDImages", QString::null );
+ OPTION_Auto_Close_Last_ICS = CFG->readBoolEntry( "AutoCloseLastICS", TRUE );
+ OPTION_Show_Extended_PGN = CFG->readEntry( "ShowExtendedPGN", FALSE );
+ OPTION_Auto_Call_Flag = CFG->readBoolEntry( "AutoCallFlag", TRUE );
+ Email_Command_Line = CFG->readEntry( "EmailCommandLine", QString("kmail -s %s --attach %m %a") );
+ Accepted_License = CFG->readBoolEntry( "Alg2p", FALSE );
+
+ /* Display */
+ OPTION_Show_Splash = CFG->readBoolEntry( "ShowSplash", TRUE );
+ OPTION_Auto_Preview = CFG->readBoolEntry( "AutoPreview", FALSE );
+ OPTION_Show_Last_Move = CFG->readBoolEntry( "ShowLastMove", TRUE );
+ OPTION_Animate_Moves = CFG->readBoolEntry( "AnimateMoves", FALSE );
+ OPTION_Show_Coord = CFG->readBoolEntry( "ShowCoord", FALSE );
+ OPTION_Board_Orientation = CFG->readBoolEntry( "BoardOrientation", 0 );
+
+ /* ICS */
+ CFG->setGroup( "ICS" );
+ OPTION_Premove = CFG->readBoolEntry( "Premove", TRUE );
+ OPTION_Kibitz = CFG->readBoolEntry( "Kibitz", TRUE );
+ OPTION_Private = CFG->readBoolEntry( "Private", FALSE );
+ OPTION_Shout = CFG->readBoolEntry( "Shout", TRUE );
+ OPTION_Tell = CFG->readBoolEntry( "Tell", TRUE );
+ OPTION_Seek = CFG->readBoolEntry( "Seek", TRUE );
+ OPTION_Profanity = CFG->readNumEntry( "Profanity", 1 );
+ Seek_Timer = CFG->readNumEntry( "SeekTimer", 70 );
+
+ /* Audio */
+ CFG->setGroup( "Audio" );
+ OPTION_Audio = CFG->readBoolEntry( "useAudio", TRUE );
+ CurrentAudio = CFG->readEntry( "CurrentAudio", "KSDefault.tar.gz" );
+ OPTION_Audio_Current_Only = CFG->readBoolEntry( "AudioCurrentOnly", FALSE );
+ Audio_Volume = CFG->readNumEntry( "AudioVolume", 0 );
+ Audio->enabled = OPTION_Audio;
+ Audio->volume = Audio_Volume;
+
+ /* Notification Prompts */
+ CFG->setGroup( "Notification Messages" );
+ PromptForSaving = CFG->readEntry( "PromptForSaving", QString::null );
+}
+///////////////////////////////////////
+//
+// resource::ConfigWrite
+//
+///////////////////////////////////////
+void resource::ConfigWrite( void )
+{
+ /* Themes */
+ CFG->setGroup( "Themes" );
+ CFG->writeEntry( "CurrentBoard", CurrentBoard );
+ CFG->writeEntry( "CurrentChessmen", CurrentChessmen );
+ CFG->writeEntry( "Size", ThemeSize );
+ CFG->writeEntry( "Use3DBoard", OPTION_3DBoard );
+
+ /* General */
+ WriteEngines();
+ WriteServers();
+ WriteMatchParam();
+ WriteColors();
+ WriteFonts();
+ CFG->setGroup( "General" );
+ CFG->writeEntry( "UserName", Local_Player );
+ CFG->writeEntry( "ConfigVersion", Config_Version );
+ CFG->writeEntry( "OnInit", OPTION_On_Init );
+ CFG->writeEntry( "ShowSplash", OPTION_Show_Splash );
+ CFG->writeEntry( "AlwaysQueen", OPTION_Auto_Queen );
+ CFG->writeEntry( "AutoPreview", OPTION_Auto_Preview );
+ CFG->writeEntry( "ShowLastMove", OPTION_Show_Last_Move );
+ CFG->writeEntry( "AnimateMoves", OPTION_Animate_Moves );
+ CFG->writeEntry( "ShowCoord", OPTION_Show_Coord );
+ CFG->writeEntry( "Ponder", OPTION_Ponder );
+ CFG->writeEntry( "BookWhite", OPTION_Book_White );
+ CFG->writeEntry( "BookBlack", OPTION_Book_Black );
+ CFG->writeEntry( "BoardOrientation", OPTION_Board_Orientation );
+ CFG->writeEntry( "PauseOnMinimize", OPTION_Pause_On_Minimize );
+ CFG->writeEntry( "ReusePGN", OPTION_Reuse_PGN );
+ CFG->writeEntry( "PGNFilename", PGN_Filename );
+ CFG->writeEntry( "AutoCloseLastICS", OPTION_Auto_Close_Last_ICS );
+ CFG->writeEntry( "ShowExtendedPGN", OPTION_Show_Extended_PGN );
+ CFG->writeEntry( "EmailCommandLine", Email_Command_Line );
+ CFG->writeEntry( "AutoCallFlag", OPTION_Auto_Call_Flag );
+ CFG->writeEntry( "SCIDImages", SCID_Image_Path );
+ CFG->writeEntry( "Alg2p", Accepted_License );
+
+ /* ICS */
+ CFG->setGroup( "ICS" );
+ CFG->writeEntry( "SeekTimer", Seek_Timer );
+ CFG->writeEntry( "Profanity", OPTION_Profanity );
+ CFG->writeEntry( "Premove", OPTION_Premove );
+ CFG->writeEntry( "Shout", OPTION_Shout );
+ CFG->writeEntry( "Kibitz", OPTION_Kibitz );
+ CFG->writeEntry( "Private", OPTION_Private );
+ CFG->writeEntry( "Tell", OPTION_Tell );
+ CFG->writeEntry( "Seek", OPTION_Seek );
+
+ /* Audio */
+ CFG->setGroup( "Audio" );
+ CFG->writeEntry( "useAudio", OPTION_Audio );
+ Audio->enabled = OPTION_Audio;
+ CFG->writeEntry( "CurrentAudio", CurrentAudio );
+ CFG->writeEntry( "AudioCurrentOnly", OPTION_Audio_Current_Only );
+ CFG->writeEntry( "AudioVolume", Audio_Volume );
+ Audio->volume = Audio_Volume;
+
+ /* Notification Prompts */
+ CFG->setGroup( "Notification Messages" );
+ CFG->writeEntry( "PromptForSaving", PromptForSaving );
+ CFG->setReadOnly( FALSE );
+ if( CFG->isReadOnly() )
+ kdWarning() << "resource::ConfigWrite: Configuration is READ ONLY. Can not write changes." << endl;
+ CFG->sync();
+}
+///////////////////////////////////////
+//
+// resource::ReadMatchParam
+//
+///////////////////////////////////////
+void resource::ReadMatchParam( void )
+{
+ QString buffer;
+ QStringList TCPs;
+ QStringList::Iterator QSL_IT;
+ TCP tempTCP;
+
+ TCPWhite.clear();
+ TCPBlack.clear();
+ CFG->setGroup( "Match Paramaters" );
+
+ /* Handle Time Controls */
+ buffer = CFG->readEntry( "WhiteTCP", "40,900,0" );
+ TCPs = QStringList::split( QString(","), buffer, FALSE );
+ for( QSL_IT = TCPs.begin(); QSL_IT != TCPs.end(); ++QSL_IT )
+ {
+ tempTCP.Moves = (*QSL_IT).toInt();
+ ++QSL_IT;
+ tempTCP.Seconds = (*QSL_IT).toInt();
+ ++QSL_IT;
+ tempTCP.Increment = (*QSL_IT).toInt();
+ TCPWhite.append( tempTCP );
+ }
+ TCPs.clear();
+ buffer = CFG->readEntry( "BlackTCP", "40,900,0" );
+ TCPs = QStringList::split( QString(","), buffer, FALSE );
+ for( QSL_IT = TCPs.begin(); QSL_IT != TCPs.end(); ++QSL_IT )
+ {
+ tempTCP.Moves = (*QSL_IT).toInt();
+ ++QSL_IT;
+ tempTCP.Seconds = (*QSL_IT).toInt();
+ ++QSL_IT;
+ tempTCP.Increment = (*QSL_IT).toInt();
+ TCPBlack.append( tempTCP );
+ }
+
+ /* Match Rules */
+ MatchRules = CFG->readNumEntry( "MatchRules", Type_Standard );
+
+ /* Handle Players */
+ Type[WHITE] = CFG->readNumEntry( "WhiteType", PLAYERLOCAL );
+ Type[WHITE_HELPER] = CFG->readNumEntry( "WhiteHelperType", PLAYERPC );
+ Type[BLACK] = CFG->readNumEntry( "BlackType", PLAYERLOCAL );
+ Type[BLACK_HELPER] = CFG->readNumEntry( "BlackHelperType", PLAYERPC );
+
+ Strength[WHITE] = CFG->readNumEntry( "WhiteStr", 18 );
+ Strength[WHITE_HELPER] = CFG->readNumEntry( "WhiteHelperStr", 18 );
+ Strength[BLACK] = CFG->readNumEntry( "BlackStr", 18 );
+ Strength[BLACK_HELPER] = CFG->readNumEntry( "BlackHelperStr", 18 );
+}
+///////////////////////////////////////
+//
+// resource::WriteMatchParam
+//
+///////////////////////////////////////
+void resource::WriteMatchParam( void )
+{
+ QString buffer;
+ TCPList::Iterator TCP_IT;
+
+ CFG->setGroup( "Match Paramaters" );
+ /* Handle Time Controls */
+ for( TCP_IT = TCPWhite.begin(); TCP_IT != TCPWhite.end(); ++TCP_IT )
+ {
+ buffer += QString::number( (*TCP_IT).Moves ) + ",";
+ buffer += QString::number( (*TCP_IT).Seconds ) + ",";
+ buffer += QString::number( (*TCP_IT).Increment ) + ",";
+ }
+ CFG->writeEntry( "WhiteTCP", buffer );
+ buffer = "";
+ for( TCP_IT = TCPBlack.begin(); TCP_IT != TCPBlack.end(); ++TCP_IT )
+ {
+ buffer += QString::number( (*TCP_IT).Moves ) + ",";
+ buffer += QString::number( (*TCP_IT).Seconds ) + ",";
+ buffer += QString::number( (*TCP_IT).Increment ) + ",";
+ }
+ CFG->writeEntry( "BlackTCP", buffer );
+ /* Match Rules */
+ CFG->writeEntry( "MatchRules", MatchRules );
+ /* Handle Players */
+ CFG->writeEntry( "WhiteType", Type[WHITE] );
+ CFG->writeEntry( "WhiteHelperType", Type[WHITE_HELPER] );
+ CFG->writeEntry( "BlackType", Type[BLACK] );
+ CFG->writeEntry( "BlackHelperType", Type[BLACK_HELPER] );
+
+ CFG->writeEntry( "WhiteStr", Strength[WHITE] );
+ CFG->writeEntry( "WhiteHelperStr", Strength[WHITE_HELPER] );
+ CFG->writeEntry( "BlackStr", Strength[BLACK] );
+ CFG->writeEntry( "BlackHelperStr", Strength[BLACK_HELPER] );
+}
+///////////////////////////////////////
+//
+// resource::ReadEngines
+//
+///////////////////////////////////////
+void resource::ReadEngines( void )
+{
+ engineResource temp;
+ QStringList engineList;
+ QStringList::Iterator engineListIT;
+ QString buffer;
+
+ engines.clear();
+ CFG->setGroup( "General" );
+ buffer = CFG->readEntry( "Engines" );
+ if( buffer.isEmpty() ) return;
+
+ engineList = QStringList::split( QString(","), buffer, FALSE );
+ for ( engineListIT = engineList.begin(); engineListIT != engineList.end(); ++engineListIT )
+ {
+ if( !CFG->hasGroup( (*engineListIT) ) ) continue;
+ CFG->setGroup( (*engineListIT) );
+ temp.Name = (*engineListIT);
+ temp.Filename = CFG->readEntry( "Filename" );
+ temp.Arguments = CFG->readEntry( "Arguments" );
+ temp.LogFile = CFG->readEntry( "Log" );
+ temp.Protocol = CFG->readNumEntry( "Protocol" );
+ temp.Wins = CFG->readNumEntry( "Wins" );
+ temp.Losses = CFG->readNumEntry( "Losses" );
+ temp.Draws = CFG->readNumEntry( "Draws" );
+ temp.CurrentRef = CFG->readNumEntry( "CurrentRef" );
+ engines.append( temp );
+ }
+}
+///////////////////////////////////////
+//
+// resource::WriteEngines
+//
+///////////////////////////////////////
+void resource::WriteEngines( void )
+{
+ QString buffer;
+
+ CFG->setGroup( "General" );
+ if( engines.isEmpty() )
+ {
+ CFG->writeEntry( "Engines", QString( "" ) );
+ return;
+ }
+ for ( enginesIT = engines.begin(); enginesIT != engines.end(); ++enginesIT )
+ {
+ buffer += (*enginesIT).Name + ",";
+ CFG->setGroup( (*enginesIT).Name );
+ CFG->writeEntry( "Filename", (*enginesIT).Filename );
+ CFG->writeEntry( "Arguments", (*enginesIT).Arguments );
+ CFG->writeEntry( "Log", (*enginesIT).LogFile );
+ CFG->writeEntry( "Protocol", (*enginesIT).Protocol );
+ CFG->writeEntry( "Wins", (*enginesIT).Wins );
+ CFG->writeEntry( "Losses", (*enginesIT).Losses );
+ CFG->writeEntry( "Draws", (*enginesIT).Draws );
+ CFG->writeEntry( "CurrentRef", (*enginesIT).CurrentRef );
+ }
+ CFG->setGroup( "General" );
+ CFG->writeEntry( "Engines", buffer );
+ CFG->sync();
+}
+///////////////////////////////////////
+//
+// resource::ReadServers
+//
+///////////////////////////////////////
+void resource::ReadServers( void )
+{
+ serverResource temp;
+ QStringList serverList;
+ QStringList::Iterator serverListIT;
+ QString buffer;
+
+ servers.clear();
+ CFG->setGroup( "General" );
+ buffer = CFG->readEntry( "Servers" );
+ if( buffer.isEmpty() ) return;
+
+ serverList = QStringList::split( QString(","), buffer, FALSE );
+ for ( serverListIT = serverList.begin(); serverListIT != serverList.end(); ++serverListIT )
+ {
+ if( !CFG->hasGroup( (*serverListIT) ) ) continue;
+ CFG->setGroup( (*serverListIT) );
+ temp.Name = (*serverListIT);
+ temp.URL = CFG->readEntry( "URL" );
+ temp.UserName = CFG->readEntry( "UserName" );
+ temp.LogFile = CFG->readEntry( "LogFile" );
+ temp.Password = decryptStr( CFG->readEntry( "Password" ) );
+ temp.StorePass = CFG->readBoolEntry( "StorePass" );
+ temp.Port = CFG->readNumEntry( "Port" );
+ temp.CurrentRef = CFG->readNumEntry( "CurrentRef" );
+ temp.Timeseal = CFG->readEntry( "Timeseal" );
+ servers.append( temp );
+ }
+}
+///////////////////////////////////////
+//
+// resource::WriteServers
+//
+///////////////////////////////////////
+void resource::WriteServers( void )
+{
+ QString buffer;
+
+ CFG->setGroup( "General" );
+ if( servers.isEmpty() )
+ {
+ CFG->writeEntry( "Servers", QString( "" ) );
+ return;
+ }
+ for ( serversIT = servers.begin(); serversIT != servers.end(); ++serversIT )
+ {
+ buffer += (*serversIT).Name + ",";
+ CFG->setGroup( (*serversIT).Name );
+ CFG->writeEntry( "URL", (*serversIT).URL );
+ CFG->writeEntry( "UserName", (*serversIT).UserName );
+ CFG->writeEntry( "LogFile", (*serversIT).LogFile );
+ if( (*serversIT).StorePass )
+ CFG->writeEntry( "Password", encryptStr( (*serversIT).Password ) );
+ else
+ CFG->writeEntry( "Password", "" );
+ CFG->writeEntry( "Port", (*serversIT).Port );
+ CFG->writeEntry( "StorePass", (*serversIT).StorePass );
+ CFG->writeEntry( "CurrentRef", (*serversIT).CurrentRef );
+ CFG->writeEntry( "Timeseal", (*serversIT).Timeseal );
+ }
+ CFG->setGroup( "General" );
+ CFG->writeEntry( "Servers", buffer );
+ CFG->sync();
+}
+///////////////////////////////////////
+//
+// resource::themeDir
+//
+///////////////////////////////////////
+QString resource::themeDir( void )
+{
+ return QString( GlobalDataDir + "themes/" );
+}
+///////////////////////////////////////
+//
+// resource::readThemeDir
+//
+///////////////////////////////////////
+void resource::readThemeDir( void )
+{
+ QDir themesDir;
+
+ Boards.clear();
+ Chessmen.clear();
+ Sounds.clear();
+
+ themesDir.setNameFilter( "KB*" );
+ themesDir = GlobalDataDir + "themes/";
+ Boards += themesDir.entryList();
+ themesDir = QDir::homeDirPath() + "/.knights/";
+ if( themesDir.exists() ) Boards += themesDir.entryList();
+ themesDir = "../media/";
+ if( themesDir.exists() ) Boards += themesDir.entryList();
+ Boards.sort();
+
+ themesDir.setNameFilter( "KC*" );
+ themesDir = GlobalDataDir + "themes/";
+ Chessmen += themesDir.entryList();
+ themesDir = QDir::homeDirPath() + "/.knights/";
+ if( themesDir.exists() ) Chessmen += themesDir.entryList();
+ themesDir = "../media/";
+ if( themesDir.exists() ) Chessmen += themesDir.entryList();
+ Chessmen.sort();
+
+ themesDir.setNameFilter( "KS*" );
+ themesDir = GlobalDataDir + "themes/";
+ Sounds += themesDir.entryList();
+ themesDir = QDir::homeDirPath() + "/.knights/";
+ if( themesDir.exists() ) Sounds += themesDir.entryList();
+ themesDir = "../media/";
+ if( themesDir.exists() ) Sounds += themesDir.entryList();
+ Sounds.sort();
+}
+///////////////////////////////////////
+//
+// resource::getBoard
+//
+///////////////////////////////////////
+QString resource::getBoard( int Index )
+{
+ if( Index > (signed)Boards.count() ) return QString::null;
+ if( Index == -1 ) return CurrentBoard;
+ return Boards[Index];
+}
+///////////////////////////////////////
+//
+// resource::getChessmen
+//
+///////////////////////////////////////
+QString resource::getChessmen( int Index )
+{
+ if( Index > (signed)Chessmen.count() ) return QString::null;
+ if( Index == -1 ) return CurrentChessmen;
+ return Chessmen[Index];
+}
+///////////////////////////////////////
+//
+// resource::getSounds
+//
+///////////////////////////////////////
+QString resource::getSounds( int Index )
+{
+ if( Index > (signed)Sounds.count() ) return QString::null;
+ if( Index == -1 ) return CurrentAudio;
+ return Sounds[Index];
+}
+///////////////////////////////////////
+//
+// resource::setAudio
+//
+///////////////////////////////////////
+void resource::setAudio( int AudioIndex )
+{
+ QString audioURL;
+
+ /* Make sure the Indexes are valid */
+ if( AudioIndex > (signed)Sounds.count() )
+ {
+ kdWarning() << "Can not access audio theme[" << AudioIndex << "]... Index out of range." << endl;
+ return;
+ }
+ /* Change the theme */
+ if( AudioIndex != -1 ) CurrentAudio = Sounds[AudioIndex];
+ audioURL = themeURL( CurrentAudio );
+ if( audioURL.isEmpty() )
+ {
+ return;
+ }
+ QApplication::setOverrideCursor( CURSOR_Thinking );
+ Audio->setTheme( audioURL );
+ QApplication::restoreOverrideCursor();
+ return;
+}
+///////////////////////////////////////
+//
+// resource::setTheme
+//
+///////////////////////////////////////
+void resource::setTheme( int BoardIndex, int ChessmenIndex )
+{
+ static bool firstTime( TRUE );
+ QString boardURL;
+ QString chessmenURL;
+ QString boardConf;
+ QString chessmenConf;
+ KSimpleConfig *boardConfig;
+ KSimpleConfig *chessmenConfig;
+
+ /* Make sure the Indexes are valid */
+ if( BoardIndex > (signed)Boards.count() )
+ {
+ kdWarning() << "Can not access board theme[" << BoardIndex << "]... Index out of range." << endl;
+ return;
+ }
+ if( ChessmenIndex > (signed)Chessmen.count() )
+ {
+ kdWarning() << "Can not access chessmen theme[" << ChessmenIndex << "]... Index out of range." << endl;
+ return;
+ }
+
+ /* Set the Cursor */
+ QApplication::setOverrideCursor( CURSOR_Thinking );
+
+ /* Change the theme */
+ if( BoardIndex != -1 )
+ CurrentBoard = Boards[BoardIndex];
+ if( ChessmenIndex != -1 )
+ CurrentChessmen = Chessmen[ChessmenIndex];
+
+ boardURL = themeURL( CurrentBoard );
+ chessmenURL = themeURL( CurrentChessmen );
+
+ if( ( boardURL.isEmpty() ) || ( chessmenURL.isEmpty() ) )
+ {
+ QApplication::restoreOverrideCursor();
+ return;
+ }
+
+ /* load the theme.conf files */
+ if( !KIO::NetAccess::download( boardURL + "theme.conf", boardConf ) )
+ kdWarning() << "Can not read theme.conf from " << boardURL << endl;
+ boardConfig = new KSimpleConfig( boardConf, TRUE );
+
+ if( !KIO::NetAccess::download( chessmenURL + "theme.conf", chessmenConf ) )
+ kdWarning() << "Can not read theme.conf from " << chessmenURL << endl;
+ chessmenConfig = new KSimpleConfig( chessmenConf, TRUE );
+
+ /* Read the headers */
+ boardConfig->setGroup( "General" );
+ boardHeader.name = boardConfig->readEntry( "Name", "Unknown" );
+ boardHeader.version = boardConfig->readEntry( "Version", "Unknown" );
+ boardHeader.author = boardConfig->readEntry( "Author", "Unknown" );
+ boardHeader.authorEmail = boardConfig->readEntry( "AuthorEmail", "Unknown" );
+ boardHeader.authorWWW = boardConfig->readEntry( "AuthorWWW", "Unknown" );
+ boardHeader.notes = boardConfig->readEntry( "Notes", "Unknown" );
+ chessmenConfig->setGroup( "General" );
+ chessmenHeader.name = chessmenConfig->readEntry( "Name", "Unknown" );
+ chessmenHeader.version = chessmenConfig->readEntry( "Version", "Unknown" );
+ chessmenHeader.author = chessmenConfig->readEntry( "Author", "Unknown" );
+ chessmenHeader.authorEmail = chessmenConfig->readEntry( "AuthorEmail", "Unknown" );
+ chessmenHeader.authorWWW = chessmenConfig->readEntry( "AuthorWWW", "Unknown" );
+ chessmenHeader.notes = chessmenConfig->readEntry( "Notes", "Unknown" );
+
+ /* Load the Board */
+ boardConfig->setGroup( "2DBoard" );
+ ThemeBorder = boardConfig->readBoolEntry( "HaveBorder", FALSE );
+ loadThemeItem( boardURL + boardConfig->readEntry("Light", "square.light.png"), pixCache->Orig_SquareLight );
+ loadThemeItem( boardURL + boardConfig->readEntry("Dark", "square.dark.png"), pixCache->Orig_SquareDark );
+ loadThemeItem( boardURL + boardConfig->readEntry("Select", "square.select.png"), pixCache->Orig_HighlightSelect );
+ loadThemeItem( boardURL + boardConfig->readEntry("Motion", "square.motion.png"), pixCache->Orig_HighlightMove );
+ loadThemeItem( boardURL + boardConfig->readEntry("Danger", "square.danger.png"), pixCache->Orig_HighlightAttack );
+ if( ThemeBorder )
+ {
+ loadThemeItem( boardURL + boardConfig->readEntry("Border", "border.png"), pixCache->Orig_Border );
+ loadThemeItem( boardURL + boardConfig->readEntry("BorderLightOn", "light_on.png"), pixCache->Orig_BorderLightOn );
+ loadThemeItem( boardURL + boardConfig->readEntry("BorderLightOff", "light_off.png"), pixCache->Orig_BorderLightOff );
+ }
+ boardConfig->setGroup( "2DBoard" );
+ COLOR_Notation = boardConfig->readColorEntry( "TextColor", &COLOR_White );
+ COLOR_Notation_Shadow = boardConfig->readColorEntry( "ShadowColor", &COLOR_Black );
+
+ /* Load 2D Chessmen */
+ chessmenConfig->setGroup( "2DBlack" );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("King", "black.king.png"), pixCache->Orig_BlackKing );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Queen", "black.queen.png"), pixCache->Orig_BlackQueen );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Bishop", "black.bishop.png"), pixCache->Orig_BlackBishop );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Knight", "black.knight.png"), pixCache->Orig_BlackKnight );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Rook", "black.rook.png"), pixCache->Orig_BlackRook );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Pawn", "black.pawn.png"), pixCache->Orig_BlackPawn );
+ chessmenConfig->setGroup( "2DWhite" );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("King", "white.king.png"), pixCache->Orig_WhiteKing );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Queen", "white.queen.png"), pixCache->Orig_WhiteQueen );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Bishop", "white.bishop.png"), pixCache->Orig_WhiteBishop );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Knight", "white.knight.png"), pixCache->Orig_WhiteKnight );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Rook", "white.rook.png"), pixCache->Orig_WhiteRook );
+ loadThemeItem( chessmenURL + chessmenConfig->readEntry("Pawn", "white.pawn.png"), pixCache->Orig_WhitePawn );
+
+ /* Remove the theme.conf files */
+ delete boardConfig;
+ delete chessmenConfig;
+ KIO::NetAccess::removeTempFile( boardConf );
+ KIO::NetAccess::removeTempFile( chessmenConf );
+
+ /* Cleanup */
+ pixCache->clear();
+ QApplication::restoreOverrideCursor();
+ pixCache->resize( ThemeSize );
+ firstTime = FALSE;
+ return;
+}
+///////////////////////////////////////
+//
+// resource::loadThemeItem
+//
+///////////////////////////////////////
+void resource::loadThemeItem( const QString &URL, QImage &Image )
+{
+ QString tempFile;
+
+ if( KIO::NetAccess::download( URL, tempFile ) )
+ {
+ if( !Image.load( tempFile ) )
+ kdError() << "resource::LoadThemeItem: Can not load " << tempFile << ", which comes from " << URL << endl;
+ KIO::NetAccess::removeTempFile( tempFile );
+ }
+ else
+ kdError() << "resource::LoadThemeItem: Can not extract " << URL << endl;
+ return;
+}
+///////////////////////////////////////
+//
+// resource::resizeTheme
+//
+///////////////////////////////////////
+void resource::resizeTheme( const int &size )
+{
+ /* Set the Cursor */
+ QApplication::setOverrideCursor( CURSOR_Thinking );
+
+ ThemeSize = size;
+ if( ThemeSize > IMAGE_MAX )
+ ThemeSize = IMAGE_MIN;
+ if( ThemeSize < IMAGE_MIN )
+ ThemeSize = IMAGE_MAX;
+ pixCache->resize( ThemeSize );
+ ConfigWrite();
+
+ QApplication::restoreOverrideCursor();
+}
+///////////////////////////////////////
+//
+// resource::LoadIcon
+//
+///////////////////////////////////////
+QPixmap resource::LoadIcon( QString Name, int Group )
+{
+ return Icons->loadIcon( Name, (KIcon::Group)Group );
+}
+///////////////////////////////////////
+//
+// resource::encryptStr
+//
+///////////////////////////////////////
+// Borrowed from KMail
+QString resource::encryptStr(const QString &aStr) const
+{
+ unsigned int i, val;
+ unsigned int len = aStr.length();
+ QCString result;
+ result.resize(len+1);
+ for (i=0; i<len; i++)
+ {
+ val = aStr[i] - ' ';
+ val = (255-' ') - val;
+ result[i] = (char)(val + ' ');
+ }
+ result[i] = '\0';
+
+ return result;
+}
+///////////////////////////////////////
+//
+// resource::decryptStr
+//
+///////////////////////////////////////
+// Borrowed from KMail
+QString resource::decryptStr(const QString &aStr) const
+{
+ return encryptStr(aStr);
+}
+///////////////////////////////////////
+//
+// resource::play
+//
+///////////////////////////////////////
+void resource::play( const char snd )
+{
+ Audio->play( snd );
+}
+///////////////////////////////////////
+//
+// resource::ReadColors
+//
+///////////////////////////////////////
+void resource::ReadColors( void )
+{
+ QColor tmp;
+
+ COLOR_White = QColor( 255, 255, 255 );
+ COLOR_Black = QColor( 0, 0, 0 );
+ CFG->setGroup( "Colors" );
+ COLOR_Background = CFG->readColorEntry( "BackgroundColor", &COLOR_White );
+ COLOR_GraphBackground = CFG->readColorEntry( "GraphBackground", &COLOR_Background );
+ COLOR_Standard = CFG->readColorEntry( "StandardColor", &COLOR_Black );
+ COLOR_GraphForeground = CFG->readColorEntry( "GraphForeground", &COLOR_Standard );
+ tmp = QColor( 128, 0, 128 ); // Purple
+ COLOR_PrivateTell = CFG->readColorEntry( "PrivateColor", &tmp );
+ tmp = QColor( 0, 0, 160 ); // Blue
+ COLOR_ChannelTell = CFG->readColorEntry( "ChannelColor", &tmp );
+ tmp = QColor( 160, 0, 0 ); // Red
+ COLOR_Shout = CFG->readColorEntry( "ShoutColor", &tmp );
+ tmp = QColor( 0, 160, 0 ); // Green
+ COLOR_Whisper = CFG->readColorEntry( "WhisperColor", &tmp );
+ tmp = QColor( 0, 128, 128 ); // Cyan
+ COLOR_Notification = CFG->readColorEntry( "NotificationColor", &tmp );
+}
+///////////////////////////////////////
+//
+// resource::WriteColors
+//
+///////////////////////////////////////
+void resource::WriteColors( void )
+{
+ CFG->setGroup( "Colors" );
+ CFG->writeEntry( "BackgroundColor", COLOR_Background );
+ CFG->writeEntry( "StandardColor", COLOR_Standard );
+ CFG->writeEntry( "PrivateColor", COLOR_PrivateTell );
+ CFG->writeEntry( "ChannelColor", COLOR_ChannelTell );
+ CFG->writeEntry( "ShoutColor", COLOR_Shout );
+ CFG->writeEntry( "WhisperColor", COLOR_Whisper );
+ CFG->writeEntry( "NotificationColor", COLOR_Notification );
+ CFG->writeEntry( "GraphForeground", COLOR_GraphForeground );
+ CFG->writeEntry( "GraphBackground", COLOR_GraphBackground );
+}
+///////////////////////////////////////
+//
+// resource::ReadFonts
+//
+///////////////////////////////////////
+void resource::ReadFonts( void )
+{
+ QFont Fixed = KGlobalSettings::fixedFont();
+ CFG->setGroup( "Fonts" );
+ FONT_Standard = CFG->readFontEntry( "StandardFont", &Fixed );
+ FONT_PrivateTell = CFG->readFontEntry( "PrivateFont", &Fixed );
+ FONT_ChannelTell = CFG->readFontEntry( "ChannelFont", &Fixed );
+ FONT_Shout = CFG->readFontEntry( "ShoutFont", &Fixed );
+ FONT_Whisper = CFG->readFontEntry( "WhisperFont", &Fixed );
+ FONT_Notification = CFG->readFontEntry( "NotificationFont", &Fixed );
+}
+///////////////////////////////////////
+//
+// resource::WriteFonts
+//
+///////////////////////////////////////
+void resource::WriteFonts( void )
+{
+ CFG->setGroup( "Fonts" );
+ CFG->writeEntry( "StandardFont", FONT_Standard );
+ CFG->writeEntry( "PrivateFont", FONT_PrivateTell );
+ CFG->writeEntry( "ChannelFont", FONT_ChannelTell );
+ CFG->writeEntry( "ShoutFont", FONT_Shout );
+ CFG->writeEntry( "WhisperFont", FONT_Whisper );
+ CFG->writeEntry( "NotificationFont", FONT_Notification );
+}
+///////////////////////////////////////
+//
+// resource::buildStyle
+//
+///////////////////////////////////////
+void resource::buildStyle( void )
+{
+ /* Configure SSI_Default */
+ SSI_Default->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_Default->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_Default->setFontFamily( FONT_Standard.family() );
+ SSI_Default->setFontSize( FONT_Standard.pointSize() );
+ SSI_Default->setFontUnderline( FONT_Standard.underline() );
+ SSI_Default->setFontItalic( FONT_Standard.italic() );
+ SSI_Default->setFontWeight( FONT_Standard.weight() );
+ SSI_Default->setColor( COLOR_Standard );
+ /* Configure SSI_PrivateTell */
+ SSI_PrivateTell->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_PrivateTell->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_PrivateTell->setFontFamily( FONT_PrivateTell.family() );
+ SSI_PrivateTell->setFontSize( FONT_PrivateTell.pointSize() );
+ SSI_PrivateTell->setFontUnderline( FONT_PrivateTell.underline() );
+ SSI_PrivateTell->setFontItalic( FONT_PrivateTell.italic() );
+ SSI_PrivateTell->setFontWeight( FONT_PrivateTell.weight() );
+ SSI_PrivateTell->setColor( COLOR_PrivateTell );
+ /* Configure SSI_ChannelTell */
+ SSI_ChannelTell->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_ChannelTell->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_ChannelTell->setFontFamily( FONT_ChannelTell.family() );
+ SSI_ChannelTell->setFontSize( FONT_ChannelTell.pointSize() );
+ SSI_ChannelTell->setFontUnderline( FONT_ChannelTell.underline() );
+ SSI_ChannelTell->setFontItalic( FONT_ChannelTell.italic() );
+ SSI_ChannelTell->setFontWeight( FONT_ChannelTell.weight() );
+ SSI_ChannelTell->setColor( COLOR_ChannelTell );
+ /* Configure SSI_Shout */
+ SSI_Shout->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_Shout->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_Shout->setFontFamily( FONT_Shout.family() );
+ SSI_Shout->setFontSize( FONT_Shout.pointSize() );
+ SSI_Shout->setFontUnderline( FONT_Shout.underline() );
+ SSI_Shout->setFontItalic( FONT_Shout.italic() );
+ SSI_Shout->setFontWeight( FONT_Shout.weight() );
+ SSI_Shout->setColor( COLOR_Shout );
+ /* Configure SSI_Whisper */
+ SSI_Whisper->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_Whisper->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_Whisper->setFontFamily( FONT_Whisper.family() );
+ SSI_Whisper->setFontSize( FONT_Whisper.pointSize() );
+ SSI_Whisper->setFontUnderline( FONT_Whisper.underline() );
+ SSI_Whisper->setFontItalic( FONT_Whisper.italic() );
+ SSI_Whisper->setFontWeight( FONT_Whisper.weight() );
+ SSI_Whisper->setColor( COLOR_Whisper );
+ /* Configure SSI_Notification */
+ SSI_Notification->setDisplayMode( QStyleSheetItem::DisplayListItem );
+ SSI_Notification->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
+ SSI_Notification->setFontFamily( FONT_Notification.family() );
+ SSI_Notification->setFontSize( FONT_Notification.pointSize() );
+ SSI_Notification->setFontUnderline( FONT_Notification.underline() );
+ SSI_Notification->setFontItalic( FONT_Notification.italic() );
+ SSI_Notification->setFontWeight( FONT_Notification.weight() );
+ SSI_Notification->setColor( COLOR_Notification );
+}
+///////////////////////////////////////
+//
+// resource::themeURL
+//
+///////////////////////////////////////
+QString resource::themeURL( const QString theme )
+{
+ QString fullURL;
+ fullURL = "tar:" + GlobalDataDir + "themes/" + theme;
+ if( !KIO::NetAccess::exists( fullURL ) )
+ {
+ fullURL = "tar:" + QDir::currentDirPath() + "../media/" + theme;
+ if( !KIO::NetAccess::exists( fullURL ) )
+ {
+ fullURL = "tar:" + QDir::homeDirPath() + "/.knights/" + theme;
+ if( !KIO::NetAccess::exists( fullURL ) )
+ {
+ kdWarning() << "The theme " << theme << " does not exist in any valid path." << endl;
+ return QString::null;
+ }
+ }
+ }
+ fullURL += "/";
+ return fullURL;
+}
+
+///////////////////////////////////////
+//
+// resource::loadSCIDImage
+//
+///////////////////////////////////////
+QPixmap resource::loadSCIDImage( const QString &name )
+{
+ const int BufferMax = 120;
+ const int ArrayMax = 21600;
+ const int SkipSize = 7200;
+
+ QPixmap newPix;
+ QString searchName = '\"' + name + '\"';
+ QByteArray base64Data( ArrayMax );
+ QByteArray rawData( ArrayMax );
+ char *array = base64Data.data();
+ char buffer[BufferMax];
+ char photo[12];
+ unsigned int index = 0;
+ unsigned int buffSize = 0;
+
+ QString source = locate( "appdata", "players.img" );
+ if( source.isNull() )
+ source = SCID_Image_Path;
+
+ strcpy( photo, "photo" );
+ QFile file( source );
+
+ if( file.open( IO_ReadOnly ) )
+ {
+ while( !file.atEnd() )
+ {
+ file.readLine( buffer, BufferMax );
+ if( strstr( buffer, photo ) != NULL )
+ {
+ if( strstr( buffer, searchName.latin1() ) != NULL )
+ {
+ /* From here on, we're reading the image */
+ index = file.readBlock( array, SkipSize );
+ buffer[0] = 0;
+ while( ( buffer[0] != '}' ) && ( !file.atEnd() ) )
+ {
+ memcpy( array + index, buffer, buffSize );
+ index += buffSize;
+ buffSize = file.readLine( buffer, BufferMax );
+ }
+ base64Data.truncate( index );
+ KCodecs::base64Decode( base64Data, rawData );
+ newPix.loadFromData( rawData );
+ break;
+ }
+ else
+ {
+ file.at( file.at() + SkipSize );
+ }
+ }
+ }
+ file.close();
+ }
+ return newPix;
+}
+
+#undef CFG
+
+
diff --git a/knights/resource.h b/knights/resource.h
new file mode 100644
index 0000000..0892988
--- /dev/null
+++ b/knights/resource.h
@@ -0,0 +1,240 @@
+/***************************************************************************
+ resource.h - description
+ -------------------
+ begin : Tue Jul 17 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+/* KDE */
+#include <kapp.h>
+#include <klocale.h>
+#include <kcursor.h>
+#include <klistview.h>
+#include <kcmdlineargs.h>
+/* Qt */
+#include <qstylesheet.h>
+#include <qvaluelist.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qimage.h>
+/* Local */
+#include "definitions.h"
+
+class audio;
+class KnightsPixCache;
+class TabManager;
+class Accel;
+
+typedef struct engineResource
+{
+ QListViewItem *Item;
+ QString Name;
+ QString Filename;
+ QString Arguments;
+ QString LogFile;
+ int Protocol;
+ int Wins;
+ int Losses;
+ int Draws;
+ int CurrentRef;
+};
+
+typedef struct serverResource
+{
+ QListViewItem *Item;
+ QString Name;
+ QString URL;
+ QString UserName;
+ QString Password;
+ QString LogFile;
+ QString Timeseal;
+ bool StorePass;
+ int Port;
+ int CurrentRef;
+};
+
+typedef QValueList<engineResource> engineList;
+typedef QValueList<serverResource> serverList;
+
+class resource
+{
+ public:
+ /* The current Theme */
+ int ThemeSize;
+ bool ThemeBorder;
+ QStyleSheet *ConsoleStyle;
+ QString CurrentBoard;
+ QString CurrentChessmen;
+ QString CurrentAudio;
+ ThemeHeader boardHeader;
+ ThemeHeader chessmenHeader;
+ ThemeHeader audioHeader;
+ KnightsPixCache *pixCache;
+ TabManager *tabManager;
+ Accel *myAccel;
+
+ /* General Settings */
+ QString Local_Player;
+ QString Local_Email_Address;
+ int Config_Version;
+ bool Accepted_License;
+ int OPTION_On_Init;
+ int Audio_Volume;
+ bool OPTION_Audio;
+ bool OPTION_Audio_Current_Only;
+ bool OPTION_Auto_Queen;
+ bool OPTION_Auto_Preview;
+ bool OPTION_Auto_Call_Flag;
+ bool OPTION_Auto_Close_Last_ICS;
+ bool OPTION_Animate_Moves;
+ bool OPTION_Book_White;
+ bool OPTION_Book_Black;
+ bool OPTION_Board_Orientation;
+ bool OPTION_Ponder;
+ bool OPTION_Show_Coord;
+ bool OPTION_Show_Last_Move;
+ bool OPTION_Show_Splash;
+ bool OPTION_Show_Extended_PGN;
+ bool OPTION_Pause_On_Minimize;
+ bool OPTION_Reuse_PGN;
+ bool OPTION_3DBoard;
+ QString PGN_Filename;
+ QString Email_Command_Line;
+ QString Email_Address;
+ QString SCID_Image_Path;
+ int Widget_Height;
+ /* ICS Options */
+ int Seek_Timer;
+ int OPTION_Profanity;
+ bool OPTION_Premove;
+ bool OPTION_Kibitz;
+ bool OPTION_Private;
+ bool OPTION_Shout;
+ bool OPTION_Tell;
+ bool OPTION_Seek;
+ /* Notification Prompts */
+ QString PromptForSaving;
+ /* Colors */
+ QColor COLOR_White;
+ QColor COLOR_Black;
+ QColor COLOR_Background;
+ QColor COLOR_Standard;
+ QColor COLOR_PrivateTell;
+ QColor COLOR_ChannelTell;
+ QColor COLOR_Shout;
+ QColor COLOR_Whisper;
+ QColor COLOR_Notification;
+ QColor COLOR_Notation;
+ QColor COLOR_Notation_Shadow;
+ QColor COLOR_GraphBackground;
+ QColor COLOR_GraphForeground;
+ /* Fonts */
+ QFont FONT_Standard;
+ QFont FONT_PrivateTell;
+ QFont FONT_ChannelTell;
+ QFont FONT_Shout;
+ QFont FONT_Whisper;
+ QFont FONT_Notification;
+ /* Cursors */
+ QCursor CURSOR_Standard;
+ QCursor CURSOR_Thinking;
+ QCursor CURSOR_Text;
+ /* Chess Engines */
+ engineList engines;
+ engineList::Iterator enginesIT;
+ /* Chess Servers */
+ serverList servers;
+ serverList::Iterator serversIT;
+ /* New Match Presets */
+ TCPList TCPWhite;
+ TCPList TCPBlack;
+ char MatchRules;
+ char Type[4];
+ char Strength[4];
+
+ resource( KCmdLineArgs *args );
+ ~resource();
+
+ void ConfigRead( void );
+ void ConfigWrite( void );
+
+ void readThemeDir( void );
+ QString getBoard( int Index=-1 );
+ QString getChessmen( int Index=-1 );
+ QString getSounds( int Index=-1 );
+ QString themeDir( void );
+ void setTheme( int BoardIndex=-1, int ChessmenIndex=-1 );
+ void setAudio( int AudioIndex=-1 );
+ void resizeTheme( const int &size );
+
+ /**
+ Call buildStyle whenever you need to reparse the Resource configuration */
+ void buildStyle( void );
+ QPixmap LoadIcon( QString Name, int Group );
+ QPixmap loadSCIDImage( const QString &name );
+ void play( const char );
+
+ private:
+
+ QStyleSheetItem *SSI_Default;
+ QStyleSheetItem *SSI_PrivateTell;
+ QStyleSheetItem *SSI_ChannelTell;
+ QStyleSheetItem *SSI_Shout;
+ QStyleSheetItem *SSI_Whisper;
+ QStyleSheetItem *SSI_Notification;
+
+ QString GlobalDataDir;
+ QString LocalDataDir;
+
+ QStringList Boards;
+ QStringList Chessmen;
+ QStringList Sounds;
+ KIconLoader *Icons;
+ audio *Audio;
+
+ void ReadEngines( void );
+ void WriteEngines( void );
+
+ void ReadServers( void );
+ void WriteServers( void );
+
+ void ReadMatchParam( void );
+ void WriteMatchParam( void );
+
+ void ReadColors( void );
+ void WriteColors( void );
+
+ void ReadFonts( void );
+ void WriteFonts( void );
+
+ /**
+ Borrowed from KMail
+ Very primitive en/de-cryption so that the password is not
+ readable in the config file. But still very easy breakable.
+ */
+ QString encryptStr( const QString& inStr ) const;
+ QString decryptStr( const QString& inStr ) const;
+ QString themeURL( const QString );
+ void loadThemeItem( const QString& URL, QImage& Image );
+};
+
+#endif
diff --git a/knights/setpageaudio.cpp b/knights/setpageaudio.cpp
new file mode 100644
index 0000000..3c51b12
--- /dev/null
+++ b/knights/setpageaudio.cpp
@@ -0,0 +1,133 @@
+/***************************************************************************
+ setpageaudio.cpp - description
+ -------------------
+ begin : Thu Jan 10 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qregexp.h>
+#include "setpageaudio.moc"
+
+setPageAudio::setPageAudio(QWidget *parent, resource *Rsrc ) : QVBoxLayout(parent)
+{
+ Parent = parent;
+ Resource = Rsrc;
+ NewSounds = 0;
+ changeTheme = FALSE;
+
+ BUTTON_enableAudio = new QCheckBox( i18n( "Enable Audio" ), parent );
+ BUTTON_enableAudio->setChecked( Resource->OPTION_Audio );
+ addWidget( BUTTON_enableAudio );
+ connect( BUTTON_enableAudio, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_enableAudio(bool) ) );
+
+ GROUP_Theme = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Audio Themes" ),
+ parent );
+ addWidget( GROUP_Theme );
+ Current_Theme = new KComboBox ( GROUP_Theme );
+ buildThemeList();
+ connect( Current_Theme, SIGNAL( activated(int) ),
+ this, SLOT( slot_currentTheme(int) ) );
+
+ BOX_Main = new QHBox( parent );
+ addWidget( BOX_Main );
+
+ GROUP_Volume = new QGroupBox( 3, Qt::Vertical, i18n( "Volume" ), BOX_Main );
+ Vol_Max = new QLabel( i18n( "Maximum" ), GROUP_Volume );
+ Current_Volume = new QSlider ( 0, 100, 10, Resource->Audio_Volume, QSlider::Vertical, GROUP_Volume );
+ connect( Current_Volume, SIGNAL( valueChanged(int) ), this, SLOT( slot_currentVolume(int) ) );
+ Current_Volume->setTickmarks( QSlider::Right );
+ Vol_Min = new QLabel( i18n( "Minimum" ), GROUP_Volume );
+
+ BOX_Options = new QVBox( BOX_Main );
+ BUTTON_AudioCurrentOnly = new QCheckBox( i18n( "For Current Match Only" ), BOX_Options );
+ BUTTON_AudioCurrentOnly->setChecked( Resource->OPTION_Audio_Current_Only );
+ connect( BUTTON_AudioCurrentOnly, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_AudioCurrentOnly(bool) ) );
+}
+setPageAudio::~setPageAudio()
+{
+}
+///////////////////////////////////////
+//
+// setPageAudio::slot_enableAudio
+//
+///////////////////////////////////////
+void setPageAudio::slot_enableAudio( bool state )
+{
+ Resource->OPTION_Audio = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageAudio::slot_currentTheme
+//
+///////////////////////////////////////
+void setPageAudio::slot_currentTheme( int Index )
+{
+ NewSounds = Index;
+ changeTheme = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageAudio::slot_currentVolume
+//
+///////////////////////////////////////
+void setPageAudio::slot_currentVolume( int Level )
+{
+ Resource->Audio_Volume = Level;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageAudio::slot_AudioCurrentOnly
+//
+///////////////////////////////////////
+void setPageAudio::slot_AudioCurrentOnly( bool state )
+{
+ Resource->OPTION_Audio_Current_Only = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageAudio::buildThemeList
+//
+///////////////////////////////////////
+void setPageAudio::buildThemeList( void )
+{
+ QString buffer;
+ int tmp(0);
+
+ Current_Theme->clear();
+ Resource->readThemeDir();
+ while(1)
+ {
+ buffer = Resource->getSounds( tmp );
+ if( buffer.isEmpty() ) break;
+ buffer.remove( 0, 2 );
+ buffer.replace( QRegExp("_"), " " );
+ buffer.replace( QRegExp(".tar"), "" );
+ buffer.replace( QRegExp(".gz"), "" );
+ buffer.replace( QRegExp(".bz2"), "" );
+ Current_Theme->insertItem( buffer, tmp );
+ if( Resource->getSounds() == Resource->getSounds( tmp ) )
+ {
+ Current_Theme->setCurrentItem( tmp );
+ NewSounds = tmp;
+ }
+ tmp++;
+ }
+}
diff --git a/knights/setpageaudio.h b/knights/setpageaudio.h
new file mode 100644
index 0000000..5d9c58b
--- /dev/null
+++ b/knights/setpageaudio.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ setpageaudio.h - description
+ -------------------
+ begin : Thu Jan 10 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SETPAGEAUDIO_H
+#define SETPAGEAUDIO_H
+
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <qwidget.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qslider.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class setPageAudio : public QVBoxLayout
+{
+ Q_OBJECT
+ public:
+ setPageAudio(QWidget *parent=0, resource *Rsrc=0);
+ ~setPageAudio();
+ void buildThemeList( void );
+ int NewSounds;
+ bool changeTheme;
+ signals:
+ void enableApply( void );
+ public slots:
+ void slot_enableAudio( bool );
+ void slot_currentTheme( int );
+ void slot_currentVolume( int );
+ void slot_AudioCurrentOnly( bool );
+ private:
+ QWidget *Parent;
+ resource *Resource;
+
+ QCheckBox *BUTTON_enableAudio;
+ QGroupBox *GROUP_Theme;
+ KComboBox *Current_Theme;
+ QHBox *BOX_Main;
+ QGroupBox *GROUP_Volume;
+ QLabel *Vol_Min;
+ QSlider *Current_Volume;
+ QLabel *Vol_Max;
+ QVBox *BOX_Options;
+ QCheckBox *BUTTON_AudioCurrentOnly;
+};
+
+#endif
diff --git a/knights/setpagedisplay.cpp b/knights/setpagedisplay.cpp
new file mode 100644
index 0000000..1cf82d9
--- /dev/null
+++ b/knights/setpagedisplay.cpp
@@ -0,0 +1,563 @@
+/***************************************************************************
+ setpagedisplay.cpp - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "setpagedisplay.moc"
+#include <kstddirs.h>
+#include <kmessagebox.h>
+#include <kcolordialog.h>
+#include <kfontdialog.h>
+#include <qstyle.h>
+#include <qregexp.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <kio/netaccess.h>
+
+setPageDisplay::setPageDisplay(QWidget *parent, resource *Rsrc ) : QVBoxLayout(parent)
+{
+ QStyle& Style = QApplication::style();
+ Resource = Rsrc;
+ margin = Style.defaultFrameWidth();
+ NewBoards = 0;
+ NewChessmen = 0;
+ changeTheme = FALSE;
+ refreshBoard = FALSE;
+ rebuildConsole = FALSE;
+
+ TabParent = new QTabWidget( parent, "setPageDisplay" );
+ initTab1();
+ initTab2();
+ addWidget( TabParent );
+}
+setPageDisplay::~setPageDisplay()
+{
+ delete Show_Splashscreen;
+ delete Board_Orientation;
+ delete GROUP_General_Graphics;
+ delete Size_Max;
+ delete Size_Min;
+ delete Current_Theme_Size;
+ delete Current_Boards;
+ delete Current_Chessmen;
+ delete GROUP_Boards;
+ delete GROUP_Chessmen;
+ delete BOX_Themes;
+ delete Tab1;
+ delete Tab2;
+ delete TabParent;
+}
+///////////////////////////////////////
+//
+// setPageDisplay::initTab1
+//
+///////////////////////////////////////
+void setPageDisplay::initTab1( void )
+{
+ Tab1 = new QVBox( TabParent );
+ Tab1->setMargin( margin );
+ BOX_Themes = new QHBox( Tab1 );
+ GROUP_Boards = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Board Themes" ),
+ BOX_Themes );
+ Current_Boards = new KComboBox ( GROUP_Boards );
+ GROUP_Chessmen = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Chessman Themes" ),
+ BOX_Themes );
+ Current_Chessmen = new KComboBox ( GROUP_Chessmen );
+
+ GROUP_Theme_Size = new QGroupBox( 3,
+ Qt::Horizontal,
+ i18n( "Theme Size" ),
+ Tab1 );
+
+ Size_Min = new QLabel( i18n( "Small" ), GROUP_Theme_Size );
+ Current_Theme_Size = new QSlider ( 0,
+ 14,
+ 2,
+ ( Resource->ThemeSize - IMAGE_MIN ) / 8 ,
+ QSlider::Horizontal,
+ GROUP_Theme_Size );
+ Size_Max = new QLabel( i18n( "Large" ), GROUP_Theme_Size );
+
+ GROUP_SCID_Images = new QGroupBox( 2, Qt::Horizontal, i18n("Player Images File:"), Tab1 );
+ EDIT_SCID_Images = new KLineEdit( GROUP_SCID_Images );
+ EDIT_SCID_Images->setText( Resource->SCID_Image_Path );
+ connect( EDIT_SCID_Images, SIGNAL( textChanged(const QString&) ), this, SLOT( slot_SCID_Images(const QString&) ) );
+ BUTTON_SCID_Images = new QPushButton( GROUP_SCID_Images );
+ BUTTON_SCID_Images->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ connect( BUTTON_SCID_Images, SIGNAL( clicked() ), this, SLOT( slot_SCID_Images_Button() ) );
+
+ GROUP_General_Graphics = new QGroupBox( 4,
+ Qt::Vertical,
+ i18n( "Other Display Options" ),
+ Tab1 );
+
+ Board_Orientation = new QCheckBox( i18n( "Reverse Board Orientation" ), GROUP_General_Graphics );
+ Board_Orientation->setChecked( Resource->OPTION_Board_Orientation );
+ connect( Board_Orientation, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Board_Orientation(bool) ) );
+
+ Show_Splashscreen = new QCheckBox( i18n( "Display Startup Logo" ), GROUP_General_Graphics );
+ Show_Splashscreen->setChecked( Resource->OPTION_Show_Splash );
+ connect( Show_Splashscreen, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Splashscreen(bool) ) );
+
+ Auto_Preview = new QCheckBox( i18n( "Automatic Preview" ), GROUP_General_Graphics );
+ Auto_Preview->setChecked( Resource->OPTION_Auto_Preview );
+ connect( Auto_Preview, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Auto_Preview(bool) ) );
+
+ Show_Last_Move = new QCheckBox( i18n( "Show Last Move" ), GROUP_General_Graphics );
+ Show_Last_Move->setChecked( Resource->OPTION_Show_Last_Move );
+ connect( Show_Last_Move, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Show_Last_Move(bool) ) );
+
+ Animate_Move = new QCheckBox( i18n( "Animate Moves" ), GROUP_General_Graphics );
+ Animate_Move->setChecked( Resource->OPTION_Animate_Moves );
+ connect( Animate_Move, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Animate_Move(bool) ) );
+
+ Show_Coord = new QCheckBox( i18n( "Show Coordinates" ), GROUP_General_Graphics );
+ Show_Coord->setChecked( Resource->OPTION_Show_Coord );
+ connect( Show_Coord, SIGNAL( toggled(bool) ),
+ this, SLOT( slotToggle_Show_Coord(bool) ) );
+
+ Current_Theme_Size->setTickmarks( QSlider::Below );
+ Current_Boards->setEditable( FALSE );
+ Current_Chessmen->setEditable( FALSE );
+ buildThemeList();
+ connect( Current_Boards, SIGNAL( activated(int) ),
+ this, SLOT( slotCurrent_Boards(int) ) );
+ connect( Current_Chessmen, SIGNAL( activated(int) ),
+ this, SLOT( slotCurrent_Chessmen(int) ) );
+ connect( Current_Theme_Size, SIGNAL( valueChanged(int) ),
+ this, SLOT( slotCurrent_Theme_Size(int) ) );
+ TabParent->addTab( Tab1, i18n("General") );
+}
+///////////////////////////////////////
+//
+// setPageDisplay::initTab2
+//
+///////////////////////////////////////
+void setPageDisplay::initTab2( void )
+{
+ QPixmap ColorsIcon( Resource->LoadIcon( QString("colorize"), KIcon::Toolbar ) );
+ Tab2 = new QFrame( TabParent );
+ Tab2->setMargin( margin );
+
+ GRID_Style = new QGridLayout( Tab2, 11, 5, margin );
+
+ Console_Sample = new QTextView( Tab2 );
+ Console_Sample->setTextFormat( Qt::RichText );
+ GRID_Style->addMultiCellWidget( Console_Sample, 5, 10, 1, 1 );
+
+ Default_Button = new QPushButton( i18n("Restore Defaults"), Tab2 );
+ connect( Default_Button, SIGNAL( clicked() ), this, SLOT( slot_setDefault() ) );
+ GRID_Style->addWidget( Default_Button, 11, 1 );
+
+ Fonts_Button_Standard = new QPushButton( i18n("Standard Font..."), Tab2 );
+ connect( Fonts_Button_Standard, SIGNAL( clicked() ), this, SLOT( slot_Font_Standard() ) );
+ GRID_Style->addWidget( Fonts_Button_Standard, 5, 3 );
+
+ Colors_Button_Standard = new QPushButton( Tab2 );
+ Colors_Button_Standard->setPixmap( ColorsIcon );
+ connect( Colors_Button_Standard, SIGNAL( clicked() ), this, SLOT( slot_Color_Standard() ) );
+ GRID_Style->addWidget( Colors_Button_Standard, 5, 5 );
+
+ Fonts_Button_PrivateTell = new QPushButton( i18n("Private Font..."), Tab2 );
+ connect( Fonts_Button_PrivateTell, SIGNAL( clicked() ), this, SLOT( slot_Font_PrivateTell() ) );
+ GRID_Style->addWidget( Fonts_Button_PrivateTell, 6, 3 );
+
+ Colors_Button_PrivateTell = new QPushButton( Tab2 );
+ Colors_Button_PrivateTell->setPixmap( ColorsIcon );
+ connect( Colors_Button_PrivateTell, SIGNAL( clicked() ), this, SLOT( slot_Color_PrivateTell() ) );
+ GRID_Style->addWidget( Colors_Button_PrivateTell, 6, 5 );
+
+ Fonts_Button_ChannelTell = new QPushButton( i18n("Channel Font..."), Tab2 );
+ connect( Fonts_Button_ChannelTell, SIGNAL( clicked() ), this, SLOT( slot_Font_ChannelTell() ) );
+ GRID_Style->addWidget( Fonts_Button_ChannelTell, 7, 3 );
+
+ Colors_Button_ChannelTell = new QPushButton( Tab2 );
+ Colors_Button_ChannelTell->setPixmap( ColorsIcon );
+ connect( Colors_Button_ChannelTell, SIGNAL( clicked() ), this, SLOT( slot_Color_ChannelTell() ) );
+ GRID_Style->addWidget( Colors_Button_ChannelTell, 7, 5 );
+
+ Fonts_Button_Shout = new QPushButton( i18n("Shout Font..."), Tab2 );
+ connect( Fonts_Button_Shout, SIGNAL( clicked() ), this, SLOT( slot_Font_Shout() ) );
+ GRID_Style->addWidget( Fonts_Button_Shout, 8, 3 );
+
+ Colors_Button_Shout = new QPushButton( Tab2 );
+ Colors_Button_Shout->setPixmap( ColorsIcon );
+ connect( Colors_Button_Shout, SIGNAL( clicked() ), this, SLOT( slot_Color_Shout() ) );
+ GRID_Style->addWidget( Colors_Button_Shout, 8, 5 );
+
+ Fonts_Button_Whisper = new QPushButton( i18n("Whisper Font..."), Tab2 );
+ connect( Fonts_Button_Whisper, SIGNAL( clicked() ), this, SLOT( slot_Font_Whisper() ) );
+ GRID_Style->addWidget( Fonts_Button_Whisper, 9, 3 );
+
+ Colors_Button_Whisper = new QPushButton( Tab2 );
+ Colors_Button_Whisper->setPixmap( ColorsIcon );
+ connect( Colors_Button_Whisper, SIGNAL( clicked() ), this, SLOT( slot_Color_Whisper() ) );
+ GRID_Style->addWidget( Colors_Button_Whisper, 9, 5 );
+
+ Fonts_Button_Notification = new QPushButton( i18n("Notification Font..."), Tab2 );
+ connect( Fonts_Button_Notification, SIGNAL( clicked() ), this, SLOT( slot_Font_Notification() ) );
+ GRID_Style->addWidget( Fonts_Button_Notification, 10, 3 );
+
+ Colors_Button_Notification = new QPushButton( Tab2 );
+ Colors_Button_Notification->setPixmap( ColorsIcon );
+ connect( Colors_Button_Notification, SIGNAL( clicked() ), this, SLOT( slot_Color_Notification() ) );
+ GRID_Style->addWidget( Colors_Button_Notification, 10, 5 );
+
+ Colors_Button_Background = new QPushButton( Tab2 );
+ Colors_Button_Background->setPixmap( ColorsIcon );
+ connect( Colors_Button_Background, SIGNAL( clicked() ), this, SLOT( slot_Color_Background() ) );
+ GRID_Style->addWidget( Colors_Button_Background, 11, 5 );
+
+ resetSampleConsole();
+ TabParent->addTab( Tab2, i18n("Console") );
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slot_setDefault
+//
+///////////////////////////////////////
+void setPageDisplay::slot_setDefault(void)
+{
+ Resource->FONT_Standard = KGlobalSettings::fixedFont();
+ Resource->FONT_PrivateTell = KGlobalSettings::fixedFont();
+ Resource->FONT_ChannelTell = KGlobalSettings::fixedFont();
+ Resource->FONT_Shout = KGlobalSettings::fixedFont();
+ Resource->FONT_Whisper = KGlobalSettings::fixedFont();
+ Resource->FONT_Notification = KGlobalSettings::fixedFont();
+ Resource->COLOR_Background = Resource->COLOR_White;
+ Resource->COLOR_Standard = Resource->COLOR_Black;
+ Resource->COLOR_PrivateTell = QColor( 128, 0, 128 ); // Purple
+ Resource->COLOR_ChannelTell = QColor( 0, 0, 160 ); // Blue
+ Resource->COLOR_Shout = QColor( 160, 0, 0 ); // Red
+ Resource->COLOR_Whisper = QColor( 0, 160, 0 ); // Green
+ Resource->COLOR_Notification = QColor( 0, 128, 128 ); // Cyan
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slot_Font_?????
+//
+///////////////////////////////////////
+void setPageDisplay::slot_Font_Standard(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_Standard );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Font_PrivateTell(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_PrivateTell );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Font_ChannelTell(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_ChannelTell );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Font_Shout(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_Shout );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Font_Whisper(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_Whisper );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Font_Notification(void)
+{
+ int value = KFontDialog::getFont( Resource->FONT_Notification );
+ if( value != KFontDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slot_Color_?????
+//
+///////////////////////////////////////
+void setPageDisplay::slot_Color_Background(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_Background );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_Standard(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_Standard );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_PrivateTell(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_PrivateTell );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_ChannelTell(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_ChannelTell );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_Shout(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_Shout );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_Whisper(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_Whisper );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+void setPageDisplay::slot_Color_Notification(void)
+{
+ int value = KColorDialog::getColor( Resource->COLOR_Notification );
+ if( value != KColorDialog::Accepted ) return;
+ resetSampleConsole();
+ rebuildConsole = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotCurrent_Boards
+//
+///////////////////////////////////////
+void setPageDisplay::slotCurrent_Boards( int Index )
+{
+ NewBoards = Index;
+ changeTheme = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotCurrent_Chessmen
+//
+///////////////////////////////////////
+void setPageDisplay::slotCurrent_Chessmen( int Index )
+{
+ NewChessmen = Index;
+ changeTheme = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotCurrent_Theme_Size
+//
+///////////////////////////////////////
+void setPageDisplay::slotCurrent_Theme_Size( int Index )
+{
+ Resource->ThemeSize = 32 + ( Index * 8 );
+ changeTheme = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Board_Orientation
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Board_Orientation( bool state )
+{
+ Resource->OPTION_Board_Orientation = state;
+ refreshBoard = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Splashscreen
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Splashscreen( bool state )
+{
+ Resource->OPTION_Show_Splash = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Auto_Preview
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Auto_Preview( bool state )
+{
+ Resource->OPTION_Auto_Preview = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Show_Last_Move
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Show_Last_Move( bool state )
+{
+ Resource->OPTION_Show_Last_Move = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Animate_Move
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Animate_Move( bool state )
+{
+ Resource->OPTION_Animate_Moves = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slotToggle_Show_Coord
+//
+///////////////////////////////////////
+void setPageDisplay::slotToggle_Show_Coord( bool state )
+{
+ Resource->OPTION_Show_Coord = state;
+ refreshBoard = TRUE;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::buildThemeList
+//
+///////////////////////////////////////
+void setPageDisplay::buildThemeList( void )
+{
+ QString buffer;
+ int tmp(0);
+
+ Current_Boards->clear();
+ Current_Chessmen->clear();
+ Resource->readThemeDir();
+ while(1)
+ {
+ buffer = Resource->getBoard( tmp );
+ if( buffer.isEmpty() ) break;
+ buffer.remove( 0, 2 );
+ buffer.replace( QRegExp("_"), " " );
+ buffer.replace( QRegExp(".tar"), "" );
+ buffer.replace( QRegExp(".gz"), "" );
+ buffer.replace( QRegExp(".bz2"), "" );
+ Current_Boards->insertItem( buffer, tmp );
+ if( Resource->getBoard() == Resource->getBoard( tmp ) )
+ {
+ Current_Boards->setCurrentItem( tmp );
+ NewBoards = tmp;
+ }
+ tmp++;
+ }
+ /* ...and for Chessmen */
+ tmp = 0;
+ while(1)
+ {
+ buffer = Resource->getChessmen( tmp );
+ if( buffer.isEmpty() ) break;
+ buffer.remove( 0, 2 );
+ buffer.replace( QRegExp("_"), " " );
+ buffer.replace( QRegExp(".tar"), "" );
+ buffer.replace( QRegExp(".gz"), "" );
+ buffer.replace( QRegExp(".bz2"), "" );
+ Current_Chessmen->insertItem( buffer, tmp );
+ if( Resource->getChessmen() == Resource->getChessmen( tmp ) )
+ {
+ Current_Chessmen->setCurrentItem( tmp );
+ NewChessmen = tmp;
+ }
+ tmp++;
+ }
+}
+///////////////////////////////////////
+//
+// setPageDisplay::resetSampleConsole
+//
+///////////////////////////////////////
+void setPageDisplay::resetSampleConsole( void )
+{
+ Resource->buildStyle();
+ Console_Sample->setPaper( QBrush( Resource->COLOR_Background ) );
+ Console_Sample->setText( QString( "<K_STD>" + i18n( "Standard" ) + "</K_STD>\n" ) );
+ Console_Sample->append( QString( "<K_PVT>" + i18n( "Private Tell" ) + "</K_PVT>\n" ) );
+ Console_Sample->append( QString( "<K_CH>" + i18n( "Channel Tell" ) + "</K_CH>\n" ) );
+ Console_Sample->append( QString( "<K_SHT>" + i18n( "Shout" ) + "</K_SHT>\n" ) );
+ Console_Sample->append( QString( "<K_WSP>" + i18n( "Whisper" ) + "</K_WSP>\n" ) );
+ Console_Sample->append( QString( "<K_NOT>" + i18n( "Notification" ) + "</K_NOT>" ) );
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slot_SCID_Images
+//
+///////////////////////////////////////
+void setPageDisplay::slot_SCID_Images( const QString& string )
+{
+ Resource->SCID_Image_Path = string;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageDisplay::slot_SCID_Images_Button
+//
+///////////////////////////////////////
+void setPageDisplay::slot_SCID_Images_Button( void )
+{
+ QString temp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ Tab1,
+ i18n( "Find Player Images File..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_SCID_Images->setText( temp );
+ Resource->SCID_Image_Path = temp;
+ emit enableApply();
+}
+
+
diff --git a/knights/setpagedisplay.h b/knights/setpagedisplay.h
new file mode 100644
index 0000000..d69fc59
--- /dev/null
+++ b/knights/setpagedisplay.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+ setpagedisplay.h - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SETPAGEDISPLAY_H
+#define SETPAGEDISPLAY_H
+
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <qtextview.h>
+#include <qtabwidget.h>
+#include <qbuttongroup.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class setPageDisplay : public QVBoxLayout
+{
+ Q_OBJECT
+
+ public:
+ setPageDisplay(QWidget *parent=0, resource *Rsrc=0);
+ ~setPageDisplay();
+ void buildThemeList( void );
+ int NewBoards;
+ int NewChessmen;
+ bool changeTheme;
+ bool refreshBoard;
+ bool rebuildConsole;
+
+ public slots:
+ void slotCurrent_Boards( int );
+ void slotCurrent_Chessmen( int );
+ void slotCurrent_Theme_Size( int );
+ void slotToggle_Board_Orientation( bool );
+ void slotToggle_Splashscreen( bool );
+ void slotToggle_Auto_Preview( bool );
+ void slotToggle_Show_Last_Move( bool );
+ void slotToggle_Animate_Move( bool );
+ void slotToggle_Show_Coord( bool );
+ void slot_SCID_Images( const QString& );
+ void slot_SCID_Images_Button( void );
+
+ void slot_setDefault(void);
+
+ void slot_Color_Background(void);
+ void slot_Color_Standard(void);
+ void slot_Color_PrivateTell(void);
+ void slot_Color_ChannelTell(void);
+ void slot_Color_Shout(void);
+ void slot_Color_Whisper(void);
+ void slot_Color_Notification(void);
+ void slot_Font_Standard(void);
+ void slot_Font_PrivateTell(void);
+ void slot_Font_ChannelTell(void);
+ void slot_Font_Shout(void);
+ void slot_Font_Whisper(void);
+ void slot_Font_Notification(void);
+
+ signals:
+ void enableApply( void );
+
+ protected:
+ void initTab1( void );
+ void initTab2( void );
+ void resetSampleConsole( void );
+
+ private:
+ resource *Resource;
+ int margin;
+
+ QTabWidget *TabParent;
+
+ /* Tab 1 : General */
+ QVBox *Tab1;
+ QHBox *BOX_Themes;
+ QGroupBox *GROUP_Boards;
+ KComboBox *Current_Boards;
+ QGroupBox *GROUP_Chessmen;
+ KComboBox *Current_Chessmen;
+ QGroupBox *GROUP_Theme_Size;
+ QLabel *Size_Min;
+ QSlider *Current_Theme_Size;
+ QLabel *Size_Max;
+ QGroupBox *GROUP_SCID_Images;
+ KLineEdit *EDIT_SCID_Images;
+ QPushButton *BUTTON_SCID_Images;
+ QGroupBox *GROUP_General_Graphics;
+ QCheckBox *Board_Orientation;
+ QCheckBox *Show_Splashscreen;
+ QCheckBox *Auto_Preview;
+ QCheckBox *Show_Last_Move;
+ QCheckBox *Animate_Move;
+ QCheckBox *Show_Coord;
+
+ /* Tab 2 : Console */
+ QFrame *Tab2;
+ QGridLayout *GRID_Style;
+ QTextView *Console_Sample;
+ QPushButton *Default_Button;
+ QPushButton *Fonts_Button_Standard;
+ QPushButton *Fonts_Button_PrivateTell;
+ QPushButton *Fonts_Button_ChannelTell;
+ QPushButton *Fonts_Button_Shout;
+ QPushButton *Fonts_Button_Whisper;
+ QPushButton *Fonts_Button_Notification;
+ QPushButton *Colors_Button_Standard;
+ QPushButton *Colors_Button_PrivateTell;
+ QPushButton *Colors_Button_ChannelTell;
+ QPushButton *Colors_Button_Shout;
+ QPushButton *Colors_Button_Whisper;
+ QPushButton *Colors_Button_Notification;
+ QPushButton *Colors_Button_Background;
+};
+
+#endif
diff --git a/knights/setpageengines.cpp b/knights/setpageengines.cpp
new file mode 100644
index 0000000..938d001
--- /dev/null
+++ b/knights/setpageengines.cpp
@@ -0,0 +1,362 @@
+/***************************************************************************
+ setpageengines.cpp - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "setpageengines.moc"
+
+setPageEngines::setPageEngines(QWidget *parent, resource *Rsrc ) : QVBoxLayout(parent)
+{
+ Parent = parent;
+ Resource = Rsrc;
+ Engine_Dialog = NULL;
+ Engines_ListView = NULL;
+
+ BOX_Current = new QHBox( parent );
+ addWidget( BOX_Current );
+
+ /* Engines to play White */
+ GROUP_White_Current = new QGroupBox( 3,
+ Qt::Vertical,
+ i18n( "Engines to Play White" ),
+ BOX_Current );
+
+ White_Use_Book = new QCheckBox( i18n( "Enable Book Engine" ), GROUP_White_Current );
+ Engines_White = new KComboBox ( GROUP_White_Current );
+ Engines_White_Book = new KComboBox ( GROUP_White_Current );
+ Engines_White->setEditable( FALSE );
+ Engines_White_Book->setEditable( FALSE );
+
+ /* Engines to play Black */
+ GROUP_Black_Current = new QGroupBox( 3,
+ Qt::Vertical,
+ i18n( "Engines to Play Black" ),
+ BOX_Current );
+
+ Black_Use_Book = new QCheckBox( i18n( "Enable Book Engine" ), GROUP_Black_Current );
+ Engines_Black = new KComboBox ( GROUP_Black_Current );
+ Engines_Black_Book = new KComboBox ( GROUP_Black_Current );
+ Engines_Black->setEditable( FALSE );
+ Engines_Black_Book->setEditable( FALSE );
+
+ /* Chess Engines ListView */
+ GROUP_Engines = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Chess Engines" ),
+ parent );
+ addWidget( GROUP_Engines );
+
+ Engines_ListView = new KListView( GROUP_Engines );
+ Engines_ListView->addColumn( i18n( "Name" ) );
+ Engines_ListView->addColumn( i18n( "Protocol" ) );
+ Engines_ListView->addColumn( i18n( "Wins" ) );
+ Engines_ListView->addColumn( i18n( "Losses" ) );
+ Engines_ListView->addColumn( i18n( "Draws" ) );
+ Engines_ListView->setAllColumnsShowFocus( TRUE );
+ Engines_ListView->setMultiSelection( FALSE );
+ Engines_ListView->setShowSortIndicator( TRUE );
+ Engines_ListView->restoreLayout( kapp->config(), "Engines_ListView" );
+
+ Engines_ButtonBox = new KButtonBox( GROUP_Engines, Vertical );
+ Engines_Button_Add = Engines_ButtonBox->addButton( i18n( "&Add..." ) );
+ Engines_Button_Change = Engines_ButtonBox->addButton( i18n( "&Modify..." ) );
+ Engines_Button_Delete = Engines_ButtonBox->addButton( i18n( "&Delete..." ) );
+ Engines_ButtonBox->layout();
+
+ BuildEngineData();
+
+ connect( Engines_Button_Add, SIGNAL( clicked() ), this, SLOT( slotEngine_Add() ) );
+ connect( Engines_Button_Change, SIGNAL( clicked() ), this, SLOT( slotEngine_Modify() ) );
+ connect( Engines_Button_Delete, SIGNAL( clicked() ), this, SLOT( slotEngine_Delete() ) );
+ connect( Engines_White, SIGNAL( activated(int) ), this, SLOT( slotCurrent_White(int) ) );
+ connect( Engines_White_Book, SIGNAL( activated(int) ), this, SLOT( slotCurrent_White_Book(int) ) );
+ connect( Engines_Black, SIGNAL( activated(int) ), this, SLOT( slotCurrent_Black(int) ) );
+ connect( Engines_Black_Book, SIGNAL( activated(int) ), this, SLOT( slotCurrent_Black_Book(int) ) );
+ connect( White_Use_Book, SIGNAL( toggled(bool) ), this, SLOT( slotToggle_White_Book(bool) ) );
+ connect( Black_Use_Book, SIGNAL( toggled(bool) ), this, SLOT( slotToggle_Black_Book(bool) ) );
+ connect( Engines_ListView, SIGNAL( selectionChanged() ), this, SLOT( selectionChanged() ) );
+}
+setPageEngines::~setPageEngines()
+{
+ Engines_ListView->saveLayout( kapp->config(), "Engines_ListView" );
+ delete Engines_ButtonBox;
+ delete Engines_ListView;
+ delete GROUP_Engines;
+ delete GROUP_Black_Current;
+ delete GROUP_White_Current;
+}
+///////////////////////////////////////
+//
+// setPageEngines::BuildEngineData
+//
+///////////////////////////////////////
+void setPageEngines::BuildEngineData( void )
+{
+ bool WHITE_FLAG(FALSE),
+ WHITE_BK_FLAG(FALSE),
+ BLACK_FLAG(FALSE),
+ BLACK_BK_FLAG(FALSE);
+ QStringList EngineList;
+ QString proto;
+ int Index(0);
+ engineList::Iterator enginesIT;
+
+ /* Clear Comboboxes */
+ Engines_White->clear();
+ Engines_White_Book->clear();
+ Engines_Black->clear();
+ Engines_Black_Book->clear();
+ Engines_ListView->clear();
+
+ /* Handle status of Book-engine boxes */
+ White_Use_Book->setChecked( Resource->OPTION_Book_White );
+ Black_Use_Book->setChecked( Resource->OPTION_Book_Black );
+ Engines_White_Book->setEnabled( Resource->OPTION_Book_White );
+ Engines_Black_Book->setEnabled( Resource->OPTION_Book_Black );
+
+ /* Read the engine list */
+ if( Resource->engines.isEmpty() ) return;
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ switch( (*enginesIT).Protocol )
+ {
+ case UCI:
+ proto = "UCI";
+ break;
+ case XBoard: // Fall through
+ default:
+ proto = "XBoard";
+ break;
+ }
+ (void) new QListViewItem( Engines_ListView,
+ (*enginesIT).Name,
+ proto,
+ QString( "%1" ).arg( (*enginesIT).Wins ),
+ QString( "%1" ).arg( (*enginesIT).Losses ),
+ QString( "%1" ).arg( (*enginesIT).Draws ) );
+ EngineList.append( (*enginesIT).Name );
+ }
+
+ /* Insert engines into comboboxes */
+ EngineList.sort();
+ Engines_White->insertStringList( EngineList );
+ Engines_Black->insertStringList( EngineList );
+ Engines_White_Book->insertStringList( EngineList );
+ Engines_Black_Book->insertStringList( EngineList );
+
+ /* Now run the list again, setting the current engine for each combobox */
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & ENGINE_WHITE_BK )
+ for( Index = 0; Index < Engines_White_Book->count(); Index++ )
+ if( Engines_White_Book->text(Index) == (*enginesIT).Name )
+ {
+ Engines_White_Book->setCurrentItem(Index);
+ WHITE_BK_FLAG = TRUE;
+ }
+ if( (*enginesIT).CurrentRef & ENGINE_BLACK_BK )
+ for( Index = 0; Index < Engines_Black_Book->count(); Index++ )
+ if( Engines_Black_Book->text(Index) == (*enginesIT).Name )
+ {
+ Engines_Black_Book->setCurrentItem(Index);
+ BLACK_BK_FLAG = TRUE;
+ }
+ if( (*enginesIT).CurrentRef & ENGINE_WHITE )
+ for( Index = 0; Index < Engines_White->count(); Index++ )
+ if( Engines_White->text(Index) == (*enginesIT).Name )
+ {
+ Engines_White->setCurrentItem(Index);
+ WHITE_FLAG = TRUE;
+ }
+ if( (*enginesIT).CurrentRef & ENGINE_BLACK )
+ for( Index = 0; Index < Engines_Black->count(); Index++ )
+ if( Engines_Black->text(Index) == (*enginesIT).Name )
+ {
+ Engines_Black->setCurrentItem(Index);
+ BLACK_FLAG = TRUE;
+ }
+ }
+
+ /* This prevents a bug where you had to modify the current_engine_comboboxes
+ before you could get any engines to run. */
+ if( ( !WHITE_FLAG ) && ( Engines_White->count() ) ) slotCurrent_White( Engines_White->currentItem() );
+ if( ( !BLACK_FLAG ) && ( Engines_Black->count() ) ) slotCurrent_Black( Engines_Black->currentItem() );
+ if( ( !WHITE_BK_FLAG ) && ( Engines_White_Book->count() ) ) slotCurrent_White_Book( Engines_White_Book->currentItem() );
+ if( ( !BLACK_BK_FLAG ) && ( Engines_Black_Book->count() ) ) slotCurrent_Black_Book( Engines_Black_Book->currentItem() );
+
+ Engines_Button_Change->setEnabled( FALSE );
+ Engines_Button_Delete->setEnabled( FALSE );
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotEngine_Add
+//
+///////////////////////////////////////
+void setPageEngines::slotEngine_Add( void )
+{
+ Engine_Dialog = new dlg_engine( Parent, "EngineDialog", Resource );
+ connect( Engine_Dialog, SIGNAL( destroyed() ), this, SLOT( BuildEngineData() ) );
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotEngine_Modify
+//
+///////////////////////////////////////
+void setPageEngines::slotEngine_Modify( void )
+{
+ QListViewItem *Item;
+ QList<QListViewItem> Select = Engines_ListView->selectedItems();
+
+ if( Select.isEmpty() ) return;
+ Item = Select.first();
+ Engine_Dialog = new dlg_engine( Parent, "EngineDialog", Resource, Item->text(0) );
+ connect( Engine_Dialog, SIGNAL( destroyed() ), this, SLOT( BuildEngineData() ) );
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotEngine_Delete
+//
+///////////////////////////////////////
+void setPageEngines::slotEngine_Delete( void )
+{
+ engineList::Iterator enginesIT;
+ QListViewItem *Item;
+ QList<QListViewItem> Select = Engines_ListView->selectedItems();
+
+ if( Select.isEmpty() ) return;
+ Item = Select.first();
+
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).Name == Item->text(0) ) break;
+ }
+ Resource->engines.remove(enginesIT);
+ BuildEngineData();
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotCurrent_White
+//
+///////////////////////////////////////
+void setPageEngines::slotCurrent_White( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = Engines_White->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & ENGINE_WHITE ) (*enginesIT).CurrentRef -= ENGINE_WHITE;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= ENGINE_WHITE;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotCurrent_White_Book
+//
+///////////////////////////////////////
+void setPageEngines::slotCurrent_White_Book( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = Engines_White_Book->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & ENGINE_WHITE_BK ) (*enginesIT).CurrentRef -= ENGINE_WHITE_BK;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= ENGINE_WHITE_BK;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotCurrent_Black
+//
+///////////////////////////////////////
+void setPageEngines::slotCurrent_Black( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = Engines_Black->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & ENGINE_BLACK ) (*enginesIT).CurrentRef -= ENGINE_BLACK;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= ENGINE_BLACK;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotCurrent_Black_Book
+//
+///////////////////////////////////////
+void setPageEngines::slotCurrent_Black_Book( int Index )
+{
+ QString Name;
+ engineList::Iterator enginesIT;
+
+ Name = Engines_Black_Book->text(Index);
+ for ( enginesIT = Resource->engines.begin(); enginesIT != Resource->engines.end(); ++enginesIT )
+ {
+ if( (*enginesIT).CurrentRef & ENGINE_BLACK_BK ) (*enginesIT).CurrentRef -= ENGINE_BLACK_BK;
+ if( (*enginesIT).Name == Name ) (*enginesIT).CurrentRef |= ENGINE_BLACK_BK;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotToggle_White_Book
+//
+///////////////////////////////////////
+void setPageEngines::slotToggle_White_Book( bool state )
+{
+ Resource->OPTION_Book_White = state;
+ BuildEngineData();
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::slotToggle_Black_Book
+//
+///////////////////////////////////////
+void setPageEngines::slotToggle_Black_Book( bool state )
+{
+ Resource->OPTION_Book_Black = state;
+ BuildEngineData();
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageEngines::selectionChanged
+//
+///////////////////////////////////////
+void setPageEngines::selectionChanged( void )
+{
+ if( Engines_ListView->selectedItem() == 0 )
+ {
+ Engines_Button_Change->setEnabled( FALSE );
+ Engines_Button_Delete->setEnabled( FALSE );
+ }
+ else
+ {
+ Engines_Button_Change->setEnabled( TRUE );
+ Engines_Button_Delete->setEnabled( TRUE );
+ }
+}
diff --git a/knights/setpageengines.h b/knights/setpageengines.h
new file mode 100644
index 0000000..130b151
--- /dev/null
+++ b/knights/setpageengines.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ setpageengines.h - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SETPAGEENGINES_H
+#define SETPAGEENGINES_H
+
+#include <kbuttonbox.h>
+#include <klistview.h>
+#include <kcombobox.h>
+#include <qstringlist.h>
+#include <qcheckbox.h>
+#include <qwidget.h>
+#include <qgroupbox.h>
+#include <qptrlist.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include "resource.h"
+#include "dlg_engine.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class setPageEngines : public QVBoxLayout
+{
+ Q_OBJECT
+ public:
+ setPageEngines(QWidget *parent=0, resource *Rsrc=0);
+ ~setPageEngines();
+
+ public slots:
+
+ void slotEngine_Add( void );
+ void slotEngine_Modify( void );
+ void slotEngine_Delete( void );
+
+ void slotCurrent_White( int );
+ void slotCurrent_White_Book( int );
+ void slotCurrent_Black( int );
+ void slotCurrent_Black_Book( int );
+
+ void slotToggle_White_Book( bool );
+ void slotToggle_Black_Book( bool );
+
+ signals:
+
+ void enableApply( void );
+
+ protected slots:
+ void BuildEngineData( void );
+ void selectionChanged( void );
+
+ private:
+ QWidget *Parent;
+ resource *Resource;
+
+ QHBox *BOX_Current;
+ QGroupBox *GROUP_White_Current;
+ KComboBox *Engines_White;
+ QCheckBox *White_Use_Book;
+ KComboBox *Engines_White_Book;
+ QGroupBox *GROUP_Black_Current;
+ KComboBox *Engines_Black;
+ QCheckBox *Black_Use_Book;
+ KComboBox *Engines_Black_Book;
+
+ QGroupBox *GROUP_Engines;
+ KListView *Engines_ListView;
+ KButtonBox *Engines_ButtonBox;
+ QPushButton *Engines_Button_Add;
+ QPushButton *Engines_Button_Change;
+ QPushButton *Engines_Button_Delete;
+ dlg_engine *Engine_Dialog;
+};
+
+#endif
diff --git a/knights/setpagegeneral.cpp b/knights/setpagegeneral.cpp
new file mode 100644
index 0000000..d79b8c9
--- /dev/null
+++ b/knights/setpagegeneral.cpp
@@ -0,0 +1,224 @@
+/***************************************************************************
+ setpagegeneral.cpp - description
+ -------------------
+ begin : Fri Nov 23 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kfiledialog.h>
+#include <kicontheme.h>
+#include "setpagegeneral.moc"
+
+setPageGeneral::setPageGeneral(QWidget *parent, resource *Rsrc ) : QVBoxLayout(parent)
+{
+ Parent = parent;
+ Resource = Rsrc;
+
+ GROUP_UserName = new QGroupBox( 1,
+ Qt::Horizontal,
+ i18n( "Your Name:" ),
+ parent );
+ addWidget( GROUP_UserName );
+ EDIT_UserName = new KLineEdit( GROUP_UserName );
+ EDIT_UserName->setText( Resource->Local_Player );
+ connect( EDIT_UserName, SIGNAL( textChanged(const QString&) ), this, SLOT( slot_UserName(const QString&) ) );
+
+ BOX_SaveInit = new QHBox( parent );
+ addWidget( BOX_SaveInit );
+
+ GROUP_OnInit = new QButtonGroup( 3, Qt::Vertical, i18n("When Knights Begins It Should:"), BOX_SaveInit );
+ BUTTON_Init_Nothing = new QRadioButton( i18n( "Do Nothing" ), GROUP_OnInit );
+ BUTTON_Init_VsPC = new QRadioButton( i18n( "Start a Match vs. PC" ), GROUP_OnInit );
+ BUTTON_Init_Connect = new QRadioButton( i18n( "Connect to ICS" ), GROUP_OnInit );
+ GROUP_OnInit->setExclusive( TRUE );
+ if( Resource->OPTION_On_Init == 0 ) GROUP_OnInit->setButton( 0 );
+ else if( Resource->OPTION_On_Init == MENU_VS_PC ) GROUP_OnInit->setButton( 1 );
+ else GROUP_OnInit->setButton( 2 );
+ connect( GROUP_OnInit, SIGNAL( clicked(int) ),
+ this, SLOT( slot_Init(int) ) );
+
+ GROUP_AutoSave = new QButtonGroup( 3, Qt::Vertical, i18n("Save Match on Close?"), BOX_SaveInit );
+ BUTTON_AutoSave_Yes = new QRadioButton( i18n( "Yes" ), GROUP_AutoSave );
+ BUTTON_AutoSave_No = new QRadioButton( i18n( "No" ), GROUP_AutoSave );
+ BUTTON_AutoSave_Ask = new QRadioButton( i18n( "Ask" ), GROUP_AutoSave );
+ GROUP_AutoSave->setExclusive( TRUE );
+ if( Resource->PromptForSaving == "Yes" ) GROUP_AutoSave->setButton( 0 );
+ else if( Resource->PromptForSaving == "No" ) GROUP_AutoSave->setButton( 1 );
+ else GROUP_AutoSave->setButton( 2 );
+ connect( GROUP_AutoSave, SIGNAL( clicked(int) ),
+ this, SLOT( slot_AutoSave(int) ) );
+
+ GROUP_Reuse_PGN = new QGroupBox( 2,
+ Qt::Vertical,
+ i18n( "Append to Save File:" ),
+ parent );
+ addWidget( GROUP_Reuse_PGN );
+ BUTTON_Reuse_PGN = new QCheckBox( i18n( "Append to Save File" ), GROUP_Reuse_PGN );
+ BUTTON_Reuse_PGN->setChecked( Resource->OPTION_Reuse_PGN );
+ connect( BUTTON_Reuse_PGN, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_Reuse_PGN(bool) ) );
+
+ BOX_Reuse_PGN = new QHBox( GROUP_Reuse_PGN );
+ EDIT_PGN_Filename = new KLineEdit( BOX_Reuse_PGN );
+ EDIT_PGN_Filename->setText( Resource->PGN_Filename );
+ connect( EDIT_PGN_Filename, SIGNAL( textChanged(const QString&) ), this, SLOT( slot_PGN_Filename(const QString&) ) );
+ BUTTON_PGN_Filename = new QPushButton( BOX_Reuse_PGN );
+ BUTTON_PGN_Filename->setPixmap( Resource->LoadIcon( QString( "fileopen" ), KIcon::Toolbar ) );
+ connect( BUTTON_PGN_Filename, SIGNAL( clicked() ), this, SLOT( slot_PGN_Filename_Button() ) );
+ EDIT_PGN_Filename->setEnabled( Resource->OPTION_Reuse_PGN );
+ BUTTON_PGN_Filename->setEnabled( Resource->OPTION_Reuse_PGN );
+
+ BUTTON_Pause_On_Minimize = new QCheckBox( i18n( "Pause on Minimize" ), parent );
+ BUTTON_Pause_On_Minimize->setChecked( Resource->OPTION_Pause_On_Minimize );
+ connect( BUTTON_Pause_On_Minimize, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_Pause_On_Minimize(bool) ) );
+ addWidget( BUTTON_Pause_On_Minimize );
+
+ BUTTON_Auto_Queen = new QCheckBox( i18n( "Always Promote to Queen" ), parent );
+ BUTTON_Auto_Queen->setChecked( Resource->OPTION_Auto_Queen );
+ connect( BUTTON_Auto_Queen, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_Auto_Queen(bool) ) );
+ addWidget( BUTTON_Auto_Queen );
+
+ BUTTON_Auto_Flag = new QCheckBox( i18n( "Call Flag Automatically" ), parent );
+ BUTTON_Auto_Flag->setChecked( Resource->OPTION_Auto_Call_Flag );
+ connect( BUTTON_Auto_Flag, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_Auto_Flag(bool) ) );
+ addWidget( BUTTON_Auto_Flag );
+}
+setPageGeneral::~setPageGeneral()
+{
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_AutoSave
+//
+///////////////////////////////////////
+void setPageGeneral::slot_AutoSave( int state )
+{
+ switch( state )
+ {
+ case 0:
+ Resource->PromptForSaving = "Yes";
+ break;
+ case 1:
+ Resource->PromptForSaving = "No";
+ break;
+ case 2:
+ Resource->PromptForSaving = "";
+ break;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_Init
+//
+///////////////////////////////////////
+void setPageGeneral::slot_Init( int state )
+{
+ switch( state )
+ {
+ case 0:
+ Resource->OPTION_On_Init = 0;
+ break;
+ case 1:
+ Resource->OPTION_On_Init = MENU_VS_PC;
+ break;
+ case 2:
+ Resource->OPTION_On_Init = MENU_CONNECT;
+ break;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_Pause_On_Minimize
+//
+///////////////////////////////////////
+void setPageGeneral::slot_Pause_On_Minimize( bool state )
+{
+ Resource->OPTION_Pause_On_Minimize = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_Auto_Queen
+//
+///////////////////////////////////////
+void setPageGeneral::slot_Auto_Queen( bool state )
+{
+ Resource->OPTION_Auto_Queen = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_Auto_Flag
+//
+///////////////////////////////////////
+void setPageGeneral::slot_Auto_Flag( bool state )
+{
+ Resource->OPTION_Auto_Call_Flag = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_UserName
+//
+///////////////////////////////////////
+void setPageGeneral::slot_UserName( const QString& string )
+{
+ Resource->Local_Player = string;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_Reuse_PGN
+//
+///////////////////////////////////////
+void setPageGeneral::slot_Reuse_PGN( bool state )
+{
+ Resource->OPTION_Reuse_PGN = state;
+ EDIT_PGN_Filename->setEnabled( state );
+ BUTTON_PGN_Filename->setEnabled( state );
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_PGN_Filename
+//
+///////////////////////////////////////
+void setPageGeneral::slot_PGN_Filename( const QString& string )
+{
+ Resource->PGN_Filename = string;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageGeneral::slot_PGN_Filename_Button
+//
+///////////////////////////////////////
+void setPageGeneral::slot_PGN_Filename_Button( void )
+{
+ QString temp;
+
+ temp = KFileDialog::getOpenFileName( QString::null,
+ QString( "*" ),
+ BOX_Reuse_PGN,
+ i18n( "Find PGN..." ) );
+ if( temp.isEmpty() ) return;
+ EDIT_PGN_Filename->setText( temp );
+ Resource->PGN_Filename = temp;
+ emit enableApply();
+}
+
diff --git a/knights/setpagegeneral.h b/knights/setpagegeneral.h
new file mode 100644
index 0000000..16ada66
--- /dev/null
+++ b/knights/setpagegeneral.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ setpagegeneral.h - description
+ -------------------
+ begin : Fri Nov 23 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SETPAGEGENERAL_H
+#define SETPAGEGENERAL_H
+
+#include <klineedit.h>
+#include <qwidget.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qbuttongroup.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class setPageGeneral : public QVBoxLayout
+{
+ Q_OBJECT
+ public:
+ setPageGeneral(QWidget *parent=0, resource *Rsrc=0);
+ ~setPageGeneral();
+ signals:
+ void enableApply( void );
+ public slots:
+ void slot_AutoSave( int state );
+ void slot_Init( int state );
+ void slot_UserName( const QString& );
+ void slot_Pause_On_Minimize( bool state );
+ void slot_Auto_Queen( bool state );
+ void slot_Auto_Flag( bool state );
+ void slot_Reuse_PGN( bool );
+ void slot_PGN_Filename( const QString& );
+ void slot_PGN_Filename_Button( void );
+ private:
+ QWidget *Parent;
+ resource *Resource;
+
+ QGroupBox *GROUP_UserName;
+ KLineEdit *EDIT_UserName;
+ QHBox *BOX_SaveInit;
+ QButtonGroup *GROUP_AutoSave;
+ QRadioButton *BUTTON_AutoSave_Yes;
+ QRadioButton *BUTTON_AutoSave_No;
+ QRadioButton *BUTTON_AutoSave_Ask;
+ QButtonGroup *GROUP_OnInit;
+ QRadioButton *BUTTON_Init_Nothing;
+ QRadioButton *BUTTON_Init_VsPC;
+ QRadioButton *BUTTON_Init_Connect;
+ QGroupBox *GROUP_Reuse_PGN;
+ QCheckBox *BUTTON_Reuse_PGN;
+ QHBox *BOX_Reuse_PGN;
+ KLineEdit *EDIT_PGN_Filename;
+ QPushButton *BUTTON_PGN_Filename;
+ QCheckBox *BUTTON_Pause_On_Minimize;
+ QCheckBox *BUTTON_Auto_Queen;
+ QCheckBox *BUTTON_Auto_Flag;
+};
+
+#endif
diff --git a/knights/setpageservers.cpp b/knights/setpageservers.cpp
new file mode 100644
index 0000000..8d570a1
--- /dev/null
+++ b/knights/setpageservers.cpp
@@ -0,0 +1,379 @@
+/***************************************************************************
+ setpageservers.cpp - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "setpageservers.moc"
+#include <qstyle.h>
+#include <kicontheme.h>
+
+setPageServers::setPageServers(QWidget *parent, resource *Rsrc ) : QVBoxLayout(parent)
+{
+ QStyle& Style = QApplication::style();
+ margin = Style.defaultFrameWidth();
+ Resource = Rsrc;
+ Servers_ListView = NULL;
+ resetServer = FALSE;
+
+ TabParent = new QTabWidget( parent, "setPageDisplay" );
+ initTab1();
+ initTab2();
+ addWidget( TabParent );
+}
+setPageServers::~setPageServers()
+{
+ Servers_ListView->saveLayout( kapp->config(), "Servers_ListView" );
+ delete Servers_ButtonBox;
+ delete Servers_ListView;
+ delete GROUP_Servers;
+ delete GROUP_Current;
+}
+///////////////////////////////////////
+//
+// setPageServers::initTab1
+//
+///////////////////////////////////////
+void setPageServers::initTab1( void )
+{
+ Tab1 = new QVBox( TabParent );
+ Tab1->setMargin( margin );
+
+ /* Current Server */
+ GROUP_Current = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Current Server" ),
+ Tab1 );
+
+ Servers = new KComboBox ( GROUP_Current );
+ Servers->setEditable( FALSE );
+
+ /* Chess Servers ListView */
+ GROUP_Servers = new QGroupBox( 2,
+ Qt::Horizontal,
+ i18n( "Chess Servers" ),
+ Tab1 );
+
+ Servers_ListView = new KListView( GROUP_Servers );
+ Servers_ListView->addColumn( i18n( "Name" ) );
+ Servers_ListView->addColumn( i18n( "URL" ) );
+ Servers_ListView->setAllColumnsShowFocus( TRUE );
+ Servers_ListView->setMultiSelection( FALSE );
+ Servers_ListView->setShowSortIndicator( TRUE );
+ Servers_ListView->restoreLayout( kapp->config(), "Servers_ListView" );
+
+ Servers_ButtonBox = new KButtonBox( GROUP_Servers, Vertical );
+ Servers_Button_Add = Servers_ButtonBox->addButton( i18n( "&Add..." ) );
+ Servers_Button_Change = Servers_ButtonBox->addButton( i18n( "&Modify..." ) );
+ Servers_Button_Delete = Servers_ButtonBox->addButton( i18n( "&Delete..." ) );
+ Servers_ButtonBox->layout();
+
+ BuildServerData();
+
+ connect( Servers_Button_Add, SIGNAL( clicked() ), this, SLOT( slotServer_Add() ) );
+ connect( Servers_Button_Change, SIGNAL( clicked() ), this, SLOT( slotServer_Modify() ) );
+ connect( Servers_Button_Delete, SIGNAL( clicked() ), this, SLOT( slotServer_Delete() ) );
+ connect( Servers, SIGNAL( activated(int) ), this, SLOT( slotCurrent(int) ) );
+ connect( Servers_ListView, SIGNAL( selectionChanged() ), this, SLOT( selectionChanged() ) );
+
+ TabParent->addTab( Tab1, i18n("Servers") );
+}
+///////////////////////////////////////
+//
+// setPageServers::initTab2
+//
+///////////////////////////////////////
+void setPageServers::initTab2( void )
+{
+ QStringList FilterLevels;
+ Tab2 = new QVBox( TabParent );
+ Tab2->setMargin( margin );
+
+ /* Current Profanity Filter */
+ BOX_Profanity = new QGroupBox( 1,
+ Qt::Vertical,
+ i18n( "Profanity Filter" ),
+ Tab2 );
+ COMBO_Profanity = new KComboBox ( BOX_Profanity );
+ COMBO_Profanity->setEditable( FALSE );
+ FilterLevels << i18n("Filter Everything") << i18n("Default") << "---" << "---" << "---" << i18n("No Filtering");
+ COMBO_Profanity->insertStringList( FilterLevels );
+ COMBO_Profanity->setCurrentItem( Resource->OPTION_Profanity );
+ connect( COMBO_Profanity, SIGNAL( activated(int) ), this, SLOT( slot_Profanity(int) ) );
+
+ BUTTON_Auto_Close_ICS = new QCheckBox( i18n( "Automatically Close Previous ICS Match" ), Tab2 );
+ BUTTON_Auto_Close_ICS->setChecked( Resource->OPTION_Auto_Close_Last_ICS );
+ connect( BUTTON_Auto_Close_ICS, SIGNAL( toggled(bool) ),
+ this, SLOT( slot_Auto_Close_ICS(bool) ) );
+
+ BUTTON_Private = new QCheckBox( i18n( "Private Matches" ), Tab2 );
+ BUTTON_Private->setChecked( Resource->OPTION_Private );
+ connect( BUTTON_Private, SIGNAL( toggled(bool) ), this, SLOT( slot_Private(bool) ) );
+
+ BUTTON_Premove = new QCheckBox( i18n( "Enable Premove" ), Tab2 );
+ BUTTON_Premove->setChecked( Resource->OPTION_Premove );
+ connect( BUTTON_Premove, SIGNAL( toggled(bool) ), this, SLOT( slot_Premove(bool) ) );
+
+ BUTTON_Kibitz = new QCheckBox( i18n( "Enable Kibitzes" ), Tab2 );
+ BUTTON_Kibitz->setChecked( Resource->OPTION_Kibitz );
+ connect( BUTTON_Kibitz, SIGNAL( toggled(bool) ), this, SLOT( slot_Kibitz(bool) ) );
+
+ BUTTON_Tell = new QCheckBox( i18n( "Enable Unregistered Tells" ), Tab2 );
+ BUTTON_Tell->setChecked( Resource->OPTION_Tell );
+ connect( BUTTON_Tell, SIGNAL( toggled(bool) ), this, SLOT( slot_Tell(bool) ) );
+
+ BUTTON_Shout = new QCheckBox( i18n( "Enable Shouts" ), Tab2 );
+ BUTTON_Shout->setChecked( Resource->OPTION_Shout );
+ connect( BUTTON_Shout, SIGNAL( toggled(bool) ), this, SLOT( slot_Shout(bool) ) );
+
+ BUTTON_Seek = new QCheckBox( i18n( "Enable Seeks" ), Tab2 );
+ BUTTON_Seek->setChecked( Resource->OPTION_Seek );
+ connect( BUTTON_Seek, SIGNAL( toggled(bool) ), this, SLOT( slot_Seek(bool) ) );
+
+ BOX_SeekTimer = new QHBox( Tab2 );
+ BUTTON_SeekTimer = new QSpinBox( 3, 120, 1, BOX_SeekTimer );
+ BUTTON_SeekTimer->setSuffix( i18n(" sec.") );
+ BUTTON_SeekTimer->setValue( Resource->Seek_Timer / 10 );
+ connect( BUTTON_SeekTimer, SIGNAL( valueChanged(int) ),
+ this, SLOT( slot_SeekTimer(int) ) );
+ LABEL_SeekTimer = new QLabel( i18n("Seconds Between Seek Updates"), BOX_SeekTimer );
+
+ TabParent->addTab( Tab2, i18n("Options") );
+}
+///////////////////////////////////////
+//
+// setPageServers::BuildServerData
+//
+///////////////////////////////////////
+void setPageServers::BuildServerData( void )
+{
+ bool SERVER_FLAG(FALSE);
+ QStringList ServerList;
+ int Index(0);
+ serverList::Iterator serversIT;
+
+ /* Clear Comboboxes */
+ Servers->clear();
+ Servers_ListView->clear();
+ /* Read the server list */
+ if( Resource->servers.isEmpty() ) return;
+ for ( serversIT = Resource->servers.begin(); serversIT != Resource->servers.end(); ++serversIT )
+ {
+ (void) new QListViewItem( Servers_ListView,
+ (*serversIT).Name,
+ (*serversIT).URL );
+ ServerList.append( (*serversIT).Name );
+ }
+ /* Insert engines into comboboxes */
+ ServerList.sort();
+ Servers->insertStringList( ServerList );
+ /* Now run the list again, setting the current engine for each combobox */
+ for ( serversIT = Resource->servers.begin(); serversIT != Resource->servers.end(); ++serversIT )
+ {
+ if( (*serversIT).CurrentRef )
+ for( Index = 0; Index < Servers->count(); Index++ )
+ if( Servers->text(Index) == (*serversIT).Name )
+ {
+ Servers->setCurrentItem(Index);
+ SERVER_FLAG = TRUE;
+ }
+ }
+ /* This prevents a bug where you had to modify the current_server_combobox
+ before you could get any servers to run. */
+ if( ( !SERVER_FLAG ) && ( Servers->count() ) ) slotCurrent( Servers->currentItem() );
+
+ Servers_Button_Change->setEnabled( FALSE );
+ Servers_Button_Delete->setEnabled( FALSE );
+}
+///////////////////////////////////////
+//
+// setPageServers::slotServer_Add
+//
+///////////////////////////////////////
+void setPageServers::slotServer_Add( void )
+{
+ Server_Dialog = new dlg_server( TabParent, "ServerDialog", Resource );
+ connect( Server_Dialog, SIGNAL( destroyed() ), this, SLOT( BuildServerData() ) );
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slotServer_Modify
+//
+///////////////////////////////////////
+void setPageServers::slotServer_Modify( void )
+{
+ QListViewItem *Item;
+ QList<QListViewItem> Select = Servers_ListView->selectedItems();
+
+ if( Select.isEmpty() ) return;
+ Item = Select.first();
+ Server_Dialog = new dlg_server( TabParent, "ServerDialog", Resource, Item->text(0) );
+ connect( Server_Dialog, SIGNAL( destroyed() ), this, SLOT( BuildServerData() ) );
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slotServer_Delete
+//
+///////////////////////////////////////
+void setPageServers::slotServer_Delete( void )
+{
+ serverList::Iterator serversIT;
+ QListViewItem *Item;
+ QList<QListViewItem> Select = Servers_ListView->selectedItems();
+
+ if( Select.isEmpty() ) return;
+ Item = Select.first();
+
+ for ( serversIT = Resource->servers.begin(); serversIT != Resource->servers.end(); ++serversIT )
+ {
+ if( (*serversIT).Name == Item->text(0) ) break;
+ }
+ Resource->servers.remove(serversIT);
+ BuildServerData();
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slotCurrent
+//
+///////////////////////////////////////
+void setPageServers::slotCurrent( int Index )
+{
+ QString Name;
+ serverList::Iterator serversIT;
+
+ Name = Servers->text(Index);
+ for ( serversIT = Resource->servers.begin(); serversIT != Resource->servers.end(); ++serversIT )
+ {
+ if( (*serversIT).CurrentRef ) (*serversIT).CurrentRef = FALSE;
+ if( (*serversIT).Name == Name ) (*serversIT).CurrentRef = TRUE;
+ }
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Profanity
+//
+///////////////////////////////////////
+void setPageServers::slot_Profanity( int Index )
+{
+ Resource->OPTION_Profanity = Index;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Premove
+//
+///////////////////////////////////////
+void setPageServers::slot_Premove( bool state )
+{
+ Resource->OPTION_Premove = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Shout
+//
+///////////////////////////////////////
+void setPageServers::slot_Shout( bool state )
+{
+ Resource->OPTION_Shout = state;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Private
+//
+///////////////////////////////////////
+void setPageServers::slot_Private( bool state )
+{
+ Resource->OPTION_Private = state;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Kibitz
+//
+///////////////////////////////////////
+void setPageServers::slot_Kibitz( bool state )
+{
+ Resource->OPTION_Kibitz = state;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Tell
+//
+///////////////////////////////////////
+void setPageServers::slot_Tell( bool state )
+{
+ Resource->OPTION_Tell = state;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Seek
+//
+///////////////////////////////////////
+void setPageServers::slot_Seek( bool state )
+{
+ Resource->OPTION_Seek = state;
+ emit enableApply();
+ resetServer = TRUE;
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_Auto_Close_ICS
+//
+///////////////////////////////////////
+void setPageServers::slot_Auto_Close_ICS( bool state )
+{
+ Resource->OPTION_Auto_Close_Last_ICS = state;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::slot_SeekTimer
+//
+///////////////////////////////////////
+void setPageServers::slot_SeekTimer( int value )
+{
+ Resource->Seek_Timer = value * 10;
+ emit enableApply();
+}
+///////////////////////////////////////
+//
+// setPageServers::selectionChanged
+//
+///////////////////////////////////////
+void setPageServers::selectionChanged( void )
+{
+ if( Servers_ListView->selectedItem() == 0 )
+ {
+ Servers_Button_Change->setEnabled( FALSE );
+ Servers_Button_Delete->setEnabled( FALSE );
+ }
+ else
+ {
+ Servers_Button_Change->setEnabled( TRUE );
+ Servers_Button_Delete->setEnabled( TRUE );
+ }
+}
diff --git a/knights/setpageservers.h b/knights/setpageservers.h
new file mode 100644
index 0000000..4f4c21c
--- /dev/null
+++ b/knights/setpageservers.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ setpageservers.h - description
+ -------------------
+ begin : Thu Aug 16 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SETPAGESERVERS_H
+#define SETPAGESERVERS_H
+
+#include <qtabwidget.h>
+#include <kbuttonbox.h>
+#include <klistview.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qstringlist.h>
+#include <qcheckbox.h>
+#include <qwidget.h>
+#include <qgroupbox.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qptrlist.h>
+#include <qlayout.h>
+#include "resource.h"
+#include "dlg_server.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class setPageServers : public QVBoxLayout
+{
+ Q_OBJECT
+ public:
+ setPageServers(QWidget *parent=0, resource *Rsrc=0);
+ ~setPageServers();
+ bool resetServer;
+
+ public slots:
+ void slotServer_Add( void );
+ void slotServer_Modify( void );
+ void slotServer_Delete( void );
+
+ void slotCurrent( int );
+
+ void slot_Premove( bool );
+ void slot_Private( bool );
+ void slot_Profanity( int );
+ void slot_Kibitz( bool );
+ void slot_Tell( bool );
+ void slot_Shout( bool );
+ void slot_Seek( bool );
+ void slot_SeekTimer( int value );
+ void slot_Auto_Close_ICS( bool state );
+
+ signals:
+ void enableApply( void );
+
+ protected slots:
+ void BuildServerData( void );
+ void selectionChanged( void );
+
+ protected:
+ void initTab1( void );
+ void initTab2( void );
+
+ private:
+ resource *Resource;
+ int margin;
+ QTabWidget *TabParent;
+
+ /* Tab 1 : Servers */
+ QVBox *Tab1;
+ QGroupBox *GROUP_Current;
+ QGroupBox *GROUP_Servers;
+ KComboBox *Servers;
+ KListView *Servers_ListView;
+ KButtonBox *Servers_ButtonBox;
+ QPushButton *Servers_Button_Add;
+ QPushButton *Servers_Button_Change;
+ QPushButton *Servers_Button_Delete;
+ dlg_server *Server_Dialog;
+ /* Tab 2 : Options */
+ QVBox *Tab2;
+ QGroupBox *BOX_Profanity;
+ KComboBox *COMBO_Profanity;
+ QCheckBox *BUTTON_Premove;
+ QCheckBox *BUTTON_Private;
+ QCheckBox *BUTTON_Kibitz;
+ QCheckBox *BUTTON_Tell;
+ QCheckBox *BUTTON_Shout;
+ QCheckBox *BUTTON_Seek;
+ QCheckBox *BUTTON_Auto_Close_ICS;
+ QHBox *BOX_SeekTimer;
+ QSpinBox *BUTTON_SeekTimer;
+ QLabel *LABEL_SeekTimer;
+};
+
+#endif
diff --git a/knights/splash.cpp b/knights/splash.cpp
new file mode 100644
index 0000000..cfccb62
--- /dev/null
+++ b/knights/splash.cpp
@@ -0,0 +1,40 @@
+/***************************************************************************
+ splash.cpp - description
+ -------------------
+ begin : Tue Jul 17 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "splash.moc"
+#include <qpixmap.h>
+#include <kstddirs.h>
+#include <kwin.h>
+#include <qapplication.h>
+
+splash::splash() :
+ QWidget( 0, "splash", Qt::WStyle_Customize | Qt::WStyle_NoBorder )
+{
+ QPixmap SplashImage( locate("data", "knights/splash.png" ) );
+ setPaletteBackgroundPixmap( SplashImage );
+
+ QSize Hint = SplashImage.size();
+ setFixedSize( Hint );
+
+ move( ( QApplication::desktop()->width() - Hint.width() ) / 2,
+ ( QApplication::desktop()->height() - Hint.height() ) / 2 );
+ show();
+ repaint( FALSE );
+}
+splash::~splash()
+{
+}
diff --git a/knights/splash.h b/knights/splash.h
new file mode 100644
index 0000000..93cdc6c
--- /dev/null
+++ b/knights/splash.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ splash.h - description
+ -------------------
+ begin : Tue Jul 17 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SPLASH_H
+#define SPLASH_H
+
+#include <qwidget.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class splash : public QWidget
+{
+ Q_OBJECT
+ public:
+ splash();
+ ~splash();
+};
+
+#endif
diff --git a/knights/tab_pgnview.cpp b/knights/tab_pgnview.cpp
new file mode 100644
index 0000000..4164f31
--- /dev/null
+++ b/knights/tab_pgnview.cpp
@@ -0,0 +1,160 @@
+/***************************************************************************
+ tab_pgnview.cpp - description
+ -------------------
+ begin : Sat Jan 25 2003
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tab_pgnview.moc"
+#include "tabmanager.h"
+#include "resource.h"
+#include "pgn.h"
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <kstddirs.h>
+#include <ktempfile.h>
+
+tab_pgnView::tab_pgnView(pgn *parent, resource *Rsrc ) : KnightsTextView(0,Rsrc)
+{
+ myParent = parent;
+ whiteImage = NULL;
+ blackImage = NULL;
+
+ QString source = locate( "appdata", "pgn_template.kml" );
+ QFile file( source );
+ if( file.open( IO_ReadOnly ) )
+ {
+ QTextStream stream( &file );
+ document = stream.read();
+ file.close();
+ }
+ else
+ {
+ kdWarning() << "tab_pgnView::tab_pgnView: Can not find PGN Template" << endl;
+ }
+}
+
+tab_pgnView::~tab_pgnView()
+{
+ if( whiteImage )
+ delete whiteImage;
+ if( blackImage )
+ delete blackImage;
+}
+///////////////////////////////////////
+//
+// tab_pgnView::init
+//
+///////////////////////////////////////
+void tab_pgnView::init( void )
+{
+ /* Replace macros with data */
+ document.replace( QRegExp( "%site%" ), myParent->TAG_Site );
+ document.replace( QRegExp( "%date%" ), myParent->TAG_Date );
+ document.replace( QRegExp( "%round%" ), myParent->TAG_Round );
+ document.replace( QRegExp( "%result%" ), myParent->TAG_Result );
+ document.replace( QRegExp( "%white%" ), myParent->TAG_White );
+ document.replace( QRegExp( "%whitetitle%" ), myParent->TAG_WhiteTitle );
+ document.replace( QRegExp( "%whiteelo%" ), myParent->TAG_WhiteElo );
+ document.replace( QRegExp( "%whiteuscf%" ), myParent->TAG_WhiteUSCF );
+ document.replace( QRegExp( "%whitena%" ), myParent->TAG_WhiteNA );
+ document.replace( QRegExp( "%whitetype%" ), myParent->TAG_WhiteType );
+ document.replace( QRegExp( "%black%" ), myParent->TAG_Black );
+ document.replace( QRegExp( "%blacktitle%" ), myParent->TAG_BlackTitle );
+ document.replace( QRegExp( "%blackelo%" ), myParent->TAG_BlackElo );
+ document.replace( QRegExp( "%blackuscf%" ), myParent->TAG_BlackUSCF );
+ document.replace( QRegExp( "%blackna%" ), myParent->TAG_BlackNA );
+ document.replace( QRegExp( "%blacktype%" ), myParent->TAG_BlackType );
+ document.replace( QRegExp( "%time%" ), myParent->TAG_Time );
+ document.replace( QRegExp( "%utctime%" ), myParent->TAG_UTCTime );
+ document.replace( QRegExp( "%utcdate%" ), myParent->TAG_UTCDate );
+ document.replace( QRegExp( "%event%" ), myParent->TAG_Event );
+ document.replace( QRegExp( "%eventdate%" ), myParent->TAG_EventDate );
+ document.replace( QRegExp( "%eventsponsor"), myParent->TAG_EventSponsor );
+ document.replace( QRegExp( "%section%" ), myParent->TAG_Section );
+ document.replace( QRegExp( "%stage%" ), myParent->TAG_Stage );
+ document.replace( QRegExp( "%board%" ), myParent->TAG_Board );
+ document.replace( QRegExp( "%opening%" ), myParent->TAG_Opening );
+ document.replace( QRegExp( "%variation%" ), myParent->TAG_Variation );
+ document.replace( QRegExp( "%subvariation%" ), myParent->TAG_SubVariation );
+ document.replace( QRegExp( "%eco%" ), myParent->TAG_ECO );
+ document.replace( QRegExp( "%nic%" ), myParent->TAG_NIC );
+ document.replace( QRegExp( "%timecontrol%" ), myParent->TAG_TimeControl );
+ document.replace( QRegExp( "%termination%" ), myParent->TAG_Termination );
+ document.replace( QRegExp( "%setup%" ), myParent->TAG_SetUp );
+ document.replace( QRegExp( "%fen%" ), myParent->TAG_FEN );
+ document.replace( QRegExp( "%annotator%" ), myParent->TAG_Annotator );
+ document.replace( QRegExp( "%mode%" ), myParent->TAG_Mode );
+ document.replace( QRegExp( "%plycount%" ), myParent->TAG_PlyCount );
+
+ /* Get the White Player's Image */
+ QPixmap wi = myResource->loadSCIDImage( myParent->TAG_White );
+ if( wi.isNull() )
+ {
+ if( myParent->TAG_WhiteType == "program" )
+ wi.load( locate("data", "knights/default-engine-portrait.jpg" ) );
+ else
+ wi.load( locate("data", "knights/default-portrait.jpg" ) );
+ }
+ whiteImage = new KTempFile();
+ whiteImage->setAutoDelete( TRUE );
+ wi.save( whiteImage->name(), "PNG" );
+ document.replace( QRegExp( "%whiteimage%" ), whiteImage->name() );
+
+ /* Get the Black Player's Image */
+ QPixmap bi = myResource->loadSCIDImage( myParent->TAG_Black );
+ if( bi.isNull() )
+ {
+ if( myParent->TAG_BlackType == "program" )
+ bi.load( locate("data", "knights/default-engine-portrait.jpg" ) );
+ else
+ bi.load( locate("data", "knights/default-portrait.jpg" ) );
+ }
+ blackImage = new KTempFile();
+ blackImage->setAutoDelete( TRUE );
+ bi.save( blackImage->name(), "PNG" );
+ document.replace( QRegExp( "%blackimage%" ), blackImage->name() );
+
+ /* Obtain the move data */
+ QString moves;
+ QStringList *list;
+ if( myParent->Move_Data.isEmpty() )
+ {
+ list = myParent->notation(2);
+ }
+ else
+ {
+ list = new QStringList( myParent->Move_Data );
+ }
+
+ /* Do some formatting and then merge the strings */
+ for( QStringList::Iterator i = list->begin(); i != list->end(); i++ )
+ {
+ (*i).replace( QRegExp( "[^\\0040-\\0176]" ), "" );
+ (*i).replace( QRegExp( "\\(" ), "<i>(" );
+ (*i).replace( QRegExp( "\\)" ), ")</i>" );
+ (*i).replace( QRegExp( "\\{" ), "<b>{" );
+ (*i).replace( QRegExp( "\\}" ), "}</b>" );
+ }
+ moves = list->join( " " );
+ delete list;
+
+ int pos = document.find( "%moves%" );
+ if( pos != -1 )
+ {
+ document.remove( (unsigned int)pos, 7 );
+ document.insert( (unsigned int)pos, moves );
+ }
+ setText( document );
+}
diff --git a/knights/tab_pgnview.h b/knights/tab_pgnview.h
new file mode 100644
index 0000000..d5a9a4b
--- /dev/null
+++ b/knights/tab_pgnview.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ tab_pgnview.h - description
+ -------------------
+ begin : Sat Jan 25 2003
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TAB_PGNVIEW_H
+#define TAB_PGNVIEW_H
+
+#include "knightstextview.h"
+#include <qstring.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class resource;
+class pgn;
+class KTempFile;
+
+class tab_pgnView : public KnightsTextView
+{
+ Q_OBJECT
+ public:
+ tab_pgnView(pgn *parent, resource *Rsrc );
+ ~tab_pgnView();
+ void init( void );
+
+ protected:
+ pgn *myParent;
+ QString document;
+ KTempFile *whiteImage;
+ KTempFile *blackImage;
+};
+
+#endif
diff --git a/knights/tab_seeklist.cpp b/knights/tab_seeklist.cpp
new file mode 100644
index 0000000..d7554a3
--- /dev/null
+++ b/knights/tab_seeklist.cpp
@@ -0,0 +1,209 @@
+/***************************************************************************
+ tab_seeklist.cpp - description
+ -------------------
+ begin : Sat Sep 14 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tab_seeklist.moc"
+#include "resource.h"
+#include <kiconloader.h>
+#include <qregexp.h>
+
+tab_SeekList::tab_SeekList(QWidget *parent, const char *name, resource *Rsrc ) : KListView(parent,name)
+{
+ myResource = Rsrc;
+ seek = FALSE;
+ addColumn( i18n( "Name" ) );
+ addColumn( i18n( "Rating" ) );
+ addColumn( i18n( "Match Type" ) );
+ addColumn( i18n( "Is Rated?" ) );
+ addColumn( i18n( "Base Time" ) );
+ addColumn( i18n( "Increment" ) );
+ setShowSortIndicator( TRUE );
+ setAllColumnsShowFocus( TRUE );
+ setMultiSelection( FALSE );
+ restoreLayout( kapp->config(), "Sought_ListView" );
+
+ menuSeek = new KPopupMenu( this );
+ menuSeek->setCheckable( TRUE );
+ menuSeek->insertItem( i18n("Seek Matches"), this, SLOT( menuFunct(int) ), 0, MENU_SEEK );
+ menuSeek->insertSeparator();
+ menuSeek->insertItem( i18n("Accept This Match"), this, SLOT( menuFunct(int) ), 0, MENU_ACCEPT_MATCH );
+ menuSeek->insertItem( i18n("Tell..."), this, SLOT( menuFunct(int) ), 0, MENU_TELL );
+ menuSeek->insertItem( i18n("Assess..."), this, SLOT( menuFunct(int) ), 0, MENU_ASSESS );
+ menuSeek->insertItem( i18n("Player Info"), this, SLOT( menuFunct(int) ), 0, MENU_FINGER );
+ menuSeek->insertItem( QIconSet( myResource->LoadIcon( QString("history"), KIcon::Small ) ),
+ i18n("Player History"), this, SLOT( menuFunct(int) ), 0, MENU_HISTORY );
+ menuSeek->insertSeparator();
+ menuSeek->insertItem( i18n("Add to Friends"), this, SLOT( menuFunct(int) ), 0, MENU_NOTIFY );
+ menuSeek->insertItem( i18n("Ignore This Player"), this, SLOT( menuFunct(int) ), 0, MENU_CENSOR );
+ menuSeek->setItemChecked( MENU_SEEK, FALSE );
+
+ connect( this, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ),
+ this, SLOT( display_menuSeek( QListViewItem*, const QPoint&, int ) ) );
+ connect( this, SIGNAL( executed( QListViewItem* ) ),
+ this, SLOT( selectMatch( QListViewItem* ) ) );
+}
+tab_SeekList::~tab_SeekList()
+{
+}
+///////////////////////////////////////
+//
+// tab_SeekList::recvCMD
+//
+///////////////////////////////////////
+void tab_SeekList::recvCMD( const Command& command )
+{
+ switch(((Command)command).getCommand())
+ {
+ case CMD_Add_Sought_Match:
+ addSoughtItem( ((Command)command).getData() );
+ break;
+ case CMD_Show_Sought_List:
+ updateSoughtList();
+ break;
+ case CMD_Hide_Sought_List:
+ clear();
+ seek = FALSE;
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// tab_SeekList::updateSoughtList
+//
+///////////////////////////////////////
+void tab_SeekList::updateSoughtList( void )
+{
+ unsigned int loop;
+
+ clear();
+ for( loop = 0; loop < SF_01.count(); loop++ )
+ {
+ (void) new KListViewItem( this,
+ SF_01[loop],
+ SF_02[loop],
+ SF_03[loop],
+ SF_04[loop],
+ SF_05[loop] + i18n(" min."),
+ SF_06[loop] + i18n(" sec."),
+ SF_07[loop] );
+ }
+ SF_01.clear();
+ SF_02.clear();
+ SF_03.clear();
+ SF_04.clear();
+ SF_05.clear();
+ SF_06.clear();
+ SF_07.clear();
+ seek = TRUE;
+}
+///////////////////////////////////////
+//
+// tab_SeekList::addSoughtItem
+//
+///////////////////////////////////////
+void tab_SeekList::addSoughtItem( const QString &src )
+{
+ QStringList fields = QStringList::split( QChar(' '), src, FALSE );
+ SF_01 << fields[2]; // Name
+ SF_02 << fields[1]; // Rating
+ SF_03 << fields[6]; // Match Type
+ SF_04 << fields[5]; // Is Rated?
+ SF_05 << fields[3]; // Base Time
+ SF_06 << fields[4]; // Increment
+ SF_07 << fields[0]; // ID#
+}
+///////////////////////////////////////
+//
+// tab_SeekList::display_menuSeek
+//
+///////////////////////////////////////
+void tab_SeekList::display_menuSeek( QListViewItem *Item, const QPoint &Pos, int )
+{
+ bool enable;
+ if( Item != NULL )
+ {
+ setSelected( Item, TRUE );
+ selectedPlayerName = Item->text(0).replace( QRegExp("\\(.+\\)"), QString("") );
+ selectedMatchID = Item->text(6).toInt();
+ enable = TRUE;
+ }
+ else
+ {
+ enable = FALSE;
+ }
+ menuSeek->setItemChecked( MENU_SEEK, seek );
+ menuSeek->setItemEnabled( MENU_FINGER, enable );
+ menuSeek->setItemEnabled( MENU_TELL, enable );
+ menuSeek->setItemEnabled( MENU_NOTIFY, enable );
+ menuSeek->setItemEnabled( MENU_CENSOR, enable );
+ menuSeek->setItemEnabled( MENU_HISTORY, enable );
+ menuSeek->setItemEnabled( MENU_ACCEPT_MATCH, enable );
+ menuSeek->setItemEnabled( MENU_ASSESS, enable );
+ menuSeek->popup( Pos );
+}
+///////////////////////////////////////
+//
+// tab_SeekList::selectMatch
+//
+///////////////////////////////////////
+void tab_SeekList::selectMatch( int matchID )
+{
+ if( matchID )
+ emit sendCMD( Command( 0, CMD_Start_Match, QString::number( matchID ) ) );
+}
+void tab_SeekList::selectMatch( QListViewItem *Item )
+{
+ selectMatch( Item->text(6).toInt() );
+}
+///////////////////////////////////////
+//
+// tab_SeekList::menuFunct
+//
+///////////////////////////////////////
+void tab_SeekList::menuFunct( int funct )
+{
+ switch( funct )
+ {
+ case MENU_SEEK:
+ emit sendCMD( Command( 0, CMD_Toggle_Seek ) );
+ break;
+ case MENU_FINGER:
+ emit sendCMD( Command( 0, CMD_Player_Finger, selectedPlayerName ) );
+ break;
+ case MENU_TELL:
+ emit sendCMD( Command( 0, CMD_Set_Input, QString( "tell %1 " ).arg( selectedPlayerName ) ) );
+ break;
+ case MENU_NOTIFY:
+ emit sendCMD( Command( 0, CMD_Add_Friend, selectedPlayerName ) );
+ break;
+ case MENU_CENSOR:
+ emit sendCMD( Command( 0, CMD_Ignore_Player, selectedPlayerName ) );
+ break;
+ case MENU_HISTORY:
+ emit sendCMD( Command( 0, CMD_Player_History, selectedPlayerName ) );
+ break;
+ case MENU_ACCEPT_MATCH:
+ emit sendCMD( Command( 0, CMD_Start_Match, QString::number( selectedMatchID ) ) );
+ break;
+ case MENU_ASSESS:
+ emit sendCMD( Command( 0, CMD_Assess, selectedPlayerName ) );
+ break;
+ default:
+ break;
+ }
+}
diff --git a/knights/tab_seeklist.h b/knights/tab_seeklist.h
new file mode 100644
index 0000000..9796130
--- /dev/null
+++ b/knights/tab_seeklist.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ tab_seeklist.h - description
+ -------------------
+ begin : Sat Sep 14 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TAB_SEEKLIST_H
+#define TAB_SEEKLIST_H
+
+#include <kpopupmenu.h>
+#include <klistview.h>
+#include <qwidget.h>
+#include <qstringlist.h>
+#include "command.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class resource;
+
+class tab_SeekList : public KListView
+{
+ Q_OBJECT
+
+ private:
+ resource *myResource;
+ KPopupMenu *menuSeek;
+ bool seek;
+ int selectedMatchID;
+ QString selectedPlayerName;
+ /*
+ These StringLists temporarily store Sought Game data
+ until all ads have been displayed.
+ */
+ QStringList SF_01;
+ QStringList SF_02;
+ QStringList SF_03;
+ QStringList SF_04;
+ QStringList SF_05;
+ QStringList SF_06;
+ QStringList SF_07;
+
+ public:
+ tab_SeekList(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~tab_SeekList();
+
+ public slots:
+ void recvCMD( const Command& );
+ void display_menuSeek( QListViewItem*, const QPoint&, int );
+ void selectMatch( QListViewItem *Item );
+ void selectMatch( int );
+ void menuFunct( int );
+
+ signals:
+ void sendCMD( const Command& );
+
+ protected:
+ void addSoughtItem( const QString& );
+ void updateSoughtList( void );
+
+};
+
+#endif
diff --git a/knights/tabbox.cpp b/knights/tabbox.cpp
new file mode 100644
index 0000000..bc8baed
--- /dev/null
+++ b/knights/tabbox.cpp
@@ -0,0 +1,208 @@
+/***************************************************************************
+ tabbox.cpp - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tabbox.moc"
+#include "tabpage.h"
+#include "resource.h"
+#include "accel.h"
+#include <klocale.h>
+#include <qstyle.h>
+#include <qtabwidget.h>
+
+TabBox::TabBox( resource *rsrc ) : QVBox(0,"TabBox",Qt::WDestructiveClose)
+{
+ myResource = rsrc;
+ setMargin( QApplication::style().defaultFrameWidth() );
+
+ myTabs = new QTabWidget( this, "myTabs" );
+ myTabs->setTabShape( QTabWidget::Rounded );
+ myTabs->setTabPosition( QTabWidget::Top );
+
+ myAccel = new Accel( this, myResource->myAccel );
+
+ connect( myTabs, SIGNAL( currentChanged( QWidget* ) ), this, SLOT( changeMyCaption( QWidget* ) ) );
+ connect( this, SIGNAL( focus( const QChar& ) ), myResource->myAccel, SIGNAL( focus( const QChar& ) ) );
+}
+TabBox::~TabBox()
+{
+ while( myTabs->count() )
+ {
+ removeTab( myTabs->page(0), TRUE );
+ }
+ delete myAccel;
+}
+///////////////////////////////////////
+//
+// TabBox::keyPressEvent
+//
+///////////////////////////////////////
+void TabBox::keyPressEvent( QKeyEvent *e )
+{
+ QChar input;
+
+ if( ( e->state() | Qt::ShiftButton ) == Qt::ShiftButton )
+ {
+ input = e->text().at(0);
+ if( input.isLetterOrNumber() )
+ {
+ emit focus( input );
+ e->accept();
+ return;
+ }
+ }
+ e->ignore();
+}
+///////////////////////////////////////
+//
+// TabBox::addTab
+//
+///////////////////////////////////////
+void TabBox::addTab( QWidget *child, const QString &caption )
+{
+ if( QString( child->className() ) == "TabPage" )
+ {
+ myTabs->addTab( child, caption );
+ myTabs->showPage( child );
+ changeMyCaption( child );
+ connect( child, SIGNAL( newParent( TabBox* ) ), this, SIGNAL( newTabBox( TabBox* ) ) );
+ connect( child, SIGNAL( requestDestruction() ), this, SLOT( destroyChild() ) );
+ }
+ else
+ {
+ TabPage *newPage = new TabPage( (QWidget*)this, child, myResource );
+ newPage->setCaption( caption );
+
+ myTabs->addTab( newPage, caption );
+ myTabs->showPage( newPage );
+ changeMyCaption( newPage );
+ connect( newPage, SIGNAL( newParent( TabBox* ) ), this, SIGNAL( newTabBox( TabBox* ) ) );
+ connect( newPage, SIGNAL( requestDestruction() ), this, SLOT( destroyChild() ) );
+ }
+}
+///////////////////////////////////////
+//
+// TabBox::removeTab
+//
+///////////////////////////////////////
+void TabBox::removeTab( QWidget *child, bool deleteChild )
+{
+ if( QString( child->className() ) == "TabPage" )
+ {
+ emit saveTabGeometry( QString( ((TabPage*)child)->getChild()->className() ), size() );
+ myTabs->removePage( child );
+ }
+ else
+ {
+ emit saveTabGeometry( QString( child->className() ), size() );
+ myTabs->removePage( child->parentWidget() );
+ }
+
+ /* Delete it if requested */
+ if( deleteChild )
+ {
+ delete child;
+ }
+}
+///////////////////////////////////////
+//
+// TabBox::showTab
+//
+///////////////////////////////////////
+void TabBox::showTab( QWidget *child )
+{
+ if( isChild( child ) )
+ myTabs->showPage( child->parentWidget() );
+}
+///////////////////////////////////////
+//
+// TabBox::destroyChild
+//
+///////////////////////////////////////
+void TabBox::destroyChild( void )
+{
+ QObject *child = ((QObject*)sender());
+
+ /* Be careful... make sure we have a valid child calling us */
+ if( child == NULL )
+ return;
+ if( !child->isWidgetType() )
+ return;
+ if( !isChild( ((QWidget*)child) ) )
+ return;
+
+ /* Nuke it */
+ removeTab( ((QWidget*)child), TRUE );
+
+ if( count() == 0 )
+ {
+ /* TabManager will be notified of the delete via QObject::destroyed(QObject*) */
+ delete this;
+ }
+}
+///////////////////////////////////////
+//
+// TabBox::changeMyCaption
+//
+///////////////////////////////////////
+void TabBox::changeMyCaption( QWidget *child )
+{
+ setCaption( i18n("%1 - Knights").arg( myTabs->tabLabel( child ) ) );
+}
+///////////////////////////////////////
+//
+// TabBox::count
+//
+///////////////////////////////////////
+int TabBox::count( void )
+{
+ return myTabs->count();
+}
+///////////////////////////////////////
+//
+// TabBox::isChild
+//
+///////////////////////////////////////
+bool TabBox::isChild( QWidget *child )
+{
+ for( int tmp=0; tmp < myTabs->count(); tmp++ )
+ {
+ if( myTabs->page(tmp) == child )
+ return TRUE;
+ if( ((TabPage*)myTabs->page(tmp))->getChild() == child )
+ return TRUE;
+ }
+ return FALSE;
+}
+///////////////////////////////////////
+//
+// TabBox::changeCaption
+//
+///////////////////////////////////////
+void TabBox::changeCaption( QWidget *child, const QString &caption )
+{
+ if( QString( child->className() ) == "TabPage" )
+ {
+ ((TabPage*)child)->setCaption( caption );
+ myTabs->setTabLabel( child, caption );
+ }
+ else if( isChild( child ) )
+ {
+ ((TabPage*)child->parentWidget())->setCaption( caption );
+ myTabs->setTabLabel( child->parentWidget(), caption );
+ }
+ changeMyCaption( myTabs->currentPage() );
+}
diff --git a/knights/tabbox.h b/knights/tabbox.h
new file mode 100644
index 0000000..0f3cffb
--- /dev/null
+++ b/knights/tabbox.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ tabbox.h - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TABBOX_H
+#define TABBOX_H
+
+#include <qvbox.h>
+#include "accel.h"
+
+class QTabWidget;
+class resource;
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class TabBox : public QVBox
+{
+ Q_OBJECT
+ public:
+ TabBox( resource *rsrc=0 );
+ virtual ~TabBox();
+ void keyPressEvent( QKeyEvent* );
+ void addTab( QWidget *child, const QString &caption );
+ void removeTab( QWidget *child, bool deleteChild=FALSE );
+ bool isChild( QWidget *child );
+ void showTab( QWidget *child );
+ void changeCaption( QWidget *child, const QString &caption );
+ int count( void );
+
+ signals:
+ void newTabBox( TabBox* );
+ void saveTabGeometry( const QString&, const QSize& );
+ void focus( const QChar& );
+
+ protected slots:
+ void changeMyCaption( QWidget *child );
+
+ /**
+ This removes and deletes a Tab if it's a child of this widget.
+ Never call this directly; Only with a Signal!
+ */
+ void destroyChild( void );
+
+ private:
+ QTabWidget *myTabs;
+ Accel *myAccel;
+ resource *myResource;
+};
+
+#endif
diff --git a/knights/tabgrip.cpp b/knights/tabgrip.cpp
new file mode 100644
index 0000000..563dd8f
--- /dev/null
+++ b/knights/tabgrip.cpp
@@ -0,0 +1,109 @@
+/***************************************************************************
+ tabgrip.cpp - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tabgrip.moc"
+#include "resource.h"
+#include <qpainter.h>
+
+TabGrip::TabGrip(QWidget *parent, const char *name ) : QWidget(parent,name)
+{
+ setMaximumSize( 3200, 12 );
+ setMinimumSize( 32, 12 );
+
+ isDragging = FALSE;
+ couldDrag = FALSE;
+
+ setCursor( Qt::SizeAllCursor );
+
+ show();
+}
+TabGrip::~TabGrip()
+{
+}
+///////////////////////////////////////
+//
+// TabGrip::paintEvent
+//
+///////////////////////////////////////
+void TabGrip::paintEvent( QPaintEvent* )
+{
+ QPainter paint( this );
+ QColorGroup group( colorGroup() );
+ paint.setPen( group.light() );
+ paint.drawLine( 2, 2, width() - 3, 2 );
+ paint.drawLine( 2, 5, width() - 3, 5 );
+ paint.drawLine( 2, 8, width() - 3, 8 );
+ paint.setPen( group.dark() );
+ paint.drawLine( 2, 3, width() - 3, 3 );
+ paint.drawLine( 2, 6, width() - 3, 6 );
+ paint.drawLine( 2, 9, width() - 3, 9 );
+}
+///////////////////////////////////////
+//
+// TabGrip::mousePressEvent
+//
+///////////////////////////////////////
+void TabGrip::mousePressEvent( QMouseEvent *event )
+{
+ event->accept();
+ if(event->button() == Qt::LeftButton)
+ {
+ couldDrag = TRUE;
+ offset = mapToGlobal( event->pos() );
+ offset.setX( topLevelWidget()->x() - offset.x() );
+ offset.setY( topLevelWidget()->y() - offset.y() );
+ }
+}
+///////////////////////////////////////
+//
+// TabGrip::mouseMoveEvent
+//
+///////////////////////////////////////
+void TabGrip::mouseMoveEvent( QMouseEvent *event )
+{
+ /*
+ By default, MouseMoveEvent is never called unless the user has
+ a button held down, so this should only be called if we're dragging.
+ */
+ event->accept();
+ if( couldDrag == TRUE )
+ {
+ /* Dragging Page */
+ isDragging = TRUE;
+ couldDrag = FALSE;
+ QApplication::setOverrideCursor( Qt::SizeAllCursor );
+ }
+}
+///////////////////////////////////////
+//
+// TabGrip::mouseReleaseEvent
+//
+///////////////////////////////////////
+void TabGrip::mouseReleaseEvent( QMouseEvent *event )
+{
+ event->accept();
+ if(event->button() == Qt::LeftButton)
+ {
+ couldDrag = FALSE;
+ if( isDragging )
+ {
+ QApplication::restoreOverrideCursor();
+ isDragging = FALSE;
+ emit wasDragged( event->globalPos(), offset );
+ }
+ }
+}
diff --git a/knights/tabgrip.h b/knights/tabgrip.h
new file mode 100644
index 0000000..a568a2e
--- /dev/null
+++ b/knights/tabgrip.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ tabgrip.h - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TABGRIP_H
+#define TABGRIP_H
+
+#include <qwidget.h>
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class TabGrip : public QWidget
+{
+ Q_OBJECT
+ public:
+ TabGrip(QWidget *parent=0, const char *name=0);
+ ~TabGrip();
+ void paintEvent( QPaintEvent* );
+ void mouseMoveEvent( QMouseEvent *event );
+ void mousePressEvent( QMouseEvent *event );
+ void mouseReleaseEvent( QMouseEvent *event );
+
+ signals:
+ void wasDragged( const QPoint&, const QPoint& );
+
+ private:
+ bool isDragging;
+ bool couldDrag;
+ QPoint offset;
+};
+
+#endif
diff --git a/knights/tabmanager.cpp b/knights/tabmanager.cpp
new file mode 100644
index 0000000..f2d72fc
--- /dev/null
+++ b/knights/tabmanager.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ tabmanager.cpp - description
+ -------------------
+ begin : Sat Sep 14 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tabmanager.moc"
+#include "resource.h"
+#include <kdebug.h>
+
+static QString myConfigGroup( "TabManager" );
+
+TabManager::TabManager( resource *rsrc ) : QObject()
+{
+ myResource = rsrc;
+ appConfig = kapp->config();
+}
+
+TabManager::~TabManager()
+{
+}
+
+///////////////////////////////////////
+//
+// TabManager::addTab
+//
+///////////////////////////////////////
+void TabManager::addTab( QWidget *child, const QString &caption )
+{
+ TabBox *boxPtr;
+
+ if( myList.count() == 0 )
+ {
+ /* First Tab always generates a new TabBox */
+ boxPtr = new TabBox( myResource );
+ manageNewBox( boxPtr );
+ boxPtr->addTab( child, caption );
+
+ /* Get Geometry from Saved Config */
+ appConfig->setGroup( myConfigGroup );
+ QSize defaultSize( 420, 360 );
+ QSize newSize = appConfig->readSizeEntry( QString( child->className() ), &defaultSize );
+ boxPtr->resize( newSize );
+ boxPtr->show();
+ }
+ else
+ {
+ boxPtr = myList.at(0);
+ boxPtr->addTab( child, caption );
+ }
+}
+///////////////////////////////////////
+//
+// TabManager::changeCaption
+//
+///////////////////////////////////////
+void TabManager::changeCaption( QWidget *child, const QString &caption )
+{
+ TabBox *boxPtr = getParentBox( child );
+
+ if( boxPtr != NULL )
+ {
+ boxPtr->changeCaption( child, caption );
+ }
+}
+///////////////////////////////////////
+//
+// TabManager::removeTab
+//
+///////////////////////////////////////
+void TabManager::removeTab( QObject *child )
+{
+ /* Make sure this is a QWidget we can manipulate */
+ if( !child->isWidgetType() )
+ {
+ kdError() << "TabManager::removeTab: Can not remove non-widget class " << child->className() << endl;
+ return;
+ }
+
+ if( myList.find( ((TabBox*)child) ) != -1 )
+ {
+ /* Remove Child Directly */
+ myList.remove( ((TabBox*)child) );
+ return;
+ }
+
+ QString childName( ((QWidget*)child)->className() );
+ TabBox *boxPtr = getParentBox( ((QWidget*)child) );
+
+ /* Remove this Child's Parent, the TabPage */
+ if( boxPtr != NULL )
+ {
+ kdDebug() << "Removing child: " << childName << endl;
+ boxPtr->removeTab( ((QWidget*)child), TRUE );
+ if( boxPtr->count() == 0 )
+ {
+ myList.remove( boxPtr );
+ delete boxPtr;
+ }
+ return;
+ }
+ kdWarning() << "Could not find child: " << childName << endl;
+}
+///////////////////////////////////////
+//
+// TabManager::showTab
+//
+///////////////////////////////////////
+void TabManager::showTab( QWidget *child )
+{
+ TabBox *boxPtr = getParentBox( child );
+ if( boxPtr != NULL )
+ {
+ boxPtr->showTab( child );
+ }
+}
+///////////////////////////////////////
+//
+// TabManager::isTab
+//
+///////////////////////////////////////
+bool TabManager::isTab( QWidget *child )
+{
+ if( getParentBox( child ) == NULL )
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+///////////////////////////////////////
+//
+// TabManager::saveTabGeometry
+//
+///////////////////////////////////////
+void TabManager::saveTabGeometry( const QString &childName, const QSize &childSize )
+{
+ /* Save This Widget's Size For Later */
+ appConfig->setGroup( myConfigGroup );
+ appConfig->writeEntry( childName, childSize );
+ appConfig->sync();
+
+ kdDebug() << "Saved geometry for Widget: " << childName << endl;
+}
+///////////////////////////////////////
+//
+// TabManager::childEvent
+//
+///////////////////////////////////////
+void TabManager::childEvent( QChildEvent *event )
+{
+ if( event->inserted() )
+ {
+ /* New Child */
+ if( QString( event->child()->className() ) == "TabBox" )
+ {
+ manageNewBox( ((TabBox*)event->child()) );
+ return;
+ }
+ addTab( ((QWidget*)event->child()), QString( "Untitled" ) );
+ }
+}
+///////////////////////////////////////
+//
+// TabManager::manageNewBox
+//
+///////////////////////////////////////
+void TabManager::manageNewBox( TabBox *newBox )
+{
+ myList.append( newBox );
+ connect( newBox, SIGNAL( destroyed( QObject* ) ), this, SLOT( removeTab( QObject* ) ) );
+ connect( newBox, SIGNAL( saveTabGeometry( const QString&, const QSize& ) ), this, SLOT( saveTabGeometry( const QString&, const QSize& ) ) );
+ connect( newBox, SIGNAL( newTabBox( TabBox* ) ), this, SLOT( manageNewBox( TabBox* ) ) );
+}
+///////////////////////////////////////
+//
+// TabManager::getParentBox
+//
+///////////////////////////////////////
+TabBox* TabManager::getParentBox( QWidget *child )
+{
+ TabBox *boxPtr;
+ for( unsigned int index=0; index < myList.count(); index++ )
+ {
+ boxPtr = myList.at(index);
+ if( boxPtr->isChild( child ) )
+ {
+ return boxPtr;
+ }
+ }
+ return NULL;
+}
diff --git a/knights/tabmanager.h b/knights/tabmanager.h
new file mode 100644
index 0000000..78ae9ac
--- /dev/null
+++ b/knights/tabmanager.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ tabmanager.h - description
+ -------------------
+ begin : Sat Sep 14 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TABMANAGER_H
+#define TABMANAGER_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+#include <kapp.h>
+#include <kconfig.h>
+#include "tabbox.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+typedef QPtrList<TabBox> TabBoxList;
+class resource;
+
+class TabManager : public QObject
+{
+ Q_OBJECT
+ public:
+ TabManager( resource *rsrc );
+ ~TabManager();
+ void addTab( QWidget *child, const QString &caption );
+ void childEvent( QChildEvent *event );
+ void changeCaption( QWidget *child, const QString &caption );
+ void showTab( QWidget *child );
+ bool isTab( QWidget *child );
+
+ public slots:
+ void removeTab( QObject *child );
+
+ protected slots:
+ void manageNewBox( TabBox *newBox );
+ void saveTabGeometry( const QString&, const QSize& );
+
+ protected:
+ TabBox* getParentBox( QWidget* );
+
+ private:
+ TabBoxList myList;
+ KConfig *appConfig;
+ resource *myResource;
+};
+
+#endif
diff --git a/knights/tabpage.cpp b/knights/tabpage.cpp
new file mode 100644
index 0000000..863e34d
--- /dev/null
+++ b/knights/tabpage.cpp
@@ -0,0 +1,164 @@
+/***************************************************************************
+ tabpage.cpp - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tabpage.moc"
+#include "tabmanager.h"
+#include "tabgrip.h"
+#include "resource.h"
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <qtoolbutton.h>
+
+///////////////////////////////////////
+//
+// TabPage::constructor
+//
+///////////////////////////////////////
+TabPage::TabPage( QWidget *parent, QWidget *child, resource *rsrc ) : QVBox(parent)
+{
+ myResource = rsrc;
+ myChild = child;
+
+ actionBar = new QHBox( this );
+ actionBar->show();
+
+ grip = new TabGrip( actionBar );
+ connect( grip, SIGNAL( wasDragged(const QPoint&, const QPoint&) ), this, SLOT( tabDragged(const QPoint&, const QPoint&) ) );
+
+ KIconLoader icons( QString( "knights" ) );
+ QPixmap map = icons.loadIcon( QString("tab_remove"), KIcon::Small, 0, KIcon::DefaultState, 0, TRUE );
+ if( map.isNull() )
+ {
+ /* Keep for backward compatability with KDE 3.0 */
+ map = icons.loadIcon( QString("fileclose"), KIcon::Small );
+ }
+
+ closeButton = new QToolButton( actionBar, "closeButton" );
+ closeButton->setIconSet( QIconSet( map ) );
+ closeButton->setAutoRaise( TRUE );
+ closeButton->setTextLabel( i18n( "Close This Tab" ), TRUE );
+ closeButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ connect( closeButton, SIGNAL( clicked() ), this, SIGNAL( requestDestruction() ) );
+
+ myChild->reparent( this, QPoint( 0, 0 ), TRUE );
+ myChild->show();
+ show();
+}
+///////////////////////////////////////
+//
+// TabPage::destructor
+//
+///////////////////////////////////////
+TabPage::~TabPage()
+{
+}
+///////////////////////////////////////
+//
+// TabPage::tabDragged
+//
+///////////////////////////////////////
+void TabPage::tabDragged( const QPoint &dest, const QPoint &offset )
+{
+ TabBox *myParent = parentTabBox();
+ if( myParent != NULL )
+ {
+ QWidget *destWidget = QApplication::widgetAt( dest, TRUE );
+ /* Find a TabBox */
+ while(1)
+ {
+ if( destWidget == NULL )
+ {
+ /* Create new TabBox */
+ TabBox *newBox = new TabBox( myResource );
+ newBox->resize( myParent->size() );
+ newBox->move( dest + offset );
+ newBox->show();
+ emit newParent( newBox );
+ myParent->removeTab( this );
+ newBox->addTab( this, myCaption );
+ break;
+ }
+ if( QString( destWidget->className() ) == "TabBox" )
+ {
+ if( myParent != ((TabBox*)destWidget) )
+ {
+ /* We can latch on here */
+ myParent->removeTab( this );
+ ((TabBox*)destWidget)->addTab( this, myCaption );
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ destWidget = destWidget->parentWidget();
+ }
+ if( myParent->count() == 0 )
+ {
+ /* TabManager will be notified of the delete via QObject::destroyed(QObject*) */
+ delete myParent;
+ }
+ }
+ else
+ {
+ kdError() << "TabPage::tabDragged: Can not move without a parent TabBox." << endl;
+ }
+}
+///////////////////////////////////////
+//
+// TabPage::setCaption
+//
+///////////////////////////////////////
+void TabPage::setCaption( const QString &caption )
+{
+ myCaption = caption;
+}
+///////////////////////////////////////
+//
+// TabPage::parentTabBox
+//
+///////////////////////////////////////
+TabBox* TabPage::parentTabBox( void )
+{
+ QWidget *myParent = this->parentWidget();
+ if( QString( myParent->className() ) == "QWidgetStack" )
+ {
+ myParent = myParent->parentWidget();
+ if( QString( myParent->className() ) == "QTabWidget" )
+ {
+ myParent = myParent->parentWidget();
+ if( QString( myParent->className() ) == "TabBox" )
+ {
+ return ((TabBox*)myParent);
+ }
+ }
+ }
+ return NULL;
+}
+///////////////////////////////////////
+//
+// TabPage::getChild
+//
+///////////////////////////////////////
+QWidget* TabPage::getChild( void )
+{
+ return myChild;
+}
+
diff --git a/knights/tabpage.h b/knights/tabpage.h
new file mode 100644
index 0000000..d5aeb28
--- /dev/null
+++ b/knights/tabpage.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ tabpage.h - description
+ -------------------
+ begin : Fri Sep 13 2002
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sf.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TABPAGE_H
+#define TABPAGE_H
+
+#include <qframe.h>
+#include <qwidget.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qstring.h>
+#include "tabbox.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+class resource;
+class QToolButton;
+class TabGrip;
+
+class TabPage : public QVBox
+{
+ Q_OBJECT
+ public:
+ TabPage( QWidget *parent, QWidget *child, resource *rsrc );
+ ~TabPage();
+ void setCaption( const QString& );
+ QWidget* getChild( void );
+
+ protected slots:
+ void tabDragged( const QPoint&, const QPoint& );
+
+ signals:
+ void newParent( TabBox* );
+ void requestDestruction( void );
+
+ protected:
+ TabBox* parentTabBox( void );
+
+ private:
+ QString myCaption;
+ QHBox *actionBar;
+ TabGrip *grip;
+ QToolButton *closeButton;
+
+ QWidget *myChild;
+ resource *myResource;
+};
+
+#endif
diff --git a/knights/thinbuttons.cpp b/knights/thinbuttons.cpp
new file mode 100644
index 0000000..ed97ba5
--- /dev/null
+++ b/knights/thinbuttons.cpp
@@ -0,0 +1,262 @@
+/***************************************************************************
+ thinbuttons.cpp - description
+ -------------------
+ begin : Tue Nov 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "thinbuttons.moc"
+#include <kicontheme.h>
+#include <qpushbutton.h>
+#include <qstyle.h>
+
+thinbuttons::thinbuttons(QWidget *parent, const char *name, resource *Rsrc ) : QFrame(parent,name)
+{
+ Resource = Rsrc;
+ rightClickID = 0;
+ setFixedSize( 8, 8 );
+
+ /* Build the pop-up menu */
+ matchMenu = new KPopupMenu( this );
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("filesave"), KIcon::Small ) ),
+ i18n("&Save Match"), MENU_SAVE );
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("filesave"), KIcon::Small ) ),
+ i18n("Save Match &As..."), MENU_SAVEAS );
+ matchMenu->insertSeparator();
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("fileprint"), KIcon::Small ) ),
+ i18n("&Print Notation..."), MENU_PRINT );
+ matchMenu->insertSeparator();
+ matchMenu->insertItem( QIconSet( Resource->LoadIcon( QString("fileclose"), KIcon::Small ) ),
+ i18n("&Close Match"), MENU_CLOSE );
+ connect( matchMenu, SIGNAL( activated(int) ), this, SLOT( menuClicked(int) ) );
+}
+thinbuttons::~thinbuttons()
+{
+}
+///////////////////////////////////////
+//
+// thinbuttons::childEvent
+//
+///////////////////////////////////////
+void thinbuttons::childEvent( QChildEvent * cev )
+{
+ /* Make sure this method only effects child buttons */
+ if( QString( cev->child()->name() ) != QString( "MatchSelector" ) )
+ return;
+ if( cev->removed() )
+ remove( (QButton*)cev->child() );
+}
+///////////////////////////////////////
+//
+// thinbuttons::create
+//
+///////////////////////////////////////
+QButton* thinbuttons::create( int id )
+{
+ Buttons *newBut;
+ QPushButton *newButton;
+
+ newButton = new QPushButton( this, "MatchSelector" );
+
+ newBut = new Buttons;
+ newBut->button = newButton;
+ newBut->ID = id;
+ buttons.append( newBut );
+
+ newButton->setToggleButton( TRUE );
+ newButton->setText( QString("Match") );
+ newButton->show();
+
+ connect( newButton, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
+ return newButton;
+}
+///////////////////////////////////////
+//
+// thinbuttons::setButton
+//
+///////////////////////////////////////
+void thinbuttons::setButton( int id )
+{
+ Buttons *currentBut;
+ unsigned int Index;
+
+ for( Index = 0; Index < buttons.count(); Index++ )
+ {
+ currentBut = buttons.at( Index );
+ if( currentBut->ID == id )
+ {
+ currentBut->button->setDown( TRUE );
+ if( currentBut->button->isToggleButton() )
+ if( currentBut->button->state() != QButton::On )
+ currentBut->button->toggle();
+ }
+ else
+ {
+ currentBut->button->setDown( FALSE );
+ if( currentBut->button->isToggleButton() )
+ if( currentBut->button->state() == QButton::On )
+ currentBut->button->toggle();
+ }
+ }
+}
+///////////////////////////////////////
+//
+// thinbuttons::find
+//
+///////////////////////////////////////
+QButton* thinbuttons::find( int id )
+{
+ unsigned int tmp;
+
+ for( tmp = 0; tmp < buttons.count(); tmp++ )
+ if( buttons.at( tmp )->ID == id )
+ return buttons.at( tmp )->button;
+ return NULL;
+}
+///////////////////////////////////////
+//
+// thinbuttons::id
+//
+///////////////////////////////////////
+int thinbuttons::id( QButton* button )
+{
+ unsigned int tmp;
+
+ for( tmp = 0; tmp < buttons.count(); tmp++ )
+ if( buttons.at( tmp )->button == button )
+ return buttons.at( tmp )->ID;
+ return -1;
+}
+///////////////////////////////////////
+//
+// thinbuttons::remove
+//
+///////////////////////////////////////
+void thinbuttons::remove( QButton* button )
+{
+ unsigned int tmp;
+
+ for( tmp = 0; tmp < buttons.count(); tmp++ )
+ if( buttons.at( tmp )->button == button )
+ {
+ disconnect( buttons.at( tmp )->button, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
+ buttons.remove( tmp );
+ }
+}
+void thinbuttons::remove( const int &id )
+{
+ QButton *butt;
+
+ butt = find(id);
+ if( butt != NULL )
+ {
+ remove( butt );
+ delete butt;
+ }
+}
+///////////////////////////////////////
+//
+// thinbuttons::buttonClicked
+//
+///////////////////////////////////////
+void thinbuttons::buttonClicked( void )
+{
+ const QObject *incomming;
+ int Clicked;
+ unsigned int tmp;
+
+ incomming = sender();
+ for( tmp = 0; tmp < buttons.count(); tmp++ )
+ if( buttons.at( tmp )->button == ( const QButton* )incomming )
+ {
+ Clicked = buttons.at( tmp )->ID;
+ if( Clicked == Null ) return;
+ setButton( Clicked );
+ emit leftClick( Clicked );
+ }
+}
+///////////////////////////////////////
+//
+// thinbuttons::resize
+//
+///////////////////////////////////////
+void thinbuttons::resize( const int Width )
+{
+ Buttons *button;
+ QStyle& Style = QApplication::style();
+ int margin;
+ unsigned int Index;
+
+ margin = Style.defaultFrameWidth();
+ if( buttons.count() != 0 ) buttWidth = ( Width / buttons.count() ) - ( margin * 2 );
+ else buttWidth = 0;
+ setFixedSize( Width, Resource->Widget_Height + margin );
+ for( Index = 0; Index < buttons.count(); Index++ )
+ {
+ button = buttons.at( Index );
+ button->button->setFixedSize( buttWidth, Resource->Widget_Height );
+ button->button->move( ( Index * ( buttWidth + ( margin * 2 ) ) ) + margin , margin );
+ }
+}
+///////////////////////////////////////
+//
+// thinbuttons::mousePressEvent
+//
+///////////////////////////////////////
+void thinbuttons::mousePressEvent( QMouseEvent *event )
+{
+ QStyle& Style = QApplication::style();
+ int margin, xpos(0), index(0);
+
+ /* We only want RightClick */
+ if(event->button() != Qt::RightButton)
+ {
+ return;
+ }
+ event->accept();
+ margin = Style.defaultFrameWidth();
+ /* No Buttons, No Menu */
+ if( !buttons.count() )
+ {
+ return;
+ }
+ /* Figure out which button was pressed */
+ xpos += margin;
+ while( xpos < event->x() )
+ {
+ if( ( event->x() >= xpos ) && ( event->x() <= ( xpos + buttWidth ) ) )
+ {
+ break;
+ }
+ xpos += ( margin << 1 ) + buttWidth;
+ index++;
+ }
+ /* Clicked the right margin */
+ if( xpos >= event->x() )
+ {
+ return;
+ }
+ /* Clicked a button, let's dance */
+ matchMenu->popup( event->globalPos() );
+ rightClickID = buttons.at(index)->ID;
+ emit rightClick( rightClickID );
+}
+///////////////////////////////////////
+//
+// thinbuttons::menuClicked
+//
+///////////////////////////////////////
+void thinbuttons::menuClicked( int item )
+{
+ emit menuItemSelected( rightClickID, item );
+}
diff --git a/knights/thinbuttons.h b/knights/thinbuttons.h
new file mode 100644
index 0000000..3171189
--- /dev/null
+++ b/knights/thinbuttons.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ thinbuttons.h - description
+ -------------------
+ begin : Tue Nov 13 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef THINBUTTONS_H
+#define THINBUTTONS_H
+
+#include <kpopupmenu.h>
+#include <qframe.h>
+#include <qbutton.h>
+#include "definitions.h"
+#include "resource.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+struct Buttons
+{
+ QButton *button;
+ int ID;
+};
+
+class thinbuttons : public QFrame
+{
+ Q_OBJECT
+ public:
+ thinbuttons(QWidget *parent=0, const char *name=0, resource *Rsrc=0);
+ ~thinbuttons();
+ void mousePressEvent( QMouseEvent *event );
+ void setButton( int id );
+ QButton* find( int id );
+ QButton* create( int id );
+ void remove( QButton* button );
+ void remove( const int &id );
+ void resize( const int Width );
+ int id( QButton * );
+
+ signals:
+ void leftClick( int id );
+ void rightClick( int id );
+ void menuItemSelected( int id, int item );
+
+ protected slots:
+ void buttonClicked(void);
+ void menuClicked( int item );
+
+ protected:
+ void childEvent( QChildEvent * );
+
+ private:
+ resource *Resource;
+ KPopupMenu *matchMenu;
+ QList<Buttons> buttons;
+ int buttWidth;
+ int rightClickID;
+};
+
+#endif
diff --git a/knights/wiz_setup.cpp b/knights/wiz_setup.cpp
new file mode 100644
index 0000000..e584de3
--- /dev/null
+++ b/knights/wiz_setup.cpp
@@ -0,0 +1,360 @@
+/***************************************************************************
+ wiz_setup.cpp - description
+ -------------------
+ begin : Wed Nov 21 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kglobalsettings.h>
+#include <kprocess.h>
+#include <kstddirs.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include "wiz_setup.moc"
+
+wiz_setup::wiz_setup(QWidget *parent, const char *name, resource *Rsrc ) : KWizard(parent,name,TRUE)
+{
+ myResource = Rsrc;
+ steps = 0;
+ setMaximumSize( 800, 600 );
+
+ /*
+ Call Order Of Pages:
+
+ Page 1 - Introduction
+ Page 6 - Accept License
+ Page 3 - Setup Engines
+ Page 4 - Setup Servers
+ Page 5 - Finished
+ */
+ initPage1();
+// initPage6();
+ if( myResource->Config_Version < 1 )
+ {
+// initPage2();
+ initPage3();
+ initPage4();
+ }
+ initPage5();
+ setCaption( i18n( "Knights Setup Wizard" ) );
+
+ connect( this, SIGNAL( selected(const QString&) ), this, SLOT( slot_Work(const QString&) ) );
+}
+wiz_setup::~wiz_setup()
+{
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage1
+//
+///////////////////////////////////////
+void wiz_setup::initPage1( void )
+{
+ Page1 = new QFrame( this );
+ P1B1 = new QGridLayout( Page1, 1, 4, 8 );
+
+ SideImage1 = new QLabel( Page1 );
+ SideImage1->setPixmap( locate("data", "knights/wizard.png" ) );
+ P1B1->addWidget( SideImage1, 1, 1 );
+
+ WelcomeMessage = new QLabel( Page1 );
+ WelcomeMessage->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
+ WelcomeMessage->setText( i18n( "Thank you for installing Knights, the graphical chess interface for KDE. To help you get started quickly, there are a few things Knights will need to setup. You should click 'Next' to see what they are." ) );
+ P1B1->addWidget( WelcomeMessage, 1, 3 );
+
+ addPage( Page1, i18n("Welcome to Knights v%1!").arg(_VERSION_) );
+ setNextEnabled( Page1, TRUE );
+ setHelpEnabled( Page1, FALSE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage2
+//
+///////////////////////////////////////
+void wiz_setup::initPage2( void )
+{
+ Page2 = new QFrame( this );
+ P2B1 = new QGridLayout( Page2, 2, 4, 8 );
+
+ SideImage2 = new QLabel( Page2 );
+ SideImage2->setPixmap( locate("data", "knights/wizard.png" ) );
+ P2B1->addMultiCellWidget( SideImage2, 1, 2, 1, 1 );
+
+ pgnExplain = new QLabel( Page2 );
+ pgnExplain->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
+ pgnExplain->setText( i18n( "When Knights saves a match to disk, it uses Portable Game Notation (PGN) to store the match. Several other computer chess games use PGN too. If you like, Knights can be the default PGN viewer on this system." ) );
+ P2B1->addWidget( pgnExplain, 1, 3 );
+
+ pgnButtons = new QButtonGroup( 2, Qt::Vertical, i18n( "Let Knights handle PGN files?" ), Page2 );
+ pgnYes = new QRadioButton( i18n( "Yes" ), pgnButtons );
+ pgnNo = new QRadioButton( i18n( "No" ), pgnButtons );
+ pgnButtons->setButton( 0 );
+ P2B1->addWidget( pgnButtons, 2, 3 );
+
+ addPage( Page2, i18n("Let Knights handle your .pgn files?") );
+ setHelpEnabled( Page2, FALSE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage3
+//
+///////////////////////////////////////
+void wiz_setup::initPage3( void )
+{
+ Page3 = new QFrame( this );
+ P3B1 = new QGridLayout( Page3, 2, 4, 8 );
+
+ SideImage3 = new QLabel( Page3 );
+ SideImage3->setPixmap( locate("data", "knights/wizard.png" ) );
+ P3B1->addMultiCellWidget( SideImage3, 1, 2, 1, 1 );
+
+ engineExplain = new QLabel( Page3 );
+ engineExplain->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
+ engineExplain->setText( i18n( "Knights can not play a chess match against you without help. Known as Chess Engines, these helpers can be found on the Internet and are often included with your distribution. Knights can look for Chess Engines that you may already have. If found, Knights will configure itself to use them." ) );
+ P3B1->addWidget( engineExplain, 1, 3 );
+
+ engineButtons = new QButtonGroup( 2, Qt::Vertical, i18n( "Let Knights search for chess engines?" ), Page3 );
+ engineYes = new QRadioButton( i18n( "Yes" ), engineButtons );
+ engineNo = new QRadioButton( i18n( "No" ), engineButtons );
+ engineButtons->setButton( 0 );
+ P3B1->addWidget( engineButtons, 2, 3 );
+
+ addPage( Page3, i18n("Let Knights search for chess engines?") );
+ setHelpEnabled( Page3, FALSE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage4
+//
+///////////////////////////////////////
+void wiz_setup::initPage4( void )
+{
+ Page4 = new QFrame( this );
+ P4B1 = new QGridLayout( Page4, 2, 4, 8 );
+
+ SideImage4 = new QLabel( Page4 );
+ SideImage4->setPixmap( locate("data", "knights/wizard.png" ) );
+ P4B1->addMultiCellWidget( SideImage4, 1, 2, 1, 1 );
+
+ serverExplain = new QLabel( Page4 );
+ serverExplain->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
+ serverExplain->setText( i18n( "In order for you to play chess online, Knights will have to connect to a chess server. Knights has a list of several of these servers. If you like, this list can be used to automatically configure Knights." ) );
+ P4B1->addWidget( serverExplain, 1, 3 );
+
+ serverButtons = new QButtonGroup( 2, Qt::Vertical, i18n( "Let Knights configure chess servers?" ), Page4 );
+ serverYes = new QRadioButton( i18n( "Yes" ), serverButtons );
+ serverNo = new QRadioButton( i18n( "No" ), serverButtons );
+ serverButtons->setButton( 0 );
+ P4B1->addWidget( serverButtons, 2, 3 );
+
+ addPage( Page4, i18n("Let Knights configure chess servers?") );
+ setHelpEnabled( Page4, FALSE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage5
+//
+///////////////////////////////////////
+void wiz_setup::initPage5( void )
+{
+ Page5 = new QFrame( this );
+ P5B1 = new QGridLayout( Page5, 2, 4, 8 );
+
+ SideImage5 = new QLabel( Page5 );
+ SideImage5->setPixmap( locate("data", "knights/wizard.png" ) );
+ P5B1->addMultiCellWidget( SideImage5, 1, 2, 1, 1 );
+
+ FinishExplain = new QLabel( Page5 );
+ FinishExplain->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
+ FinishExplain->setText( i18n( "Knights has now configured itself according to your choices. We strongly recommend that you read the documentation to make full use of all that Knights has to offer. You can access it by pressing F1." ) );
+ P5B1->addWidget( FinishExplain, 1, 3 );
+
+ addPage( Page5, i18n("Setup Complete") );
+ setFinish( Page5, TRUE );
+ setHelpEnabled( Page5, FALSE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::initPage6
+//
+///////////////////////////////////////
+void wiz_setup::initPage6( void )
+{
+ QString f( locate("data", "LICENSES/GPL_V2") );
+ QString licenseText("<K_STD>");
+ Page6 = new QVBox( this );
+
+ /* Setup License View */
+ licenseView = new KnightsTextView( Page6, myResource );
+ if (!f.isEmpty())
+ {
+ QFile file(f);
+ if (file.open(IO_ReadOnly))
+ {
+ QTextStream str(&file);
+ licenseText += str.read();
+ }
+ }
+ licenseText.append( "</K_STD>" );
+ licenseView->setText( licenseText );
+
+ licenseButtons = new QButtonGroup( 2, Qt::Horizontal, i18n( "Do you accept the terms of our license?" ), Page6 );
+ licenseYes = new QRadioButton( i18n( "Yes" ), licenseButtons );
+ licenseNo = new QRadioButton( i18n( "No" ), licenseButtons );
+ licenseButtons->setButton( 1 );
+
+ addPage( Page6, i18n("Please read and accept our license:") );
+ setHelpEnabled( Page6, FALSE );
+ connect( licenseButtons, SIGNAL( clicked(int) ), this, SLOT( slot_License(int) ) );
+}
+///////////////////////////////////////
+//
+// wiz_setup::slot_Work
+//
+///////////////////////////////////////
+void wiz_setup::slot_Work( const QString& pageTitle )
+{
+ /* Don't let 'em past the license */
+ if( pageTitle == title( Page6 ) )
+ {
+ setNextEnabled( Page6, FALSE );
+ }
+
+ /* Don't proceed unless we're ready to work */
+ if( pageTitle != title( Page5 ) ) return;
+ setBackEnabled( Page5, FALSE );
+ if( myResource->Config_Version < 1 )
+ {
+// if( pgnButtons->selected() == pgnYes )
+// setupPGN();
+ if( engineButtons->selected() == engineYes )
+ findEngines();
+ if( serverButtons->selected() == serverYes )
+ setupServers();
+ }
+ myResource->ConfigWrite();
+ setFinishEnabled( Page5, TRUE );
+}
+///////////////////////////////////////
+//
+// wiz_setup::setupPGN
+//
+///////////////////////////////////////
+void wiz_setup::setupPGN( void )
+{
+}
+///////////////////////////////////////
+//
+// wiz_setup::setupServers
+//
+///////////////////////////////////////
+void wiz_setup::setupServers( void )
+{
+ serverResource *newServer;
+ QStringList names, urls, ports;
+ unsigned int loop;
+
+ names << i18n("Free Internet Chess Server") << i18n("Internet Chess Club") << i18n("Global Chess Server") << i18n("Chess.Net");
+ names << i18n("Chess-Square.Com") << i18n("Australian FICS") << i18n("Brazilian FICS") << i18n("Chilean FICS");
+ names << i18n("Croatian FICS") << i18n("Dutch FICS") << i18n("French FICS") << i18n("German FICS") << i18n("Swedish FICS");
+ urls << "freechess.org" << "chessclub.com" << "global.chessparlor.com" << "chess.net";
+ urls << "chess-square.com" << "zics.org" << "jogo.cex.org.br" << "ajedrez.cec.uchile.cl";
+ urls << "fly.cc.fer.hr" << "freechess.nl" << "jeu.echecs.com" << "chess.unix-ag.uni-kl.de" << "chess.mds.mdh.se";
+ ports << "5000" << "5000" << "6000" << "5000" << "5000" << "5000" << "5000" << "5000";
+ ports << "7890" << "5000" << "5000" << "5000" << "5000";
+
+ for( loop = 0; loop < names.count(); loop++ )
+ {
+ kdDebug() << "adding " << names[loop] << endl;
+ newServer = new serverResource;
+ newServer->Name = names[loop];
+ newServer->URL = urls[loop];
+ newServer->Port = ports[loop].toInt();
+ newServer->LogFile = QString::null;
+ newServer->UserName = QString::null;
+ newServer->Password = QString::null;
+ newServer->StorePass = FALSE;
+ if( !loop ) newServer->CurrentRef = TRUE;
+ else newServer->CurrentRef = FALSE;
+ myResource->servers.append( *newServer );
+ delete newServer;
+ }
+}
+///////////////////////////////////////
+//
+// wiz_setup::findEngines
+//
+///////////////////////////////////////
+void wiz_setup::findEngines( void )
+{
+ engineResource *newEngine;
+ QStringList names, filenames;
+ KProcess *Shell;
+ bool foundOne( FALSE );
+ unsigned int loop;
+
+ names << "GNUChess" << "Crafty" << "Sjeng" << "KnightCap" << "BabyChess" << "Phalanx-XXII";
+ names << "Bowron Abernethy Chess Engine" << "Cilian" << "Faile" << "OliThink" << "Pepito";
+ names << "Yace";
+ filenames << "gnuchessx" << "crafty" << "sjeng" << "KnightCap" << "babychess-xboard-engine";
+ filenames << "phalanx" << "BACE" << "linuxCilian.exe" << "faile" << "olithink" << "pepito";
+ filenames << "yace";
+
+ for( loop = 0; loop < filenames.count(); loop++ )
+ {
+ Shell = new KProcess();
+ (*Shell) << filenames[loop];
+ if( Shell->start() )
+ {
+ kdWarning() << "Adding " << names[loop] << " to knightsrc" << endl;
+ newEngine = new engineResource;
+ newEngine->Name = names[loop];
+ newEngine->Filename = filenames[loop];
+ newEngine->Arguments = QString::null;
+ newEngine->LogFile = QString::null;
+ newEngine->Protocol = XBoard;
+ newEngine->Wins = 0;
+ newEngine->Losses = 0;
+ newEngine->Draws = 0;
+ if( foundOne )
+ newEngine->CurrentRef = 0;
+ else
+ newEngine->CurrentRef = ENGINE_WHITE | ENGINE_BLACK | ENGINE_WHITE_BK | ENGINE_BLACK_BK;
+ myResource->engines.append( *newEngine );
+ delete newEngine;
+ foundOne = TRUE;
+ }
+ Shell->kill();
+ delete Shell;
+ }
+}
+///////////////////////////////////////
+//
+// wiz_setup::slot_License
+//
+///////////////////////////////////////
+void wiz_setup::slot_License( int index )
+{
+ if( index == 0 )
+ {
+ setNextEnabled( Page6, TRUE );
+ myResource->Accepted_License = TRUE;
+ }
+ else
+ {
+ setNextEnabled( Page6, FALSE );
+ myResource->Accepted_License = FALSE;
+ }
+}
diff --git a/knights/wiz_setup.h b/knights/wiz_setup.h
new file mode 100644
index 0000000..edd5f9e
--- /dev/null
+++ b/knights/wiz_setup.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ wiz_setup.h - description
+ -------------------
+ begin : Wed Nov 21 2001
+ copyright : (C) 2003 by Troy Corbin Jr.
+ email : tcorbin@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef WIZ_SETUP_H
+#define WIZ_SETUP_H
+
+#include <kwizard.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qlabel.h>
+#include "resource.h"
+#include "definitions.h"
+#include "knightstextview.h"
+
+/**
+ *@author Troy Corbin Jr.
+ */
+
+class wiz_setup : public KWizard
+{
+ Q_OBJECT
+ public:
+ wiz_setup( QWidget *parent=0, const char *name=0, resource *Rsrc=0 );
+ ~wiz_setup();
+ protected slots:
+ void slot_Work( const QString& pageTitle );
+ void slot_License( int );
+ protected:
+ void initPage1( void );
+ void initPage2( void );
+ void initPage3( void );
+ void initPage4( void );
+ void initPage5( void );
+ void initPage6( void );
+ void findEngines( void );
+ void setupServers( void );
+ void setupPGN( void );
+ private:
+ resource *myResource;
+ int steps;
+
+ QFrame *Page1;
+ QGridLayout *P1B1;
+ QLabel *SideImage1;
+ QLabel *WelcomeMessage;
+ QFrame *Page2;
+ QGridLayout *P2B1;
+ QLabel *SideImage2;
+ QLabel *pgnExplain;
+ QButtonGroup *pgnButtons;
+ QRadioButton *pgnYes;
+ QRadioButton *pgnNo;
+ QFrame *Page3;
+ QGridLayout *P3B1;
+ QLabel *SideImage3;
+ QLabel *engineExplain;
+ QButtonGroup *engineButtons;
+ QRadioButton *engineYes;
+ QRadioButton *engineNo;
+ QFrame *Page4;
+ QGridLayout *P4B1;
+ QLabel *SideImage4;
+ QLabel *serverExplain;
+ QButtonGroup *serverButtons;
+ QRadioButton *serverYes;
+ QRadioButton *serverNo;
+ QFrame *Page5;
+ QGridLayout *P5B1;
+ QLabel *SideImage5;
+ QLabel *FinishExplain;
+ QVBox *Page6;
+ KnightsTextView *licenseView;
+ QButtonGroup *licenseButtons;
+ QRadioButton *licenseYes;
+ QRadioButton *licenseNo;
+};
+
+#endif