diff --git a/src/maps.h b/src/maps.h --- a/src/maps.h +++ b/src/maps.h @@ -46,10 +46,15 @@ class Q_DECL_EXPORT MapBaseQObject : public QObject { Q_OBJECT + +public: + virtual int count() const = 0; + virtual QObject *objectAt(int index) const = 0; + virtual int indexOfObject(QObject *object) const = 0; + signals: - void added(quint32 index); - void updated(quint32 index); - void removed(quint32 index); + void added(int index); + void removed(int index); }; /** @@ -66,37 +71,28 @@ const QMap &data() const { return m_data; } - int modelIndexForQObject(QObject *qobject) const + int count() const Q_DECL_OVERRIDE { - Type *t = qobject_cast(qobject); - if (!t) - return -1; - int key = m_data.key(t, -1); - if (key == -1) - return -1; - return m_data.keys().indexOf(key); + return m_data.count(); } - /** - * @param dataIndex index in the data model - * @return -1 on invalid index, otherwise PA index - */ - qint64 dataIndexToPaIndex(int dataIndex) const + int indexOfObject(QObject *object) const Q_DECL_OVERRIDE { - auto list = m_data.values(); - qCDebug(PLASMAPA) << Q_FUNC_INFO << list.length() << dataIndex; - if (list.length() <= dataIndex) { - return -1; + int index = 0; + QMapIterator it(m_data); + while (it.hasNext()) { + it.next(); + if (it.value() == object) { + return index; + } + index++; } - qCDebug(PLASMAPA) << " " << list.at(dataIndex)->index(); - qCDebug(PLASMAPA) << " " << list.at(dataIndex)->name(); - return list.at(dataIndex)->index(); + return -1; } - int paIndexToDataIndex(quint32 index) const + QObject *objectAt(int index) const Q_DECL_OVERRIDE { - qCDebug(PLASMAPA) << m_data.keys() << index; - return m_data.keys().indexOf(index); + return (m_data.constBegin() + index).value(); } void reset() @@ -133,8 +129,6 @@ if (isNew) { emit added(modelIndex); - } else { - emit updated(modelIndex); } } @@ -144,7 +138,7 @@ m_pendingRemovals.insert(index); } else { const int modelIndex = m_data.keys().indexOf(index); - m_data.take(index)->deleteLater(); + delete m_data.take(index); emit removed(modelIndex); } } diff --git a/src/pulseaudio.h b/src/pulseaudio.h --- a/src/pulseaudio.h +++ b/src/pulseaudio.h @@ -1,5 +1,6 @@ /* Copyright 2014-2015 Harald Sitter + Copyright 2016 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -22,9 +23,8 @@ #define PULSEAUDIO_H #include -#include -#include "context.h" +#include "maps.h" #include "ref.h" namespace QPulseAudio @@ -34,173 +34,83 @@ { Q_OBJECT public: - virtual QHash roleNames() const Q_DECL_OVERRIDE Q_DECL_FINAL; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE = 0; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE = 0; + enum ItemRole { + PulseObjectRole = Qt::UserRole + 1 + }; - Q_INVOKABLE int role(const QByteArray &roleName) const; + QHash roleNames() const Q_DECL_FINAL; + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_FINAL; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_FINAL; + bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_FINAL; -protected slots: - virtual void onDataAdded(quint32 index); - virtual void onDataUpdated(quint32 index); - virtual void onDataRemoved(quint32 index); + Q_INVOKABLE int role(const QByteArray &roleName) const; protected: AbstractModel(const MapBaseQObject *map, QObject *parent); void initRoleNames(const QMetaObject &qobjectMetaObject); - QVariant dataForRole(QObject *obj, int role) const; +private slots: + void propertyChanged(); +private: + void onDataAdded(int index); + void onDataRemoved(int index); + QMetaMethod propertyChangedMetaMethod() const; + + const MapBaseQObject *m_map; QHash m_roles; - QMap m_objectProperties; - QMap m_signalIndexToProperties; + QHash m_objectProperties; + QHash m_signalIndexToProperties; private: // Prevent leaf-classes from default constructing as we want to enforce // them passing us a context or explicit nullptrs. AbstractModel() {} }; +class Q_DECL_EXPORT CardModel : public AbstractModel +{ + Q_OBJECT +public: + CardModel(QObject *parent = nullptr); +}; + class Q_DECL_EXPORT SinkModel : public AbstractModel { Q_OBJECT Q_PROPERTY(QPulseAudio::Sink *defaultSink READ defaultSink NOTIFY defaultSinkChanged) public: - enum ItemRole { - IndexRole = Qt::UserRole + 1, - PulseObjectRole, - }; - Q_ENUMS(ItemRole) - SinkModel(QObject *parent = nullptr); - Sink *defaultSink() const; - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE; - signals: - void sinksChanged(); void defaultSinkChanged(); +}; -protected: - virtual void onDataAdded(quint32 index) Q_DECL_OVERRIDE Q_DECL_FINAL; - virtual void onDataRemoved(quint32 index) Q_DECL_OVERRIDE Q_DECL_FINAL; - -private slots: - void propertyChanged(); - -private: - QMetaMethod propertyChangedMetaMethod() const; +class Q_DECL_EXPORT SinkInputModel : public AbstractModel +{ + Q_OBJECT +public: + SinkInputModel(QObject *parent = nullptr); }; class Q_DECL_EXPORT SourceModel : public AbstractModel { Q_OBJECT Q_PROPERTY(QPulseAudio::Source *defaultSource READ defaultSource NOTIFY defaultSourceChanged) public: - enum ItemRole { - IndexRole = Qt::UserRole + 1, - PulseObjectRole, - }; - Q_ENUMS(ItemRole) - SourceModel(QObject *parent = nullptr); - Source *defaultSource() const; - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE; - signals: - void sourcesChanged(); void defaultSourceChanged(); - -protected: - virtual void onDataAdded(quint32 index) Q_DECL_OVERRIDE Q_DECL_FINAL; - virtual void onDataRemoved(quint32 index) Q_DECL_OVERRIDE Q_DECL_FINAL; - -private slots: - void propertyChanged(); - -private: - QMetaMethod propertyChangedMetaMethod() const; }; class Q_DECL_EXPORT SourceOutputModel : public AbstractModel { Q_OBJECT public: - enum ItemRole { - IndexRole = Qt::UserRole + 1, - PulseObjectRole - }; - Q_ENUMS(ItemRole) - SourceOutputModel(QObject *parent = nullptr); - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; -}; - -class Q_DECL_EXPORT ClientModel : public AbstractModel -{ - Q_OBJECT -public: - enum ItemRole { - NameRole = Qt::UserRole + 1, - PulseObjectRole, - }; - Q_ENUMS(ItemRole) - - ClientModel(QObject *parent = nullptr); - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; -}; - -class Q_DECL_EXPORT CardModel : public AbstractModel -{ - Q_OBJECT -public: - enum ItemRole { - IndexRole = Qt::UserRole + 1, - PulseObjectRole - }; - Q_ENUMS(ItemRole) - - CardModel(QObject *parent = nullptr); - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; -}; - -class Q_DECL_EXPORT SinkInputModel : public AbstractModel -{ - Q_OBJECT -public: - enum ItemRole { - IndexRole = Qt::UserRole + 1, - PulseObjectRole - }; - Q_ENUMS(ItemRole) - - SinkInputModel(QObject *parent = nullptr); - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; -}; - -class Q_DECL_EXPORT ReverseFilterModel : public QSortFilterProxyModel -{ - Q_OBJECT - Q_PROPERTY(QAbstractItemModel * sourceModel READ sourceModel WRITE setSourceModel) -public: - ReverseFilterModel(QObject *parent = nullptr); - - Q_INVOKABLE void initialSort(); }; } // QPulseAudio diff --git a/src/pulseaudio.cpp b/src/pulseaudio.cpp --- a/src/pulseaudio.cpp +++ b/src/pulseaudio.cpp @@ -1,5 +1,6 @@ /* Copyright 2014-2015 Harald Sitter + Copyright 2016 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,419 +22,183 @@ #include "pulseaudio.h" #include "debug.h" -#include - #include "card.h" -#include "client.h" #include "sink.h" #include "sinkinput.h" #include "source.h" #include "sourceoutput.h" #include "server.h" -namespace QPulseAudio -{ - -ClientModel::ClientModel(QObject *parent) - : AbstractModel(&context()->clients(), parent) -{ - initRoleNames(Client::staticMetaObject); -} - -int ClientModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - if (!context()) - return 0; - return context()->clients().data().count(); -} - -QVariant ClientModel::data(const QModelIndex &index, int role) const -{ - Client *data = context()->clients().data().values().at(index.row()); - Q_ASSERT(data); - switch(static_cast(role)){ - case NameRole: - return data->name(); - case PulseObjectRole: - return QVariant::fromValue(data); - } - return dataForRole(data, role); -} - -SinkInputModel::SinkInputModel(QObject *parent) - : AbstractModel(&context()->sinkInputs(), parent) -{ - initRoleNames(SinkInput::staticMetaObject); -} - -int AbstractModel::role(const QByteArray &roleName) const -{ - qCDebug(PLASMAPA) << roleName << m_roles.key(roleName, -1); - return m_roles.key(roleName, -1); -} +#include -int SinkInputModel::rowCount(const QModelIndex &parent) const +namespace QPulseAudio { - Q_UNUSED(parent); - if (!context()) - return 0; - return context()->sinkInputs().data().count(); -} -QVariant SinkInputModel::data(const QModelIndex &index, int role) const +AbstractModel::AbstractModel(const MapBaseQObject *map, QObject *parent) + : QAbstractListModel(parent) + , m_map(map) { - SinkInput *data = context()->sinkInputs().data().values().at(index.row()); - Q_ASSERT(data); - switch ((ItemRole) role) { - case IndexRole: - return data->index(); - case PulseObjectRole: - return QVariant::fromValue(data); - } - return dataForRole(data, role); + connect(m_map, &MapBaseQObject::added, this, &AbstractModel::onDataAdded); + connect(m_map, &MapBaseQObject::removed, this, &AbstractModel::onDataRemoved); } QHash AbstractModel::roleNames() const { if (!m_roles.empty()) { qCDebug(PLASMAPA) << "returning roles" << m_roles; return m_roles; } - Q_ASSERT(false); + Q_UNREACHABLE(); return QHash(); } -SinkModel::SinkModel(QObject *parent) - : AbstractModel(&context()->sinks(), parent) -{ - initRoleNames(Sink::staticMetaObject); - - connect(&context()->sinks(), &SinkMap::added, this, &SinkModel::sinksChanged); - connect(&context()->sinks(), &SinkMap::updated, this, &SinkModel::sinksChanged); - connect(&context()->sinks(), &SinkMap::removed, this, &SinkModel::sinksChanged); - connect(context()->server(), &Server::defaultSinkChanged, this, &SinkModel::defaultSinkChanged); - - emit sinksChanged(); -} - -Sink *SinkModel::defaultSink() const -{ - return context()->server()->defaultSink(); -} - -int SinkModel::rowCount(const QModelIndex &parent) const +int AbstractModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - if (!context()) - return 0; - return context()->sinks().data().count(); + return m_map->count(); } -QVariant SinkModel::data(const QModelIndex &index, int role) const +QVariant AbstractModel::data(const QModelIndex &index, int role) const { - Sink *data = context()->sinks().data().values().at(index.row()); + QObject *data = m_map->objectAt(index.row()); Q_ASSERT(data); - switch(static_cast(role)) { - case IndexRole: - return data->index(); - case PulseObjectRole: + if (role == PulseObjectRole) { return QVariant::fromValue(data); } - return dataForRole(data, role); + int property = m_objectProperties.value(role, -1); + if (property == -1) { + return QVariant(); + } + return data->metaObject()->property(property).read(data); } -bool SinkModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool AbstractModel::setData(const QModelIndex &index, const QVariant &value, int role) { int propertyIndex = m_objectProperties.value(role, -1); - if (propertyIndex == -1) + if (propertyIndex == -1) { return false; - Sink *data = context()->sinks().data().values().at(index.row()); + } + QObject *data = m_map->objectAt(index.row()); auto property = data->metaObject()->property(propertyIndex); return property.write(data, value); } -void SinkModel::onDataAdded(quint32 index) -{ - beginInsertRows(QModelIndex(), index, index); - Sink *data = context()->sinks().data().values().at(index); - const QMetaObject *mo = data->metaObject(); - // We have all the data changed notify signals already stored - auto keys = m_signalIndexToProperties.keys(); - foreach(int index, keys){ - QMetaMethod meth = mo->method(index); - connect(data, meth, this, propertyChangedMetaMethod()); - } - endInsertRows(); -} - -void SinkModel::onDataRemoved(quint32 index) -{ - beginRemoveRows(QModelIndex(), index, index); - endRemoveRows(); -} - -void SinkModel::propertyChanged() -{ - if (!sender() || senderSignalIndex() == -1) - return; - int propertyIndex = m_signalIndexToProperties.value(senderSignalIndex(), -1); - if (propertyIndex == -1) - return; - int role = m_objectProperties.key(propertyIndex, -1); - if (role == -1) - return; - int index = context()->sinks().modelIndexForQObject(sender()); - qCDebug(PLASMAPA) << "PROPERTY CHANGED (" << index << ") :: " << role << roleNames().value(role); - emit dataChanged(createIndex(index, 0), createIndex(index, 0), QVector() << role); -} - -QMetaMethod SinkModel::propertyChangedMetaMethod() const -{ - auto mo = metaObject(); - int methodIndex = mo->indexOfMethod(QMetaObject::normalizedSignature("propertyChanged()").data()); - if(methodIndex == -1){ - return QMetaMethod(); - } - return mo->method(methodIndex); -} - -void AbstractModel::onDataAdded(quint32 index) -{ - beginInsertRows(QModelIndex(), index, index); - endInsertRows(); -} - -void AbstractModel::onDataUpdated(quint32 index) -{ - emit dataChanged(createIndex(index, 0), createIndex(index, 0)); -} - -void AbstractModel::onDataRemoved(quint32 index) -{ - beginRemoveRows(QModelIndex(), index, index); - endRemoveRows(); -} - -AbstractModel::AbstractModel(const MapBaseQObject *map, QObject *parent) - : QAbstractListModel(parent) +int AbstractModel::role(const QByteArray &roleName) const { - connect(map, &MapBaseQObject::added, this, &AbstractModel::onDataAdded); - connect(map, &MapBaseQObject::updated, this, &AbstractModel::onDataUpdated); - connect(map, &MapBaseQObject::removed, this, &AbstractModel::onDataRemoved); + qCDebug(PLASMAPA) << roleName << m_roles.key(roleName, -1); + return m_roles.key(roleName, -1); } void AbstractModel::initRoleNames(const QMetaObject &qobjectMetaObject) { - QMetaEnum enumerator; - for (int i = 0; i < metaObject()->enumeratorCount(); ++i) { - if (metaObject()->enumerator(i).name() == QLatin1Literal("ItemRole")) { - enumerator = metaObject()->enumerator(i); - break; - } - } - - Q_ASSERT(enumerator.scope() == metaObject()->className()); - // No valid enum found, leaf probably doesn't implement ItemRole (correctly). - Q_ASSERT(enumerator.isValid()); - - for (int i = 0; i < enumerator.keyCount(); ++i) { - // Clip the Role suffix and glue it in the hash. - static int roleLength = strlen("Role"); - QByteArray key(enumerator.key(i)); - // Enum values must end in Role or the enum is crap - Q_ASSERT(key.right(roleLength) == QByteArray("Role")); - key.chop(roleLength); - m_roles[enumerator.value(i)] = key; - } + m_roles[PulseObjectRole] = QByteArrayLiteral("PulseObject"); + int maxEnumValue = PulseObjectRole; - int maxEnumValue = -1; - for (auto it = m_roles.constBegin(); it != m_roles.constEnd(); ++it) { - if (it.key() > maxEnumValue) - maxEnumValue = it.key(); - } - Q_ASSERT(maxEnumValue != -1); auto mo = qobjectMetaObject; for (int i = 0; i < mo.propertyCount(); ++i) { QMetaProperty property = mo.property(i); QString name(property.name()); name.replace(0, 1, name.at(0).toUpper()); m_roles[++maxEnumValue] = name.toLatin1(); m_objectProperties.insert(maxEnumValue, i); - if (!property.hasNotifySignal()) + if (!property.hasNotifySignal()) { continue; + } m_signalIndexToProperties.insert(property.notifySignalIndex(), i); } qCDebug(PLASMAPA) << m_roles; } -QVariant AbstractModel::dataForRole(QObject *obj, int role) const +void AbstractModel::propertyChanged() { - int property = m_objectProperties.value(role, -1); - if (property == -1) { - return QVariant(); + if (!sender() || senderSignalIndex() == -1) { + return; } - return obj->metaObject()->property(property).read(obj); -} - -ReverseFilterModel::ReverseFilterModel(QObject *parent) - : QSortFilterProxyModel(parent) -{ - setDynamicSortFilter(true); - setFilterKeyColumn(0); -} - -void ReverseFilterModel::initialSort() -{ - QSortFilterProxyModel::sort(0, Qt::DescendingOrder); -} - -SourceModel::SourceModel(QObject *parent) - : AbstractModel(&context()->sources(), parent) -{ - initRoleNames(Source::staticMetaObject); - - connect(&context()->sources(), &SourceMap::added, this, &SourceModel::sourcesChanged); - connect(&context()->sources(), &SourceMap::updated, this, &SourceModel::sourcesChanged); - connect(&context()->sources(), &SourceMap::removed, this, &SourceModel::sourcesChanged); - connect(context()->server(), &Server::defaultSourceChanged, this, &SourceModel::defaultSourceChanged); - - emit sourcesChanged(); -} - -Source *SourceModel::defaultSource() const -{ - return context()->server()->defaultSource(); -} - -int SourceModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - if (!context()) - return 0; - return context()->sources().data().count(); -} - -QVariant SourceModel::data(const QModelIndex &index, int role) const -{ - Source *data = context()->sources().data().values().at(index.row()); - Q_ASSERT(data); - switch(static_cast(role)) { - case IndexRole: - return data->index(); - case PulseObjectRole: - return QVariant::fromValue(data); + int propertyIndex = m_signalIndexToProperties.value(senderSignalIndex(), -1); + if (propertyIndex == -1) { + return; } - return dataForRole(data, role); -} - -bool SourceModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - int propertyIndex = m_objectProperties.value(role, -1); - if (propertyIndex == -1) - return false; - Source *data = context()->sources().data().values().at(index.row()); - auto property = data->metaObject()->property(propertyIndex); - return property.write(data, value); + int role = m_objectProperties.key(propertyIndex, -1); + if (role == -1) { + return; + } + int index = m_map->indexOfObject(sender()); + qCDebug(PLASMAPA) << "PROPERTY CHANGED (" << index << ") :: " << role << roleNames().value(role); + emit dataChanged(createIndex(index, 0), createIndex(index, 0), {role}); } -void SourceModel::onDataAdded(quint32 index) +void AbstractModel::onDataAdded(int index) { beginInsertRows(QModelIndex(), index, index); - Source *data = context()->sources().data().values().at(index); + QObject *data = m_map->objectAt(index); const QMetaObject *mo = data->metaObject(); // We have all the data changed notify signals already stored auto keys = m_signalIndexToProperties.keys(); - foreach(int index, keys){ + foreach (int index, keys) { QMetaMethod meth = mo->method(index); connect(data, meth, this, propertyChangedMetaMethod()); } endInsertRows(); } -void SourceModel::onDataRemoved(quint32 index) +void AbstractModel::onDataRemoved(int index) { beginRemoveRows(QModelIndex(), index, index); endRemoveRows(); } -void SourceModel::propertyChanged() -{ - if (!sender() || senderSignalIndex() == -1) - return; - int propertyIndex = m_signalIndexToProperties.value(senderSignalIndex(), -1); - if (propertyIndex == -1) - return; - int role = m_objectProperties.key(propertyIndex, -1); - if (role == -1) - return; - int index = context()->sources().modelIndexForQObject(sender()); - qCDebug(PLASMAPA) << "PROPERTY CHANGED (" << index << ") :: " << role << roleNames().value(role); - emit dataChanged(createIndex(index, 0), createIndex(index, 0), QVector() << role); -} - -QMetaMethod SourceModel::propertyChangedMetaMethod() const +QMetaMethod AbstractModel::propertyChangedMetaMethod() const { auto mo = metaObject(); - int methodIndex = mo->indexOfMethod(QMetaObject::normalizedSignature("propertyChanged()").data()); - if(methodIndex == -1){ + int methodIndex = mo->indexOfMethod("propertyChanged()"); + if (methodIndex == -1) { return QMetaMethod(); } return mo->method(methodIndex); } -SourceOutputModel::SourceOutputModel(QObject *parent) - : AbstractModel(&context()->sourceOutputs(), parent) +SinkModel::SinkModel(QObject *parent) + : AbstractModel(&context()->sinks(), parent) { - initRoleNames(SourceOutput::staticMetaObject); + initRoleNames(Sink::staticMetaObject); + + connect(context()->server(), &Server::defaultSinkChanged, this, &SinkModel::defaultSinkChanged); } -int SourceOutputModel::rowCount(const QModelIndex &parent) const +Sink *SinkModel::defaultSink() const { - Q_UNUSED(parent); - if (!context()) - return 0; - return context()->sourceOutputs().data().count(); + return context()->server()->defaultSink(); } -QVariant SourceOutputModel::data(const QModelIndex &index, int role) const +SourceModel::SourceModel(QObject *parent) + : AbstractModel(&context()->sources(), parent) { - SourceOutput *data = context()->sourceOutputs().data().values().at(index.row()); - Q_ASSERT(data); - switch ((ItemRole) role) { - case IndexRole: - return data->index(); - case PulseObjectRole: - return QVariant::fromValue(data); - } - return dataForRole(data, role); + initRoleNames(Source::staticMetaObject); + + connect(context()->server(), &Server::defaultSourceChanged, this, &SourceModel::defaultSourceChanged); } -CardModel::CardModel(QObject *parent) - : AbstractModel(&context()->cards(), parent) +Source *SourceModel::defaultSource() const { - initRoleNames(Card::staticMetaObject); + return context()->server()->defaultSource(); } -int CardModel::rowCount(const QModelIndex &parent) const +SinkInputModel::SinkInputModel(QObject *parent) + : AbstractModel(&context()->sinkInputs(), parent) { - Q_UNUSED(parent); - if (!context()) - return 0; - return context()->cards().data().count(); + initRoleNames(SinkInput::staticMetaObject); } -QVariant CardModel::data(const QModelIndex &index, int role) const +SourceOutputModel::SourceOutputModel(QObject *parent) + : AbstractModel(&context()->sourceOutputs(), parent) { - Card *data = context()->cards().data().values().at(index.row()); - Q_ASSERT(data); - switch ((ItemRole) role) { - case IndexRole: - return data->index(); - case PulseObjectRole: - return QVariant::fromValue(data); - } - return dataForRole(data, role); + initRoleNames(SourceOutput::staticMetaObject); +} + +CardModel::CardModel(QObject *parent) + : AbstractModel(&context()->cards(), parent) +{ + initRoleNames(Card::staticMetaObject); } } // QPulseAudio diff --git a/src/qml/plugin.cpp b/src/qml/plugin.cpp --- a/src/qml/plugin.cpp +++ b/src/qml/plugin.cpp @@ -33,10 +33,8 @@ void Plugin::registerTypes(const char* uri) { qmlRegisterType(uri, 0, 1, "CardModel"); - qmlRegisterType(uri, 0, 1, "ClientModel"); qmlRegisterType(uri, 0, 1, "SinkModel"); qmlRegisterType(uri, 0, 1, "SinkInputModel"); - qmlRegisterType(uri, 0, 1, "ReverseFilterModel"); qmlRegisterType(uri, 0, 1, "SourceModel"); qmlRegisterType(uri, 0, 1, "SourceOutputModel"); qmlRegisterType(uri, 0, 1, "GlobalAction");