##### START HEADER ###### #include #include #include class TreeItem; class BluetoothChooserModelThread; class BluetoothChooserModel : public QAbstractItemModel { Q_OBJECT public: BluetoothChooserModel(QObject *parent = 0); ~BluetoothChooserModel(); Qt::ItemFlags flags ( const QModelIndex & index ) const; QVariant data(const QModelIndex &index, int role) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent ( const QModelIndex & index ) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const; public slots: void discoveryStarted(); void addRemote(const QString &ubi,int,int); void discoveryFinished(); void serviceDiscoveryStarted(const QString &ubi); void addService(const QString &ubi, const Solid::Control::ServiceRecord &service); void serviceDiscoveryFinished(const QString &ubi); void updateInterface(const QString &ubi = QString()); private: TreeItem *rootItem; Solid::Control::BluetoothInterface *interface; BluetoothChooserModelThread *thread; QList devices; friend class BluetoothChooserModelThread; }; ##### END HEADER ###### ##### START IMPLEMENTATION ###### #include "model.h" #include #include #include using namespace Solid::Control; class TreeItem { public: enum Type {RemoteDevice,Service,Root}; TreeItem(); TreeItem(const ServiceRecord &record,TreeItem *parent); TreeItem(const BluetoothRemoteDevice &remote,TreeItem *parent); ~TreeItem(); ServiceRecord record(); BluetoothRemoteDevice remote(); TreeItem *parent(); Type type(); int childCount() const; int row() const; void appendChild(TreeItem *item); TreeItem *child(int row); private: ServiceRecord m_record; BluetoothRemoteDevice m_remote; TreeItem *m_parent; QList childs; Type m_type; }; class BluetoothChooserModelThread :public QThread { public: BluetoothChooserModelThread(BluetoothChooserModel *model); void run(); private: BluetoothChooserModel *model; }; TreeItem::TreeItem() :m_parent(0),m_type(TreeItem::Root) { } TreeItem::TreeItem(const ServiceRecord & record, TreeItem * parent) :m_record(record),m_parent(parent),m_type(TreeItem::Service) { } TreeItem::TreeItem(const BluetoothRemoteDevice & remote, TreeItem * parent) :m_remote(remote),m_parent(parent),m_type(TreeItem::RemoteDevice) { } TreeItem::~ TreeItem() { qDeleteAll(childs); } ServiceRecord TreeItem::record() { return m_record; } BluetoothRemoteDevice TreeItem::remote() { return m_remote; } TreeItem * TreeItem::parent() { return m_parent; } TreeItem::Type TreeItem::type() { return m_type; } int TreeItem::childCount() const { return childs.size(); } int TreeItem::row() const { if(m_parent) return m_parent->childs.indexOf(const_cast(this)); return 0; } void TreeItem::appendChild(TreeItem * item) { childs.append(item); } TreeItem * TreeItem::child(int row) { return childs.at(row); } BluetoothChooserModel::BluetoothChooserModel(QObject * parent) :QAbstractItemModel(parent),rootItem(new TreeItem()),interface(0) { // updateInterface(); // ServiceRecord r; // r.name = "A"; // rootItem->appendChild(new TreeItem(r,rootItem)); // r.name = "B"; // rootItem->child(0)->appendChild(new TreeItem(r,rootItem->child(0))); thread = new BluetoothChooserModelThread(this); thread->start(); } BluetoothChooserModel::~ BluetoothChooserModel() { delete rootItem; } QModelIndex BluetoothChooserModel::index(int row, int column, const QModelIndex & parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); TreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); TreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex BluetoothChooserModel::parent(const QModelIndex & index) const { if (!index.isValid()) return QModelIndex(); TreeItem *childItem = static_cast(index.internalPointer()); TreeItem *parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } int BluetoothChooserModel::rowCount(const QModelIndex & parent) const { TreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } int BluetoothChooserModel::columnCount(const QModelIndex &) const { return 1; } QVariant BluetoothChooserModel::data(const QModelIndex & index, int role) const { if (!index.isValid() || role != Qt::DisplayRole) return QVariant(); TreeItem *item = static_cast(index.internalPointer()); if(item->type() == TreeItem::RemoteDevice) return item->remote().name(); else if(item->type() == TreeItem::Service) return item->record().name; else return "Empty"; } Qt::ItemFlags BluetoothChooserModel::flags(const QModelIndex & index) const { if (!index.isValid()) return 0; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } void BluetoothChooserModel::discoveryStarted() { // if(rootItem->childCount()>0) // { // beginRemoveRows(QModelIndex(),0,rootItem->childCount()-1); // delete rootItem; // rootItem = new TreeItem; // endRemoveRows(); // } } void BluetoothChooserModel::addRemote(const QString & ubi, int , int ) { kDebug() << k_funcinfo << endl; BluetoothRemoteDevice device = interface->findBluetoothRemoteDevice(ubi); beginInsertRows(QModelIndex(),rootItem->childCount(),rootItem->childCount()+1); TreeItem *newItem = new TreeItem(device,rootItem); rootItem->appendChild(newItem); kDebug() << "Child count " << rootItem->childCount() << endl; endInsertRows(); BluetoothRemoteDevice *ref =new BluetoothRemoteDevice(device); QObject::connect(ref,SIGNAL(addService(const QString &, const Solid::Control::ServiceRecord &)), this,SLOT(addService(const QString &, const Solid::Control::ServiceRecord &))); ref->findServices(); devices << ref; } void BluetoothChooserModel::discoveryFinished() { QObject::disconnect(interface,SIGNAL(discoveryStarted()), this,SLOT(discoveryStarted())); QObject::disconnect(interface,SIGNAL(remoteDeviceFound( const QString&, int, int )), this,SLOT(addRemote(const QString&, int, int))); QObject::disconnect(interface,SIGNAL(discoveryCompleted()), this,SLOT(discoveryFinished())); } void BluetoothChooserModel::serviceDiscoveryStarted(const QString & ubi) { } void BluetoothChooserModel::addService(const QString & ubi, const Solid::Control::ServiceRecord & service) { kDebug() << "Inserting services" << endl; for(int i = 0; i < rootItem->childCount();i++) { TreeItem *act = rootItem->child(i); BluetoothRemoteDevice remote = act->remote(); if(remote.ubi() == ubi) { beginInsertRows(index(0,0,QModelIndex()).child(i,0),act->childCount(),act->childCount()+1); act->appendChild(new TreeItem(service,act)); endInsertRows(); break; } } } void BluetoothChooserModel::serviceDiscoveryFinished(const QString & ubi) { } void BluetoothChooserModel::updateInterface(const QString & ubi) { BluetoothManager &mgr = BluetoothManager::self(); QString m_ubi = ubi; if(m_ubi.isEmpty())//Check if we are looking for default iface { m_ubi = mgr.defaultInterface(); } if(interface) { QObject::disconnect(interface,SIGNAL(discoveryStarted()), this,SLOT(discoveryStarted())); QObject::disconnect(interface,SIGNAL(remoteDeviceFound( const QString&, int, int )), this,SLOT(addRemote(const QString&, int, int))); QObject::disconnect(interface,SIGNAL(discoveryCompleted()), this,SLOT(discoveryFinished())); delete interface; interface = 0; } interface = new BluetoothInterface(m_ubi); QObject::connect(interface,SIGNAL(discoveryStarted()), this,SLOT(discoveryStarted())); QObject::connect(interface,SIGNAL(remoteDeviceFound( const QString&, int, int )), this,SLOT(addRemote(const QString&, int, int))); QObject::connect(interface,SIGNAL(discoveryCompleted()), this,SLOT(discoveryFinished())); interface->discoverDevices(); } BluetoothChooserModelThread::BluetoothChooserModelThread(BluetoothChooserModel * model) { this->model = model; } void BluetoothChooserModelThread::run() { model->updateInterface(); exec(); } QVariant BluetoothChooserModel::headerData(int section, Qt::Orientation orientation, int role) const { // kDebug() << "Section : " << section << endl; if(role == Qt::DisplayRole) { if(section == 0) return "Devices"; else if(section == 1) return "Services"; } return QVariant(); } bool BluetoothChooserModel::hasChildren(const QModelIndex & parent) const { TreeItem *p; if(parent.isValid()) p = static_cast(parent.internalPointer()); else p = rootItem; bool out = p->childCount()>0; kDebug() << k_funcinfo << " : " << out << endl; return out; } #include "model.moc" ##### END ######