File indexing completed on 2024-05-05 08:07:30

0001 /*
0002     SPDX-FileCopyrightText: 2001-2003 Nicolas Hadacek <hadacek@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "kexthighscore_gui.h"
0008 
0009 #include <QApplication>
0010 #include <QFileDialog>
0011 #include <QGridLayout>
0012 #include <QGroupBox>
0013 #include <QHBoxLayout>
0014 #include <QHeaderView>
0015 #include <QIcon>
0016 #include <QLabel>
0017 #include <QPushButton>
0018 #include <QTabWidget>
0019 #include <QTemporaryFile>
0020 #include <QTextStream>
0021 #include <QVBoxLayout>
0022 
0023 #include <KIO/OpenUrlJob>
0024 #include <KIO/JobUiDelegateFactory>
0025 #include <KGuiItem>
0026 #include <KIO/StatJob>
0027 #include <KIO/CopyJob>
0028 #include <KJobWidgets>
0029 #include <KMessageBox>
0030 #include <KUrlLabel>
0031 
0032 #include "kexthighscore_internal.h"
0033 #include "kexthighscore_tab.h"
0034 
0035 
0036 namespace KExtHighscore
0037 {
0038 
0039 //-----------------------------------------------------------------------------
0040 ShowItem::ShowItem(QTreeWidget *list, bool highlight)
0041     : QTreeWidgetItem(list), _highlight(highlight)
0042 {
0043 //   kDebug(11001) ;
0044   if (_highlight) {
0045     for (int i=0; i < columnCount();i++) {
0046       setForeground(i, Qt::red);
0047     }
0048   }
0049 }
0050 
0051 //-----------------------------------------------------------------------------
0052 ScoresList::ScoresList(QWidget *parent)
0053     : QTreeWidget(parent)
0054 {
0055 //   kDebug(11001) ;
0056     setSelectionMode(QTreeWidget::NoSelection);
0057 //     setItemMargin(3);
0058     setAllColumnsShowFocus(true);
0059 //     setSorting(-1);
0060     header()->setSectionsClickable(false);
0061     header()->setSectionsMovable(false);
0062 }
0063 
0064 void ScoresList::addHeader(const ItemArray &items)
0065 {
0066 //   kDebug(11001) ;
0067     addLineItem(items, 0, nullptr);
0068 }
0069 
0070 QTreeWidgetItem *ScoresList::addLine(const ItemArray &items,
0071                                    uint index, bool highlight)
0072 {
0073 //   kDebug(11001) ;
0074     QTreeWidgetItem *item = new ShowItem(this, highlight);
0075     addLineItem(items, index, item);
0076     return item;
0077 }
0078 
0079 void ScoresList::addLineItem(const ItemArray &items,
0080                              uint index, QTreeWidgetItem *line)
0081 {
0082 //   kDebug(11001) ;
0083     uint k = 0;
0084     for (int i=0; i<items.size(); i++) {
0085         const ItemContainer& container = *items[i];
0086         if ( !container.item()->isVisible() ) {
0087       continue;
0088     }
0089         if (line) {
0090       line->setText(k, itemText(container, index));
0091       line->setTextAlignment(k, container.item()->alignment());
0092     }
0093         else {
0094         headerItem()->setText(k, container.item()->label() );
0095             headerItem()->setTextAlignment(k, container.item()->alignment());
0096         }
0097         k++;
0098     }
0099     update();
0100 }
0101 
0102 //-----------------------------------------------------------------------------
0103 HighscoresList::HighscoresList(QWidget *parent)
0104     : ScoresList(parent)
0105 {
0106 //   kDebug(11001) ;
0107 }
0108 
0109 QString HighscoresList::itemText(const ItemContainer &item, uint row) const
0110 {
0111 //   kDebug(11001) ;
0112     return item.pretty(row);
0113 }
0114 
0115 void HighscoresList::load(const ItemArray &items, int highlight)
0116 {
0117 //     kDebug(11001) ;
0118     clear();
0119     QTreeWidgetItem *line = nullptr;
0120     for (int j=items.nbEntries()-1; j>=0; j--) {
0121         QTreeWidgetItem *item = addLine(items, j, j==highlight);
0122         if ( j==highlight ) line = item;
0123     }
0124     scrollTo(indexFromItem(line));
0125 }
0126 
0127 //-----------------------------------------------------------------------------
0128 HighscoresWidget::HighscoresWidget(QWidget *parent)
0129     : QWidget(parent)
0130 {
0131 //     kDebug(11001) << ": HighscoresWidget";
0132 
0133     setObjectName( QStringLiteral("show_highscores_widget" ));
0134     const ScoreInfos &s = internal->scoreInfos();
0135     const PlayerInfos &p = internal->playerInfos();
0136 
0137     QVBoxLayout *vbox = new QVBoxLayout(this);
0138     vbox->setSpacing(fontMetrics().lineSpacing());
0139 
0140     _tw = new QTabWidget(this);
0141     connect(_tw, &QTabWidget::currentChanged, this, &HighscoresWidget::handleTabChanged);
0142     vbox->addWidget(_tw);
0143 
0144     // scores tab
0145     _scoresList = new HighscoresList(nullptr);
0146     _scoresList->addHeader(s);
0147     _tw->addTab(_scoresList, i18n("Best &Scores"));
0148 
0149     // players tab
0150     _playersList = new HighscoresList(nullptr);
0151     _playersList->addHeader(p);
0152     _tw->addTab(_playersList, i18n("&Players"));
0153 
0154     // statistics tab
0155     if ( internal->showStatistics ) {
0156         _statsTab = new StatisticsTab(nullptr);
0157         _tw->addTab(_statsTab, i18n("Statistics"));
0158     }
0159 
0160     // histogram tab
0161     if ( p.histogram().size()!=0 ) {
0162         _histoTab = new HistogramTab(nullptr);
0163         _tw->addTab(_histoTab, i18n("Histogram"));
0164     }
0165 
0166     // url labels
0167     if ( internal->isWWHSAvailable() ) {
0168         QUrl url = internal->queryUrl(ManagerPrivate::Scores);
0169         _scoresUrl = new KUrlLabel(url.url(),
0170                                    i18n("View world-wide highscores"), this);
0171         connect(_scoresUrl, &KUrlLabel::leftClickedUrl, this, &HighscoresWidget::handleUrlClicked);
0172         vbox->addWidget(_scoresUrl);
0173 
0174         url = internal->queryUrl(ManagerPrivate::Players);
0175         _playersUrl = new KUrlLabel(url.url(),
0176                                     i18n("View world-wide players"), this);
0177         connect(_playersUrl, &KUrlLabel::leftClickedUrl, this, &HighscoresWidget::handleUrlClicked);
0178         vbox->addWidget(_playersUrl);
0179     }
0180     load(-1);
0181 }
0182 
0183 void HighscoresWidget::changeTab(int i)
0184 {
0185 //   kDebug(11001) ;
0186     if ( i!=_tw->currentIndex() )
0187         _tw->setCurrentIndex(i);
0188 }
0189 
0190 void HighscoresWidget::handleUrlClicked()
0191 {
0192     auto* label = qobject_cast<KUrlLabel*>(sender());
0193     if (!label) {
0194         return;
0195     }
0196 //   kDebug(11001) ;
0197     auto *job = new KIO::OpenUrlJob(QUrl(label->url()));
0198     job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
0199     job->start();
0200 }
0201 
0202 void HighscoresWidget::load(int rank)
0203 {
0204 //   kDebug(11001) << rank;
0205     _scoresList->load(internal->scoreInfos(), rank);
0206     _playersList->load(internal->playerInfos(), internal->playerInfos().id());
0207     if (_scoresUrl)
0208         _scoresUrl->setUrl(internal->queryUrl(ManagerPrivate::Scores).url());
0209     if (_playersUrl)
0210         _playersUrl->setUrl(internal->queryUrl(ManagerPrivate::Players).url());
0211     if (_statsTab) _statsTab->load();
0212     if (_histoTab) _histoTab->load();
0213 }
0214 
0215 //-----------------------------------------------------------------------------
0216 HighscoresDialog::HighscoresDialog(int rank, QWidget *parent)
0217     : KPageDialog(parent), _rank(rank), _tab(0)
0218 {
0219 //     kDebug(11001) << ": HighscoresDialog";
0220 
0221     setWindowTitle(i18nc("@title:window", "Highscores"));
0222 // TODO    setButtons( Close|User1|User2 );
0223 // TODO    setDefaultButton( Close );
0224     if ( internal->nbGameTypes()>1 )
0225         setFaceType( KPageDialog::Tree );
0226     else
0227         setFaceType( KPageDialog::Plain );
0228 // TODO    setButtonGuiItem( User1, KGuiItem(i18n("Configure..."), QLatin1String( "configure" )) );
0229 // TODO    setButtonGuiItem( User2, KGuiItem(i18n("Export...")) );
0230 
0231     for (uint i=0; i<internal->nbGameTypes(); i++) {
0232         QString title = internal->manager.gameTypeLabel(i, Manager::I18N);
0233         QString icon = internal->manager.gameTypeLabel(i, Manager::Icon);
0234         HighscoresWidget *hsw = new HighscoresWidget(nullptr);
0235         KPageWidgetItem *pageItem = new KPageWidgetItem( hsw, title);
0236         const int iconSize = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
0237         pageItem->setIcon(QIcon::fromTheme(icon).pixmap(iconSize));
0238         addPage( pageItem );
0239         _pages.append(pageItem);
0240         connect(hsw, &HighscoresWidget::tabChanged, this, &HighscoresDialog::tabChanged);
0241     }
0242 
0243     connect(this, &KPageDialog::currentPageChanged,
0244             this, &HighscoresDialog::highscorePageChanged);
0245     setCurrentPage(_pages[internal->gameType()]);
0246 
0247     setStandardButtons(QDialogButtonBox::Close);
0248 }
0249 
0250 void HighscoresDialog::highscorePageChanged(KPageWidgetItem* page, KPageWidgetItem* pageold)
0251 {
0252     Q_UNUSED(pageold);
0253 //   kDebug(11001) ;
0254     int idx = _pages.indexOf( page );
0255     Q_ASSERT(idx != -1);
0256 
0257     internal->hsConfig().readCurrentConfig();
0258     uint type = internal->gameType();
0259     bool several = ( internal->nbGameTypes()>1 );
0260     if (several)
0261         internal->setGameType(idx);
0262     HighscoresWidget *hsw = static_cast<HighscoresWidget*>(page->widget());
0263     hsw->load(uint(idx)==type ? _rank : -1);
0264     if (several) setGameType(type);
0265     hsw->changeTab(_tab);
0266 }
0267 
0268 void HighscoresDialog::slotUser1()
0269 {
0270 //   kDebug(11001) ;
0271     if ( KExtHighscore::configure(this) )
0272         highscorePageChanged(currentPage(), nullptr);//update data
0273 }
0274 
0275 void HighscoresDialog::slotUser2()
0276 {
0277 //   kDebug(11001) ;
0278     QUrl url = QFileDialog::getSaveFileUrl(this, tr("HighscoresDialog"), QUrl(), QString());
0279     if ( url.isEmpty() ) return;
0280     auto job = KIO::stat(url, KIO::StatJob::SourceSide, KIO::StatNoDetails);
0281     KJobWidgets::setWindow(job, this);
0282     job->exec();
0283     if (!job->error()) {
0284         KGuiItem gi = KStandardGuiItem::save();
0285         gi.setText(i18n("Overwrite"));
0286         int res = KMessageBox::warningContinueCancel(this,
0287                                  i18n("The file already exists. Overwrite?"),
0288                                  i18n("Export"), gi);
0289         if ( res==KMessageBox::Cancel ) return;
0290     }
0291     QTemporaryFile tmp;
0292     tmp.open();
0293     QTextStream stream(&tmp);
0294     internal->exportHighscores(stream);
0295     stream.flush();
0296 //     KIO::NetAccess::upload(tmp.fileName(), url, this);
0297     auto copyJob = KIO::copy(QUrl::fromLocalFile(tmp.fileName()), url);
0298     copyJob->exec();
0299 }
0300 
0301 //-----------------------------------------------------------------------------
0302 LastMultipleScoresList::LastMultipleScoresList(
0303                             const QList<Score> &scores, QWidget *parent)
0304     : ScoresList(parent), _scores(scores)
0305 {
0306 //     kDebug(11001) << ": LastMultipleScoresList";
0307 
0308     const ScoreInfos &s = internal->scoreInfos();
0309     addHeader(s);
0310     for (int i=0; i<scores.size(); i++) addLine(s, i, false);
0311 }
0312 
0313 void LastMultipleScoresList::addLineItem(const ItemArray &si,
0314                                          uint index, QTreeWidgetItem *line)
0315 {
0316 //   kDebug(11001) ;
0317     uint k = 1; // skip "id"
0318     for (int i=0; i<si.size()-2; i++) {
0319         if ( i==3 ) k = 5; // skip "date"
0320         const ItemContainer& container = *si[k];
0321         k++;
0322         if (line) {
0323       line->setText(i, itemText(container, index));
0324       line->setTextAlignment(i, container.item()->alignment());
0325     }
0326         else {
0327         headerItem()->setText(i, container.item()->label() );
0328             headerItem()->setTextAlignment(i, container.item()->alignment());
0329         }
0330     }
0331 }
0332 
0333 QString LastMultipleScoresList::itemText(const ItemContainer &item,
0334                                          uint row) const
0335 {
0336 //   kDebug(11001) ;
0337     QString name = item.name();
0338     if ( name==QLatin1String( "rank" ) )
0339         return (_scores[row].type()==Won ? i18n("Winner") : QString());
0340     QVariant v = _scores[row].data(name);
0341     if ( name==QLatin1String( "name" ) ) return v.toString();
0342     return item.item()->pretty(row, v);
0343 }
0344 
0345 //-----------------------------------------------------------------------------
0346 TotalMultipleScoresList::TotalMultipleScoresList(
0347                             const QList<Score> &scores, QWidget *parent)
0348     : ScoresList(parent), _scores(scores)
0349 {
0350 //     kDebug(11001) << ": TotalMultipleScoresList";
0351     const ScoreInfos &s = internal->scoreInfos();
0352     addHeader(s);
0353     for (int i=0; i<scores.size(); i++) addLine(s, i, false);
0354 }
0355 
0356 void TotalMultipleScoresList::addLineItem(const ItemArray &si,
0357                                           uint index, QTreeWidgetItem *line)
0358 {
0359 //   kDebug(11001) ;
0360     const PlayerInfos &pi = internal->playerInfos();
0361     uint k = 1; // skip "id"
0362     for (uint i=0; i<4; i++) { // skip additional fields
0363         const ItemContainer *container;
0364         if ( i==2 ) container = pi.item(QStringLiteral( "nb games" ));
0365         else if ( i==3 ) container = pi.item(QStringLiteral( "mean score" ));
0366         else {
0367             container = si[k];
0368             k++;
0369         }
0370 
0371         if (line) {
0372       line->setText(i, itemText(*container, index));
0373       line->setTextAlignment(i, container->item()->alignment());
0374     }
0375         else {
0376             QString label =
0377                 (i==2 ? i18n("Won Games") : container->item()->label());
0378         headerItem()->setText(i, label );
0379             headerItem()->setTextAlignment(i, container->item()->alignment());
0380         }
0381     }
0382 }
0383 
0384 QString TotalMultipleScoresList::itemText(const ItemContainer &item,
0385                                           uint row) const
0386 {
0387 //   kDebug(11001) ;
0388     QString name = item.name();
0389     if ( name==QLatin1String( "rank" ) ) return QString::number(_scores.size()-row);
0390     else if ( name==QLatin1String( "nb games" ) )
0391         return QString::number( _scores[row].data(QStringLiteral( "nb won games" )).toUInt() );
0392     QVariant v = _scores[row].data(name);
0393     if ( name==QLatin1String( "name" ) ) return v.toString();
0394     return item.item()->pretty(row, v);
0395 }
0396 
0397 
0398 //-----------------------------------------------------------------------------
0399 ConfigDialog::ConfigDialog(QWidget *parent)
0400     : QDialog(parent),
0401       _saved(false), _WWHEnabled(nullptr)
0402 {
0403 //     kDebug(11001) << ": ConfigDialog";
0404     
0405     setWindowTitle(i18nc("@title:window", "Configure Highscores"));
0406     setModal( true );
0407     
0408     QWidget *page = nullptr;
0409     QTabWidget *tab = nullptr;
0410     
0411     QVBoxLayout *layout = new QVBoxLayout;
0412     setLayout(layout);
0413     
0414     if ( internal->isWWHSAvailable() ) {
0415         tab = new QTabWidget(this);
0416         layout->addWidget(tab);
0417         page = new QWidget;
0418         tab->addTab(page, i18n("Main"));
0419     } 
0420     
0421     else {
0422         page = new QWidget(this);
0423         layout->addWidget(page);
0424     }
0425 
0426     QGridLayout *pageTop =
0427         new QGridLayout(page);
0428     //pageTop->setMargin(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
0429     //pageTop->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
0430     
0431     layout->addLayout(pageTop);
0432 
0433     QLabel *label = new QLabel(i18n("Nickname:"), page);
0434     pageTop->addWidget(label, 0, 0);
0435     _nickname = new QLineEdit(page);
0436     connect(_nickname, &QLineEdit::textChanged,
0437             this, &ConfigDialog::modifiedSlot);
0438     connect(_nickname, &QLineEdit::textChanged,
0439             this, &ConfigDialog::nickNameChanged);
0440 
0441     _nickname->setMaxLength(16);
0442     pageTop->addWidget(_nickname, 0, 1);
0443 
0444     label = new QLabel(i18n("Comment:"), page);
0445     pageTop->addWidget(label, 1, 0);
0446     _comment = new QLineEdit(page);
0447     connect(_comment, &QLineEdit::textChanged,
0448             this, &ConfigDialog::modifiedSlot);
0449     _comment->setMaxLength(50);
0450     pageTop->addWidget(_comment, 1, 1);
0451 
0452     if (tab) {
0453         _WWHEnabled
0454             = new QCheckBox(i18n("World-wide highscores enabled"), page);
0455         connect(_WWHEnabled, &QAbstractButton::toggled,
0456                 this, &ConfigDialog::modifiedSlot);
0457         pageTop->addWidget(_WWHEnabled, 2, 0, 1, 2 );
0458 
0459         // advanced tab
0460         QWidget *page = new QWidget;
0461         tab->addTab(page, i18n("Advanced"));
0462         QVBoxLayout *pageTop = new QVBoxLayout(page);
0463         //pageTop->setMargin(QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin));
0464         //pageTop->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
0465 
0466         QGroupBox *group = new QGroupBox(page);
0467         group->setTitle( i18n("Registration Data") );
0468         pageTop->addWidget(group);
0469         QGridLayout *groupLayout = new QGridLayout(group);
0470         //groupLayout->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
0471 
0472         label = new QLabel(i18n("Nickname:"), group);
0473         groupLayout->addWidget(label, 0, 0);
0474         _registeredName = new QLineEdit(group);
0475         _registeredName->setReadOnly(true);
0476         groupLayout->addWidget(_registeredName, 0, 1);
0477 
0478         label = new QLabel(i18n("Key:"), group);
0479         groupLayout->addWidget(label, 1, 0);
0480         _key = new QLineEdit(group);
0481         _key->setReadOnly(true);
0482         groupLayout->addWidget(_key, 1, 1);
0483 
0484         KGuiItem gi = KStandardGuiItem::clear();
0485         gi.setText(i18n("Remove"));
0486         _removeButton = new QPushButton(group);
0487     KGuiItem::assign(_removeButton, gi);
0488     groupLayout->addWidget(_removeButton, 2, 0);
0489         connect(_removeButton, &QAbstractButton::clicked, this, &ConfigDialog::removeSlot);
0490     }
0491     
0492     buttonBox = new QDialogButtonBox(this);
0493     
0494     buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel); 
0495     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0496     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0497     // TODO mapping for Apply button
0498     pageTop->addWidget(buttonBox);
0499 
0500     load();
0501     buttonBox->button(QDialogButtonBox::Ok)->setEnabled( !_nickname->text().isEmpty() );
0502     buttonBox->button(QDialogButtonBox::Apply)->setEnabled( false );
0503     
0504 }
0505 
0506 void ConfigDialog::nickNameChanged(const QString &text)
0507 {
0508     buttonBox->button(QDialogButtonBox::Ok)->setEnabled( !text.isEmpty() );
0509 }
0510 
0511 
0512 void ConfigDialog::modifiedSlot()
0513 {
0514     buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true && !_nickname->text().isEmpty() );
0515 }
0516 
0517 void ConfigDialog::accept()
0518 {
0519     if ( save() ) {
0520         QDialog::accept();
0521         KSharedConfig::openConfig()->sync(); // safer
0522     }
0523 }
0524 
0525 void ConfigDialog::removeSlot()
0526 {
0527     KGuiItem gi = KStandardGuiItem::clear();
0528     gi.setText(i18n("Remove"));
0529     int res = KMessageBox::warningContinueCancel(this,
0530                                i18n("This will permanently remove your "
0531                                "registration key. You will not be able to use "
0532                                "the currently registered nickname anymore."),
0533                                QString(), gi);
0534     if ( res==KMessageBox::Continue ) {
0535         internal->playerInfos().removeKey();
0536         _registeredName->clear();
0537         _key->clear();
0538         _removeButton->setEnabled(false);
0539         _WWHEnabled->setChecked(false);
0540         modifiedSlot();
0541     }
0542 }
0543 
0544 void ConfigDialog::load()
0545 {
0546     internal->hsConfig().readCurrentConfig();
0547     const PlayerInfos &infos = internal->playerInfos();
0548     _nickname->setText(infos.isAnonymous() ? QString() : infos.name());
0549     _comment->setText(infos.comment());
0550     if (_WWHEnabled) {
0551         _WWHEnabled->setChecked(infos.isWWEnabled());
0552         if ( !infos.key().isEmpty() ) {
0553             _registeredName->setText(infos.registeredName());
0554             _registeredName->home(false);
0555             _key->setText(infos.key());
0556             _key->home(false);
0557         }
0558         _removeButton->setEnabled(!infos.key().isEmpty());
0559     }
0560 }
0561 
0562 bool ConfigDialog::save()
0563 {
0564     bool enabled = (_WWHEnabled ? _WWHEnabled->isChecked() : false);
0565 
0566     // do not bother the user with "nickname empty" if he has not
0567     // messed with nickname settings ...
0568     QString newName = _nickname->text();
0569     if ( newName.isEmpty() && !internal->playerInfos().isAnonymous()
0570          && !enabled ) return true;
0571 
0572     if ( newName.isEmpty() ) {
0573         KMessageBox::error(this, i18n("Please choose a non empty nickname."));
0574         return false;
0575     }
0576     if ( internal->playerInfos().isNameUsed(newName) ) {
0577         KMessageBox::error(this, i18n("Nickname already in use. Please "
0578                                       "choose another one"));
0579         return false;
0580     }
0581 
0582     int res =
0583         internal->modifySettings(newName, _comment->text(), enabled, this);
0584     if (res) {
0585         load(); // needed to update view when "apply" is clicked
0586         buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
0587     }
0588     _saved = true;
0589     return res;
0590 }
0591 
0592 //-----------------------------------------------------------------------------
0593 AskNameDialog::AskNameDialog(QWidget *parent)
0594     : QDialog(parent)
0595 {
0596 //     kDebug(11001) << ": AskNameDialog";
0597 
0598     setWindowTitle(i18nc("@title:window", "Enter Your Nickname"));
0599 
0600     internal->hsConfig().readCurrentConfig();
0601     QVBoxLayout *top = new QVBoxLayout;
0602     //top->setMargin( QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin) );
0603     //top->setSpacing( QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing) );
0604     setLayout(top);
0605         
0606     QLabel *label =
0607         new QLabel(i18n("Congratulations, you have won!"), this);
0608     top->addWidget(label);
0609 
0610     QHBoxLayout *hbox = new QHBoxLayout;
0611     top->addLayout(hbox);
0612     label = new QLabel(i18n("Enter your nickname:"), this);
0613     hbox->addWidget(label);
0614     _edit = new QLineEdit(this);
0615     _edit->setFocus();
0616     connect(_edit, &QLineEdit::textChanged, this, &AskNameDialog::nameChanged);
0617     hbox->addWidget(_edit);
0618 
0619     //top->addSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
0620     _checkbox = new QCheckBox(i18n("Do not ask again."),  this);
0621     top->addWidget(_checkbox);
0622     
0623     _buttonBox = new QDialogButtonBox(this);
0624     
0625     _buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0626     connect(_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0627     connect(_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0628     top->addWidget(_buttonBox);
0629 
0630     nameChanged();
0631 }
0632 
0633 void AskNameDialog::nameChanged()
0634 {
0635     _buttonBox->button(QDialogButtonBox::Ok)->setEnabled( !name().isEmpty()
0636                       && !internal->playerInfos().isNameUsed(name())); 
0637 }
0638 
0639 } // namespace
0640 
0641 #include "moc_kexthighscore_gui.cpp"