/* This file is part of the TDE games library Copyright (C) 2001-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. */ #include "kexthighscore_gui.h" #include "kexthighscore_gui.moc" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kexthighscore_internal.h" #include "kexthighscore.h" #include "kexthighscore_tab.h" namespace KExtHighscore { //----------------------------------------------------------------------------- ShowItem::ShowItem(TQListView *list, bool highlight) : KListViewItem(list), _highlight(highlight) {} void ShowItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align) { TQColorGroup cgrp(cg); if (_highlight) cgrp.setColor(TQColorGroup::Text, red); KListViewItem::paintCell(p, cgrp, column, width, align); } //----------------------------------------------------------------------------- ScoresList::ScoresList(TQWidget *parent) : KListView(parent) { setSelectionMode(TQListView::NoSelection); setItemMargin(3); setAllColumnsShowFocus(true); setSorting(-1); header()->setClickEnabled(false); header()->setMovingEnabled(false); } void ScoresList::addHeader(const ItemArray &items) { addLineItem(items, 0, 0); } TQListViewItem *ScoresList::addLine(const ItemArray &items, uint index, bool highlight) { TQListViewItem *item = new ShowItem(this, highlight); addLineItem(items, index, item); return item; } void ScoresList::addLineItem(const ItemArray &items, uint index, TQListViewItem *line) { uint k = 0; for (uint i=0; iisVisible() ) continue; if (line) line->setText(k, itemText(container, index)); else { addColumn( container.item()->label() ); setColumnAlignment(k, container.item()->alignment()); } k++; } } //----------------------------------------------------------------------------- HighscoresList::HighscoresList(TQWidget *parent) : ScoresList(parent) {} TQString HighscoresList::itemText(const ItemContainer &item, uint row) const { return item.pretty(row); } void HighscoresList::load(const ItemArray &items, int highlight) { clear(); TQListViewItem *line = 0; for (int j=items.nbEntries()-1; j>=0; j--) { TQListViewItem *item = addLine(items, j, j==highlight); if ( j==highlight ) line = item; } if (line) ensureItemVisible(line); } //----------------------------------------------------------------------------- HighscoresWidget::HighscoresWidget(TQWidget *parent) : TQWidget(parent, "show_highscores_widget"), _scoresUrl(0), _playersUrl(0), _statsTab(0), _histoTab(0) { const ScoreInfos &s = internal->scoreInfos(); const PlayerInfos &p = internal->playerInfos(); TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialogBase::spacingHint()); _tw = new TQTabWidget(this); connect(_tw, TQT_SIGNAL(currentChanged(TQWidget *)), TQT_SLOT(tabChanged())); vbox->addWidget(_tw); // scores tab _scoresList = new HighscoresList(_tw); _scoresList->addHeader(s); _tw->addTab(_scoresList, i18n("Best &Scores")); // players tab _playersList = new HighscoresList(_tw); _playersList->addHeader(p); _tw->addTab(_playersList, i18n("&Players")); // statistics tab if ( internal->showStatistics ) { _statsTab = new StatisticsTab(_tw); _tw->addTab(_statsTab, i18n("Statistics")); } // histogram tab if ( p.histogram().size()!=0 ) { _histoTab = new HistogramTab(_tw); _tw->addTab(_histoTab, i18n("Histogram")); } // url labels if ( internal->isWWHSAvailable() ) { KURL url = internal->queryURL(ManagerPrivate::Scores); _scoresUrl = new KURLLabel(url.url(), i18n("View world-wide highscores"), this); connect(_scoresUrl, TQT_SIGNAL(leftClickedURL(const TQString &)), TQT_SLOT(showURL(const TQString &))); vbox->addWidget(_scoresUrl); url = internal->queryURL(ManagerPrivate::Players); _playersUrl = new KURLLabel(url.url(), i18n("View world-wide players"), this); connect(_playersUrl, TQT_SIGNAL(leftClickedURL(const TQString &)), TQT_SLOT(showURL(const TQString &))); vbox->addWidget(_playersUrl); } } void HighscoresWidget::changeTab(int i) { if ( i!=_tw->currentPageIndex() ) _tw->setCurrentPage(i); } void HighscoresWidget::showURL(const TQString &url) const { (void)new KRun(KURL(url)); } void HighscoresWidget::load(int rank) { _scoresList->load(internal->scoreInfos(), rank); _playersList->load(internal->playerInfos(), internal->playerInfos().id()); if (_scoresUrl) _scoresUrl->setURL(internal->queryURL(ManagerPrivate::Scores).url()); if (_playersUrl) _playersUrl->setURL(internal->queryURL(ManagerPrivate::Players).url()); if (_statsTab) _statsTab->load(); if (_histoTab) _histoTab->load(); } //----------------------------------------------------------------------------- HighscoresDialog::HighscoresDialog(int rank, TQWidget *parent) : KDialogBase(internal->nbGameTypes()>1 ? TreeList : Plain, i18n("Highscores"), Close|User1|User2, Close, parent, "show_highscores", true, true, KGuiItem(i18n("Configure..."), "configure"), KGuiItem(i18n("Export..."))), _rank(rank), _tab(0) { _widgets.resize(internal->nbGameTypes(), 0); if ( internal->nbGameTypes()>1 ) { for (uint i=0; inbGameTypes(); i++) { TQString title = internal->manager.gameTypeLabel(i, Manager::I18N); TQString icon = internal->manager.gameTypeLabel(i, Manager::Icon); TQWidget *w = addVBoxPage(title, TQString(), BarIcon(icon, KIcon::SizeLarge)); if ( i==internal->gameType() ) createPage(w); } connect(this, TQT_SIGNAL(aboutToShowPage(TQWidget *)), TQT_SLOT(createPage(TQWidget *))); showPage(internal->gameType()); } else { TQVBoxLayout *vbox = new TQVBoxLayout(plainPage()); createPage(plainPage()); vbox->addWidget(_widgets[0]); setMainWidget(_widgets[0]); } } void HighscoresDialog::createPage(TQWidget *page) { internal->hsConfig().readCurrentConfig(); _current = page; bool several = ( internal->nbGameTypes()>1 ); int i = (several ? pageIndex(page) : 0); if ( _widgets[i]==0 ) { _widgets[i] = new HighscoresWidget(page); connect(_widgets[i], TQT_SIGNAL(tabChanged(int)), TQT_SLOT(tabChanged(int))); } uint type = internal->gameType(); if (several) internal->setGameType(i); _widgets[i]->load(uint(i)==type ? _rank : -1); if (several) setGameType(type); _widgets[i]->changeTab(_tab); } void HighscoresDialog::slotUser1() { if ( KExtHighscore::configure(this) ) createPage(_current); } void HighscoresDialog::slotUser2() { KURL url = KFileDialog::getSaveURL(TQString(), TQString(), this); if ( url.isEmpty() ) return; if ( TDEIO::NetAccess::exists(url, true, this) ) { KGuiItem gi = KStdGuiItem::save(); gi.setText(i18n("Overwrite")); int res = KMessageBox::warningContinueCancel(this, i18n("The file already exists. Overwrite?"), i18n("Export"), gi); if ( res==KMessageBox::Cancel ) return; } KTempFile tmp; internal->exportHighscores(*tmp.textStream()); tmp.close(); TDEIO::NetAccess::upload(tmp.name(), url, this); tmp.unlink(); } //----------------------------------------------------------------------------- LastMultipleScoresList::LastMultipleScoresList( const TQValueVector &scores, TQWidget *parent) : ScoresList(parent), _scores(scores) { const ScoreInfos &s = internal->scoreInfos(); addHeader(s); for (uint i=0; isetText(i, itemText(*container, index)); else { addColumn( container->item()->label() ); setColumnAlignment(i, container->item()->alignment()); } } } TQString LastMultipleScoresList::itemText(const ItemContainer &item, uint row) const { TQString name = item.name(); if ( name=="rank" ) return (_scores[row].type()==Won ? i18n("Winner") : TQString()); TQVariant v = _scores[row].data(name); if ( name=="name" ) return v.toString(); return item.item()->pretty(row, v); } //----------------------------------------------------------------------------- TotalMultipleScoresList::TotalMultipleScoresList( const TQValueVector &scores, TQWidget *parent) : ScoresList(parent), _scores(scores) { const ScoreInfos &s = internal->scoreInfos(); addHeader(s); for (uint i=0; iplayerInfos(); uint k = 1; // skip "id" for (uint i=0; i<4; i++) { // skip additional fields const ItemContainer *container; if ( i==2 ) container = pi.item("nb games"); else if ( i==3 ) container = pi.item("mean score"); else { container = si[k]; k++; } if (line) line->setText(i, itemText(*container, index)); else { TQString label = (i==2 ? i18n("Won Games") : container->item()->label()); addColumn(label); setColumnAlignment(i, container->item()->alignment()); } } } TQString TotalMultipleScoresList::itemText(const ItemContainer &item, uint row) const { TQString name = item.name(); if ( name=="rank" ) return TQString::number(_scores.size()-row); if ( name=="nb games" ) return TQString::number( _scores[row].data("nb won games").toUInt() ); TQVariant v = _scores[row].data(name); if ( name=="name" ) return v.toString(); return item.item()->pretty(row, v); } //----------------------------------------------------------------------------- ConfigDialog::ConfigDialog(TQWidget *parent) : KDialogBase(Swallow, i18n("Configure Highscores"), Ok|Apply|Cancel, Cancel, parent, "configure_highscores", true, true), _saved(false), _WWHEnabled(0) { TQWidget *page = 0; TQTabWidget *tab = 0; if ( internal->isWWHSAvailable() ) { tab = new TQTabWidget(this); setMainWidget(tab); page = new TQWidget(tab); tab->addTab(page, i18n("Main")); } else { page = new TQWidget(this); setMainWidget(page); } TQGridLayout *pageTop = new TQGridLayout(page, 2, 2, spacingHint(), spacingHint()); TQLabel *label = new TQLabel(i18n("Nickname:"), page); pageTop->addWidget(label, 0, 0); _nickname = new TQLineEdit(page); connect(_nickname, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(modifiedSlot())); connect(_nickname, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(nickNameChanged(const TQString &))); _nickname->setMaxLength(16); pageTop->addWidget(_nickname, 0, 1); label = new TQLabel(i18n("Comment:"), page); pageTop->addWidget(label, 1, 0); _comment = new TQLineEdit(page); connect(_comment, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(modifiedSlot())); _comment->setMaxLength(50); pageTop->addWidget(_comment, 1, 1); if (tab) { _WWHEnabled = new TQCheckBox(i18n("World-wide highscores enabled"), page); connect(_WWHEnabled, TQT_SIGNAL(toggled(bool)), TQT_SLOT(modifiedSlot())); pageTop->addMultiCellWidget(_WWHEnabled, 2, 2, 0, 1); // advanced tab TQWidget *page = new TQWidget(tab); tab->addTab(page, i18n("Advanced")); TQVBoxLayout *pageTop = new TQVBoxLayout(page, spacingHint(), spacingHint()); TQVGroupBox *group = new TQVGroupBox(i18n("Registration Data"), page); pageTop->addWidget(group); TQGrid *grid = new TQGrid(2, group); grid->setSpacing(spacingHint()); label = new TQLabel(i18n("Nickname:"), grid); _registeredName = new KLineEdit(grid); _registeredName->setReadOnly(true); label = new TQLabel(i18n("Key:"), grid); _key = new KLineEdit(grid); _key->setReadOnly(true); KGuiItem gi = KStdGuiItem::clear(); gi.setText(i18n("Remove")); _removeButton = new KPushButton(gi, grid); connect(_removeButton, TQT_SIGNAL(clicked()), TQT_SLOT(removeSlot())); } load(); enableButtonOK( !_nickname->text().isEmpty() ); enableButtonApply(false); } void ConfigDialog::nickNameChanged(const TQString &text) { enableButtonOK( !text.isEmpty() ); } void ConfigDialog::modifiedSlot() { enableButtonApply(true && !_nickname->text().isEmpty() ); } void ConfigDialog::accept() { if ( save() ) { KDialogBase::accept(); kapp->config()->sync(); // safer } } void ConfigDialog::removeSlot() { KGuiItem gi = KStdGuiItem::clear(); gi.setText(i18n("Remove")); int res = KMessageBox::warningContinueCancel(this, i18n("This will permanently remove your " "registration key. You will not be able to use " "the currently registered nickname anymore."), TQString(), gi); if ( res==KMessageBox::Continue ) { internal->playerInfos().removeKey(); _registeredName->clear(); _key->clear(); _removeButton->setEnabled(false); _WWHEnabled->setChecked(false); modifiedSlot(); } } void ConfigDialog::load() { internal->hsConfig().readCurrentConfig(); const PlayerInfos &infos = internal->playerInfos(); _nickname->setText(infos.isAnonymous() ? TQString() : infos.name()); _comment->setText(infos.comment()); if (_WWHEnabled) { _WWHEnabled->setChecked(infos.isWWEnabled()); if ( !infos.key().isEmpty() ) { _registeredName->setText(infos.registeredName()); _registeredName->home(false); _key->setText(infos.key()); _key->home(false); } _removeButton->setEnabled(!infos.key().isEmpty()); } } bool ConfigDialog::save() { bool enabled = (_WWHEnabled ? _WWHEnabled->isChecked() : false); // do not bother the user with "nickname empty" if he has not // messed with nickname settings ... TQString newName = _nickname->text(); if ( newName.isEmpty() && !internal->playerInfos().isAnonymous() && !enabled ) return true; if ( newName.isEmpty() ) { KMessageBox::sorry(this, i18n("Please choose a non empty nickname.")); return false; } if ( internal->playerInfos().isNameUsed(newName) ) { KMessageBox::sorry(this, i18n("Nickname already in use. Please " "choose another one")); return false; } int res = internal->modifySettings(newName, _comment->text(), enabled, this); if (res) { load(); // needed to update view when "apply" is clicked enableButtonApply(false); } _saved = true; return res; } //----------------------------------------------------------------------------- AskNameDialog::AskNameDialog(TQWidget *parent) : KDialogBase(Plain, i18n("Enter Your Nickname"), Ok | Cancel, Ok, parent, "ask_name_dialog") { internal->hsConfig().readCurrentConfig(); TQVBoxLayout *top = new TQVBoxLayout(plainPage(), marginHint(), spacingHint()); TQLabel *label = new TQLabel(i18n("Congratulations, you have won!"), plainPage()); top->addWidget(label); TQHBoxLayout *hbox = new TQHBoxLayout(top); label = new TQLabel(i18n("Enter your nickname:"), plainPage()); hbox->addWidget(label); _edit = new TQLineEdit(plainPage()); _edit->setFocus(); connect(_edit, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(nameChanged())); hbox->addWidget(_edit); top->addSpacing(spacingHint()); _checkbox = new TQCheckBox(i18n("Do not ask again."), plainPage()); top->addWidget(_checkbox); nameChanged(); } void AskNameDialog::nameChanged() { enableButtonOK( !name().isEmpty() && !internal->playerInfos().isNameUsed(name()) ); } } // namespace