File indexing completed on 2024-12-08 03:46:00

0001 /*
0002     This file is part of the KDE games library
0003     SPDX-FileCopyrightText: 2001 Andreas Beckermann (b_mann@gmx.de)
0004     SPDX-FileCopyrightText: 2001 Martin Heni (kde at heni-online.de)
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kgameconnectdialog.h"
0010 
0011 // own
0012 #include "kfourinline_debug.h"
0013 // KF
0014 #include <KDNSSD/ServiceBrowser>
0015 #include <KLocalizedString>
0016 // Qt
0017 #include <QButtonGroup>
0018 #include <QComboBox>
0019 #include <QGroupBox>
0020 #include <QLabel>
0021 #include <QLineEdit>
0022 #include <QList>
0023 #include <QPushButton>
0024 #include <QRadioButton>
0025 #include <QSpinBox>
0026 #include <QVBoxLayout>
0027 
0028 class KGameConnectWidgetPrivate
0029 {
0030 public:
0031     KGameConnectWidgetPrivate()
0032     {
0033         mPort = nullptr;
0034         mHost = nullptr;
0035         mButtonGroup = nullptr;
0036         mBrowser = nullptr;
0037     }
0038 
0039     QSpinBox *mPort;
0040     QLineEdit *mHost;
0041     QButtonGroup *mButtonGroup;
0042     QComboBox *mClientName;
0043     QLabel *mClientNameLabel;
0044     KDNSSD::ServiceBrowser *mBrowser;
0045     QLabel *mServerNameLabel;
0046     QLineEdit *mServerName;
0047     QString mType;
0048 };
0049 
0050 KGameConnectWidget::KGameConnectWidget(QWidget *parent)
0051     : QWidget(parent)
0052 {
0053     d = new KGameConnectWidgetPrivate;
0054 
0055     QVBoxLayout *vb = new QVBoxLayout(this);
0056     vb->setContentsMargins(0, 0, 0, 0);
0057     QGroupBox *box = new QGroupBox(this);
0058     QVBoxLayout *boxlay = new QVBoxLayout(box);
0059     d->mButtonGroup = new QButtonGroup(this);
0060     d->mButtonGroup->setExclusive(true);
0061     vb->addWidget(box);
0062     connect(d->mButtonGroup, static_cast<void (QButtonGroup::*)(QAbstractButton *)>(&QButtonGroup::buttonClicked), this, &KGameConnectWidget::slotTypeChanged);
0063     QRadioButton *buttonCreate = new QRadioButton(i18n("Create a network game"), box);
0064     boxlay->addWidget(buttonCreate);
0065     d->mButtonGroup->addButton(buttonCreate, 0);
0066     QRadioButton *buttonJoin = new QRadioButton(i18n("Join a network game"), box);
0067     boxlay->addWidget(buttonJoin);
0068     d->mButtonGroup->addButton(buttonJoin, 1);
0069 
0070     QWidget *g = new QWidget(this);
0071     vb->addWidget(g);
0072     d->mServerNameLabel = new QLabel(i18n("Game name:"), g);
0073     d->mServerName = new QLineEdit(g);
0074     d->mClientNameLabel = new QLabel(i18n("Network games:"), g);
0075     d->mClientName = new QComboBox(g);
0076 
0077     QGridLayout *layout = new QGridLayout(g);
0078     layout->setContentsMargins(0, 0, 0, 0);
0079     layout->addWidget(d->mServerNameLabel, 0, 0);
0080     layout->addWidget(d->mServerName, 0, 1);
0081     layout->addWidget(d->mClientNameLabel, 1, 0);
0082     layout->addWidget(d->mClientName, 1, 1);
0083     connect(d->mClientName, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &KGameConnectWidget::slotGameSelected);
0084     QLabel *label = new QLabel(i18n("Port to connect to:"), g);
0085     d->mPort = new QSpinBox(g);
0086     d->mPort->setMinimum(1024);
0087     d->mPort->setMaximum(65535);
0088     layout->addWidget(label, 2, 0);
0089     layout->addWidget(d->mPort, 2, 1);
0090     label = new QLabel(i18n("Host to connect to:"), g);
0091     d->mHost = new QLineEdit(g);
0092     layout->addWidget(label, 3, 0);
0093     layout->addWidget(d->mHost, 3, 1);
0094 
0095     QPushButton *button = new QPushButton(i18n("&Start Network"), this);
0096     connect(button, &QPushButton::clicked, this, &KGameConnectWidget::signalNetworkSetup);
0097     vb->addWidget(button);
0098     // Hide until type is set
0099     d->mClientName->hide();
0100     d->mClientNameLabel->hide();
0101     d->mServerName->hide();
0102     d->mServerNameLabel->hide();
0103 }
0104 
0105 void KGameConnectWidget::showDnssdControls()
0106 {
0107     if (!d->mBrowser)
0108         return;
0109     if (d->mHost->isEnabled()) { // client
0110         d->mClientName->show();
0111         d->mClientNameLabel->show();
0112         d->mServerName->hide();
0113         d->mServerNameLabel->hide();
0114         slotGameSelected(d->mClientName->currentIndex());
0115     } else {
0116         d->mClientName->hide();
0117         d->mClientNameLabel->hide();
0118         d->mServerName->show();
0119         d->mServerNameLabel->show();
0120     }
0121 }
0122 
0123 void KGameConnectWidget::setType(const QString &type)
0124 {
0125     d->mType = type;
0126     delete d->mBrowser;
0127     d->mBrowser = new KDNSSD::ServiceBrowser(type);
0128     connect(d->mBrowser, &KDNSSD::ServiceBrowser::finished, this, &KGameConnectWidget::slotGamesFound);
0129     d->mBrowser->startBrowse();
0130     showDnssdControls();
0131 }
0132 
0133 void KGameConnectWidget::slotGamesFound()
0134 {
0135     bool autoselect = false;
0136     if (!d->mClientName->count())
0137         autoselect = true;
0138     d->mClientName->clear();
0139     QStringList names;
0140 
0141     QListIterator<KDNSSD::RemoteService::Ptr> it(d->mBrowser->services());
0142     while (it.hasNext())
0143         names << it.next()->serviceName();
0144     d->mClientName->addItems(names);
0145     if (autoselect && d->mClientName->count())
0146         slotGameSelected(0);
0147 }
0148 
0149 void KGameConnectWidget::setName(const QString &name)
0150 {
0151     d->mServerName->setText(name);
0152 }
0153 
0154 QString KGameConnectWidget::gameName() const
0155 {
0156     return d->mServerName->text();
0157 }
0158 
0159 QString KGameConnectWidget::type() const
0160 {
0161     return d->mType;
0162 }
0163 
0164 void KGameConnectWidget::slotGameSelected(int nr)
0165 {
0166     if (nr >= (d->mBrowser->services().count()) || nr < 0)
0167         return;
0168     if (!d->mHost->isEnabled())
0169         return; // this is server mode, do not overwrite host and port controls
0170     KDNSSD::RemoteService::Ptr srv = d->mBrowser->services()[nr];
0171     if (!srv->isResolved() && !srv->resolve())
0172         return;
0173     d->mHost->setText(srv->hostName());
0174     d->mPort->setValue(srv->port());
0175 }
0176 KGameConnectWidget::~KGameConnectWidget()
0177 {
0178     delete d->mBrowser;
0179     delete d;
0180 }
0181 
0182 QString KGameConnectWidget::host() const
0183 {
0184     if (d->mHost->isEnabled()) {
0185         return d->mHost->text();
0186     } else {
0187         return QString();
0188     }
0189 }
0190 
0191 unsigned short int KGameConnectWidget::port() const
0192 {
0193     return d->mPort->value();
0194 }
0195 
0196 void KGameConnectWidget::setHost(const QString &host)
0197 {
0198     d->mHost->setText(host);
0199 }
0200 
0201 void KGameConnectWidget::setPort(unsigned short int port)
0202 {
0203     d->mPort->setValue(port);
0204 }
0205 
0206 void KGameConnectWidget::setDefault(int state)
0207 {
0208     QAbstractButton *button = d->mButtonGroup->button(state);
0209     if (button == nullptr) {
0210         qCCritical(KFOURINLINE_LOG) << "KGameConnectWidget::setDefault" << state;
0211         return;
0212     }
0213     button->setChecked(true);
0214     slotTypeChanged(button);
0215 }
0216 
0217 void KGameConnectWidget::slotTypeChanged(QAbstractButton *button)
0218 {
0219     if (button) {
0220         const int t = d->mButtonGroup->id(button);
0221         if (t == 0) {
0222             d->mHost->setEnabled(false);
0223         } else if (t == 1) {
0224             d->mHost->setEnabled(true);
0225         }
0226         showDnssdControls();
0227         Q_EMIT signalServerTypeChanged(t);
0228     }
0229 }
0230 
0231 #include "moc_kgameconnectdialog.cpp"