File indexing completed on 2024-04-14 14:55:41

0001 /*
0002     SPDX-FileCopyrightText: 2014-2015 Harald Sitter <sitter@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "card.h"
0008 #include "card_p.h"
0009 #include "debug.h"
0010 
0011 #include "context.h"
0012 #include "indexedpulseobject_p.h"
0013 #include "port_p.h"
0014 #include "profile_p.h"
0015 
0016 namespace PulseAudioQt
0017 {
0018 Card::Card(QObject *parent)
0019     : IndexedPulseObject(parent)
0020     , d(new CardPrivate(this))
0021 {
0022     connect(Context::instance(), &Context::sinkAdded, this, &Card::sinksChanged);
0023     connect(Context::instance(), &Context::sinkRemoved, this, &Card::sinksChanged);
0024 
0025     connect(Context::instance(), &Context::sourceAdded, this, &Card::sourcesChanged);
0026     connect(Context::instance(), &Context::sourceRemoved, this, &Card::sourcesChanged);
0027 }
0028 
0029 Card::~Card()
0030 {
0031     delete d;
0032 }
0033 
0034 CardPrivate::CardPrivate(Card *q)
0035     : q(q)
0036 {
0037 }
0038 
0039 CardPrivate::~CardPrivate()
0040 {
0041 }
0042 
0043 void CardPrivate::update(const pa_card_info *info)
0044 {
0045     q->IndexedPulseObject::d->updatePulseObject(info);
0046     q->PulseObject::d->updateProperties(info);
0047 
0048     QStringList newProfiles;
0049     QStringList existingProfiles;
0050 
0051     for (const Profile *profile : qAsConst(m_profiles)) {
0052         existingProfiles << profile->name();
0053     }
0054 
0055     for (auto **it = info->profiles2; it && *it != nullptr; ++it) {
0056         const QString name = QString::fromUtf8((*it)->name);
0057         newProfiles << name;
0058         Profile *profile = nullptr;
0059         if (existingProfiles.contains(name)) {
0060             profile = m_profiles[existingProfiles.indexOf(name)];
0061         } else {
0062             profile = new Profile(q);
0063             m_profiles << profile;
0064         }
0065         profile->d->setInfo(*it);
0066     }
0067 
0068     QMutableListIterator<Profile *> it(m_profiles);
0069     while (it.hasNext()) {
0070         Profile *profile = it.next();
0071 
0072         if (!newProfiles.contains(profile->name())) {
0073             it.remove();
0074             delete profile;
0075         }
0076     }
0077 
0078     for (Profile *profile : qAsConst(m_profiles)) {
0079         if (info->active_profile2->name == profile->name()) {
0080             m_activeProfileIndex = m_profiles.indexOf(profile);
0081         }
0082     }
0083 
0084     Q_EMIT q->profilesChanged();
0085     Q_EMIT q->activeProfileIndexChanged();
0086 
0087     QStringList newPorts;
0088     QStringList existingPorts;
0089 
0090     for (const Port *port : qAsConst(m_ports)) {
0091         existingPorts << port->name();
0092     }
0093     for (auto **it = info->ports; it && *it != nullptr; ++it) {
0094         const QString name = QString::fromUtf8((*it)->name);
0095         newPorts << name;
0096         CardPort *port = nullptr;
0097         if (existingPorts.contains(name)) {
0098             port = m_ports[existingPorts.indexOf(name)];
0099         } else {
0100             port = new CardPort(q);
0101             m_ports << port;
0102         }
0103         port->d->setInfo(*it);
0104     }
0105 
0106     for (CardPort *port : qAsConst(m_ports)) {
0107         if (!newPorts.contains(port->name())) {
0108             m_ports.removeOne(port);
0109             delete port;
0110         }
0111     }
0112 
0113     Q_EMIT q->portsChanged();
0114 }
0115 
0116 QList<Profile *> Card::profiles() const
0117 {
0118     return d->m_profiles;
0119 }
0120 
0121 quint32 Card::activeProfileIndex() const
0122 {
0123     return d->m_activeProfileIndex;
0124 }
0125 
0126 void Card::setActiveProfileIndex(quint32 profileIndex)
0127 {
0128     const Profile *profile = qobject_cast<Profile *>(profiles().at(profileIndex));
0129     Context::instance()->setCardProfile(index(), profile->name());
0130 }
0131 
0132 QList<CardPort *> Card::ports() const
0133 {
0134     return d->m_ports;
0135 }
0136 
0137 QList<Sink *> Card::sinks() const
0138 {
0139     QList<Sink *> ret;
0140 
0141     const auto allSinks = Context::instance()->sinks();
0142     for (Sink *sink : allSinks) {
0143         if (sink->cardIndex() == IndexedPulseObject::d->m_index) {
0144             ret << sink;
0145         }
0146     }
0147 
0148     return ret;
0149 }
0150 
0151 QList<Source *> Card::sources() const
0152 {
0153     QList<Source *> ret;
0154 
0155     const auto allSources = Context::instance()->sources();
0156     for (Source *source : allSources) {
0157         if (source->cardIndex() == IndexedPulseObject::d->m_index) {
0158             ret << source;
0159         }
0160     }
0161 
0162     return ret;
0163 }
0164 
0165 } // PulseAudioQt