libkdegames Library API Documentation

kexthighscore_gui.cpp

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., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "kexthighscore_gui.h" 00021 #include "kexthighscore_gui.moc" 00022 00023 #include <qlayout.h> 00024 #include <qtextstream.h> 00025 #include <qheader.h> 00026 #include <qgrid.h> 00027 #include <qvgroupbox.h> 00028 00029 #include <kapplication.h> 00030 #include <kmessagebox.h> 00031 #include <kurllabel.h> 00032 #include <kopenwith.h> 00033 #include <krun.h> 00034 #include <kfiledialog.h> 00035 #include <ktempfile.h> 00036 #include <kio/netaccess.h> 00037 #include <kiconloader.h> 00038 00039 #include "kexthighscore_internal.h" 00040 #include "kexthighscore.h" 00041 #include "kexthighscore_tab.h" 00042 00043 00044 namespace KExtHighscore 00045 { 00046 00047 //----------------------------------------------------------------------------- 00048 ShowItem::ShowItem(QListView *list, bool highlight) 00049 : KListViewItem(list), _highlight(highlight) 00050 {} 00051 00052 void ShowItem::paintCell(QPainter *p, const QColorGroup &cg, 00053 int column, int width, int align) 00054 { 00055 QColorGroup cgrp(cg); 00056 if (_highlight) cgrp.setColor(QColorGroup::Text, red); 00057 KListViewItem::paintCell(p, cgrp, column, width, align); 00058 } 00059 00060 //----------------------------------------------------------------------------- 00061 ScoresList::ScoresList(QWidget *parent) 00062 : KListView(parent) 00063 { 00064 setSelectionMode(QListView::NoSelection); 00065 setItemMargin(3); 00066 setAllColumnsShowFocus(true); 00067 setSorting(-1); 00068 header()->setClickEnabled(false); 00069 header()->setMovingEnabled(false); 00070 } 00071 00072 void ScoresList::addHeader(const ItemArray &items) 00073 { 00074 addLineItem(items, 0, 0); 00075 } 00076 00077 QListViewItem *ScoresList::addLine(const ItemArray &items, 00078 uint index, bool highlight) 00079 { 00080 QListViewItem *item = new ShowItem(this, highlight); 00081 addLineItem(items, index, item); 00082 return item; 00083 } 00084 00085 void ScoresList::addLineItem(const ItemArray &items, 00086 uint index, QListViewItem *line) 00087 { 00088 uint k = 0; 00089 for (uint i=0; i<items.size(); i++) { 00090 const ItemContainer &container = *items[i]; 00091 if ( !container.item()->isVisible() ) continue; 00092 if (line) line->setText(k, itemText(container, index)); 00093 else { 00094 addColumn( container.item()->label() ); 00095 setColumnAlignment(k, container.item()->alignment()); 00096 } 00097 k++; 00098 } 00099 } 00100 00101 //----------------------------------------------------------------------------- 00102 HighscoresList::HighscoresList(QWidget *parent) 00103 : ScoresList(parent) 00104 {} 00105 00106 QString HighscoresList::itemText(const ItemContainer &item, uint row) const 00107 { 00108 return item.pretty(row); 00109 } 00110 00111 void HighscoresList::load(const ItemArray &items, int highlight) 00112 { 00113 clear(); 00114 QListViewItem *line = 0; 00115 for (int j=items.nbEntries()-1; j>=0; j--) { 00116 QListViewItem *item = addLine(items, j, j==highlight); 00117 if ( j==highlight ) line = item; 00118 } 00119 if (line) ensureItemVisible(line); 00120 } 00121 00122 //----------------------------------------------------------------------------- 00123 HighscoresWidget::HighscoresWidget(QWidget *parent) 00124 : QWidget(parent, "show_highscores_widget"), 00125 _scoresUrl(0), _playersUrl(0), _statsTab(0), _histoTab(0) 00126 { 00127 const ScoreInfos &s = internal->scoreInfos(); 00128 const PlayerInfos &p = internal->playerInfos(); 00129 00130 QVBoxLayout *vbox = new QVBoxLayout(this, KDialogBase::spacingHint()); 00131 00132 _tw = new QTabWidget(this); 00133 connect(_tw, SIGNAL(currentChanged(QWidget *)), SLOT(tabChanged())); 00134 vbox->addWidget(_tw); 00135 00136 // scores tab 00137 _scoresList = new HighscoresList(_tw); 00138 _scoresList->addHeader(s); 00139 _tw->addTab(_scoresList, i18n("Best &Scores")); 00140 00141 // players tab 00142 _playersList = new HighscoresList(_tw); 00143 _playersList->addHeader(p); 00144 _tw->addTab(_playersList, i18n("&Players")); 00145 00146 // statistics tab 00147 if ( internal->showStatistics ) { 00148 _statsTab = new StatisticsTab(_tw); 00149 _tw->addTab(_statsTab, i18n("Statistics")); 00150 } 00151 00152 // histogram tab 00153 if ( p.histogram().size()!=0 ) { 00154 _histoTab = new HistogramTab(_tw); 00155 _tw->addTab(_histoTab, i18n("Histogram")); 00156 } 00157 00158 // url labels 00159 if ( internal->isWWHSAvailable() ) { 00160 KURL url = internal->queryURL(ManagerPrivate::Scores); 00161 _scoresUrl = new KURLLabel(url.url(), 00162 i18n("View world-wide highscores"), this); 00163 connect(_scoresUrl, SIGNAL(leftClickedURL(const QString &)), 00164 SLOT(showURL(const QString &))); 00165 vbox->addWidget(_scoresUrl); 00166 00167 url = internal->queryURL(ManagerPrivate::Players); 00168 _playersUrl = new KURLLabel(url.url(), 00169 i18n("View world-wide players"), this); 00170 connect(_playersUrl, SIGNAL(leftClickedURL(const QString &)), 00171 SLOT(showURL(const QString &))); 00172 vbox->addWidget(_playersUrl); 00173 } 00174 } 00175 00176 void HighscoresWidget::changeTab(int i) 00177 { 00178 if ( i!=_tw->currentPageIndex() ) 00179 _tw->setCurrentPage(i); 00180 } 00181 00182 void HighscoresWidget::showURL(const QString &url) const 00183 { 00184 KFileOpenWithHandler foo; 00185 (void)new KRun(KURL(url)); 00186 } 00187 00188 void HighscoresWidget::load(int rank) 00189 { 00190 _scoresList->load(internal->scoreInfos(), rank); 00191 _playersList->load(internal->playerInfos(), internal->playerInfos().id()); 00192 if (_scoresUrl) 00193 _scoresUrl->setURL(internal->queryURL(ManagerPrivate::Scores).url()); 00194 if (_playersUrl) 00195 _playersUrl->setURL(internal->queryURL(ManagerPrivate::Players).url()); 00196 if (_statsTab) _statsTab->load(); 00197 if (_histoTab) _histoTab->load(); 00198 } 00199 00200 //----------------------------------------------------------------------------- 00201 HighscoresDialog::HighscoresDialog(int rank, QWidget *parent) 00202 : KDialogBase(internal->nbGameTypes()>1 ? TreeList : Plain, 00203 i18n("Highscores"), Close|User1|User2, Close, 00204 parent, "show_highscores", true, true, 00205 KGuiItem(i18n("Configure..."), "configure"), 00206 KGuiItem(i18n("Export..."))), _rank(rank), _tab(0) 00207 { 00208 _widgets.resize(internal->nbGameTypes(), 0); 00209 00210 if ( internal->nbGameTypes()>1 ) { 00211 for (uint i=0; i<internal->nbGameTypes(); i++) { 00212 QString title = internal->manager.gameTypeLabel(i, Manager::I18N); 00213 QString icon = internal->manager.gameTypeLabel(i, Manager::Icon); 00214 QWidget *w = addVBoxPage(title, QString::null, 00215 BarIcon(icon, KIcon::SizeLarge)); 00216 if ( i==internal->gameType() ) createPage(w); 00217 } 00218 00219 connect(this, SIGNAL(aboutToShowPage(QWidget *)), 00220 SLOT(createPage(QWidget *))); 00221 showPage(internal->gameType()); 00222 } else { 00223 QVBoxLayout *vbox = new QVBoxLayout(plainPage()); 00224 createPage(plainPage()); 00225 vbox->addWidget(_widgets[0]); 00226 setMainWidget(_widgets[0]); 00227 } 00228 } 00229 00230 void HighscoresDialog::createPage(QWidget *page) 00231 { 00232 internal->hsConfig().readCurrentConfig(); 00233 _current = page; 00234 bool several = ( internal->nbGameTypes()>1 ); 00235 int i = (several ? pageIndex(page) : 0); 00236 if ( _widgets[i]==0 ) { 00237 _widgets[i] = new HighscoresWidget(page); 00238 connect(_widgets[i], SIGNAL(tabChanged(int)), SLOT(tabChanged(int))); 00239 } 00240 uint type = internal->gameType(); 00241 if (several) internal->setGameType(i); 00242 _widgets[i]->load(uint(i)==type ? _rank : -1); 00243 if (several) setGameType(type); 00244 _widgets[i]->changeTab(_tab); 00245 } 00246 00247 void HighscoresDialog::slotUser1() 00248 { 00249 if ( KExtHighscore::configure(this) ) 00250 createPage(_current); 00251 } 00252 00253 void HighscoresDialog::slotUser2() 00254 { 00255 KURL url = KFileDialog::getSaveURL(QString::null, QString::null, this); 00256 if ( url.isEmpty() ) return; 00257 if ( KIO::NetAccess::exists(url, true, this) ) { 00258 KGuiItem gi = KStdGuiItem::save(); 00259 gi.setText(i18n("Overwrite")); 00260 int res = KMessageBox::warningYesNo(this, 00261 i18n("The file already exists. Overwrite?"), 00262 i18n("Export"), gi, KStdGuiItem::cancel()); 00263 if ( res==KMessageBox::No ) return; 00264 } 00265 KTempFile tmp; 00266 internal->exportHighscores(*tmp.textStream()); 00267 tmp.close(); 00268 KIO::NetAccess::upload(tmp.name(), url, this); 00269 tmp.unlink(); 00270 } 00271 00272 //----------------------------------------------------------------------------- 00273 LastMultipleScoresList::LastMultipleScoresList( 00274 const QValueVector<Score> &scores, QWidget *parent) 00275 : ScoresList(parent), _scores(scores) 00276 { 00277 const ScoreInfos &s = internal->scoreInfos(); 00278 addHeader(s); 00279 for (uint i=0; i<scores.size(); i++) addLine(s, i, false); 00280 } 00281 00282 void LastMultipleScoresList::addLineItem(const ItemArray &si, 00283 uint index, QListViewItem *line) 00284 { 00285 uint k = 1; // skip "id" 00286 for (uint i=0; i<si.size()-2; i++) { 00287 if ( i==3 ) k = 5; // skip "date" 00288 const ItemContainer *container = si[k]; 00289 k++; 00290 if (line) line->setText(i, itemText(*container, index)); 00291 else { 00292 addColumn( container->item()->label() ); 00293 setColumnAlignment(i, container->item()->alignment()); 00294 } 00295 } 00296 } 00297 00298 QString LastMultipleScoresList::itemText(const ItemContainer &item, 00299 uint row) const 00300 { 00301 QString name = item.name(); 00302 if ( name=="rank" ) 00303 return (_scores[row].type()==Won ? i18n("Winner") : QString::null); 00304 QVariant v = _scores[row].data(name); 00305 if ( name=="name" ) return v.toString(); 00306 return item.item()->pretty(row, v); 00307 } 00308 00309 //----------------------------------------------------------------------------- 00310 TotalMultipleScoresList::TotalMultipleScoresList( 00311 const QValueVector<Score> &scores, QWidget *parent) 00312 : ScoresList(parent), _scores(scores) 00313 { 00314 const ScoreInfos &s = internal->scoreInfos(); 00315 addHeader(s); 00316 for (uint i=0; i<scores.size(); i++) addLine(s, i, false); 00317 } 00318 00319 void TotalMultipleScoresList::addLineItem(const ItemArray &si, 00320 uint index, QListViewItem *line) 00321 { 00322 const PlayerInfos &pi = internal->playerInfos(); 00323 uint k = 1; // skip "id" 00324 for (uint i=0; i<4; i++) { // skip additional fields 00325 const ItemContainer *container; 00326 if ( i==2 ) container = pi.item("nb games"); 00327 else if ( i==3 ) container = pi.item("mean score"); 00328 else { 00329 container = si[k]; 00330 k++; 00331 } 00332 if (line) line->setText(i, itemText(*container, index)); 00333 else { 00334 QString label = 00335 (i==2 ? i18n("Won Games") : container->item()->label()); 00336 addColumn(label); 00337 setColumnAlignment(i, container->item()->alignment()); 00338 } 00339 } 00340 } 00341 00342 QString TotalMultipleScoresList::itemText(const ItemContainer &item, 00343 uint row) const 00344 { 00345 QString name = item.name(); 00346 if ( name=="rank" ) return QString::number(_scores.size()-row); 00347 if ( name=="nb games" ) 00348 return QString::number( _scores[row].data("nb won games").toUInt() ); 00349 QVariant v = _scores[row].data(name); 00350 if ( name=="name" ) return v.toString(); 00351 return item.item()->pretty(row, v); 00352 } 00353 00354 00355 //----------------------------------------------------------------------------- 00356 ConfigDialog::ConfigDialog(QWidget *parent) 00357 : KDialogBase(Swallow, i18n("Configure Highscores"), 00358 Ok|Apply|Cancel, Cancel, 00359 parent, "configure_highscores", true, true), 00360 _saved(false), _WWHEnabled(0) 00361 { 00362 QWidget *page = 0; 00363 QTabWidget *tab = 0; 00364 if ( internal->isWWHSAvailable() ) { 00365 tab = new QTabWidget(this); 00366 setMainWidget(tab); 00367 page = new QWidget(tab); 00368 tab->addTab(page, i18n("Main")); 00369 } else { 00370 page = new QWidget(this); 00371 setMainWidget(page); 00372 } 00373 00374 QGridLayout *pageTop = 00375 new QGridLayout(page, 2, 2, spacingHint(), spacingHint()); 00376 00377 QLabel *label = new QLabel(i18n("Nickname:"), page); 00378 pageTop->addWidget(label, 0, 0); 00379 _nickname = new QLineEdit(page); 00380 connect(_nickname, SIGNAL(textChanged(const QString &)), 00381 SLOT(modifiedSlot())); 00382 connect(_nickname, SIGNAL(textChanged(const QString &)), 00383 SLOT(nickNameChanged(const QString &))); 00384 00385 _nickname->setMaxLength(16); 00386 pageTop->addWidget(_nickname, 0, 1); 00387 00388 label = new QLabel(i18n("Comment:"), page); 00389 pageTop->addWidget(label, 1, 0); 00390 _comment = new QLineEdit(page); 00391 connect(_comment, SIGNAL(textChanged(const QString &)), 00392 SLOT(modifiedSlot())); 00393 _comment->setMaxLength(50); 00394 pageTop->addWidget(_comment, 1, 1); 00395 00396 if (tab) { 00397 _WWHEnabled 00398 = new QCheckBox(i18n("World-wide highscores enabled"), page); 00399 connect(_WWHEnabled, SIGNAL(toggled(bool)), 00400 SLOT(modifiedSlot())); 00401 pageTop->addMultiCellWidget(_WWHEnabled, 2, 2, 0, 1); 00402 00403 // advanced tab 00404 QWidget *page = new QWidget(tab); 00405 tab->addTab(page, i18n("Advanced")); 00406 QVBoxLayout *pageTop = 00407 new QVBoxLayout(page, spacingHint(), spacingHint()); 00408 00409 QVGroupBox *group = new QVGroupBox(i18n("Registration Data"), page); 00410 pageTop->addWidget(group); 00411 QGrid *grid = new QGrid(2, group); 00412 grid->setSpacing(spacingHint()); 00413 00414 label = new QLabel(i18n("Nickname:"), grid); 00415 _registeredName = new KLineEdit(grid); 00416 _registeredName->setReadOnly(true); 00417 00418 label = new QLabel(i18n("Key:"), grid); 00419 _key = new KLineEdit(grid); 00420 _key->setReadOnly(true); 00421 00422 KGuiItem gi = KStdGuiItem::clear(); 00423 gi.setText(i18n("Remove")); 00424 _removeButton = new KPushButton(gi, grid); 00425 connect(_removeButton, SIGNAL(clicked()), SLOT(removeSlot())); 00426 } 00427 00428 load(); 00429 enableButtonOK( !_nickname->text().isEmpty() ); 00430 enableButtonApply(false); 00431 } 00432 00433 void ConfigDialog::nickNameChanged(const QString &text) 00434 { 00435 enableButtonOK( !text.isEmpty() ); 00436 } 00437 00438 00439 void ConfigDialog::modifiedSlot() 00440 { 00441 enableButtonApply(true && !_nickname->text().isEmpty() ); 00442 } 00443 00444 void ConfigDialog::accept() 00445 { 00446 if ( save() ) { 00447 KDialogBase::accept(); 00448 kapp->config()->sync(); // safer 00449 } 00450 } 00451 00452 void ConfigDialog::removeSlot() 00453 { 00454 KGuiItem gi = KStdGuiItem::clear(); 00455 gi.setText(i18n("Remove")); 00456 int res = KMessageBox::warningYesNo(this, 00457 i18n("This will permanently remove your " 00458 "registration key. You will not be able to use " 00459 "the currently registered nickname anymore."), 00460 QString::null, gi, KStdGuiItem::cancel()); 00461 if ( res==KMessageBox::Yes ) { 00462 internal->playerInfos().removeKey(); 00463 _registeredName->clear(); 00464 _key->clear(); 00465 _removeButton->setEnabled(false); 00466 _WWHEnabled->setChecked(false); 00467 modifiedSlot(); 00468 } 00469 } 00470 00471 void ConfigDialog::load() 00472 { 00473 internal->hsConfig().readCurrentConfig(); 00474 const PlayerInfos &infos = internal->playerInfos(); 00475 _nickname->setText(infos.isAnonymous() ? QString::null : infos.name()); 00476 _comment->setText(infos.comment()); 00477 if (_WWHEnabled) { 00478 _WWHEnabled->setChecked(infos.isWWEnabled()); 00479 if ( !infos.key().isEmpty() ) { 00480 _registeredName->setText(infos.registeredName()); 00481 _registeredName->home(false); 00482 _key->setText(infos.key()); 00483 _key->home(false); 00484 } 00485 _removeButton->setEnabled(!infos.key().isEmpty()); 00486 } 00487 } 00488 00489 bool ConfigDialog::save() 00490 { 00491 bool enabled = (_WWHEnabled ? _WWHEnabled->isChecked() : false); 00492 00493 // do not bother the user with "nickname empty" if he has not 00494 // messed with nickname settings ... 00495 QString newName = _nickname->text().lower(); 00496 if ( newName.isEmpty() && !internal->playerInfos().isAnonymous() 00497 && !enabled ) return true; 00498 00499 if ( newName.isEmpty() ) { 00500 KMessageBox::sorry(this, i18n("Please choose a non empty nickname.")); 00501 return false; 00502 } 00503 if ( internal->playerInfos().isNameUsed(newName) ) { 00504 KMessageBox::sorry(this, i18n("Nickname already in use. Please " 00505 "choose another one")); 00506 return false; 00507 } 00508 00509 int res = 00510 internal->modifySettings(newName, _comment->text(), enabled, this); 00511 if (res) { 00512 load(); // needed to update view when "apply" is clicked 00513 enableButtonApply(false); 00514 } 00515 _saved = true; 00516 return res; 00517 } 00518 00519 //----------------------------------------------------------------------------- 00520 AskNameDialog::AskNameDialog(QWidget *parent) 00521 : KDialogBase(Plain, i18n("Enter Your Nickname"), Ok | Cancel, Ok, 00522 parent, "ask_name_dialog") 00523 { 00524 internal->hsConfig().readCurrentConfig(); 00525 00526 QVBoxLayout *top = 00527 new QVBoxLayout(plainPage(), marginHint(), spacingHint()); 00528 QLabel *label = 00529 new QLabel(i18n("Congratulations, you have won!"), plainPage()); 00530 top->addWidget(label); 00531 00532 QHBoxLayout *hbox = new QHBoxLayout(top); 00533 label = new QLabel(i18n("Enter your nickname:"), plainPage()); 00534 hbox->addWidget(label); 00535 _edit = new QLineEdit(plainPage()); 00536 _edit->setFocus(); 00537 connect(_edit, SIGNAL(textChanged(const QString &)), SLOT(nameChanged())); 00538 hbox->addWidget(_edit); 00539 00540 top->addSpacing(spacingHint()); 00541 _checkbox = new QCheckBox(i18n("Do not ask again."), plainPage()); 00542 top->addWidget(_checkbox); 00543 00544 nameChanged(); 00545 } 00546 00547 void AskNameDialog::nameChanged() 00548 { 00549 enableButtonOK( !name().isEmpty() 00550 && !internal->playerInfos().isNameUsed(name()) ); 00551 } 00552 00553 } // namespace
KDE Logo
This file is part of the documentation for libkdegames Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Aug 26 00:21:38 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003