summaryrefslogtreecommitdiffstats
path: root/libkdegames/highscore/khighscore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkdegames/highscore/khighscore.cpp')
-rw-r--r--libkdegames/highscore/khighscore.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/libkdegames/highscore/khighscore.cpp b/libkdegames/highscore/khighscore.cpp
new file mode 100644
index 00000000..4e1f68e5
--- /dev/null
+++ b/libkdegames/highscore/khighscore.cpp
@@ -0,0 +1,262 @@
+/*
+ This file is part of the KDE games library
+ Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
+ Copyright (C) 2003 Nicolas Hadacek <hadacek@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/*
+ $Id$
+*/
+
+#include <config.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/file.h>
+
+#include <kapplication.h>
+#include <ksimpleconfig.h>
+#include <kglobal.h>
+#include <kstdguiitem.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kstaticdeleter.h>
+
+#include "khighscore.h"
+#include "kconfigrawbackend.h"
+#include "kfilelock.h"
+
+#define GROUP "KHighscore"
+
+class KHighscorePrivate
+{
+public:
+ KHighscorePrivate() {}
+
+ QString group;
+ bool global;
+};
+
+KFileLock *KHighscore::_lock = 0;
+KRawConfig *KHighscore::_config = 0;
+static KStaticDeleter<KFileLock> lockSD;
+static KStaticDeleter<KRawConfig> configSD;
+
+
+KHighscore::KHighscore(QObject* parent)
+ : QObject(parent)
+{
+ init(true);
+}
+
+KHighscore::KHighscore(bool forceLocal, QObject* parent)
+ : QObject(parent)
+{
+ init(forceLocal);
+}
+
+void KHighscore::init(bool forceLocal)
+{
+ d = new KHighscorePrivate;
+#ifdef HIGHSCORE_DIRECTORY
+ d->global = !forceLocal;
+ if ( d->global && _lock==0 )
+ kdFatal(11002) << "KHighscore::init should be called before!!" << endl;
+#else
+ d->global = false;
+ Q_UNUSED(forceLocal);
+#endif
+ readCurrentConfig();
+}
+
+bool KHighscore::isLocked() const
+{
+ return (d->global ? _lock->isLocked() : true);
+}
+
+void KHighscore::readCurrentConfig()
+{
+ if ( d->global ) _config->reparseConfiguration();
+}
+
+void KHighscore::init(const char *appname)
+{
+#ifdef HIGHSCORE_DIRECTORY
+ const QString filename = QString::fromLocal8Bit("%1/%2.scores")
+ .arg(HIGHSCORE_DIRECTORY).arg(appname);
+ int fd = open(filename.local8Bit(), O_RDWR);
+ if ( fd<0 ) kdFatal(11002) << "cannot open global highscore file \""
+ << filename << "\"" << endl;
+ lockSD.setObject(_lock, new KFileLock(fd));
+ configSD.setObject(_config, new KRawConfig(fd, true)); // read-only
+
+ // drop the effective gid
+ int gid = getgid();
+ setregid(gid, gid);
+#else
+ Q_UNUSED(appname);
+#endif
+}
+
+bool KHighscore::lockForWriting(QWidget *widget)
+{
+ if ( isLocked() ) return true;
+
+ bool first = true;
+ for (;;) {
+ kdDebug(11002) << "try locking" << endl;
+ // lock the highscore file (it should exist)
+ int result = _lock->lock();
+ bool ok = ( result==0 );
+ kdDebug(11002) << "locking system-wide highscore file res="
+ << result << " (ok=" << ok << ")" << endl;
+ if (ok) {
+ readCurrentConfig();
+ _config->setReadOnly(false);
+ return true;
+ }
+
+ if ( !first ) {
+ KGuiItem item = KStdGuiItem::cont();
+ item.setText(i18n("Retry"));
+ int res = KMessageBox::warningContinueCancel(widget, i18n("Cannot access the highscore file. Another user is probably currently writing to it."), QString::null, item, "ask_lock_global_highscore_file");
+ if ( res==KMessageBox::Cancel ) break;
+ } else sleep(1);
+ first = false;
+ }
+ return false;
+}
+
+void KHighscore::writeAndUnlock()
+{
+ if ( !d->global ) {
+ kapp->config()->sync();
+ return;
+ }
+ if ( !isLocked() ) return;
+
+ kdDebug(11002) << "unlocking" << endl;
+ _config->sync(); // write config
+ _lock->unlock();
+ _config->setReadOnly(true);
+}
+
+KHighscore::~KHighscore()
+{
+ writeAndUnlock();
+ delete d;
+}
+
+KConfig* KHighscore::config() const
+{
+ return (d->global ? _config : kapp->config());
+}
+
+void KHighscore::writeEntry(int entry, const QString& key, const QVariant& value)
+{
+ Q_ASSERT( isLocked() );
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ cg.config()->writeEntry(confKey, value);
+}
+
+void KHighscore::writeEntry(int entry, const QString& key, int value)
+{
+ Q_ASSERT( isLocked() );
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ cg.config()->writeEntry(confKey, value);
+}
+
+void KHighscore::writeEntry(int entry, const QString& key, const QString &value)
+{
+ Q_ASSERT (isLocked() );
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ cg.config()->writeEntry(confKey, value);
+}
+
+QVariant KHighscore::readPropertyEntry(int entry, const QString& key, const QVariant& pDefault) const
+{
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ return cg.config()->readPropertyEntry(confKey, pDefault);
+}
+
+QString KHighscore::readEntry(int entry, const QString& key, const QString& pDefault) const
+{
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ return cg.config()->readEntry(confKey, pDefault);
+}
+
+int KHighscore::readNumEntry(int entry, const QString& key, int pDefault) const
+{
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ return cg.config()->readNumEntry(confKey, pDefault);
+}
+
+bool KHighscore::hasEntry(int entry, const QString& key) const
+{
+ KConfigGroupSaver cg(config(), group());
+ QString confKey = QString("%1_%2").arg(entry).arg(key);
+ return cg.config()->hasKey(confKey);
+}
+
+QStringList KHighscore::readList(const QString& key, int lastEntry) const
+{
+ QStringList list;
+ for (int i = 1; hasEntry(i, key) && ((lastEntry > 0) ? (i <= lastEntry) : true); i++) {
+ list.append(readEntry(i, key));
+ }
+ return list;
+}
+
+void KHighscore::writeList(const QString& key, const QStringList& list)
+{
+ for (int unsigned i = 1; i <= list.count(); i++) {
+ writeEntry(i, key, list[i - 1]);
+ }
+}
+
+void KHighscore::setHighscoreGroup(const QString& group)
+{
+ d->group = group;
+}
+
+const QString& KHighscore::highscoreGroup() const
+{
+ return d->group;
+}
+
+QString KHighscore::group() const
+{
+ if ( highscoreGroup().isNull() )
+ return (d->global ? QString::null : GROUP);
+ return (d->global ? highscoreGroup()
+ : QString("%1_%2").arg(GROUP).arg(highscoreGroup()));
+}
+
+bool KHighscore::hasTable() const
+{ return config()->hasGroup(group()); }
+
+void KHighscore::sync()
+{
+ writeAndUnlock();
+}
+
+#include "khighscore.moc"