File indexing completed on 2024-12-01 12:29:47

0001 /*
0002  * BluezQt - Asynchronous Bluez wrapper library
0003  *
0004  * SPDX-FileCopyrightText: 2014 David Rosca <nowrep@gmail.com>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #include "devicesmodel.h"
0010 #include "adapter.h"
0011 #include "device.h"
0012 #include "manager.h"
0013 
0014 namespace BluezQt
0015 {
0016 class DevicesModelPrivate : public QObject
0017 {
0018 public:
0019     explicit DevicesModelPrivate(DevicesModel *qq);
0020 
0021     void init();
0022 
0023     void deviceAdded(DevicePtr device);
0024     void deviceRemoved(DevicePtr device);
0025     void deviceChanged(DevicePtr device);
0026     void adapterChanged(AdapterPtr adapter);
0027 
0028     DevicesModel *q;
0029     Manager *m_manager;
0030     QList<DevicePtr> m_devices;
0031 };
0032 
0033 DevicesModelPrivate::DevicesModelPrivate(DevicesModel *qq)
0034     : QObject(qq)
0035     , q(qq)
0036     , m_manager(nullptr)
0037 {
0038 }
0039 
0040 void DevicesModelPrivate::init()
0041 {
0042     m_devices = m_manager->devices();
0043 
0044     connect(m_manager, &Manager::deviceAdded, this, &DevicesModelPrivate::deviceAdded);
0045     connect(m_manager, &Manager::deviceRemoved, this, &DevicesModelPrivate::deviceRemoved);
0046     connect(m_manager, &Manager::deviceChanged, this, &DevicesModelPrivate::deviceChanged);
0047     connect(m_manager, &Manager::adapterChanged, this, &DevicesModelPrivate::adapterChanged);
0048 }
0049 
0050 void DevicesModelPrivate::deviceAdded(DevicePtr device)
0051 {
0052     q->beginInsertRows(QModelIndex(), m_devices.size(), m_devices.size());
0053     m_devices.append(device);
0054     q->endInsertRows();
0055 }
0056 
0057 void DevicesModelPrivate::deviceRemoved(DevicePtr device)
0058 {
0059     int offset = m_devices.indexOf(device);
0060     Q_ASSERT(offset >= 0);
0061 
0062     q->beginRemoveRows(QModelIndex(), offset, offset);
0063     m_devices.removeAt(offset);
0064     q->endRemoveRows();
0065 }
0066 
0067 void DevicesModelPrivate::deviceChanged(DevicePtr device)
0068 {
0069     int offset = m_devices.indexOf(device);
0070     Q_ASSERT(offset >= 0);
0071 
0072     QModelIndex idx = q->createIndex(offset, 0);
0073     Q_EMIT q->dataChanged(idx, idx);
0074 }
0075 
0076 void DevicesModelPrivate::adapterChanged(AdapterPtr adapter)
0077 {
0078     const auto devices = adapter->devices();
0079     for (const DevicePtr &device : devices) {
0080         deviceChanged(device);
0081     }
0082 }
0083 
0084 DevicesModel::DevicesModel(Manager *manager, QObject *parent)
0085     : QAbstractListModel(parent)
0086     , d(new DevicesModelPrivate(this))
0087 {
0088     d->m_manager = manager;
0089     d->init();
0090 }
0091 
0092 DevicesModel::~DevicesModel()
0093 {
0094     delete d;
0095 }
0096 
0097 QHash<int, QByteArray> DevicesModel::roleNames() const
0098 {
0099     QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
0100 
0101     roles[UbiRole] = QByteArrayLiteral("Ubi");
0102     roles[AddressRole] = QByteArrayLiteral("Address");
0103     roles[NameRole] = QByteArrayLiteral("Name");
0104     roles[FriendlyNameRole] = QByteArrayLiteral("FriendlyName");
0105     roles[RemoteNameRole] = QByteArrayLiteral("RemoteName");
0106     roles[ClassRole] = QByteArrayLiteral("Class");
0107     roles[TypeRole] = QByteArrayLiteral("Type");
0108     roles[AppearanceRole] = QByteArrayLiteral("Appearance");
0109     roles[IconRole] = QByteArrayLiteral("Icon");
0110     roles[PairedRole] = QByteArrayLiteral("Paired");
0111     roles[TrustedRole] = QByteArrayLiteral("Trusted");
0112     roles[BlockedRole] = QByteArrayLiteral("Blocked");
0113     roles[LegacyPairingRole] = QByteArrayLiteral("LegacyPairing");
0114     roles[RssiRole] = QByteArrayLiteral("Rssi");
0115     roles[ConnectedRole] = QByteArrayLiteral("Connected");
0116     roles[UuidsRole] = QByteArrayLiteral("Uuids");
0117     roles[ModaliasRole] = QByteArrayLiteral("Modalias");
0118     roles[AdapterNameRole] = QByteArrayLiteral("AdapterName");
0119     roles[AdapterAddressRole] = QByteArrayLiteral("AdapterAddress");
0120     roles[AdapterPoweredRole] = QByteArrayLiteral("AdapterPowered");
0121     roles[AdapterDiscoverableRole] = QByteArrayLiteral("AdapterDiscoverable");
0122     roles[AdapterPairableRole] = QByteArrayLiteral("AdapterPairable");
0123     roles[AdapterDiscoveringRole] = QByteArrayLiteral("AdapterDiscovering");
0124     roles[AdapterUuidsRole] = QByteArrayLiteral("AdapterUuids");
0125 
0126     return roles;
0127 }
0128 
0129 int DevicesModel::rowCount(const QModelIndex &parent) const
0130 {
0131     if (parent.isValid()) {
0132         return 0;
0133     }
0134     return d->m_devices.size();
0135 }
0136 
0137 QVariant DevicesModel::data(const QModelIndex &index, int role) const
0138 {
0139     DevicePtr dev = device(index);
0140     if (!dev) {
0141         return QVariant();
0142     }
0143 
0144     switch (role) {
0145     case Qt::DisplayRole:
0146         return dev->name();
0147     case UbiRole:
0148         return dev->ubi();
0149     case AddressRole:
0150         return dev->address();
0151     case NameRole:
0152         return dev->name();
0153     case FriendlyNameRole:
0154         return dev->friendlyName();
0155     case RemoteNameRole:
0156         return dev->remoteName();
0157     case ClassRole:
0158         return dev->deviceClass();
0159     case TypeRole:
0160         return dev->type();
0161     case AppearanceRole:
0162         return dev->appearance();
0163     case IconRole:
0164         return dev->icon();
0165     case PairedRole:
0166         return dev->isPaired();
0167     case TrustedRole:
0168         return dev->isTrusted();
0169     case BlockedRole:
0170         return dev->isBlocked();
0171     case LegacyPairingRole:
0172         return dev->hasLegacyPairing();
0173     case RssiRole:
0174         return dev->rssi();
0175     case ConnectedRole:
0176         return dev->isConnected();
0177     case UuidsRole:
0178         return dev->uuids();
0179     case ModaliasRole:
0180         return dev->modalias();
0181     case AdapterNameRole:
0182         return dev->adapter()->name();
0183     case AdapterAddressRole:
0184         return dev->adapter()->address();
0185     case AdapterPoweredRole:
0186         return dev->adapter()->isPowered();
0187     case AdapterDiscoverableRole:
0188         return dev->adapter()->isDiscoverable();
0189     case AdapterPairableRole:
0190         return dev->adapter()->isPairable();
0191     case AdapterDiscoveringRole:
0192         return dev->adapter()->isDiscovering();
0193     case AdapterUuidsRole:
0194         return dev->adapter()->uuids();
0195     default:
0196         return QVariant();
0197     }
0198 }
0199 
0200 QModelIndex DevicesModel::index(int row, int column, const QModelIndex &parent) const
0201 {
0202     if (!hasIndex(row, column, parent)) {
0203         return QModelIndex();
0204     }
0205     return createIndex(row, 0);
0206 }
0207 
0208 DevicePtr DevicesModel::device(const QModelIndex &index) const
0209 {
0210     if (!index.isValid()) {
0211         return DevicePtr();
0212     }
0213     return d->m_devices.at(index.row());
0214 }
0215 
0216 } // namespace BluezQt
0217 
0218 #include "moc_devicesmodel.cpp"