• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libtdegames
 

libtdegames

  • libtdegames
  • highscore
kexthighscore_internal.cpp
1/*
2 This file is part of the TDE games library
3 Copyright (C) 2001-2004 Nicolas Hadacek (hadacek@kde.org)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kexthighscore_internal.h"
21
22#include <pwd.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26#include <tqfile.h>
27#include <tqlayout.h>
28#include <tqdom.h>
29
30#include <tdeglobal.h>
31#include <tdeio/netaccess.h>
32#include <tdeio/job.h>
33#include <tdemessagebox.h>
34#include <kmdcodec.h>
35#include <kdebug.h>
36
37#include "config.h"
38#include "kexthighscore.h"
39#include "kexthighscore_gui.h"
40#include "tdeemailsettings.h"
41
42
43namespace KExtHighscore
44{
45
46//-----------------------------------------------------------------------------
47const char ItemContainer::ANONYMOUS[] = "_";
48const char ItemContainer::ANONYMOUS_LABEL[] = I18N_NOOP("anonymous");
49
50ItemContainer::ItemContainer()
51 : _item(0)
52{}
53
54ItemContainer::~ItemContainer()
55{
56 delete _item;
57}
58
59void ItemContainer::setItem(Item *item)
60{
61 delete _item;
62 _item = item;
63}
64
65TQString ItemContainer::entryName() const
66{
67 if ( _subGroup.isEmpty() ) return _name;
68 return _name + "_" + _subGroup;
69}
70
71TQVariant ItemContainer::read(uint i) const
72{
73 Q_ASSERT(_item);
74
75 TQVariant v = _item->defaultValue();
76 if ( isStored() ) {
77 internal->hsConfig().setHighscoreGroup(_group);
78 v = internal->hsConfig().readPropertyEntry(i+1, entryName(), v);
79 }
80 return _item->read(i, v);
81}
82
83TQString ItemContainer::pretty(uint i) const
84{
85 Q_ASSERT(_item);
86 return _item->pretty(i, read(i));
87}
88
89void ItemContainer::write(uint i, const TQVariant &value) const
90{
91 Q_ASSERT( isStored() );
92 Q_ASSERT( internal->hsConfig().isLocked() );
93 internal->hsConfig().setHighscoreGroup(_group);
94 internal->hsConfig().writeEntry(i+1, entryName(), value);
95}
96
97uint ItemContainer::increment(uint i) const
98{
99 uint v = read(i).toUInt() + 1;
100 write(i, v);
101 return v;
102}
103
104//-----------------------------------------------------------------------------
105ItemArray::ItemArray()
106 : _group(""), _subGroup("") // no null groups
107{}
108
109ItemArray::~ItemArray()
110{
111 for (uint i=0; i<size(); i++) delete at(i);
112}
113
114int ItemArray::findIndex(const TQString &name) const
115{
116 for (uint i=0; i<size(); i++)
117 if ( at(i)->name()==name ) return i;
118 return -1;
119}
120
121const ItemContainer *ItemArray::item(const TQString &name) const
122{
123 int i = findIndex(name);
124 if ( i==-1 ) kdError(11002) << k_funcinfo << "no item named \"" << name
125 << "\"" << endl;
126 return at(i);
127}
128
129ItemContainer *ItemArray::item(const TQString &name)
130{
131 int i = findIndex(name);
132 if ( i==-1 ) kdError(11002) << k_funcinfo << "no item named \"" << name
133 << "\"" << endl;
134 return at(i);
135}
136
137void ItemArray::setItem(const TQString &name, Item *item)
138{
139 int i = findIndex(name);
140 if ( i==-1 ) kdError(11002) << k_funcinfo << "no item named \"" << name
141 << "\"" << endl;
142 bool stored = at(i)->isStored();
143 bool canHaveSubGroup = at(i)->canHaveSubGroup();
144 _setItem(i, name, item, stored, canHaveSubGroup);
145}
146
147void ItemArray::addItem(const TQString &name, Item *item,
148 bool stored, bool canHaveSubGroup)
149{
150 if ( findIndex(name)!=-1 )
151 kdError(11002) << "item already exists \"" << name << "\"" << endl;
152 uint i = size();
153 resize(i+1);
154 at(i) = new ItemContainer;
155 _setItem(i, name, item, stored, canHaveSubGroup);
156}
157
158void ItemArray::_setItem(uint i, const TQString &name, Item *item,
159 bool stored, bool canHaveSubGroup)
160{
161 at(i)->setItem(item);
162 at(i)->setName(name);
163 at(i)->setGroup(stored ? _group : TQString());
164 at(i)->setSubGroup(canHaveSubGroup ? _subGroup : TQString());
165}
166
167void ItemArray::setGroup(const TQString &group)
168{
169 Q_ASSERT( !group.isNull() );
170 _group = group;
171 for (uint i=0; i<size(); i++)
172 if ( at(i)->isStored() ) at(i)->setGroup(group);
173}
174
175void ItemArray::setSubGroup(const TQString &subGroup)
176{
177 Q_ASSERT( !subGroup.isNull() );
178 _subGroup = subGroup;
179 for (uint i=0; i<size(); i++)
180 if ( at(i)->canHaveSubGroup() ) at(i)->setSubGroup(subGroup);
181}
182
183void ItemArray::read(uint k, Score &data) const
184{
185 for (uint i=0; i<size(); i++) {
186 if ( !at(i)->isStored() ) continue;
187 data.setData(at(i)->name(), at(i)->read(k));
188 }
189}
190
191void ItemArray::write(uint k, const Score &data, uint nb) const
192{
193 for (uint i=0; i<size(); i++) {
194 if ( !at(i)->isStored() ) continue;
195 for (uint j=nb-1; j>k; j--) at(i)->write(j, at(i)->read(j-1));
196 at(i)->write(k, data.data(at(i)->name()));
197 }
198}
199
200void ItemArray::exportToText(TQTextStream &s) const
201{
202 for (uint k=0; k<nbEntries()+1; k++) {
203 for (uint i=0; i<size(); i++) {
204 const Item *item = at(i)->item();
205 if ( item->isVisible() ) {
206 if ( i!=0 ) s << '\t';
207 if ( k==0 ) s << item->label();
208 else s << at(i)->pretty(k-1);
209 }
210 }
211 s << endl;
212 }
213}
214
215//-----------------------------------------------------------------------------
216class ScoreNameItem : public NameItem
217{
218 public:
219 ScoreNameItem(const ScoreInfos &score, const PlayerInfos &infos)
220 : _score(score), _infos(infos) {}
221
222 TQString pretty(uint i, const TQVariant &v) const {
223 uint id = _score.item("id")->read(i).toUInt();
224 if ( id==0 ) return NameItem::pretty(i, v);
225 return _infos.prettyName(id-1);
226 }
227
228 private:
229 const ScoreInfos &_score;
230 const PlayerInfos &_infos;
231};
232
233//-----------------------------------------------------------------------------
234ScoreInfos::ScoreInfos(uint maxNbEntries, const PlayerInfos &infos)
235 : _maxNbEntries(maxNbEntries)
236{
237 addItem("id", new Item((uint)0));
238 addItem("rank", new RankItem, false);
239 addItem("name", new ScoreNameItem(*this, infos));
240 addItem("score", Manager::createItem(Manager::ScoreDefault));
241 addItem("date", new DateItem);
242}
243
244uint ScoreInfos::nbEntries() const
245{
246 uint i = 0;
247 for (; i<_maxNbEntries; i++)
248 if ( item("score")->read(i)==item("score")->item()->defaultValue() )
249 break;
250 return i;
251}
252
253//-----------------------------------------------------------------------------
254const char *HS_ID = "player id";
255const char *HS_KEY = "player key";
256
257PlayerInfos::PlayerInfos()
258{
259 setGroup("players");
260
261 // standard items
262 addItem("name", new NameItem);
263 Item *it = new Item((uint)0, i18n("Games Count"),TQt::AlignRight);
264 addItem("nb games", it, true, true);
265 it = Manager::createItem(Manager::MeanScoreDefault);
266 addItem("mean score", it, true, true);
267 it = Manager::createItem(Manager::BestScoreDefault);
268 addItem("best score", it, true, true);
269 addItem("date", new DateItem, true, true);
270 it = new Item(TQString(), i18n("Comment"), TQt::AlignLeft);
271 addItem("comment", it);
272
273 // statistics items
274 addItem("nb black marks", new Item((uint)0), true, true); // legacy
275 addItem("nb lost games", new Item((uint)0), true, true);
276 addItem("nb draw games", new Item((uint)0), true, true);
277 addItem("current trend", new Item((int)0), true, true);
278 addItem("max lost trend", new Item((uint)0), true, true);
279 addItem("max won trend", new Item((uint)0), true, true);
280
281 struct passwd *pwd = getpwuid(getuid());
282 TQString username = pwd->pw_name;
283#ifdef HIGHSCORE_DIRECTORY
284 internal->hsConfig().setHighscoreGroup("players");
285 for (uint i=0; ;i++) {
286 if ( !internal->hsConfig().hasEntry(i+1, "username") ) {
287 _newPlayer = true;
288 _id = i;
289 break;
290 }
291 if ( internal->hsConfig().readEntry(i+1, "username")==username ) {
292 _newPlayer = false;
293 _id = i;
294 return;
295 }
296 }
297#endif
298 internal->hsConfig().lockForWriting();
299 KEMailSettings emailConfig;
300 emailConfig.setProfile(emailConfig.defaultProfileName());
301 TQString name = emailConfig.getSetting(KEMailSettings::RealName);
302 if ( name.isEmpty() || isNameUsed(name) ) name = username;
303 if ( isNameUsed(name) ) name= TQString(ItemContainer::ANONYMOUS);
304#ifdef HIGHSCORE_DIRECTORY
305 internal->hsConfig().writeEntry(_id+1, "username", username);
306 item("name")->write(_id, name);
307#endif
308
309 ConfigGroup cg;
310 _oldLocalPlayer = cg.config()->hasKey(HS_ID);
311 _oldLocalId = cg.config()->readUnsignedNumEntry(HS_ID);
312#ifdef HIGHSCORE_DIRECTORY
313 if (_oldLocalPlayer) { // player already exists in local config file
314 // copy player data
315 TQString prefix = TQString("%1_").arg(_oldLocalId+1);
316 TQMap<TQString, TQString> entries =
317 cg.config()->entryMap("KHighscore_players");
318 TQMap<TQString, TQString>::const_iterator it;
319 for (it=entries.begin(); it!=entries.end(); ++it) {
320 TQString key = it.key();
321 if ( key.find(prefix)==0 ) {
322 TQString name = key.right(key.length()-prefix.length());
323 if ( name!="name" || !isNameUsed(it.data()) )
324 internal->hsConfig().writeEntry(_id+1, name, it.data());
325 }
326 }
327 }
328#else
329 _newPlayer = !_oldLocalPlayer;
330 if (_oldLocalPlayer) _id = _oldLocalId;
331 else {
332 _id = nbEntries();
333 cg.config()->writeEntry(HS_ID, _id);
334 item("name")->write(_id, name);
335 }
336#endif
337 _bound = true;
338 internal->hsConfig().writeAndUnlock();
339}
340
341void PlayerInfos::createHistoItems(const TQMemArray<uint> &scores, bool bound)
342{
343 Q_ASSERT( _histogram.size()==0 );
344 _bound = bound;
345 _histogram = scores;
346 for (uint i=1; i<histoSize(); i++)
347 addItem(histoName(i), new Item((uint)0), true, true);
348}
349
350bool PlayerInfos::isAnonymous() const
351{
352 return ( name()==ItemContainer::ANONYMOUS );
353}
354
355uint PlayerInfos::nbEntries() const
356{
357 internal->hsConfig().setHighscoreGroup("players");
358 TQStringList list = internal->hsConfig().readList("name", -1);
359 return list.count();
360}
361
362TQString PlayerInfos::key() const
363{
364 ConfigGroup cg;
365 return cg.config()->readEntry(HS_KEY, TQString());
366}
367
368TQString PlayerInfos::histoName(uint i) const
369{
370 const TQMemArray<uint> &sh = _histogram;
371 Q_ASSERT( i<sh.size() || (_bound || i==sh.size()) );
372 if ( i==sh.size() )
373 return TQString("nb scores greater than %1").arg(sh[sh.size()-1]);
374 return TQString("nb scores less than %1").arg(sh[i]);
375}
376
377uint PlayerInfos::histoSize() const
378{
379 return _histogram.size() + (_bound ? 0 : 1);
380}
381
382void PlayerInfos::submitScore(const Score &score) const
383{
384 // update counts
385 uint nbGames = item("nb games")->increment(_id);
386 switch (score.type()) {
387 case Lost:
388 item("nb lost games")->increment(_id);
389 break;
390 case Won: break;
391 case Draw:
392 item("nb draw games")->increment(_id);
393 break;
394 };
395
396 // update mean
397 if ( score.type()==Won ) {
398 uint nbWonGames = nbGames - item("nb lost games")->read(_id).toUInt()
399 - item("nb draw games")->read(_id).toUInt()
400 - item("nb black marks")->read(_id).toUInt(); // legacy
401 double mean = (nbWonGames==1 ? 0.0
402 : item("mean score")->read(_id).toDouble());
403 mean += (double(score.score()) - mean) / nbWonGames;
404 item("mean score")->write(_id, mean);
405 }
406
407 // update best score
408 Score best = score; // copy optionnal fields (there are not taken into account here)
409 best.setScore( item("best score")->read(_id).toUInt() );
410 if ( best<score ) {
411 item("best score")->write(_id, score.score());
412 item("date")->write(_id, score.data("date").toDateTime());
413 }
414
415 // update trends
416 int current = item("current trend")->read(_id).toInt();
417 switch (score.type()) {
418 case Won: {
419 if ( current<0 ) current = 0;
420 current++;
421 uint won = item("max won trend")->read(_id).toUInt();
422 if ( (uint)current>won ) item("max won trend")->write(_id, current);
423 break;
424 }
425 case Lost: {
426 if ( current>0 ) current = 0;
427 current--;
428 uint lost = item("max lost trend")->read(_id).toUInt();
429 uint clost = -current;
430 if ( clost>lost ) item("max lost trend")->write(_id, clost);
431 break;
432 }
433 case Draw:
434 current = 0;
435 break;
436 }
437 item("current trend")->write(_id, current);
438
439 // update histogram
440 if ( score.type()==Won ) {
441 const TQMemArray<uint> &sh = _histogram;
442 for (uint i=1; i<histoSize(); i++)
443 if ( i==sh.size() || score.score()<sh[i] ) {
444 item(histoName(i))->increment(_id);
445 break;
446 }
447 }
448}
449
450bool PlayerInfos::isNameUsed(const TQString &newName) const
451{
452 if ( newName==name() ) return false; // own name...
453 for (uint i=0; i<nbEntries(); i++)
454 if ( newName.lower()==item("name")->read(i).toString().lower() ) return true;
455 if ( newName==i18n(ItemContainer::ANONYMOUS_LABEL) ) return true;
456 return false;
457}
458
459void PlayerInfos::modifyName(const TQString &newName) const
460{
461 item("name")->write(_id, newName);
462}
463
464void PlayerInfos::modifySettings(const TQString &newName,
465 const TQString &comment,
466 const TQString &newKey) const
467{
468 modifyName(newName);
469 item("comment")->write(_id, comment);
470 ConfigGroup cg;
471 if ( !newKey.isEmpty() ) cg.config()->writeEntry(HS_KEY, newKey);
472}
473
474void PlayerInfos::removeKey()
475{
476 ConfigGroup cg;
477
478 // save old key/nickname
479 uint i = 0;
480 TQString str = "%1 old #%2";
481 TQString sk;
482 do {
483 i++;
484 sk = str.arg(HS_KEY).arg(i);
485 } while ( !cg.config()->readEntry(sk, TQString()).isEmpty() );
486 cg.config()->writeEntry(sk, key());
487
488 // clear current key/nickname
489 cg.config()->deleteEntry(HS_KEY);
490}
491
492//-----------------------------------------------------------------------------
493ManagerPrivate::ManagerPrivate(uint nbGameTypes, Manager &m)
494 : manager(m), showStatistics(false), showDrawGames(false),
495 trackLostGames(false), trackDrawGames(false),
496 showMode(Manager::ShowForHigherScore),
497 _first(true), _nbGameTypes(nbGameTypes), _gameType(0)
498{}
499
500void ManagerPrivate::init(uint maxNbEntries)
501{
502 _hsConfig = new KHighscore(false, 0);
503 _playerInfos = new PlayerInfos;
504 _scoreInfos = new ScoreInfos(maxNbEntries, *_playerInfos);
505}
506
507ManagerPrivate::~ManagerPrivate()
508{
509 delete _scoreInfos;
510 delete _playerInfos;
511 delete _hsConfig;
512}
513
514// strings that needs to be translated (coming from the highscores server)
515const char *DUMMY_STRINGS[] = {
516 I18N_NOOP("Undefined error."),
517 I18N_NOOP("Missing argument(s)."),
518 I18N_NOOP("Invalid argument(s)."),
519
520 I18N_NOOP("Unable to connect to MySQL server."),
521 I18N_NOOP("Unable to select database."),
522 I18N_NOOP("Error on database query."),
523 I18N_NOOP("Error on database insert."),
524
525 I18N_NOOP("Nickname already registered."),
526 I18N_NOOP("Nickname not registered."),
527 I18N_NOOP("Invalid key."),
528 I18N_NOOP("Invalid submit key."),
529
530 I18N_NOOP("Invalid level."),
531 I18N_NOOP("Invalid score.")
532};
533
534const char *UNABLE_TO_CONTACT =
535 I18N_NOOP("Unable to contact world-wide highscore server");
536
537bool ManagerPrivate::getFromQuery(const TQDomNamedNodeMap &map,
538 const TQString &name, TQString &value,
539 TQWidget *parent)
540{
541 TQDomAttr attr = map.namedItem(name).toAttr();
542 if ( attr.isNull() ) {
543 KMessageBox::sorry(parent,
544 i18n("Invalid answer from world-wide "
545 "highscores server (missing item: %1).").arg(name));
546 return false;
547 }
548 value = attr.value();
549 return true;
550}
551
552Score ManagerPrivate::readScore(uint i) const
553{
554 Score score(Won);
555 _scoreInfos->read(i, score);
556 return score;
557}
558
559int ManagerPrivate::rank(const Score &score) const
560{
561 uint nb = _scoreInfos->nbEntries();
562 uint i = 0;
563 for (; i<nb; i++)
564 if ( readScore(i)<score ) break;
565 return (i<_scoreInfos->maxNbEntries() ? (int)i : -1);
566}
567
568bool ManagerPrivate::modifySettings(const TQString &newName,
569 const TQString &comment,
570 TQWidget *widget)
571{
572 TQString newKey;
573 bool newPlayer = false;
574
575 bool ok = _hsConfig->lockForWriting(widget); // no GUI when locking
576 if (ok) {
577 // check again name in case the config file has been changed...
578 // if it has, it is unfortunate because the WWW name is already
579 // committed but should be very rare and not really problematic
580 ok = ( !_playerInfos->isNameUsed(newName) );
581 if (ok)
582 _playerInfos->modifySettings(newName, comment, newKey);
583 _hsConfig->writeAndUnlock();
584 }
585 return ok;
586}
587
588void ManagerPrivate::convertToGlobal()
589{
590 // read old highscores
591 KHighscore *tmp = _hsConfig;
592 _hsConfig = new KHighscore(true, 0);
593 TQValueVector<Score> scores(_scoreInfos->nbEntries());
594 for (uint i=0; i<scores.count(); i++)
595 scores[i] = readScore(i);
596
597 // commit them
598 delete _hsConfig;
599 _hsConfig = tmp;
600 _hsConfig->lockForWriting();
601 for (uint i=0; i<scores.count(); i++)
602 if ( scores[i].data("id").toUInt()==_playerInfos->oldLocalId()+1 )
603 submitLocal(scores[i]);
604 _hsConfig->writeAndUnlock();
605}
606
607void ManagerPrivate::setGameType(uint type)
608{
609 if (_first) {
610 _first = false;
611 if ( _playerInfos->isNewPlayer() ) {
612 // convert legacy highscores
613 for (uint i=0; i<_nbGameTypes; i++) {
614 setGameType(i);
615 manager.convertLegacy(i);
616 }
617
618#ifdef HIGHSCORE_DIRECTORY
619 if ( _playerInfos->isOldLocalPlayer() ) {
620 // convert local to global highscores
621 for (uint i=0; i<_nbGameTypes; i++) {
622 setGameType(i);
623 convertToGlobal();
624 }
625 }
626#endif
627 }
628 }
629
630 Q_ASSERT( type<_nbGameTypes );
631 _gameType = kMin(type, _nbGameTypes-1);
632 TQString str = "scores";
633 TQString lab = manager.gameTypeLabel(_gameType, Manager::Standard);
634 if ( !lab.isEmpty() ) {
635 _playerInfos->setSubGroup(lab);
636 str += "_" + lab;
637 }
638 _scoreInfos->setGroup(str);
639}
640
641void ManagerPrivate::checkFirst()
642{
643 if (_first) setGameType(0);
644}
645
646int ManagerPrivate::submitScore(const Score &ascore,
647 TQWidget *widget, bool askIfAnonymous)
648{
649 checkFirst();
650
651 Score score = ascore;
652 score.setData("id", _playerInfos->id() + 1);
653 score.setData("date", TQDateTime::currentDateTime());
654
655 // ask new name if anonymous and winner
656 const char *dontAskAgainName = "highscore_ask_name_dialog";
657 TQString newName;
658 KMessageBox::ButtonCode dummy;
659 if ( score.type()==Won && askIfAnonymous && _playerInfos->isAnonymous()
660 && KMessageBox::shouldBeShownYesNo(dontAskAgainName, dummy) ) {
661 AskNameDialog d(widget);
662 if ( d.exec()==TQDialog::Accepted ) newName = d.name();
663 if ( d.dontAskAgain() )
664 KMessageBox::saveDontShowAgainYesNo(dontAskAgainName,
665 KMessageBox::No);
666 }
667
668 int rank = -1;
669 if ( _hsConfig->lockForWriting(widget) ) { // no GUI when locking
670 // check again new name in case the config file has been changed...
671 if ( !newName.isEmpty() && !_playerInfos->isNameUsed(newName) )
672 _playerInfos->modifyName(newName);
673
674 // commit locally
675 _playerInfos->submitScore(score);
676 if ( score.type()==Won ) rank = submitLocal(score);
677 _hsConfig->writeAndUnlock();
678 }
679
680 return rank;
681}
682
683int ManagerPrivate::submitLocal(const Score &score)
684{
685 int r = rank(score);
686 if ( r!=-1 ) {
687 uint nb = _scoreInfos->nbEntries();
688 if ( nb<_scoreInfos->maxNbEntries() ) nb++;
689 _scoreInfos->write(r, score, nb);
690 }
691 return r;
692}
693
694void ManagerPrivate::exportHighscores(TQTextStream &s)
695{
696 uint tmp = _gameType;
697
698 for (uint i=0; i<_nbGameTypes; i++) {
699 setGameType(i);
700 if ( _nbGameTypes>1 ) {
701 if ( i!=0 ) s << endl;
702 s << "--------------------------------" << endl;
703 s << "Game type: "
704 << manager.gameTypeLabel(_gameType, Manager::I18N)
705 << endl;
706 s << endl;
707 }
708 s << "Players list:" << endl;
709 _playerInfos->exportToText(s);
710 s << endl;
711 s << "Highscores list:" << endl;
712 _scoreInfos->exportToText(s);
713 }
714
715 setGameType(tmp);
716}
717
718} // namespace
KHighscore
Class for managing highscore tables.
Definition khighscore.h:85
KHighscore::lockForWriting
bool lockForWriting(TQWidget *widget=0)
Definition khighscore.cpp:114
KHighscore::readEntry
TQString readEntry(int entry, const TQString &key, const TQString &pDefault=TQString()) const
Reads an entry from the highscore table.
Definition khighscore.cpp:199
KHighscore::isLocked
bool isLocked() const
Definition khighscore.cpp:85
KHighscore::readList
TQStringList readList(const TQString &key, int lastEntry=20) const
Reads a list of entries from the highscore table starting at 1 until lastEntry.
Definition khighscore.cpp:220
KHighscore::readPropertyEntry
TQVariant readPropertyEntry(int entry, const TQString &key, const TQVariant &pDefault) const
Read a TQVariant entry.
Definition khighscore.cpp:192
KHighscore::writeEntry
void writeEntry(int entry, const TQString &key, const TQString &value)
Definition khighscore.cpp:184
KHighscore::writeAndUnlock
void writeAndUnlock()
Definition khighscore.cpp:143
KHighscore::hasEntry
bool hasEntry(int entry, const TQString &key) const
Definition khighscore.cpp:213
KHighscore::setHighscoreGroup
void setHighscoreGroup(const TQString &groupname=TQString())
Set the new highscore group.
Definition khighscore.cpp:236

libtdegames

Skip menu "libtdegames"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libtdegames

Skip menu "libtdegames"
  • libtdegames
Generated for libtdegames by doxygen 1.15.0
This website is maintained by Timothy Pearson.