File indexing completed on 2024-10-13 07:52:44

0001 /*
0002  * This file is part of the KDE project
0003  *
0004  * SPDX-FileCopyrightText: 2010-2011 Alejandro Fiestas Olivares <afiestas@kde.org>
0005  * SPDX-FileCopyrightText: 2010-2011 UFO Coders <info@ufocoders.com>
0006  *
0007  * SPDX-License-Identifier: LGPL-2.0-or-later
0008  */
0009 
0010 #include "discoverwidget.h"
0011 #include "bluedevil_sendfile.h"
0012 
0013 #include <QAction>
0014 #include <QIcon>
0015 #include <QLabel>
0016 #include <QListView>
0017 #include <QListWidgetItem>
0018 #include <QSortFilterProxyModel>
0019 #include <QTimer>
0020 
0021 #include <KMessageWidget>
0022 
0023 #include <BluezQt/Adapter>
0024 #include <BluezQt/Device>
0025 #include <BluezQt/DevicesModel>
0026 #include <BluezQt/Manager>
0027 #include <BluezQt/Services>
0028 
0029 class DevicesProxyModel : public QSortFilterProxyModel
0030 {
0031 public:
0032     explicit DevicesProxyModel(QObject *parent);
0033 
0034     void setDevicesModel(BluezQt::DevicesModel *model);
0035 
0036     QVariant data(const QModelIndex &index, int role) const override;
0037     bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
0038 
0039     BluezQt::DevicePtr device(const QModelIndex &index) const;
0040 
0041 private:
0042     BluezQt::DevicesModel *m_devicesModel = nullptr;
0043 };
0044 
0045 DevicesProxyModel::DevicesProxyModel(QObject *parent)
0046     : QSortFilterProxyModel(parent)
0047 {
0048     setDynamicSortFilter(true);
0049     sort(0, Qt::DescendingOrder);
0050 }
0051 
0052 void DevicesProxyModel::setDevicesModel(BluezQt::DevicesModel *model)
0053 {
0054     m_devicesModel = model;
0055     setSourceModel(model);
0056 }
0057 
0058 QVariant DevicesProxyModel::data(const QModelIndex &index, int role) const
0059 {
0060     switch (role) {
0061     case Qt::DecorationRole:
0062         return QIcon::fromTheme(index.data(BluezQt::DevicesModel::IconRole).toString(), QIcon::fromTheme(QStringLiteral("preferences-system-bluetooth")));
0063 
0064     default:
0065         return QSortFilterProxyModel::data(index, role);
0066     }
0067 }
0068 
0069 bool DevicesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
0070 {
0071     QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
0072 
0073     const QStringList &uuids = index.data(BluezQt::DevicesModel::UuidsRole).toStringList();
0074     bool adapterPowered = index.data(BluezQt::DevicesModel::AdapterPoweredRole).toBool();
0075 
0076     return adapterPowered && uuids.contains(BluezQt::Services::ObexObjectPush);
0077 }
0078 
0079 BluezQt::DevicePtr DevicesProxyModel::device(const QModelIndex &index) const
0080 {
0081     Q_ASSERT(m_devicesModel);
0082     return m_devicesModel->device(mapToSource(index));
0083 }
0084 
0085 DiscoverWidget::DiscoverWidget(BluezQt::Manager *manager, QWidget *parent)
0086     : QWidget(parent)
0087     , m_manager(manager)
0088     , m_warningWidget(nullptr)
0089 {
0090     setupUi(this);
0091 
0092     m_model = new DevicesProxyModel(this);
0093     m_model->setDevicesModel(new BluezQt::DevicesModel(m_manager, this));
0094     devices->setModel(m_model);
0095 
0096     checkAdapters();
0097     connect(m_manager, &BluezQt::Manager::adapterAdded, this, &DiscoverWidget::checkAdapters);
0098     connect(m_manager, &BluezQt::Manager::adapterChanged, this, &DiscoverWidget::checkAdapters);
0099     connect(m_manager, &BluezQt::Manager::usableAdapterChanged, this, &DiscoverWidget::checkAdapters);
0100     connect(m_manager, &BluezQt::Manager::bluetoothBlockedChanged, this, &DiscoverWidget::checkAdapters);
0101 
0102     connect(devices->selectionModel(), &QItemSelectionModel::currentChanged, this, &DiscoverWidget::indexSelected);
0103 }
0104 
0105 void DiscoverWidget::indexSelected(const QModelIndex index)
0106 {
0107     Q_EMIT deviceSelected(m_model->device(index));
0108 }
0109 
0110 void DiscoverWidget::checkAdapters()
0111 {
0112     bool error = false;
0113 
0114     Q_FOREACH (BluezQt::AdapterPtr adapter, m_manager->adapters()) {
0115         if (!adapter->isPowered()) {
0116             error = true;
0117             break;
0118         }
0119     }
0120 
0121     delete m_warningWidget;
0122     m_warningWidget = nullptr;
0123 
0124     if (!error && !m_manager->isBluetoothBlocked()) {
0125         return;
0126     }
0127 
0128     m_warningWidget = new KMessageWidget(this);
0129     m_warningWidget->setMessageType(KMessageWidget::Warning);
0130     m_warningWidget->setCloseButtonVisible(false);
0131     QString fixBluetoothButtonString;
0132 
0133     if (m_manager->isBluetoothBlocked()) {
0134         m_warningWidget->setText(i18n("Bluetooth is disabled."));
0135         fixBluetoothButtonString = i18nc("Action to enable Bluetooth adapter", "Enable");
0136     } else {
0137         m_warningWidget->setText(i18n("Your Bluetooth adapter is powered off."));
0138         fixBluetoothButtonString = i18nc("Action to turn on Bluetooth adapter", "Turn On");
0139     }
0140 
0141     QAction *fixAdapters = new QAction(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")), fixBluetoothButtonString, m_warningWidget);
0142     connect(fixAdapters, &QAction::triggered, this, &DiscoverWidget::fixAdaptersError);
0143     m_warningWidget->addAction(fixAdapters);
0144     verticalLayout->insertWidget(0, m_warningWidget);
0145 }
0146 
0147 void DiscoverWidget::fixAdaptersError()
0148 {
0149     m_manager->setBluetoothBlocked(false);
0150 
0151     Q_FOREACH (BluezQt::AdapterPtr adapter, m_manager->adapters()) {
0152         adapter->setPowered(true);
0153     }
0154 }
0155 
0156 #include "moc_discoverwidget.cpp"