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()) {
68 qCDebug(PULSEAUDIOQT) <<
"returning roles" << d->m_roles;
75int AbstractModel::rowCount(
const QModelIndex &parent)
const
80 return d->m_map->count();
85 if (!hasIndex(index.
row(), index.
column())) {
88 QObject *data = d->m_map->objectAt(index.
row());
90 if (role == PulseObjectRole) {
93 return static_cast<PulseObject *
>(data)->
name();
95 int property = d->m_objectProperties.value(role, -1);
104 if (!hasIndex(index.
row(), index.
column())) {
107 int propertyIndex = d->m_objectProperties.
value(role, -1);
108 if (propertyIndex == -1) {
111 QObject *data = d->m_map->objectAt(index.
row());
113 return property.
write(data, value);
116int AbstractModel::role(
const QByteArray &roleName)
const
118 qCDebug(PULSEAUDIOQT) << roleName << d->m_roles.key(roleName, -1);
119 return d->m_roles.key(roleName, -1);
122Context *AbstractModel::context()
const
124 return Context::instance();
127void AbstractModel::initRoleNames(
const QMetaObject &qobjectMetaObject)
129 d->m_roles[PulseObjectRole] = QByteArrayLiteral(
"PulseObject");
132 for (
int i = 0; i < metaObject()->enumeratorCount(); ++i) {
133 if (metaObject()->enumerator(i).name() ==
QLatin1String(
"ItemRole")) {
134 enumerator = metaObject()->enumerator(i);
139 for (
int i = 0; i < enumerator.
keyCount(); ++i) {
141 const int roleLength = 4;
144 Q_ASSERT(key.right(roleLength) == QByteArrayLiteral(
"Role"));
145 key.chop(roleLength);
146 d->m_roles[enumerator.
value(i)] = key;
149 int maxEnumValue = -1;
150 for (
auto it = d->m_roles.constBegin(); it != d->m_roles.constEnd(); ++it) {
151 if (it.key() > maxEnumValue) {
152 maxEnumValue = it.key();
155 Q_ASSERT(maxEnumValue != -1);
156 auto mo = qobjectMetaObject;
157 for (
int i = 0; i < mo.propertyCount(); ++i) {
162 d->m_objectProperties.
insert(maxEnumValue, i);
163 if (!property.hasNotifySignal()) {
166 d->m_signalIndexToProperties.
insert(property.notifySignalIndex(), i);
168 qCDebug(PULSEAUDIOQT) << d->m_roles;
171 for (
int i = 0; i < d->m_map->count(); ++i) {
176void AbstractModel::propertyChanged()
178 if (!sender() || senderSignalIndex() == -1) {
181 int propertyIndex = d->m_signalIndexToProperties.value(senderSignalIndex(), -1);
182 if (propertyIndex == -1) {
185 int role = d->m_objectProperties.key(propertyIndex, -1);
189 int index = d->m_map->indexOfObject(sender());
190 qCDebug(PULSEAUDIOQT) <<
"PROPERTY CHANGED (" << index <<
") :: " << role << roleNames().value(role);
191 Q_EMIT dataChanged(createIndex(index, 0), createIndex(index, 0), {role});
194void AbstractModel::onDataAdded(
int index)
196 QObject *data = d->m_map->objectAt(index);
199 const auto keys = d->m_signalIndexToProperties.keys();
200 for (
const auto &index : keys) {
202 connect(data, meth,
this, propertyChangedMetaMethod());
206QMetaMethod AbstractModel::propertyChangedMetaMethod()
const
208 auto mo = metaObject();
210 if (methodIndex == -1) {
213 return mo->
method(methodIndex);
216SinkModel::SinkModel(
QObject *parent)
217 : AbstractModel(&context()->d->m_sinks, parent)
219 initRoleNames(Sink::staticMetaObject);
224 if (role == SortByDefaultRole) {
226 const QString pulseIndex = data(index, AbstractModel::role(QByteArrayLiteral(
"Index"))).toString();
227 const QString defaultDevice = data(index, AbstractModel::role(QByteArrayLiteral(
"Default"))).toString();
228 return defaultDevice + pulseIndex;
230 return AbstractModel::data(index, role);
233SourceModel::SourceModel(
QObject *parent)
234 : AbstractModel(&context()->d->m_sources, parent)
236 initRoleNames(Source::staticMetaObject);
241 if (role == SortByDefaultRole) {
243 const QString pulseIndex = data(index, AbstractModel::role(QByteArrayLiteral(
"Index"))).toString();
244 const QString defaultDevice = data(index, AbstractModel::role(QByteArrayLiteral(
"Default"))).toString();
245 return 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(StandardShortcut 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)