• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkdegames/highscore

kexthighscore_gui.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the KDE games library
00003     Copyright (C) 2001-2003 Nicolas Hadacek (hadacek@kde.org)
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License version 2 as published by the Free Software Foundation.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kexthighscore_gui.h"
00021 #include "kexthighscore_gui.moc"
00022 
00023 #include <QLayout>
00024 #include <QTextStream>
00025 #include <QGridLayout>
00026 #include <QHBoxLayout>
00027 #include <QLabel>
00028 #include <QVBoxLayout>
00029 #include <QGroupBox>
00030 #include <QHeaderView>
00031 #include <QtGui/QTabWidget>
00032 
00033 #include <kmessagebox.h>
00034 #include <kurllabel.h>
00035 #include <krun.h>
00036 #include <kfiledialog.h>
00037 #include <kvbox.h>
00038 #include <ktemporaryfile.h>
00039 #include <kio/netaccess.h>
00040 #include <kicon.h>
00041 #include <kiconloader.h>
00042 #include <klineedit.h>
00043 #include <kpushbutton.h>
00044 
00045 #include "kexthighscore_internal.h"
00046 #include "kexthighscore.h"
00047 #include "kexthighscore_tab.h"
00048 
00049 
00050 namespace KExtHighscore
00051 {
00052 
00053 //-----------------------------------------------------------------------------
00054 ShowItem::ShowItem(QTreeWidget *list, bool highlight)
00055     : QTreeWidgetItem(list), _highlight(highlight)
00056 {
00057 //   kDebug(11001) ;
00058   if (_highlight) {
00059     for (int i=0; i < columnCount();i++) {
00060       setForeground(i, Qt::red);
00061     }
00062   }
00063 }
00064 
00065 //-----------------------------------------------------------------------------
00066 ScoresList::ScoresList(QWidget *parent)
00067     : QTreeWidget(parent)
00068 {
00069 //   kDebug(11001) ;
00070     setSelectionMode(QTreeWidget::NoSelection);
00071 //     setItemMargin(3);
00072     setAllColumnsShowFocus(true);
00073 //     setSorting(-1);
00074     header()->setClickable(false);
00075     header()->setMovable(false);
00076 }
00077 
00078 void ScoresList::addHeader(const ItemArray &items)
00079 {
00080 //   kDebug(11001) ;
00081     addLineItem(items, 0, 0);
00082 }
00083 
00084 QTreeWidgetItem *ScoresList::addLine(const ItemArray &items,
00085                                    uint index, bool highlight)
00086 {
00087 //   kDebug(11001) ;
00088     QTreeWidgetItem *item = new ShowItem(this, highlight);
00089     addLineItem(items, index, item);
00090     return item;
00091 }
00092 
00093 void ScoresList::addLineItem(const ItemArray &items,
00094                              uint index, QTreeWidgetItem *line)
00095 {
00096 //   kDebug(11001) ;
00097     uint k = 0;
00098     for (int i=0; i<items.size(); i++) {
00099         const ItemContainer& container = *items[i];
00100         if ( !container.item()->isVisible() ) {
00101       continue;
00102     }
00103         if (line) { 
00104       line->setText(k, itemText(container, index));
00105       line->setTextAlignment(k, container.item()->alignment());
00106     }
00107         else {
00108         headerItem()->setText(k, container.item()->label() );
00109             headerItem()->setTextAlignment(k, container.item()->alignment());
00110         }
00111         k++;
00112     }
00113     update();
00114 }
00115 
00116 //-----------------------------------------------------------------------------
00117 HighscoresList::HighscoresList(QWidget *parent)
00118     : ScoresList(parent)
00119 {
00120 //   kDebug(11001) ;
00121 }
00122 
00123 QString HighscoresList::itemText(const ItemContainer &item, uint row) const
00124 {
00125 //   kDebug(11001) ;
00126     return item.pretty(row);
00127 }
00128 
00129 void HighscoresList::load(const ItemArray &items, int highlight)
00130 {
00131 //     kDebug(11001) ;
00132     clear();
00133     QTreeWidgetItem *line = 0;
00134     for (int j=items.nbEntries()-1; j>=0; j--) {
00135         QTreeWidgetItem *item = addLine(items, j, j==highlight);
00136         if ( j==highlight ) line = item;
00137     }
00138     scrollTo(indexFromItem(line));
00139 }
00140 
00141 //-----------------------------------------------------------------------------
00142 HighscoresWidget::HighscoresWidget(QWidget *parent)
00143     : QWidget(parent),
00144       _scoresUrl(0), _playersUrl(0), _statsTab(0), _histoTab(0)
00145 {
00146 //     kDebug(11001) << ": HighscoresWidget";
00147 
00148     setObjectName("show_highscores_widget");
00149     const ScoreInfos &s = internal->scoreInfos();
00150     const PlayerInfos &p = internal->playerInfos();
00151 
00152     QVBoxLayout *vbox = new QVBoxLayout(this);
00153     vbox->setSpacing(KDialog::spacingHint());
00154 
00155     _tw = new QTabWidget(this);
00156     connect(_tw, SIGNAL(currentChanged(int)), SLOT(tabChanged()));
00157     vbox->addWidget(_tw);
00158 
00159     // scores tab
00160     _scoresList = new HighscoresList(0);
00161     _scoresList->addHeader(s);
00162     _tw->addTab(_scoresList, i18n("Best &Scores"));
00163 
00164     // players tab
00165     _playersList = new HighscoresList(0);
00166     _playersList->addHeader(p);
00167     _tw->addTab(_playersList, i18n("&Players"));
00168 
00169     // statistics tab
00170     if ( internal->showStatistics ) {
00171         _statsTab = new StatisticsTab(0);
00172         _tw->addTab(_statsTab, i18n("Statistics"));
00173     }
00174 
00175     // histogram tab
00176     if ( p.histogram().size()!=0 ) {
00177         _histoTab = new HistogramTab(0);
00178         _tw->addTab(_histoTab, i18n("Histogram"));
00179     }
00180 
00181     // url labels
00182     if ( internal->isWWHSAvailable() ) {
00183         KUrl url = internal->queryUrl(ManagerPrivate::Scores);
00184         _scoresUrl = new KUrlLabel(url.url(),
00185                                    i18n("View world-wide highscores"), this);
00186         connect(_scoresUrl, SIGNAL(leftClickedUrl(const QString &)),
00187                 SLOT(showURL(const QString &)));
00188         vbox->addWidget(_scoresUrl);
00189 
00190         url = internal->queryUrl(ManagerPrivate::Players);
00191         _playersUrl = new KUrlLabel(url.url(),
00192                                     i18n("View world-wide players"), this);
00193         connect(_playersUrl, SIGNAL(leftClickedUrl(const QString &)),
00194                 SLOT(showURL(const QString &)));
00195         vbox->addWidget(_playersUrl);
00196     }
00197     load(-1);
00198 }
00199 
00200 void HighscoresWidget::changeTab(int i)
00201 {
00202 //   kDebug(11001) ;
00203     if ( i!=_tw->currentIndex() )
00204         _tw->setCurrentIndex(i);
00205 }
00206 
00207 void HighscoresWidget::showURL(const QString &url)
00208 {
00209 //   kDebug(11001) ;
00210     (void)new KRun(KUrl(url), this);
00211 }
00212 
00213 void HighscoresWidget::load(int rank)
00214 {
00215 //   kDebug(11001) << rank;
00216     _scoresList->load(internal->scoreInfos(), rank);
00217     _playersList->load(internal->playerInfos(), internal->playerInfos().id());
00218     if (_scoresUrl)
00219         _scoresUrl->setUrl(internal->queryUrl(ManagerPrivate::Scores).url());
00220     if (_playersUrl)
00221         _playersUrl->setUrl(internal->queryUrl(ManagerPrivate::Players).url());
00222     if (_statsTab) _statsTab->load();
00223     if (_histoTab) _histoTab->load();
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 HighscoresDialog::HighscoresDialog(int rank, QWidget *parent)
00228     : KPageDialog(parent), _rank(rank), _tab(0)
00229 {
00230 //     kDebug(11001) << ": HighscoresDialog";
00231 
00232     setCaption( i18n("Highscores") );
00233     setButtons( Close|User1|User2 );
00234     setDefaultButton( Close );
00235     if ( internal->nbGameTypes()>1 )
00236         setFaceType( KPageDialog::Tree );
00237     else
00238         setFaceType( KPageDialog::Plain );
00239     setButtonGuiItem( User1, KGuiItem(i18n("Configure..."), "configure") );
00240     setButtonGuiItem( User2, KGuiItem(i18n("Export...")) );
00241     connect( this, SIGNAL(user1Clicked()), SLOT(slotUser1()) );
00242     connect( this, SIGNAL(user2Clicked()), SLOT(slotUser2()) );
00243 
00244     for (uint i=0; i<internal->nbGameTypes(); i++) {
00245         QString title = internal->manager.gameTypeLabel(i, Manager::I18N);
00246         QString icon = internal->manager.gameTypeLabel(i, Manager::Icon);
00247         HighscoresWidget *hsw = new HighscoresWidget(0);
00248         KPageWidgetItem *pageItem = new KPageWidgetItem( hsw, title);
00249         pageItem->setIcon( KIcon( BarIcon(icon, KIconLoader::SizeLarge) ) );
00250         addPage( pageItem );
00251         _pages.append(pageItem);
00252         connect(hsw, SIGNAL(tabChanged(int)), SLOT(tabChanged(int)));
00253     }
00254 
00255     connect(this, SIGNAL( currentPageChanged(KPageWidgetItem *, KPageWidgetItem *)),
00256             SLOT(highscorePageChanged(KPageWidgetItem *, KPageWidgetItem *)));
00257     setCurrentPage(_pages[internal->gameType()]);
00258 }
00259 
00260 void HighscoresDialog::highscorePageChanged(KPageWidgetItem* page, KPageWidgetItem* pageold)
00261 {
00262     Q_UNUSED(pageold);
00263 //   kDebug(11001) ;
00264     int idx = _pages.indexOf( page );
00265     Q_ASSERT(idx != -1);
00266 
00267     internal->hsConfig().readCurrentConfig();
00268     uint type = internal->gameType();
00269     bool several = ( internal->nbGameTypes()>1 );
00270     if (several)
00271         internal->setGameType(idx);
00272     HighscoresWidget *hsw = static_cast<HighscoresWidget*>(page->widget());
00273     hsw->load(uint(idx)==type ? _rank : -1);
00274     if (several) setGameType(type);
00275     hsw->changeTab(_tab);
00276 }
00277 
00278 void HighscoresDialog::slotUser1()
00279 {
00280 //   kDebug(11001) ;
00281     if ( KExtHighscore::configure(this) )
00282         highscorePageChanged(currentPage(), 0);//update data
00283 }
00284 
00285 void HighscoresDialog::slotUser2()
00286 {
00287 //   kDebug(11001) ;
00288     KUrl url = KFileDialog::getSaveUrl(KUrl(), QString(), this);
00289     if ( url.isEmpty() ) return;
00290     if ( KIO::NetAccess::exists(url, KIO::NetAccess::SourceSide, this) ) {
00291         KGuiItem gi = KStandardGuiItem::save();
00292         gi.setText(i18n("Overwrite"));
00293         int res = KMessageBox::warningContinueCancel(this,
00294                                  i18n("The file already exists. Overwrite?"),
00295                                  i18n("Export"), gi);
00296         if ( res==KMessageBox::Cancel ) return;
00297     }
00298     KTemporaryFile tmp;
00299     tmp.open();
00300     QTextStream stream(&tmp);
00301     internal->exportHighscores(stream);
00302     stream.flush();
00303     KIO::NetAccess::upload(tmp.fileName(), url, this);
00304 }
00305 
00306 //-----------------------------------------------------------------------------
00307 LastMultipleScoresList::LastMultipleScoresList(
00308                             const QVector<Score> &scores, QWidget *parent)
00309     : ScoresList(parent), _scores(scores)
00310 {
00311 //     kDebug(11001) << ": LastMultipleScoresList";
00312 
00313     const ScoreInfos &s = internal->scoreInfos();
00314     addHeader(s);
00315     for (int i=0; i<scores.size(); i++) addLine(s, i, false);
00316 }
00317 
00318 void LastMultipleScoresList::addLineItem(const ItemArray &si,
00319                                          uint index, QTreeWidgetItem *line)
00320 {
00321 //   kDebug(11001) ;
00322     uint k = 1; // skip "id"
00323     for (int i=0; i<si.size()-2; i++) {
00324         if ( i==3 ) k = 5; // skip "date"
00325         const ItemContainer& container = *si[k];
00326         k++;
00327         if (line) {
00328       line->setText(i, itemText(container, index));
00329       line->setTextAlignment(i, container.item()->alignment());
00330     }
00331         else {
00332         headerItem()->setText(i, container.item()->label() );
00333             headerItem()->setTextAlignment(i, container.item()->alignment());
00334         }
00335     }
00336 }
00337 
00338 QString LastMultipleScoresList::itemText(const ItemContainer &item,
00339                                          uint row) const
00340 {
00341 //   kDebug(11001) ;
00342     QString name = item.name();
00343     if ( name=="rank" )
00344         return (_scores[row].type()==Won ? i18n("Winner") : QString());
00345     QVariant v = _scores[row].data(name);
00346     if ( name=="name" ) return v.toString();
00347     return item.item()->pretty(row, v);
00348 }
00349 
00350 //-----------------------------------------------------------------------------
00351 TotalMultipleScoresList::TotalMultipleScoresList(
00352                             const QVector<Score> &scores, QWidget *parent)
00353     : ScoresList(parent), _scores(scores)
00354 {
00355 //     kDebug(11001) << ": TotalMultipleScoresList";
00356     const ScoreInfos &s = internal->scoreInfos();
00357     addHeader(s);
00358     for (int i=0; i<scores.size(); i++) addLine(s, i, false);
00359 }
00360 
00361 void TotalMultipleScoresList::addLineItem(const ItemArray &si,
00362                                           uint index, QTreeWidgetItem *line)
00363 {
00364 //   kDebug(11001) ;
00365     const PlayerInfos &pi = internal->playerInfos();
00366     uint k = 1; // skip "id"
00367     for (uint i=0; i<4; i++) { // skip additional fields
00368         const ItemContainer *container;
00369         if ( i==2 ) container = pi.item("nb games");
00370         else if ( i==3 ) container = pi.item("mean score");
00371         else {
00372             container = si[k];
00373             k++;
00374         }
00375 
00376         if (line) {
00377       line->setText(i, itemText(*container, index));
00378       line->setTextAlignment(i, container->item()->alignment());
00379     }
00380         else {
00381             QString label =
00382                 (i==2 ? i18n("Won Games") : container->item()->label());
00383         headerItem()->setText(i, label );
00384             headerItem()->setTextAlignment(i, container->item()->alignment());
00385         }
00386     }
00387 }
00388 
00389 QString TotalMultipleScoresList::itemText(const ItemContainer &item,
00390                                           uint row) const
00391 {
00392 //   kDebug(11001) ;
00393     QString name = item.name();
00394     if ( name=="rank" ) return QString::number(_scores.size()-row);
00395     if ( name=="nb games" )
00396         return QString::number( _scores[row].data("nb won games").toUInt() );
00397     QVariant v = _scores[row].data(name);
00398     if ( name=="name" ) return v.toString();
00399     return item.item()->pretty(row, v);
00400 }
00401 
00402 
00403 //-----------------------------------------------------------------------------
00404 ConfigDialog::ConfigDialog(QWidget *parent)
00405     : KDialog(parent),
00406       _saved(false), _WWHEnabled(0)
00407 {
00408 //     kDebug(11001) << ": ConfigDialog";
00409     setCaption( i18n("Configure Highscores") );
00410     setButtons( Ok|Apply|Cancel );
00411     setDefaultButton( Cancel );
00412     setModal( true );
00413     QWidget *page = 0;
00414     QTabWidget *tab = 0;
00415     if ( internal->isWWHSAvailable() ) {
00416         tab = new QTabWidget(this);
00417         setMainWidget(tab);
00418         page = new QWidget;
00419         tab->addTab(page, i18n("Main"));
00420     } else {
00421         page = new QWidget(this);
00422         setMainWidget(page);
00423     }
00424 
00425     QGridLayout *pageTop =
00426         new QGridLayout(page);
00427     pageTop->setMargin(spacingHint());
00428     pageTop->setSpacing(spacingHint());
00429 
00430     QLabel *label = new QLabel(i18n("Nickname:"), page);
00431     pageTop->addWidget(label, 0, 0);
00432     _nickname = new QLineEdit(page);
00433     connect(_nickname, SIGNAL(textChanged(const QString &)),
00434             SLOT(modifiedSlot()));
00435     connect(_nickname, SIGNAL(textChanged(const QString &)),
00436             SLOT(nickNameChanged(const QString &)));
00437 
00438     _nickname->setMaxLength(16);
00439     pageTop->addWidget(_nickname, 0, 1);
00440 
00441     label = new QLabel(i18n("Comment:"), page);
00442     pageTop->addWidget(label, 1, 0);
00443     _comment = new QLineEdit(page);
00444     connect(_comment, SIGNAL(textChanged(const QString &)),
00445             SLOT(modifiedSlot()));
00446     _comment->setMaxLength(50);
00447     pageTop->addWidget(_comment, 1, 1);
00448 
00449     if (tab) {
00450         _WWHEnabled
00451             = new QCheckBox(i18n("World-wide highscores enabled"), page);
00452         connect(_WWHEnabled, SIGNAL(toggled(bool)),
00453                 SLOT(modifiedSlot()));
00454         pageTop->addWidget(_WWHEnabled, 2, 0, 1, 2 );
00455 
00456         // advanced tab
00457         QWidget *page = new QWidget;
00458         tab->addTab(page, i18n("Advanced"));
00459         QVBoxLayout *pageTop = new QVBoxLayout(page);
00460         pageTop->setMargin(marginHint());
00461         pageTop->setSpacing(spacingHint());
00462 
00463         QGroupBox *group = new QGroupBox(page);
00464         group->setTitle( i18n("Registration Data") );
00465         pageTop->addWidget(group);
00466         QGridLayout *groupLayout = new QGridLayout(group);
00467         groupLayout->setSpacing(spacingHint());
00468 
00469         label = new QLabel(i18n("Nickname:"), group);
00470         groupLayout->addWidget(label, 0, 0);
00471         _registeredName = new KLineEdit(group);
00472         _registeredName->setReadOnly(true);
00473         groupLayout->addWidget(_registeredName, 0, 1);
00474 
00475         label = new QLabel(i18n("Key:"), group);
00476         groupLayout->addWidget(label, 1, 0);
00477         _key = new KLineEdit(group);
00478         _key->setReadOnly(true);
00479         groupLayout->addWidget(_key, 1, 1);
00480 
00481         KGuiItem gi = KStandardGuiItem::clear();
00482         gi.setText(i18n("Remove"));
00483         _removeButton = new KPushButton(gi, group);
00484         groupLayout->addWidget(_removeButton, 2, 0);
00485         connect(_removeButton, SIGNAL(clicked()), SLOT(removeSlot()));
00486     }
00487 
00488     load();
00489     enableButtonOk( !_nickname->text().isEmpty() );
00490     enableButtonApply(false);
00491 }
00492 
00493 void ConfigDialog::nickNameChanged(const QString &text)
00494 {
00495     enableButtonOk( !text.isEmpty() );
00496 }
00497 
00498 
00499 void ConfigDialog::modifiedSlot()
00500 {
00501     enableButtonApply(true && !_nickname->text().isEmpty() );
00502 }
00503 
00504 void ConfigDialog::accept()
00505 {
00506     if ( save() ) {
00507         KDialog::accept();
00508         KGlobal::config()->sync(); // safer
00509     }
00510 }
00511 
00512 void ConfigDialog::removeSlot()
00513 {
00514     KGuiItem gi = KStandardGuiItem::clear();
00515     gi.setText(i18n("Remove"));
00516     int res = KMessageBox::warningContinueCancel(this,
00517                                i18n("This will permanently remove your "
00518                                "registration key. You will not be able to use "
00519                                "the currently registered nickname anymore."),
00520                                QString(), gi);
00521     if ( res==KMessageBox::Continue ) {
00522         internal->playerInfos().removeKey();
00523         _registeredName->clear();
00524         _key->clear();
00525         _removeButton->setEnabled(false);
00526         _WWHEnabled->setChecked(false);
00527         modifiedSlot();
00528     }
00529 }
00530 
00531 void ConfigDialog::load()
00532 {
00533     internal->hsConfig().readCurrentConfig();
00534     const PlayerInfos &infos = internal->playerInfos();
00535     _nickname->setText(infos.isAnonymous() ? QString() : infos.name());
00536     _comment->setText(infos.comment());
00537     if (_WWHEnabled) {
00538         _WWHEnabled->setChecked(infos.isWWEnabled());
00539         if ( !infos.key().isEmpty() ) {
00540             _registeredName->setText(infos.registeredName());
00541             _registeredName->home(false);
00542             _key->setText(infos.key());
00543             _key->home(false);
00544         }
00545         _removeButton->setEnabled(!infos.key().isEmpty());
00546     }
00547 }
00548 
00549 bool ConfigDialog::save()
00550 {
00551     bool enabled = (_WWHEnabled ? _WWHEnabled->isChecked() : false);
00552 
00553     // do not bother the user with "nickname empty" if he has not
00554     // messed with nickname settings ...
00555     QString newName = _nickname->text();
00556     if ( newName.isEmpty() && !internal->playerInfos().isAnonymous()
00557          && !enabled ) return true;
00558 
00559     if ( newName.isEmpty() ) {
00560         KMessageBox::sorry(this, i18n("Please choose a non empty nickname."));
00561         return false;
00562     }
00563     if ( internal->playerInfos().isNameUsed(newName) ) {
00564         KMessageBox::sorry(this, i18n("Nickname already in use. Please "
00565                                       "choose another one"));
00566         return false;
00567     }
00568 
00569     int res =
00570         internal->modifySettings(newName, _comment->text(), enabled, this);
00571     if (res) {
00572         load(); // needed to update view when "apply" is clicked
00573         enableButtonApply(false);
00574     }
00575     _saved = true;
00576     return res;
00577 }
00578 
00579 //-----------------------------------------------------------------------------
00580 AskNameDialog::AskNameDialog(QWidget *parent)
00581     : KDialog(parent)
00582 {
00583 //     kDebug(11001) << ": AskNameDialog";
00584 
00585     setCaption( i18n("Enter Your Nickname") );
00586     setButtons( Ok | Cancel );
00587     setDefaultButton( Ok );
00588 
00589     internal->hsConfig().readCurrentConfig();
00590     QWidget *main = new QWidget( this );
00591     setMainWidget( main );
00592     QVBoxLayout *top = new QVBoxLayout( main );
00593     top->setMargin( marginHint() );
00594     top->setSpacing( spacingHint() );
00595 
00596     QLabel *label =
00597         new QLabel(i18n("Congratulations, you have won!"), main);
00598     top->addWidget(label);
00599 
00600     QHBoxLayout *hbox = new QHBoxLayout;
00601     top->addLayout(hbox);
00602     label = new QLabel(i18n("Enter your nickname:"), main);
00603     hbox->addWidget(label);
00604     _edit = new QLineEdit(main);
00605     _edit->setFocus();
00606     connect(_edit, SIGNAL(textChanged(const QString &)), SLOT(nameChanged()));
00607     hbox->addWidget(_edit);
00608 
00609     top->addSpacing(spacingHint());
00610     _checkbox = new QCheckBox(i18n("Do not ask again."),  main);
00611     top->addWidget(_checkbox);
00612 
00613     nameChanged();
00614 }
00615 
00616 void AskNameDialog::nameChanged()
00617 {
00618     enableButtonOk( !name().isEmpty()
00619                     && !internal->playerInfos().isNameUsed(name()) );
00620 }
00621 
00622 } // namespace

libkdegames/highscore

Skip menu "libkdegames/highscore"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • kblackbox
  • kgoldrunner
  • kmahjongg
  • ksquares
  • libkdegames
  •   highscore
  •   kgame
  •   kggzgames
  •   kggzmod
  •   kggznet
  • libkmahjongg
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal