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()
54AbstractModelPrivate::AbstractModelPrivate(AbstractModel *q,
const MapBaseQObject *map)
60AbstractModelPrivate::~AbstractModelPrivate()
66 if (!d->m_roles.empty()) {
73int AbstractModel::rowCount(
const QModelIndex &parent)
const
78 return d->m_map->count();
83 if (!hasIndex(index.
row(), index.
column())) {
86 QObject *data = d->m_map->objectAt(index.
row());
88 if (role == PulseObjectRole) {
91 return static_cast<PulseObject *
>(data)->
name();
93 int property = d->m_objectProperties.value(role, -1);
102 if (!hasIndex(index.
row(), index.
column())) {
105 int propertyIndex = d->m_objectProperties.
value(role, -1);
106 if (propertyIndex == -1) {
109 QObject *data = d->m_map->objectAt(index.
row());
111 return property.
write(data, value);
114int AbstractModel::role(
const QByteArray &roleName)
const
116 qCDebug(PULSEAUDIOQT) << roleName << d->m_roles.key(roleName, -1);
117 return d->m_roles.key(roleName, -1);
120Context *AbstractModel::context()
const
122 return Context::instance();
125void AbstractModel::initRoleNames(
const QMetaObject &qobjectMetaObject)
127 d->m_roles[PulseObjectRole] = QByteArrayLiteral(
"PulseObject");
130 for (
int i = 0; i < metaObject()->enumeratorCount(); ++i) {
132 enumerator = metaObject()->enumerator(i);
137 for (
int i = 0; i < enumerator.
keyCount(); ++i) {
139 const int roleLength = 4;
142 Q_ASSERT(key.right(roleLength) == QByteArrayLiteral(
"Role"));
143 key.chop(roleLength);
144 d->m_roles[enumerator.
value(i)] = key;
147 int maxEnumValue = -1;
148 for (
auto it = d->m_roles.constBegin(); it != d->m_roles.constEnd(); ++it) {
149 if (it.key() > maxEnumValue) {
150 maxEnumValue = it.key();
153 Q_ASSERT(maxEnumValue != -1);
154 auto mo = qobjectMetaObject;
155 for (
int i = 0; i < mo.propertyCount(); ++i) {
160 d->m_objectProperties.
insert(maxEnumValue, i);
161 if (!property.hasNotifySignal()) {
164 d->m_signalIndexToProperties.
insert(property.notifySignalIndex(), i);
166 qCDebug(PULSEAUDIOQT) << d->m_roles;
169 for (
int i = 0; i < d->m_map->count(); ++i) {
174void AbstractModel::propertyChanged()
176 if (!sender() || senderSignalIndex() == -1) {
179 int propertyIndex = d->m_signalIndexToProperties.value(senderSignalIndex(), -1);
180 if (propertyIndex == -1) {
183 int role = d->m_objectProperties.key(propertyIndex, -1);
187 int index = d->m_map->indexOfObject(sender());
188 qCDebug(PULSEAUDIOQT) <<
"PROPERTY CHANGED (" << index <<
") :: " << role << roleNames().value(role);
189 Q_EMIT dataChanged(createIndex(index, 0), createIndex(index, 0), {role});
192void AbstractModel::onDataAdded(
int index)
194 QObject *data = d->m_map->objectAt(index);
197 const auto keys = d->m_signalIndexToProperties.keys();
198 for (
const auto &index : keys) {
200 connect(data, meth,
this, propertyChangedMetaMethod());
204QMetaMethod AbstractModel::propertyChangedMetaMethod()
const
206 auto mo = metaObject();
208 if (methodIndex == -1) {
211 return mo->
method(methodIndex);
214SinkModel::SinkModel(
QObject *parent)
215 : AbstractModel(&context()->d->m_sinks, parent)
217 initRoleNames(Sink::staticMetaObject);
222 if (role == SortByDefaultRole) {
224 const QString pulseIndex = data(index, AbstractModel::role(QByteArrayLiteral(
"Index"))).toString();
225 const QString defaultDevice = data(index, AbstractModel::role(QByteArrayLiteral(
"Default"))).toString();
226 const QString ret = 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 const QString ret = defaultDevice + pulseIndex;
247 return AbstractModel::data(index, role);
250SinkInputModel::SinkInputModel(
QObject *parent)
251 : AbstractModel(&context()->d->m_sinkInputs, parent)
253 initRoleNames(SinkInput::staticMetaObject);
256SourceOutputModel::SourceOutputModel(
QObject *parent)
257 : AbstractModel(&context()->d->m_sourceOutputs, parent)
259 initRoleNames(SourceOutput::staticMetaObject);
262CardModel::CardModel(
QObject *parent)
263 : AbstractModel(&context()->d->m_cards, parent)
265 initRoleNames(Card::staticMetaObject);
268StreamRestoreModel::StreamRestoreModel(
QObject *parent)
269 : AbstractModel(&context()->d->m_streamRestores, parent)
271 initRoleNames(StreamRestore::staticMetaObject);
274ModuleModel::ModuleModel(
QObject *parent)
275 : AbstractModel(&context()->d->m_modules, parent)
277 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 fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
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)