File indexing completed on 2024-04-28 05:26:12

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Alejandro Fiestas Olivares <alex@eyeos.org>
0003  *   SPDX-FileCopyrightText: 2010 Eduardo Robles Elvira <edulix@gmail.com>
0004  *   SPDX-FileCopyrightText: 2010 UFO Coders <info@ufocoders.com>
0005  *   SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com>
0006  *
0007  *   SPDX-License-Identifier: GPL-2.0-or-later
0008  */
0009 
0010 #include "requestpin.h"
0011 #include "bluedevil_kded.h"
0012 #include "ui_requestpin.h"
0013 
0014 #include <QDialog>
0015 #include <QIcon>
0016 #include <QPushButton>
0017 #include <QRegularExpressionValidator>
0018 
0019 #include <KLocalizedString>
0020 #include <KNotification>
0021 #include <KX11Extras>
0022 
0023 RequestPin::RequestPin(BluezQt::DevicePtr device, bool numeric, QObject *parent)
0024     : QObject(parent)
0025     , m_device(device)
0026     , m_numeric(numeric)
0027 {
0028     m_notification = new KNotification(QStringLiteral("RequestPin"), KNotification::Persistent, this);
0029 
0030     m_notification->setComponentName(QStringLiteral("bluedevil"));
0031     m_notification->setTitle(QStringLiteral("%1 (%2)").arg(m_device->name().toHtmlEscaped(), m_device->address().toHtmlEscaped()));
0032     m_notification->setText(
0033         i18nc("Shown in a notification to announce that a PIN is needed to accomplish a pair action,"
0034               "%1 is the name of the bluetooth device",
0035               "PIN needed to pair with %1",
0036               m_device->name().toHtmlEscaped()));
0037 
0038     auto action = m_notification->addAction(i18nc("Notification button which once clicked, a dialog to introduce the PIN will be shown", "Introduce PIN"));
0039 
0040     connect(action, &KNotificationAction::activated, this, &RequestPin::introducePin);
0041     connect(m_notification, &KNotification::closed, this, &RequestPin::quit);
0042     connect(m_notification, &KNotification::ignored, this, &RequestPin::quit);
0043     connect(parent, SIGNAL(agentCanceled()), this, SLOT(quit()));
0044 
0045     m_notification->sendEvent();
0046 }
0047 
0048 void RequestPin::introducePin()
0049 {
0050     m_notification->disconnect();
0051     m_notification->close();
0052     m_notification->deleteLater();
0053 
0054     QDialog *dialog = new QDialog;
0055     dialog->setAttribute(Qt::WA_DeleteOnClose);
0056     dialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("preferences-system-bluetooth")));
0057 
0058     dialog->setWindowTitle(i18nc("Shown in the caption of a dialog where the user introduce the PIN", "Introduce PIN"));
0059 
0060     m_dialogWidget = new Ui::DialogWidget;
0061     m_dialogWidget->setupUi(dialog);
0062     m_dialogWidget->descLabel->setText(
0063         i18nc("Shown in a dialog which asks to introduce a PIN that will be used to pair a Bluetooth device,"
0064               "%1 is the name of the Bluetooth device",
0065               "In order to pair this computer with %1, you have to enter a PIN. Please do it below.",
0066               m_device->name()));
0067 
0068     m_dialogWidget->pixmap->setPixmap(QIcon::fromTheme(QStringLiteral("preferences-system-bluetooth")).pixmap(64));
0069     m_dialogWidget->pin->setFocus(Qt::ActiveWindowFocusReason);
0070 
0071     if (m_numeric) {
0072         QRegularExpression rx(QStringLiteral("[0-9]{1,6}"));
0073         m_dialogWidget->pin->setValidator(new QRegularExpressionValidator(rx, this));
0074     } else {
0075         QRegularExpression rx(QStringLiteral("[A-Za-z0-9]{1,16}"));
0076         m_dialogWidget->pin->setValidator(new QRegularExpressionValidator(rx, this));
0077     }
0078 
0079     m_dialogWidget->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
0080     dialog->setFixedSize(dialog->sizeHint());
0081 
0082     connect(dialog, &QDialog::finished, this, &RequestPin::dialogFinished);
0083     connect(m_dialogWidget->pin, &QLineEdit::textChanged, this, &RequestPin::checkPin);
0084     connect(m_dialogWidget->buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
0085     connect(m_dialogWidget->buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
0086 
0087     dialog->setWindowFlags(Qt::WindowStaysOnTopHint);
0088 
0089     dialog->show();
0090 
0091     KX11Extras::forceActiveWindow(dialog->winId());
0092 }
0093 
0094 void RequestPin::checkPin(const QString &pin)
0095 {
0096     m_dialogWidget->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!pin.isEmpty());
0097 }
0098 
0099 void RequestPin::dialogFinished(int result)
0100 {
0101     deleteLater();
0102 
0103     if (!result) {
0104         qCDebug(BLUEDEVIL_KDED_LOG) << "PIN dialog rejected:" << m_device->name() << m_device->address();
0105         Q_EMIT done(QString());
0106         return;
0107     }
0108 
0109     qCDebug(BLUEDEVIL_KDED_LOG) << "PIN dialog accepted:" << m_device->name() << m_device->address();
0110     Q_EMIT done(m_dialogWidget->pin->text().toLatin1().constData());
0111 }
0112 
0113 void RequestPin::quit()
0114 {
0115     qCDebug(BLUEDEVIL_KDED_LOG) << "Rejected to introduce PIN:" << m_device->name() << m_device->address();
0116 
0117     deleteLater();
0118     Q_EMIT done(QString());
0119 }
0120 
0121 #include "moc_requestpin.cpp"