File indexing completed on 2023-12-03 11:41:42

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     for (Profile *profile : qAsConst(m_profiles)) {
0069         if (!newProfiles.contains(profile->name())) {
0070             m_profiles.removeOne(profile);
0071             delete profile;
0072         }
0073     }
0074 
0075     for (Profile *profile : qAsConst(m_profiles)) {
0076         if (info->active_profile2->name == profile->name()) {
0077             m_activeProfileIndex = m_profiles.indexOf(profile);
0078         }
0079     }
0080 
0081     Q_EMIT q->profilesChanged();
0082     Q_EMIT q->activeProfileIndexChanged();
0083 
0084     QStringList newPorts;
0085     QStringList existingPorts;
0086 
0087     for (const Port *port : qAsConst(m_ports)) {
0088         existingPorts << port->name();
0089     }
0090     for (auto **it = info->ports; it && *it != nullptr; ++it) {
0091         const QString name = QString::fromUtf8((*it)->name);
0092         newPorts << name;
0093         CardPort *port = nullptr;
0094         if (existingPorts.contains(name)) {
0095             port = m_ports[existingPorts.indexOf(name)];
0096         } else {
0097             port = new CardPort(q);
0098             m_ports << port;
0099         }
0100         port->d->setInfo(*it);
0101     }
0102 
0103     for (CardPort *port : qAsConst(m_ports)) {
0104         if (!newPorts.contains(port->name())) {
0105             m_ports.removeOne(port);
0106             delete port;
0107         }
0108     }
0109 
0110     Q_EMIT q->portsChanged();
0111 }
0112 
0113 QList<Profile *> Card::profiles() const
0114 {
0115     return d->m_profiles;
0116 }
0117 
0118 quint32 Card::activeProfileIndex() const
0119 {
0120     return d->m_activeProfileIndex;
0121 }
0122 
0123 void Card::setActiveProfileIndex(quint32 profileIndex)
0124 {
0125     const Profile *profile = qobject_cast<Profile *>(profiles().at(profileIndex));
0126     Context::instance()->setCardProfile(index(), profile->name());
0127 }
0128 
0129 QList<CardPort *> Card::ports() const
0130 {
0131     return d->m_ports;
0132 }
0133 
0134 QList<Sink *> Card::sinks() const
0135 {
0136     QList<Sink *> ret;
0137 
0138     const auto allSinks = Context::instance()->sinks();
0139     for (Sink *sink : allSinks) {
0140         if (sink->cardIndex() == IndexedPulseObject::d->m_index) {
0141             ret << sink;
0142         }
0143     }
0144 
0145     return ret;
0146 }
0147 
0148 QList<Source *> Card::sources() const
0149 {
0150     QList<Source *> ret;
0151 
0152     const auto allSources = Context::instance()->sources();
0153     for (Source *source : allSources) {
0154         if (source->cardIndex() == IndexedPulseObject::d->m_index) {
0155             ret << source;
0156         }
0157     }
0158 
0159     return ret;
0160 }
0161 
0162 } // PulseAudioQt