File indexing completed on 2024-04-28 15:40:16

0001 /* SPDX-FileCopyrightText: 2014-2019 The KPhotoAlbum Development Team
0002 
0003    SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "ConnectionIndicator.h"
0007 
0008 #include "RemoteInterface.h"
0009 
0010 #include <MainWindow/Options.h>
0011 #include <kpabase/SettingsData.h>
0012 
0013 #include <KLocalizedString>
0014 #include <QDialog>
0015 #include <QHBoxLayout>
0016 #include <QHostAddress>
0017 #include <QIcon>
0018 #include <QLabel>
0019 #include <QLineEdit>
0020 #include <QTimer>
0021 #include <QValidator>
0022 
0023 namespace RemoteControl
0024 {
0025 
0026 ConnectionIndicator::ConnectionIndicator(QWidget *parent)
0027     : QLabel(parent)
0028     , m_state(Off)
0029 {
0030     setToolTip(i18n("This icon indicates if KPhotoAlbum is connected to an android device.\n"
0031                     "Click on the icon to toggle listening for clients in the local area network.\n"
0032                     "If the local area network doesn't allow broadcast packages between the android client "
0033                     "and KPhotoAlbum, then right click on the icon and specify the android device's address.\n"
0034                     "The android client can be downloaded from google play."));
0035 
0036     connect(&RemoteInterface::instance(), SIGNAL(connected()), this, SLOT(on()));
0037     connect(&RemoteInterface::instance(), SIGNAL(disConnected()), this, SLOT(wait()));
0038     connect(&RemoteInterface::instance(), SIGNAL(listening()), this, SLOT(wait()));
0039     connect(&RemoteInterface::instance(), SIGNAL(stoppedListening()), this, SLOT(off()));
0040 
0041     m_timer = new QTimer(this);
0042     connect(m_timer, &QTimer::timeout, this, &ConnectionIndicator::waitingAnimation);
0043 
0044     off();
0045 }
0046 
0047 void ConnectionIndicator::mouseReleaseEvent(QMouseEvent *)
0048 {
0049     if (m_state == Off) {
0050         QHostAddress bindTo = MainWindow::Options::the()->listen();
0051         if (bindTo.isNull())
0052             bindTo = QHostAddress::Any;
0053         RemoteInterface::instance().listen(bindTo);
0054 
0055         wait();
0056     } else {
0057         RemoteInterface::instance().stopListening();
0058         m_state = Off;
0059         m_timer->stop();
0060         off();
0061     }
0062 }
0063 
0064 namespace
0065 {
0066     class IPValidator : public QValidator
0067     {
0068     protected:
0069         State validate(QString &input, int &) const override
0070         {
0071             for (int pos = 0; pos < 15; pos += 4) {
0072                 bool ok1;
0073                 int i = input.mid(pos, 1).toInt(&ok1);
0074                 bool ok2;
0075                 int j = input.mid(pos + 1, 1).toInt(&ok2);
0076                 bool ok3;
0077                 int k = input.mid(pos + 2, 1).toInt(&ok3);
0078 
0079                 if ((ok1 && i > 2) || (ok1 && ok2 && i == 2 && j > 5) || (ok1 && ok2 && ok3 && i * 100 + j * 10 + k > 255))
0080                     return Invalid;
0081             }
0082             return Acceptable;
0083         }
0084     };
0085 } // namespace
0086 
0087 void ConnectionIndicator::contextMenuEvent(QContextMenuEvent *)
0088 {
0089     QDialog dialog;
0090     QLabel label(i18n("Android device address: "), &dialog);
0091     QLineEdit edit(&dialog);
0092     edit.setInputMask(QString::fromUtf8("000.000.000.000;_"));
0093     edit.setText(Settings::SettingsData::instance()->recentAndroidAddress());
0094     IPValidator validator;
0095     edit.setValidator(&validator);
0096 
0097     QHBoxLayout layout(&dialog);
0098     layout.addWidget(&label);
0099     layout.addWidget(&edit);
0100 
0101     connect(&edit, &QLineEdit::returnPressed, &dialog, &QDialog::accept);
0102     int code = dialog.exec();
0103 
0104     if (code == QDialog::Accepted) {
0105         RemoteInterface::instance().connectTo(QHostAddress(edit.text()));
0106         wait();
0107         Settings::SettingsData::instance()->setRecentAndroidAddress(edit.text());
0108     }
0109 }
0110 
0111 void ConnectionIndicator::on()
0112 {
0113     m_state = On;
0114     m_timer->stop();
0115     QIcon icon { QIcon::fromTheme(QString::fromUtf8("network-wireless")) };
0116     setPixmap(icon.pixmap(32, 32));
0117 }
0118 
0119 void ConnectionIndicator::off()
0120 {
0121     m_timer->stop();
0122     m_state = Off;
0123     QIcon icon { QIcon::fromTheme(QString::fromUtf8("network-disconnect")) };
0124     setPixmap(icon.pixmap(32, 32));
0125 }
0126 
0127 void ConnectionIndicator::wait()
0128 {
0129     m_timer->start(300);
0130     m_state = Connecting;
0131 }
0132 
0133 void ConnectionIndicator::waitingAnimation()
0134 {
0135     static int index = 0;
0136     static QList<QPixmap> icons;
0137     if (icons.isEmpty()) {
0138         icons.append(QIcon::fromTheme(QString::fromUtf8("network-wireless-disconnected")).pixmap(32, 32));
0139         icons.append(QIcon::fromTheme(QString::fromUtf8("network-wireless-connected-25")).pixmap(32, 32));
0140         icons.append(QIcon::fromTheme(QString::fromUtf8("network-wireless-connected-50")).pixmap(32, 32));
0141         icons.append(QIcon::fromTheme(QString::fromUtf8("network-wireless-connected-75")).pixmap(32, 32));
0142         icons.append(QIcon::fromTheme(QString::fromUtf8("network-wireless")).pixmap(32, 32));
0143     }
0144     index = (index + 1) % icons.count();
0145     setPixmap(icons[index]);
0146 }
0147 
0148 } // namespace RemoteControl
0149 
0150 #include "moc_ConnectionIndicator.cpp"