00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include <config.h>
00025
#include <fcntl.h>
00026
#include <unistd.h>
00027
#include <sys/file.h>
00028
00029
#include <kapplication.h>
00030
#include <ksimpleconfig.h>
00031
#include <kglobal.h>
00032
#include <kstdguiitem.h>
00033
#include <klocale.h>
00034
#include <kmessagebox.h>
00035
#include <kdebug.h>
00036
#include <kstaticdeleter.h>
00037
00038
#include "khighscore.h"
00039
#include "kconfigrawbackend.h"
00040
#include "kfilelock.h"
00041
00042
#define GROUP "KHighscore"
00043
00044
class KHighscorePrivate
00045 {
00046
public:
00047 KHighscorePrivate() {}
00048
00049
QString group;
00050
bool global;
00051 };
00052
00053 KFileLock *KHighscore::_lock = 0;
00054 KRawConfig *KHighscore::_config = 0;
00055
static KStaticDeleter<KFileLock> lockSD;
00056
static KStaticDeleter<KRawConfig> configSD;
00057
00058
00059 KHighscore::KHighscore(
QObject* parent)
00060 :
QObject(parent)
00061 {
00062
init(
true);
00063 }
00064
00065 KHighscore::KHighscore(
bool forceLocal,
QObject* parent)
00066 :
QObject(parent)
00067 {
00068
init(forceLocal);
00069 }
00070
00071
void KHighscore::init(
bool forceLocal)
00072 {
00073 d =
new KHighscorePrivate;
00074
#ifdef HIGHSCORE_DIRECTORY
00075
d->global = !forceLocal;
00076
if ( d->global && _lock==0 )
00077 kdFatal(11002) <<
"KHighscore::init should be called before!!" << endl;
00078
#else
00079
d->global =
false;
00080 Q_UNUSED(forceLocal);
00081
#endif
00082
readCurrentConfig();
00083 }
00084
00085 bool KHighscore::isLocked()
const
00086
{
00087
return (d->global ? _lock->isLocked() :
true);
00088 }
00089
00090 void KHighscore::readCurrentConfig()
00091 {
00092
if ( d->global ) _config->reparseConfiguration();
00093 }
00094
00095 void KHighscore::init(
const char *appname)
00096 {
00097
#ifdef HIGHSCORE_DIRECTORY
00098
const QString filename = QString::fromLocal8Bit(
"%1/%2.scores")
00099 .arg(HIGHSCORE_DIRECTORY).arg(appname);
00100
int fd = open(filename.local8Bit(), O_RDWR);
00101
if ( fd<0 ) kdFatal(11002) <<
"cannot open global highscore file \""
00102 << filename <<
"\"" << endl;
00103 lockSD.setObject(_lock,
new KFileLock(fd));
00104 configSD.setObject(_config,
new KRawConfig(fd,
true));
00105
00106
00107
int gid = getgid();
00108 setregid(gid, gid);
00109
#else
00110
Q_UNUSED(appname);
00111
#endif
00112
}
00113
00114 bool KHighscore::lockForWriting(
QWidget *widget)
00115 {
00116
if (
isLocked() )
return true;
00117
00118
bool first =
true;
00119
for (;;) {
00120 kdDebug(11002) <<
"try locking" << endl;
00121
00122
int result = _lock->lock();
00123
bool ok = ( result==0 );
00124 kdDebug(11002) <<
"locking system-wide highscore file res="
00125 << result <<
" (ok=" << ok <<
")" << endl;
00126
if (ok) {
00127
readCurrentConfig();
00128 _config->setReadOnly(
false);
00129
return true;
00130 }
00131
00132
if ( !first ) {
00133 KGuiItem item = KStdGuiItem::cont();
00134 item.setText(i18n(
"Retry"));
00135
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");
00136
if ( res==KMessageBox::Cancel )
break;
00137 }
else sleep(1);
00138 first =
false;
00139 }
00140
return false;
00141 }
00142
00143 void KHighscore::writeAndUnlock()
00144 {
00145
if ( !d->global ) {
00146 kapp->config()->sync();
00147
return;
00148 }
00149
if ( !
isLocked() )
return;
00150
00151 kdDebug(11002) <<
"unlocking" << endl;
00152 _config->sync();
00153 _lock->unlock();
00154 _config->setReadOnly(
true);
00155 }
00156
00157 KHighscore::~KHighscore()
00158 {
00159
writeAndUnlock();
00160
delete d;
00161 }
00162
00163 KConfig*
KHighscore::config()
const
00164
{
00165
return (d->global ? _config : kapp->config());
00166 }
00167
00168 void KHighscore::writeEntry(
int entry,
const QString& key,
const QVariant& value)
00169 {
00170 Q_ASSERT(
isLocked() );
00171 KConfigGroupSaver cg(
config(),
group());
00172
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00173 cg.config()->writeEntry(confKey, value);
00174 }
00175
00176 void KHighscore::writeEntry(
int entry,
const QString& key,
int value)
00177 {
00178 Q_ASSERT(
isLocked() );
00179 KConfigGroupSaver cg(
config(),
group());
00180
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00181 cg.config()->writeEntry(confKey, value);
00182 }
00183
00184 void KHighscore::writeEntry(
int entry,
const QString& key,
const QString &value)
00185 {
00186 Q_ASSERT (
isLocked() );
00187 KConfigGroupSaver cg(
config(),
group());
00188
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00189 cg.config()->writeEntry(confKey, value);
00190 }
00191
00192 QVariant KHighscore::readPropertyEntry(
int entry,
const QString& key,
const QVariant& pDefault)
const
00193
{
00194 KConfigGroupSaver cg(
config(),
group());
00195
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00196
return cg.config()->readPropertyEntry(confKey, pDefault);
00197 }
00198
00199 QString KHighscore::readEntry(
int entry,
const QString& key,
const QString& pDefault)
const
00200
{
00201 KConfigGroupSaver cg(
config(),
group());
00202
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00203
return cg.config()->readEntry(confKey, pDefault);
00204 }
00205
00206 int KHighscore::readNumEntry(
int entry,
const QString& key,
int pDefault)
const
00207
{
00208 KConfigGroupSaver cg(
config(),
group());
00209
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00210
return cg.config()->readNumEntry(confKey, pDefault);
00211 }
00212
00213 bool KHighscore::hasEntry(
int entry,
const QString& key)
const
00214
{
00215 KConfigGroupSaver cg(
config(),
group());
00216
QString confKey =
QString(
"%1_%2").arg(entry).arg(key);
00217
return cg.config()->hasKey(confKey);
00218 }
00219
00220 QStringList KHighscore::readList(
const QString& key,
int lastEntry)
const
00221
{
00222
QStringList list;
00223
for (
int i = 1;
hasEntry(i, key) && ((lastEntry > 0) ? (i <= lastEntry) :
true); i++) {
00224 list.append(
readEntry(i, key));
00225 }
00226
return list;
00227 }
00228
00229 void KHighscore::writeList(
const QString& key,
const QStringList& list)
00230 {
00231
for (
int unsigned i = 1; i <= list.count(); i++) {
00232
writeEntry(i, key, list[i - 1]);
00233 }
00234 }
00235
00236 void KHighscore::setHighscoreGroup(
const QString& group)
00237 {
00238 d->group = group;
00239 }
00240
00241 const QString&
KHighscore::highscoreGroup()
const
00242
{
00243
return d->group;
00244 }
00245
00246 QString KHighscore::group()
const
00247
{
00248
if (
highscoreGroup().isNull() )
00249
return (d->global ? QString::null : GROUP);
00250
return (d->global ?
highscoreGroup()
00251 :
QString(
"%1_%2").arg(GROUP).arg(
highscoreGroup()));
00252 }
00253
00254 bool KHighscore::hasTable()
const
00255
{
return config()->hasGroup(
group()); }
00256
00257 void KHighscore::sync()
00258 {
00259
writeAndUnlock();
00260 }
00261
00262
#include "khighscore.moc"