20#include "sourceoutput.h"
21#include "streamrestore.h"
28AbstractModel::AbstractModel(
const MapBaseQObject *map,
QObject *parent)
30 , d(new AbstractModelPrivate(this,
map))
32 connect(d->m_map, &MapBaseQObject::aboutToBeAdded,
this, [
this](
int index) {
33 beginInsertRows(QModelIndex(), index, index);
35 connect(d->m_map, &MapBaseQObject::added,
this, [
this](
int index) {
38 Q_EMIT countChanged();
40 connect(d->m_map, &MapBaseQObject::aboutToBeRemoved,
this, [
this](
int index) {
41 beginRemoveRows(QModelIndex(), index, index);
43 connect(d->m_map, &MapBaseQObject::removed,
this, [
this](
int index) {
46 Q_EMIT countChanged();
50AbstractModel::~AbstractModel()
55AbstractModelPrivate::AbstractModelPrivate(AbstractModel *q,
const MapBaseQObject *map)
61AbstractModelPrivate::~AbstractModelPrivate()
67 if (!d->m_roles.empty()) {
74int AbstractModel::rowCount(
const QModelIndex &parent)
const
79 return d->m_map->count();
84 if (!hasIndex(index.
row(), index.
column())) {
87 QObject *data = d->m_map->objectAt(index.
row());
89 if (role == PulseObjectRole) {
92 return static_cast<PulseObject *
>(data)->
name();
94 int property = d->m_objectProperties.value(role, -1);
103 if (!hasIndex(index.
row(), index.
column())) {
106 int propertyIndex = d->m_objectProperties.
value(role, -1);
107 if (propertyIndex == -1) {
110 QObject *data = d->m_map->objectAt(index.
row());
112 return property.
write(data, value);
115int AbstractModel::role(
const QByteArray &roleName)
const
117 qCDebug(PULSEAUDIOQT) << roleName << d->m_roles.key(roleName, -1);
118 return d->m_roles.key(roleName, -1);
121Context *AbstractModel::context()
const
123 return Context::instance();
126void AbstractModel::initRoleNames(
const QMetaObject &qobjectMetaObject)
128 d->m_roles[PulseObjectRole] = QByteArrayLiteral(
"PulseObject");
131 for (
int i = 0; i < metaObject()->enumeratorCount(); ++i) {
133 enumerator = metaObject()->enumerator(i);
138 for (
int i = 0; i < enumerator.
keyCount(); ++i) {
140 const int roleLength = 4;
143 Q_ASSERT(key.right(roleLength) == QByteArrayLiteral(
"Role"));
144 key.chop(roleLength);
145 d->m_roles[enumerator.
value(i)] = key;
148 int maxEnumValue = -1;
149 for (
auto it = d->m_roles.constBegin(); it != d->m_roles.constEnd(); ++it) {
150 if (it.key() > maxEnumValue) {
151 maxEnumValue = it.key();
154 Q_ASSERT(maxEnumValue != -1);
155 auto mo = qobjectMetaObject;
156 for (
int i = 0; i < mo.propertyCount(); ++i) {
161 d->m_objectProperties.
insert(maxEnumValue, i);
162 if (!property.hasNotifySignal()) {
165 d->m_signalIndexToProperties.
insert(property.notifySignalIndex(), i);
167 qCDebug(PULSEAUDIOQT) << d->m_roles;
170 for (
int i = 0; i < d->m_map->count(); ++i) {
175void AbstractModel::propertyChanged()
177 if (!sender() || senderSignalIndex() == -1) {
180 int propertyIndex = d->m_signalIndexToProperties.value(senderSignalIndex(), -1);
181 if (propertyIndex == -1) {
184 int role = d->m_objectProperties.key(propertyIndex, -1);
188 int index = d->m_map->indexOfObject(sender());
189 qCDebug(PULSEAUDIOQT) <<
"PROPERTY CHANGED (" << index <<
") :: " << role << roleNames().value(role);
190 Q_EMIT dataChanged(createIndex(index, 0), createIndex(index, 0), {role});
193void AbstractModel::onDataAdded(
int index)
195 QObject *data = d->m_map->objectAt(index);
198 const auto keys = d->m_signalIndexToProperties.keys();
199 for (
const auto &index : keys) {
201 connect(data, meth,
this, propertyChangedMetaMethod());
205QMetaMethod AbstractModel::propertyChangedMetaMethod()
const
207 auto mo = metaObject();
209 if (methodIndex == -1) {
212 return mo->
method(methodIndex);
215SinkModel::SinkModel(
QObject *parent)
216 : AbstractModel(&context()->d->m_sinks, parent)
218 initRoleNames(Sink::staticMetaObject);
223 if (role == SortByDefaultRole) {
225 const QString pulseIndex = data(index, AbstractModel::role(QByteArrayLiteral(
"Index"))).toString();
226 const QString defaultDevice = data(index, AbstractModel::role(QByteArrayLiteral(
"Default"))).toString();
227 return defaultDevice + pulseIndex;
229 return AbstractModel::data(index, role);
232SourceModel::SourceModel(
QObject *parent)
233 : AbstractModel(&context()->d->m_sources, parent)
235 initRoleNames(Source::staticMetaObject);
240 if (role == SortByDefaultRole) {
242 const QString pulseIndex = data(index, AbstractModel::role(QByteArrayLiteral(
"Index"))).toString();
243 const QString defaultDevice = data(index, AbstractModel::role(QByteArrayLiteral(
"Default"))).toString();
244 return defaultDevice + pulseIndex;
246 return AbstractModel::data(index, role);
249SinkInputModel::SinkInputModel(
QObject *parent)
250 : AbstractModel(&context()->d->m_sinkInputs, parent)
252 initRoleNames(SinkInput::staticMetaObject);
255SourceOutputModel::SourceOutputModel(
QObject *parent)
256 : AbstractModel(&context()->d->m_sourceOutputs, parent)
258 initRoleNames(SourceOutput::staticMetaObject);
261CardModel::CardModel(
QObject *parent)
262 : AbstractModel(&context()->d->m_cards, parent)
264 initRoleNames(Card::staticMetaObject);
267StreamRestoreModel::StreamRestoreModel(
QObject *parent)
268 : AbstractModel(&context()->d->m_streamRestores, parent)
270 initRoleNames(StreamRestore::staticMetaObject);
273ModuleModel::ModuleModel(
QObject *parent)
274 : AbstractModel(&context()->d->m_modules, parent)
276 initRoleNames(Module::staticMetaObject);
QString name(StandardAction id)
The primary namespace of PulseAudioQt.
QByteArray & insert(qsizetype i, QByteArrayView data)
char32_t toUpper(char32_t ucs4)
bool isValid() const const
const QChar at(qsizetype position) const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QByteArray toLatin1() const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)