summaryrefslogtreecommitdiffstats
path: root/kmahjongg/HighScore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmahjongg/HighScore.cpp')
-rw-r--r--kmahjongg/HighScore.cpp541
1 files changed, 541 insertions, 0 deletions
diff --git a/kmahjongg/HighScore.cpp b/kmahjongg/HighScore.cpp
new file mode 100644
index 00000000..2e55c15a
--- /dev/null
+++ b/kmahjongg/HighScore.cpp
@@ -0,0 +1,541 @@
+#include <unistd.h>
+#include "HighScore.h"
+#include "HighScore.moc"
+
+
+#include <qlabel.h>
+#include <qfileinfo.h>
+#include <kmessagebox.h>
+#include "klocale.h"
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <kapplication.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+static const QString highScoreMagic1_0 = "kmahjongg-scores-v1.0";
+static const QString highScoreMagic1_1 = "kmahjongg-scores-v1.1";
+
+static const char * highScoreFilename = "/kmahjonggHiscores";
+
+const char * defNames[numScores] = {
+ "David Black",
+ "Mathias Mueller",
+ "Osvaldo Stark",
+ "Steve Taylor",
+ "Clare Brizzolara",
+ "Angela Simpson",
+ "Michael O'Brien",
+ "Kelvin Bell",
+ "Jenifferi O'Keeffe",
+ "Phil Lamdin"
+};
+
+int defScores[numScores] =
+ {400, 350, 300, 250, 200, 150, 100, 50, 20, 10};
+
+const int ages = 59+(59*60)+(2*60*60);
+int defTimes[numScores] = {ages, ages-1, ages-2, ages-3,
+ ages-4, ages-5, ages-6, ages-7, ages-8, ages-9};
+
+
+HighScore::HighScore
+(
+ QWidget* parent,
+ const char* name
+)
+ :
+ QDialog( parent, name, true, 0 )
+{
+
+ // form the target name
+
+
+ filename = locateLocal("appdata", highScoreFilename);
+
+ QFont fnt;
+ // Number
+ QLabel* qtarch_Label_3;
+ qtarch_Label_3 = new QLabel( this, "Label_3" );
+ qtarch_Label_3->setGeometry( 10, 45, 30, 30 );
+ qtarch_Label_3->setFrameStyle( 50 );
+ qtarch_Label_3->setText( i18n("Pos") );
+ qtarch_Label_3->setAlignment( AlignCenter );
+ fnt = qtarch_Label_3->font();
+ fnt.setBold(true);
+ qtarch_Label_3->setFont(fnt);
+
+
+ // name
+
+ QLabel* qtarch_Label_4;
+ qtarch_Label_4 = new QLabel( this, "Label_4" );
+ qtarch_Label_4->setGeometry( 40, 45, 150, 30 );
+ qtarch_Label_4->setFrameStyle( 50 );
+ qtarch_Label_4->setText( i18n("Name") );
+ qtarch_Label_4->setFont(fnt);
+
+
+ // board number
+ QLabel* boardTitle;
+ boardTitle= new QLabel( this, "" );
+ boardTitle->setGeometry( 190, 45, 80, 30 );
+ boardTitle->setFrameStyle( 50 );
+ boardTitle->setText( i18n("Board") );
+ boardTitle->setFont(fnt);
+
+ // score
+ QLabel* qtarch_Label_5;
+ qtarch_Label_5 = new QLabel( this, "Label_5" );
+ qtarch_Label_5->setGeometry( 270, 45, 70, 30 );
+ qtarch_Label_5->setFrameStyle( 50 );
+ qtarch_Label_5->setText( i18n("Score") );
+ qtarch_Label_5->setFont(fnt);
+
+ // time
+ QLabel* qtarch_Label_6;
+ qtarch_Label_6 = new QLabel( this, "Label_6" );
+ qtarch_Label_6->setGeometry( 340, 45, 70, 30 );
+ qtarch_Label_6->setFrameStyle( 50 );
+ qtarch_Label_6->setText( i18n("Time") );
+ qtarch_Label_6->setFont(fnt);
+
+
+
+ for (int row=0; row<numScores; row++)
+ addRow(row);
+
+ QPushButton* qtarch_PushButton_1;
+ qtarch_PushButton_1 = new KPushButton( KStdGuiItem::ok(), this, "PushButton_1" );
+ qtarch_PushButton_1->setGeometry( 110+35, 340+50, 100, 30 );
+ qtarch_PushButton_1->setMinimumSize( 0, 0 );
+ qtarch_PushButton_1->setMaximumSize( 32767, 32767 );
+ qtarch_PushButton_1->setFocusPolicy( QWidget::TabFocus );
+ qtarch_PushButton_1->setAutoRepeat( false );
+ qtarch_PushButton_1->setAutoResize( false );
+ qtarch_PushButton_1->setDefault(true);
+
+ QPushButton* resetBtn;
+ resetBtn= new QPushButton( this, "resetBtn" );
+ resetBtn->setGeometry( 10, 5, 25, 25);
+ resetBtn->setMinimumSize( 0, 0 );
+ resetBtn->setMaximumSize( 32767, 32767 );
+ resetBtn->setFocusPolicy( QWidget::TabFocus );
+ //resetBtn->setText(i18n( "Reset" ));
+ resetBtn->setAutoRepeat( false );
+ resetBtn->setAutoResize( false );
+
+ KIconLoader *loader = KGlobal::iconLoader();
+ resetBtn->setPixmap(loader->loadIcon("editdelete", KIcon::Toolbar));
+
+
+
+ /* We create the ediat area for the hi score name entry and move it */
+ /* off screen. it is moved over and placed in position when a */
+ /* new name is added */
+
+ lineEdit = new QLineEdit(this, "");
+ lineEdit->setGeometry( 50, 40+(20*30), 190, 30 );
+ lineEdit->setFocusPolicy(QWidget::StrongFocus);
+ lineEdit->setFrame(true);
+ lineEdit->setEchoMode(QLineEdit::Normal);
+ lineEdit->setText("");
+
+ // the drop down for the board names
+
+ combo = new QComboBox( false, this, "combo" );
+ combo->setGeometry( 65, 5, 220, 25 );
+ combo->setMinimumSize( 0, 0 );
+ combo->setMaximumSize( 32767, 32767 );
+ combo->setFocusPolicy( QWidget::StrongFocus );
+ combo->setSizeLimit( 10 );
+ combo->setAutoResize( false );
+ connect( combo, SIGNAL(activated(int)), SLOT(selectionChanged(int)) );
+
+
+ resize( 350+70,390+45 );
+ setFixedSize(350+70,390+45);
+
+ tables = NULL;
+ loadTables();
+ currTable = tables;
+
+ setCaption(kapp->makeStdCaption(i18n("Scores")));
+
+ selectedLine = -1;
+
+ connect(lineEdit, SIGNAL( textChanged(const QString &)),
+ SLOT( nameChanged(const QString &)));
+
+
+ connect(qtarch_PushButton_1, SIGNAL(clicked()), SLOT(reject()));
+ connect(resetBtn, SIGNAL(clicked()), SLOT(reset()));
+}
+
+// free up the table structures
+
+HighScore::~HighScore()
+{
+ TableInstance *t, *t1;
+
+ if (tables != NULL) {
+ t = tables;
+ while(t != NULL)
+ {
+ t1 = t;
+ t = t -> next;
+ delete t1;
+ }
+ }
+ tables = NULL;
+}
+
+
+
+// return a pointer to a linked list of table entries from the
+// saved hi score tables file. If no such file exists then
+// return a single default hiscore table.
+
+void HighScore::loadTables() {
+ char buff[1024];
+
+ // open the file, on error set up the default table
+ FILE *fp = fopen( QFile::encodeName(highScoreFile()), "r");
+ if (fp == NULL)
+ goto error;
+
+ // check magic
+ fscanf(fp, "%1023s\n", buff);
+ if (highScoreMagic1_1 != buff) {
+ goto error;
+ }
+
+ int num;
+ fscanf(fp, "%d\n", &num);
+
+ for (int p=0; p<num; p++) {
+ TableInstance *t = new TableInstance;
+ t->next = tables;
+
+
+ tables = t;
+
+ fgets(buff, sizeof(buff), fp);
+ if (buff[strlen(buff)-1] == '\n')
+ buff[strlen(buff)-1] = '\0';
+ t->name = buff;
+ combo->insertItem(t->name);
+ setComboTo(t->name);
+ for (int e=0; e<numScores; e++) {
+ fscanf(fp, "%ld\n", &(t->entries[e].score));
+ fscanf(fp, "%ld\n", &(t->entries[e].elapsed));
+ fscanf(fp, "%ld\n", &(t->entries[e].board));
+ fgets(buff, sizeof(buff), fp);
+ if (buff[strlen(buff)-1] == '\n')
+ buff[strlen(buff)-1] = '\0';
+ t->entries[e].name=QString::fromUtf8(buff,-1);
+ }
+ }
+
+
+ fclose(fp);
+ return;
+
+
+error:
+ selectTable("default");
+ saveTables();
+ return;
+}
+
+void HighScore::saveTables() {
+
+ TableInstance *p;
+ int num = 0;
+
+ // Nothing to do
+ if (tables == NULL)
+ return;
+
+
+ // open the outrput file, with naff error handling
+ FILE *fp = fopen( QFile::encodeName(highScoreFile()), "w");
+ if (fp == NULL)
+ return;
+
+ // count up the number of tables to save
+ for (p=tables; p != NULL; p = p->next)
+ num++;
+
+ // output the file magic
+ fprintf(fp,"%s\n", highScoreMagic1_1.utf8().data());
+
+ // output the count of tables to process
+ fprintf(fp, "%d\n", num);
+
+ // output each table
+ for (p=tables; p != NULL; p = p->next) {
+ fprintf(fp, "%s\n", p->name.utf8().data());
+ for (int e=0; e<numScores; e++) {
+ fprintf(fp,"%ld\n%ld\n%ld\n%s\n",
+ p->entries[e].score,
+ p->entries[e].elapsed,
+ p->entries[e].board,
+ p->entries[e].name.utf8().data());
+ }
+ }
+ fclose(fp);
+
+}
+
+// traverse the list of hi score tables and set the
+// current table to the specified board. Create it if it does not
+// exist.
+
+void HighScore::selectTable(const QString &board) {
+
+ TableInstance *pos = tables;
+
+
+ while (pos != NULL) {
+ if (pos->name == board)
+ break;
+ pos = pos->next;
+ }
+
+
+
+ if (pos == NULL) {
+ // not found, add new board to the front of the list
+ TableInstance *n = new TableInstance;
+ n->next = tables;
+ n->name = board;
+
+
+
+ for (int p =0; p < numScores; p ++) {
+ n->entries[p].name = defNames[p];
+ n->entries[p].score = defScores[p];
+ n->entries[p].board = 928364243l+(p *3);
+ n->entries[p].elapsed = defTimes[p];
+ }
+ tables = n;
+ currTable = n;
+ combo->insertItem(board);
+ setComboTo(board);
+ return;
+ }
+ currTable = pos;
+ setComboTo(board);
+ return;
+}
+
+
+
+void HighScore::addRow(int num) {
+ QFont tmp;
+
+ // game number
+ numbersWidgets[num] = new QLabel( this);
+ numbersWidgets[num]->setGeometry( 10, 75+(num*30), 30, 30 );
+ numbersWidgets[num]->setFrameStyle( 50 );
+ numbersWidgets[num]->setAlignment( AlignRight | AlignVCenter );
+ numbersWidgets[num]->setNum(num+1);
+
+
+ // name
+ namesWidgets[num] = new QLabel( this);
+ namesWidgets[num]->setGeometry( 40, 75+(num*30), 150, 30 );
+ namesWidgets[num]->setFrameStyle( 50 );
+ namesWidgets[num]->setAlignment( 289 );
+
+ // board
+ boardWidgets[num] = new QLabel( this);
+ boardWidgets[num]->setGeometry( 190, 75+(num*30), 80, 30 );
+ boardWidgets[num]->setFrameStyle( 50 );
+ boardWidgets[num]->setAlignment( 289 );
+
+ // score
+ scoresWidgets[num] = new QLabel( this);
+ scoresWidgets[num]->setGeometry( 270, 75+(num*30), 70, 30 );
+ scoresWidgets[num]->setFrameStyle( 50 );
+ tmp = scoresWidgets[num]->font();
+ tmp.setItalic(true);
+ scoresWidgets[num]->setFont(tmp);
+
+ // elapsed time
+ elapsedWidgets[num] = new QLabel( this);
+ elapsedWidgets[num]->setGeometry( 270+70, 75+(num*30), 70, 30 );
+ elapsedWidgets[num]->setFrameStyle( 50 );
+ tmp = elapsedWidgets[num]->font();
+ tmp.setItalic(true);
+ elapsedWidgets[num]->setFont(tmp);
+
+
+}
+
+void HighScore::copyTableToScreen(const QString &name) {
+ char buff[256];
+ QString base;
+ getBoardName(name, base);
+ selectTable(base);
+ for (int p=0; p<numScores;p++) {
+ scoresWidgets[p]->setNum((int)currTable->entries[p].score);
+ namesWidgets[p]->setText(currTable->entries[p].name);
+ boardWidgets[p]->setNum((int)currTable->entries[p].board);
+
+ int e = currTable->entries[p].elapsed;
+ int s = e % 60;
+ e = e-s;
+ int m = (e % (60*60)) / 60;
+ e = e - (e % (60*60));
+ int h = (e % (60*60*60)) / (60*60);
+ sprintf(buff, "%2.2d:%2.2d:%2.2d", h, m , s);
+ elapsedWidgets[p]->setText(buff);
+
+ }
+ repaint(false);
+}
+
+int HighScore::exec(QString &layout) {
+ copyTableToScreen(layout);
+ return(QDialog::exec());
+}
+
+void HighScore::checkHighScore(int s, int e, long gameNum, QString &name) {
+ int pos;
+
+ QString board;
+ getBoardName(name, board);
+
+ // make this board name the current one!
+ // creates it if it does not exist
+ selectTable(board);
+
+
+ for (pos=0; pos <numScores; pos++) {
+ if (s > currTable->entries[pos].score) {
+ break;
+ }
+ }
+ if (pos >= numScores) {
+ return;
+ }
+ for (int move= numScores-1; move >pos; move--) {
+ currTable->entries[move].score = currTable->entries[move-1].score;
+ currTable->entries[move].name = currTable->entries[move-1].name;
+ currTable->entries[move].board = currTable->entries[move-1].board;
+ currTable->entries[move].elapsed = currTable->entries[move-1].elapsed;
+ }
+
+ currTable->entries[pos].score = s;
+ currTable->entries[pos].board = gameNum;
+ currTable->entries[pos].elapsed = e;
+
+ lineEdit->setEnabled(true);
+ lineEdit->setGeometry( 40, 75+(pos*30), 150, 30 );
+ lineEdit->setFocus();
+ lineEdit->setText("");
+ selectedLine = pos;
+ nameChanged("");
+
+ // no board change when entering data
+ combo->setEnabled(false);
+ exec(board);
+ combo->setEnabled(true);
+
+ selectedLine = -1;
+ lineEdit->setGeometry( 40, 75+(20*30), 150, 30);
+ lineEdit->setEnabled(false);
+
+ // sync the hiscore table to disk now
+ saveTables();
+
+}
+
+void HighScore::nameChanged(const QString &s) {
+
+ if (selectedLine == -1)
+ return;
+
+ if (s.isEmpty())
+ currTable->entries[selectedLine].name =
+ i18n("Anonymous");
+ else
+ currTable->entries[selectedLine].name = s;
+}
+
+
+void HighScore::getBoardName(QString in, QString &out) {
+
+ QFileInfo fi( in );
+ out = fi.baseName();
+}
+
+void HighScore::setComboTo(const QString &to) {
+ for (int p=0; p<combo->count(); p++) {
+ if (combo->text(p) == to)
+ combo->setCurrentItem(p);
+ }
+}
+
+
+void HighScore::selectionChanged(int ) {
+ copyTableToScreen(combo->currentText());
+
+}
+
+
+// reset the high score table. Caution the user
+// before acting
+
+
+void HighScore::reset() {
+
+ int res=KMessageBox::warningContinueCancel(this,
+ i18n("Resetting the high scores will "
+ "remove all high score entries "
+ "both in memory and on disk. Do "
+ "you wish to proceed?"),
+ i18n("Reset High Scores"),i18n("Reset"));
+ if (res != KMessageBox::Continue)
+ return ;
+
+ // delete the file
+ res = unlink( QFile::encodeName(highScoreFile()));
+
+ // wipe ou the in memory list of tables
+ TableInstance *t, *d;
+
+ if (tables != NULL) {
+ t = tables;
+ while (t != NULL) {
+ d = t;
+ t = t->next;
+ d->next=0;
+ delete d;
+ }
+
+ }
+
+ // set the list empty
+ tables = NULL;
+ currTable=NULL;
+
+ // clear out the combobox
+ combo->clear();
+
+ // stick in a default
+ selectTable("default");
+
+ // make sure tha the on screen data does not
+ // point to deleted data
+ copyTableToScreen("default");
+}
+
+QString &HighScore::highScoreFile() {
+ return filename;
+
+}