summaryrefslogtreecommitdiffstats
path: root/kolf/newgame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kolf/newgame.cpp')
-rw-r--r--kolf/newgame.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/kolf/newgame.cpp b/kolf/newgame.cpp
new file mode 100644
index 00000000..d038185e
--- /dev/null
+++ b/kolf/newgame.cpp
@@ -0,0 +1,347 @@
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kmessagebox.h>
+#include <kglobal.h>
+#include <kscoredialog.h>
+#include <kstandarddirs.h>
+#include <kseparator.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kurllabel.h>
+
+#include <qcheckbox.h>
+#include <qevent.h>
+#include <qframe.h>
+#include <qpen.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <klistbox.h>
+#include <qstyle.h>
+#include <qrect.h>
+#include <qmap.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qwidget.h>
+#include <qscrollview.h>
+#include <qvaluelist.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qstring.h>
+#include <qvbox.h>
+
+#include "newgame.h"
+#include "game.h"
+
+NewGameDialog::NewGameDialog(bool enableCourses, QWidget *parent, const char *_name)
+ : KDialogBase(KDialogBase::TreeList, i18n("New Game"), Ok | Cancel, Ok, parent, _name)
+{
+ this->enableCourses = enableCourses;
+
+ editors.setAutoDelete(true);
+ KConfig *config = kapp->config();
+
+ // lots o' colors :)
+ startColors << yellow << blue << red << lightGray << cyan << darkBlue << magenta << darkGray << darkMagenta << darkYellow;
+
+ playerPage = addPage(i18n("Players"));
+ QVBoxLayout *bigLayout = new QVBoxLayout(playerPage, marginHint(), spacingHint());
+
+ addButton = new KPushButton(i18n("&New Player"), playerPage);
+ bigLayout->addWidget(addButton);
+
+ connect(addButton, SIGNAL(clicked()), this, SLOT(addPlayer()));
+
+ scroller = new QScrollView(playerPage);
+ bigLayout->addWidget(scroller);
+ layout = new QVBox(scroller->viewport());
+ if (!QPixmapCache::find("grass", grass))
+ {
+ grass.load(locate("appdata", "pics/grass.png"));
+ QPixmapCache::insert("grass", grass);
+ }
+ scroller->viewport()->setBackgroundPixmap(grass);
+ scroller->addChild(layout);
+
+ QMap<QString, QString> entries = config->entryMap("New Game Dialog");
+ unsigned int i = 0;
+ for (QMap<QString, QString>::Iterator it = entries.begin(); it != entries.end(); ++it)
+ {
+ if (i > startColors.count())
+ return;
+
+ addPlayer();
+ editors.last()->setName(it.key().right(it.key().length() - 1));
+ editors.last()->setColor(QColor(it.data()));
+ ++i;
+ }
+
+ if (editors.isEmpty())
+ {
+ addPlayer();
+ addPlayer();
+ }
+
+ enableButtons();
+
+ if (enableCourses)
+ {
+ coursePage = addPage(i18n("Course"), i18n("Choose Course to Play"));
+ QVBoxLayout *coursePageLayout = new QVBoxLayout(coursePage, marginHint(), spacingHint());
+
+ KURLLabel *coursesLink = new KURLLabel("http://web.mit.edu/~jasonkb/www/kolf/", "http://web.mit.edu/~jasonkb/www/kolf/", coursePage);
+ connect(coursesLink, SIGNAL(leftClickedURL(const QString &)), kapp, SLOT(invokeBrowser(const QString &)));
+ coursePageLayout->addWidget(coursesLink);
+
+ QHBoxLayout *hlayout = new QHBoxLayout(coursePageLayout, spacingHint());
+
+ // following use this group
+ config->setGroup("New Game Dialog Mode");
+
+ // find other courses
+ externCourses = config->readListEntry("extra");
+
+ /// course loading
+ QStringList items = externCourses + KGlobal::dirs()->findAllResources("appdata", "courses/*");
+ QStringList nameList;
+ const QString lastCourse(config->readEntry("course", ""));
+ int curItem = 0;
+ i = 0;
+ for (QStringList::Iterator it = items.begin(); it != items.end(); ++it, ++i)
+ {
+ QString file = *it;
+ CourseInfo curinfo;
+ KolfGame::courseInfo(curinfo, file);
+ info[file] = curinfo;
+ names.append(file);
+ nameList.append(curinfo.name);
+
+ if (lastCourse == file)
+ curItem = i;
+ }
+
+ const QString newName(i18n("Create New"));
+ info[QString::null] = CourseInfo(newName, newName, i18n("You"), 0, 0);
+ names.append(QString::null);
+ nameList.append(newName);
+
+ courseList = new KListBox(coursePage);
+ hlayout->addWidget(courseList);
+ courseList->insertStringList(nameList);
+ courseList->setCurrentItem(curItem);
+ connect(courseList, SIGNAL(highlighted(int)), this, SLOT(courseSelected(int)));
+ connect(courseList, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+
+ QVBoxLayout *detailLayout = new QVBoxLayout(hlayout, spacingHint());
+ name = new QLabel(coursePage);
+ detailLayout->addWidget(name);
+ author = new QLabel(coursePage);
+ detailLayout->addWidget(author);
+
+ QHBoxLayout *minorLayout = new QHBoxLayout(detailLayout, spacingHint());
+ par = new QLabel(coursePage);
+ minorLayout->addWidget(par);
+ holes = new QLabel(coursePage);
+ minorLayout->addWidget(holes);
+
+ detailLayout->addStretch();
+ KPushButton *scores = new KPushButton(i18n("Highscores"), coursePage);
+ connect(scores, SIGNAL(clicked()), this, SLOT(showHighscores()));
+ detailLayout->addWidget(scores);
+
+ detailLayout->addStretch();
+ detailLayout->addWidget(new KSeparator(coursePage));
+
+ minorLayout = new QHBoxLayout(detailLayout, spacingHint());
+
+ KPushButton *addCourseButton = new KPushButton(i18n("Add..."), coursePage);
+ minorLayout->addWidget(addCourseButton);
+ connect(addCourseButton, SIGNAL(clicked()), this, SLOT(addCourse()));
+
+ remove = new KPushButton(i18n("Remove"), coursePage);
+ minorLayout->addWidget(remove);
+ connect(remove, SIGNAL(clicked()), this, SLOT(removeCourse()));
+
+ courseSelected(curItem);
+ selectionChanged();
+ }
+
+ // options page
+ optionsPage = addPage(i18n("Options"), i18n("Game Options"));
+ QVBoxLayout *vlayout = new QVBoxLayout(optionsPage, marginHint(), spacingHint());
+
+ mode = new QCheckBox(i18n("&Strict mode"), optionsPage);
+ vlayout->addWidget(mode);
+ mode->setChecked(config->readBoolEntry("competition", false));
+
+ QLabel *desc = new QLabel(i18n("In strict mode, undo, editing, and switching holes is not allowed. This is generally for competition. Only in strict mode are highscores kept."), optionsPage);
+ desc->setTextFormat(RichText);
+ vlayout->addWidget(desc);
+}
+
+void NewGameDialog::slotOk()
+{
+ KConfig *config = kapp->config();
+
+ config->setGroup("New Game Dialog Mode");
+ config->writeEntry("competition", mode->isChecked());
+ if (enableCourses)
+ {
+ config->writeEntry("course", currentCourse);
+ config->writeEntry("extra", externCourses);
+ }
+
+ config->deleteGroup("New Game Dialog");
+ config->setGroup("New Game Dialog");
+
+ PlayerEditor *curEditor = 0;
+ int i = 0;
+ for (curEditor = editors.first(); curEditor; curEditor = editors.next(), ++i)
+ config->writeEntry(QString::number(i) + curEditor->name(), curEditor->color().name());
+
+ config->sync();
+
+ KDialogBase::slotOk();
+}
+
+void NewGameDialog::courseSelected(int index)
+{
+ currentCourse = *names.at(index);
+
+ CourseInfo &curinfo = info[currentCourse];
+
+ name->setText(QString("<strong>%1</strong>").arg(curinfo.name));
+
+ author->setText(i18n("By %1").arg(curinfo.author));
+ par->setText(i18n("Par %1").arg(curinfo.par));
+ holes->setText(i18n("%1 Holes").arg(curinfo.holes));
+}
+
+void NewGameDialog::showHighscores()
+{
+ KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Custom1 | KScoreDialog::Score, this);
+ scoreDialog->addField(KScoreDialog::Custom1, i18n("Par"), "Par");
+ scoreDialog->setConfigGroup(info[currentCourse].untranslatedName + QString(" Highscores"));
+ scoreDialog->setComment(i18n("High Scores for %1").arg(info[currentCourse].name));
+ scoreDialog->show();
+}
+
+void NewGameDialog::removeCourse()
+{
+ int curItem = courseList->currentItem();
+ if (curItem < 0)
+ return;
+
+ QString file = *names.at(curItem);
+ if (externCourses.contains(file) < 1)
+ return;
+
+ names.remove(file);
+ externCourses.remove(file);
+ courseList->removeItem(curItem);
+
+ selectionChanged();
+}
+
+void NewGameDialog::selectionChanged()
+{
+ const int curItem = courseList->currentItem();
+ remove->setEnabled(!(curItem < 0 || externCourses.contains(*names.at(curItem)) < 1));
+}
+
+void NewGameDialog::addCourse()
+{
+ QStringList files = KFileDialog::getOpenFileNames(":kourses", QString::fromLatin1("application/x-kourse"), this, i18n("Pick Kolf Course"));
+
+ bool hasDuplicates = false;
+
+ for (QStringList::Iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt)
+ {
+ if (names.contains(*fileIt) > 0)
+ {
+ hasDuplicates = true;
+ continue;
+ }
+
+ CourseInfo curinfo;
+ KolfGame::courseInfo(curinfo, *fileIt);
+ info[*fileIt] = curinfo;
+ names.prepend(*fileIt);
+ externCourses.prepend(*fileIt);
+
+ courseList->insertItem(curinfo.name, 0);
+ }
+
+ if (hasDuplicates)
+ KMessageBox::information(this, i18n("Chosen course is already on course list."));
+
+ courseList->setCurrentItem(0);
+ courseSelected(0);
+ selectionChanged();
+}
+
+void NewGameDialog::addPlayer()
+{
+ if (editors.count() >= startColors.count())
+ return;
+
+ editors.append(new PlayerEditor(i18n("Player %1").arg(editors.count() + 1), *startColors.at(editors.count()), layout));
+ editors.last()->show();
+ connect(editors.last(), SIGNAL(deleteEditor(PlayerEditor *)), this, SLOT(deleteEditor(PlayerEditor *)));
+
+ enableButtons();
+}
+
+void NewGameDialog::deleteEditor(PlayerEditor *editor)
+{
+ if (editors.count() < 2)
+ return;
+
+ editors.removeRef(editor);
+
+ enableButtons();
+}
+
+void NewGameDialog::enableButtons()
+{
+ addButton->setEnabled(!(editors.count() >= startColors.count()));
+}
+
+/////////////////////////
+
+PlayerEditor::PlayerEditor(QString startName, QColor startColor, QWidget *parent, const char *_name)
+ : QWidget(parent, _name)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this, KDialogBase::spacingHint());
+
+ if (!QPixmapCache::find("grass", grass))
+ {
+ grass.load(locate("appdata", "pics/grass.png"));
+ QPixmapCache::insert("grass", grass);
+ }
+ setBackgroundPixmap(grass);
+
+ editor = new KLineEdit(this);
+ layout->addWidget(editor);
+ editor->setFrame(false);
+ editor->setText(startName);
+ layout->addStretch();
+ layout->addWidget(colorButton = new KColorButton(startColor, this));
+ colorButton->setAutoMask(true);
+ colorButton->setBackgroundPixmap(grass);
+
+ KPushButton *remove = new KPushButton(i18n("Remove"), this);
+ remove->setAutoMask(true);
+ layout->addWidget(remove);
+ remove->setBackgroundPixmap(grass);
+ connect(remove, SIGNAL(clicked()), this, SLOT(removeMe()));
+}
+
+void PlayerEditor::removeMe()
+{
+ emit deleteEditor(this);
+}
+
+#include "newgame.moc"