summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2022-08-31 15:58:15 +0200
committerSimon Rettberg2022-08-31 15:58:15 +0200
commitda330b0a0ab5426b1502f2f97254478940f1f094 (patch)
treec175727f9aa50972984496a6914f2257c50fe003
parentBig refactor, minor design tweak along the way (diff)
downloadpavucontrol-slx-da330b0a0ab5426b1502f2f97254478940f1f094.tar.gz
pavucontrol-slx-da330b0a0ab5426b1502f2f97254478940f1f094.tar.xz
pavucontrol-slx-da330b0a0ab5426b1502f2f97254478940f1f094.zip
WIP: Support input too
TODO: Layout, UI, etc.
-rw-r--r--src/main.cpp225
-rw-r--r--src/main.h4
-rw-r--r--src/mainwindow.cpp41
-rw-r--r--src/mainwindow.h6
-rw-r--r--src/mainwindow.ui19
-rw-r--r--src/slxoutput.cpp6
-rw-r--r--src/slxoutput.h3
7 files changed, 231 insertions, 73 deletions
diff --git a/src/main.cpp b/src/main.cpp
index adf515b..cc149a4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -28,8 +28,10 @@ bool g_IgnoreGui;
// Private
-/** If not empty, on profile change, if profile belings to this card, make its sink default */
-static QString _pendingCardDefault;
+/** If not empty, on profile change, if profile belongs to this card, make its sink default */
+static QString _pendingCardDefaultId;
+/** If not empty, on sink appearance, if port belongs to this sink, make it sink's default */
+static QString _pendingCardDefaultPort;
/** While running, we want to set each port's volume to 100% the first time we see it. Unfortunately
* a port only startes to exist once its according profile is selected, so there is no way to have
@@ -55,6 +57,31 @@ static void queueGuiUpdate(int ms = 50)
_updateDelay.start(ms);
}
+static void addDevicePortToWindow(PulseAudioQt::Card *card, PulseAudioQt::Device *device, PulseAudioQt::Port *port, int portIndex, bool isOutput)
+{
+ //if (port->availability() == PulseAudioQt::Port::Unavailable)
+ // continue;
+ bool portIsActive = portIndex == device->activePortIndex();
+ bool defaultSinkAndPort = (device->isDefault() && portIsActive);
+ qint64 volume = device->volume();
+ printf("[%c] Output: '%s %s', volume: %d, mute: %d\n",
+ defaultSinkAndPort ? 'x' : ' ',
+ device->description().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(),
+ (int)volume, (int)device->isMuted());
+ QString id = device->name() + port->name();
+ // Only once, update port volume to be 100% if it's low
+ if (defaultSinkAndPort && !_donePorts.contains(id)) {
+ _donePorts.insert(id);
+ if (volume < 60000) {
+ volume = 65535;
+ device->setVolume(volume);
+ }
+ }
+ //knownCardPortCombos.insert(card->name() + ":" + port->name());
+ _mainWindow->getDevice(card, device, port, isOutput)->updateDeviceAndPort(defaultSinkAndPort, device->isMuted(),
+ (portIsActive && device->isVolumeWritable()) ? device->volume() : -1);
+}
+
/**
* The actual GUI update logic. Iterate over all sinks and their ports, and add them to the GUI.
* Then iterate over all non-selected profiles, and add them to the GUI too, so we have a simple, flat
@@ -69,6 +96,7 @@ static void updateActiveOutput()
auto cards = i->cards();
printf(".--------------------------------------------.\n");
+ //QSet<QString> knownCardPortCombos;
for (auto *sink : i->sinks()) {
PulseAudioQt::Card *card = nullptr;
if (sink->cardIndex() < cards.size()) {
@@ -77,30 +105,34 @@ static void updateActiveOutput()
int portIndex = -1;
for (auto *port : sink->ports()) {
portIndex++;
- //if (port->availability() == PulseAudioQt::Port::Unavailable)
- // continue;
- bool portIsActive = portIndex == sink->activePortIndex();
- bool defaultSinkAndPort = (sink->isDefault() && portIsActive);
- qint64 volume = sink->volume();
- printf("[%c] Output: '%s %s', volume: %d, mute: %d\n",
- defaultSinkAndPort ? 'x' : ' ',
- sink->description().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(),
- (int)volume, (int)sink->isMuted());
- QString id = sink->name() + port->name();
- // Only once, update port volume to be 100% if it's low
- if (defaultSinkAndPort && !_donePorts.contains(id)) {
- _donePorts.insert(id);
- if (volume < 60000) {
- volume = 65535;
- sink->setVolume(volume);
- }
- }
- _mainWindow->getDevice(card, sink, port)->updateDeviceAndPort(defaultSinkAndPort, sink->isMuted(),
- (portIsActive && sink->isVolumeWritable()) ? sink->volume() : -1);
+ addDevicePortToWindow(card, sink, port, portIndex, true);
+ }
+ }
+ for (auto *source : i->sources()) {
+ PulseAudioQt::Card *card = nullptr;
+ if (source->cardIndex() < cards.size()) {
+ card = cards.at(source->cardIndex());
+ }
+ int portIndex = -1;
+ for (auto *port : source->ports()) {
+ portIndex++;
+ addDevicePortToWindow(card, source, port, portIndex, false);
}
}
// Now find all the profiles from all cards that are not active and add an entry to the list for each one
for (auto *card : cards) {
+ /*
+ * Don't do this for now - even though we know now that there might be another port for a card that currently
+ * doesn't exist for any of its sinks, we don't know what profile we need to switch to to get a sink with that port.
+ * Rather refactor the UI a little bit to have a card switcher.
+ int portIndex = -1;
+ for (auto *port : card->ports()) {
+ portIndex++;
+ if (knownCardPortCombos.contains(card->name() + ":" + port->name()))
+ continue;
+ _mainWindow->getCardPort(card, port)->updateCardAndProfile();
+ }
+ */
int profIndex = -1;
for (auto *profile : card->profiles()) {
profIndex++;
@@ -108,7 +140,7 @@ static void updateActiveOutput()
if (profIndex == card->activeProfileIndex() || profile->availability() == PulseAudioQt::Profile::Unavailable)
continue;
// No point in selecting something that doesn't have any way to output sound
- if (profile->sinks() == 0)
+ if (profile->sinks() == 0 && profile->sources() == 0)
continue;
printf("[ ] Output: '%s', sinks: %d\n",
profile->description().toLocal8Bit().constData(), profile->sinks());
@@ -121,22 +153,40 @@ static void updateActiveOutput()
}
/**
+ * Called some time after the user changed to a profile/port that was not enabled at the time of clicking, so
+ * wait for PA state to update and then set the port as default port.
+ */
+static void checkShouldSetDefaultPort(PulseAudioQt::Device *sink)
+{
+ if (_pendingCardDefaultPort.isEmpty())
+ return;
+ int portIdx = -1;
+ for (auto *port : sink->ports()) {
+ portIdx++;
+ if (port->name() == _pendingCardDefaultPort) {
+ _pendingCardDefaultPort.clear();
+ sink->setActivePortIndex(portIdx);
+ }
+ }
+}
+
+/**
* Called after the user set a GUI entry as default that represents a profile, after the active profile
* or the list of available ports changed. Only after this happened can we actually set as default the sink/port
* that was created from selecting that profile as the default sink.
*/
-static void checkShouldSetDefault()
+static void checkShouldSetDefaultSink()
{
- if (_pendingCardDefault.isEmpty()) // No switch actually pending
+ if (_pendingCardDefaultId.isEmpty()) // No switch actually pending
return;
// Otherwise, it's the ID of the card that the profile belongs to that the user wants to set as default
- printf("Pending card default to %s\n", _pendingCardDefault.toLocal8Bit().constData());
+ printf("Pending card default to %s\n", _pendingCardDefaultId.toLocal8Bit().constData());
auto *i = PulseAudioQt::Context::instance();
int cardIdx = -1;
// Find the current index of that card
for (auto *card : i->cards()) {
cardIdx++;
- if (card->name() == _pendingCardDefault && !card->ports().isEmpty())
+ if (card->name() == _pendingCardDefaultId && !card->ports().isEmpty())
break;
}
// Then iterate over all sinks until we find one that belongs to the card
@@ -146,7 +196,8 @@ static void checkShouldSetDefault()
// Set as default, unmute, and clear the pending switch
sink->setDefault(true);
sink->setMuted(false);
- _pendingCardDefault.clear();
+ _pendingCardDefaultId.clear();
+ checkShouldSetDefaultPort(sink);
}
}
}
@@ -164,12 +215,12 @@ static void newCardAppeared(PulseAudioQt::Card *card)
});
QCoreApplication::connect(card, &PulseAudioQt::Card::activeProfileIndexChanged, [=]() {
printf("Card %p active profile index changed\n", card);
- checkShouldSetDefault();
+ checkShouldSetDefaultSink();
queueGuiUpdate();
});
QCoreApplication::connect(card, &PulseAudioQt::Card::portsChanged, [=]() {
printf("Card %p ports changed\n", card);
- checkShouldSetDefault();
+ checkShouldSetDefaultSink();
queueGuiUpdate();
});
/*
@@ -180,39 +231,47 @@ static void newCardAppeared(PulseAudioQt::Card *card)
}
/**
- * Called when PA tells us about a new sink; start listening to signals we're interested in.
+ * Called when PA tells us about a new device; start listening to signals we're interested in.
*/
-static void newSinkAppeared(PulseAudioQt::Sink *sink)
+static void newDeviceAppeared(PulseAudioQt::Device *device)
{
- for (auto *port : sink->ports()) {
- printf(" Port: %s\n", port->name().toLocal8Bit().constData());
- }
- QCoreApplication::connect(sink, &PulseAudioQt::Sink::activePortIndexChanged, [=]() {
- printf("Sink %p changed active port\n", sink);
+ QCoreApplication::connect(device, &PulseAudioQt::Sink::activePortIndexChanged, [device]() {
+ printf("Sink %p changed active port\n", device);
queueGuiUpdate();
});
- QCoreApplication::connect(sink, &PulseAudioQt::Sink::defaultChanged, [=]() {
- printf("Sink %p changed default\n", sink);
+ QCoreApplication::connect(device, &PulseAudioQt::Sink::defaultChanged, [device]() {
+ printf("Sink %p changed default\n", device);
queueGuiUpdate();
});
- QCoreApplication::connect(sink, &PulseAudioQt::Sink::volumeChanged, [=]() {
+ QCoreApplication::connect(device, &PulseAudioQt::Sink::portsChanged, [device]() {
+ printf("Sink %p ports changed\n", device);
+ checkShouldSetDefaultPort(device);
queueGuiUpdate();
});
- QCoreApplication::connect(sink, &PulseAudioQt::Sink::isVolumeWritableChanged, [=]() {
+ QCoreApplication::connect(device, &PulseAudioQt::Sink::volumeChanged, [device]() {
+ queueGuiUpdate(250);
+ });
+ QCoreApplication::connect(device, &PulseAudioQt::Sink::isVolumeWritableChanged, [device]() {
queueGuiUpdate();
});
+ checkShouldSetDefaultPort(device);
queueGuiUpdate();
}
/**
- * Mute/unmute sink by its string identifier.
+ * Mute/unmute device by its string identifier.
*/
-void setMuted(const QString &sink, bool muted)
+void setMuted(const QString &deviceId, bool muted)
{
auto *i = PulseAudioQt::Context::instance();
for (auto *sp : i->sinks()) {
- if (sp->name() == sink) {
+ if (sp->name() == deviceId) {
+ sp->setMuted(muted);
+ }
+ }
+ for (auto *sp : i->sources()) {
+ if (sp->name() == deviceId) {
sp->setMuted(muted);
}
}
@@ -220,14 +279,20 @@ void setMuted(const QString &sink, bool muted)
}
/**
- * Set a sink's volume, by its string identifier.
+ * Set a device's volume, by its string identifier.
*/
-void setSinkVolume(const QString &sink, int volume)
+void setSinkVolume(const QString &deviceId, int volume)
{
auto *i = PulseAudioQt::Context::instance();
for (auto *sp : i->sinks()) {
- if (sp->name() == sink) {
+ if (sp->name() == deviceId) {
+ sp->setVolume(volume);
+ queueGuiUpdate(250);
+ }
+ }
+ for (auto *sp : i->sources()) {
+ if (sp->name() == deviceId) {
sp->setVolume(volume);
queueGuiUpdate(250);
}
@@ -240,14 +305,15 @@ void setSinkVolume(const QString &sink, int volume)
* to use a profile that contains the string "Duplex" in its name,
* otherwise, just use the first profile available.
*/
-void enableCard(const QString &card, const QString &profile)
+void enableCard(const QString &card, const QString &profile, const QString &port)
{
auto *i = PulseAudioQt::Context::instance();
PulseAudioQt::Card *matchingCard = nullptr;
int profileIdx = -1;
int cardIdx = -1;
- _pendingCardDefault.clear();
+ _pendingCardDefaultId.clear();
+ _pendingCardDefaultPort.clear();
for (auto *cp : i->cards()) {
cardIdx++;
if (cp->name() != card)
@@ -280,18 +346,28 @@ void enableCard(const QString &card, const QString &profile)
}
if (matchingCard != nullptr && profileIdx < matchingCard->profiles().size()) {
if (matchingCard->activeProfileIndex() == profileIdx) {
+ // Profile already active, just unmute sink
for (auto *sink : i->sinks()) {
if (sink->cardIndex() == cardIdx) {
sink->setMuted(false);
sink->setDefault(true);
+ _pendingCardDefaultPort = port;
+ checkShouldSetDefaultPort(sink);
+ }
+ }
+ for (auto *source : i->sources()) {
+ if (source->cardIndex() == cardIdx) {
+ source->setMuted(false);
+ source->setDefault(true);
}
}
} else {
- matchingCard->setActiveProfileIndex(profileIdx);
// Remember the ID of the card we switched to; we need this as only after PA is done
// switching to the desired profile will we see any sink belonging to it, so we can only
// set the according sink as fallback after that happens. See checkShouldSetDefault().
- _pendingCardDefault = matchingCard->name();
+ _pendingCardDefaultId = matchingCard->name();
+ _pendingCardDefaultPort = port;
+ matchingCard->setActiveProfileIndex(profileIdx);
}
}
queueGuiUpdate();
@@ -306,7 +382,8 @@ void enableSink(const QString &sink, const QString &port)
{
auto *i = PulseAudioQt::Context::instance();
- _pendingCardDefault.clear();
+ _pendingCardDefaultId.clear();
+ _pendingCardDefaultPort.clear();
for (auto *sp : i->sinks()) {
if (sp->name() != sink)
continue;
@@ -323,6 +400,33 @@ void enableSink(const QString &sink, const QString &port)
queueGuiUpdate();
}
+/**
+ * Set given source as default source, unmute it, and switch to its
+ * port as passed to this function. If the source doesn't have a
+ * port with this ID, nothing happens.
+ */
+void enableSource(const QString &source, const QString &port)
+{
+ auto *i = PulseAudioQt::Context::instance();
+
+ _pendingCardDefaultId.clear();
+ _pendingCardDefaultPort.clear();
+ for (auto *sp : i->sources()) {
+ if (sp->name() != source)
+ continue;
+ int i = -1;
+ for (auto *pp : sp->ports()) {
+ i++;
+ if (pp->name() == port) {
+ sp->setDefault(true);
+ sp->setMuted(false);
+ sp->setActivePortIndex(i);
+ }
+ }
+ }
+ queueGuiUpdate();
+}
+
int main(int argc, char **argv)
{
QApplication a(argc, argv);
@@ -341,15 +445,26 @@ int main(int argc, char **argv)
printf(" Profile: %s\n", profile->name().toLocal8Bit().constData());
}
for (auto *port : card->ports()) {
- printf(" Port: %s\n", port->name().toLocal8Bit().constData());
+ printf(" Port: %s -- %s (%i)\n", port->name().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(), (int)port->availability());
}
}
for (auto *sink : i->sinks()) {
printf("Sink: %s (for card index %d)\n", sink->name().toLocal8Bit().constData(), sink->cardIndex());
- newSinkAppeared(sink);
+ for (auto *port : sink->ports()) {
+ printf(" Port: %s -- %s (%i)\n", port->name().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(), (int)port->availability());
+ }
+ newDeviceAppeared(sink);
+ }
+ for (auto *source : i->sources()) {
+ printf("Source: %s (for card index %d)\n", source->name().toLocal8Bit().constData(), source->cardIndex());
+ for (auto *port : source->ports()) {
+ printf(" Port: %s -- %s (%i)\n", port->name().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(), (int)port->availability());
+ }
+ newDeviceAppeared(source);
}
QCoreApplication::connect(i, &PulseAudioQt::Context::cardAdded, &newCardAppeared);
- QCoreApplication::connect(i, &PulseAudioQt::Context::sinkAdded, &newSinkAppeared);
+ QCoreApplication::connect(i, &PulseAudioQt::Context::sinkAdded, &newDeviceAppeared);
+ QCoreApplication::connect(i, &PulseAudioQt::Context::sourceAdded, &newDeviceAppeared);
printf("Initial output\n");
queueGuiUpdate();
});
diff --git a/src/main.h b/src/main.h
index 7402d6e..343f452 100644
--- a/src/main.h
+++ b/src/main.h
@@ -9,8 +9,10 @@ void setMuted(const QString &sink, bool muted);
void setSinkVolume(const QString &sink, int volume);
-void enableCard(const QString &card, const QString &profile);
+void enableCard(const QString &card, const QString &profile, const QString &port);
void enableSink(const QString &sink, const QString &port);
+void enableSource(const QString &source, const QString &port);
+
#endif
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index b35a8f9..0fc6341 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -10,6 +10,8 @@ MainWindow::MainWindow() : QDialog()
{
setupUi(this);
setWindowFlags(Qt::WindowStaysOnTopHint | windowFlags());
+ outputTab->setLayout(new QVBoxLayout(outputTab));
+ inputTab->setLayout(new QVBoxLayout(inputTab));
}
MainWindow::~MainWindow()
@@ -17,11 +19,11 @@ MainWindow::~MainWindow()
}
-SlxOutput* MainWindow::getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Sink *sink, const PulseAudioQt::Port *port)
+SlxOutput* MainWindow::getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Device *device, const PulseAudioQt::Port *port, bool output)
{
PulseAudioQt::Profile *profile = nullptr;
QString cardId;
- QString id = sink->name() + port->name();
+ QString id = device->name() + port->name();
SlxOutput* w = _widgets.value(id, nullptr);
QString heading = port->description();
@@ -37,8 +39,8 @@ SlxOutput* MainWindow::getDevice(const PulseAudioQt::Card *card, const PulseAudi
return w;
}
- w = new SlxOutput(SlxOutput::SinkPortItem, id, cardId, QLatin1String(), sink->name(), port->name(),
- heading, sink->description());
+ w = new SlxOutput(output ? SlxOutput::SinkPortItem : SlxOutput::SourcePortItem, id, cardId, QLatin1String(), device->name(), port->name(),
+ heading, device->description());
_widgets.insert(id, w);
insertItemWidget(w, true);
@@ -47,7 +49,6 @@ SlxOutput* MainWindow::getDevice(const PulseAudioQt::Card *card, const PulseAudi
SlxOutput* MainWindow::getCardProfile(const PulseAudioQt::Card *card, const PulseAudioQt::Profile *profile)
{
-
QString id = card->name() + profile->name();
SlxOutput* w = _widgets.value(id, nullptr);
if (w != nullptr)
@@ -61,22 +62,40 @@ SlxOutput* MainWindow::getCardProfile(const PulseAudioQt::Card *card, const Puls
return w;
}
+SlxOutput* MainWindow::getCardPort(const PulseAudioQt::Card *card, const PulseAudioQt::Port *port)
+{
+ QString id = card->name() + port->name();
+ SlxOutput* w = _widgets.value(id, nullptr);
+ if (w != nullptr)
+ return w;
+
+ w = new SlxOutput(SlxOutput::CardProfileItem, id, card->name(), port->name(), QLatin1String(), QLatin1String(),
+ port->description(), card->description());
+ _widgets.insert(id, w);
+
+ insertItemWidget(w, false);
+ return w;
+}
+
void MainWindow::insertItemWidget(SlxOutput* w, bool isDevice)
{
bool done = false;
int idx;
+ QBoxLayout *container;
+ if (w->type() == SlxOutput::CardProfileItem) {
+ container = cards;
+ } else if (w->type() == SlxOutput::SinkPortItem) {
+ container = qobject_cast<QBoxLayout*>(outputTab->layout());
+ } else {
+ container = qobject_cast<QBoxLayout*>(inputTab->layout());
+ }
for (idx = 0; idx < container->count(); ++idx) {
auto *l = container->itemAt(idx);
SlxOutput *other = qobject_cast<SlxOutput*>(l->widget());
if (other == nullptr)
continue;
printf(" Comparing %s - %s\n", other->isDevice() ? "SINK" : "PROF", other->nameLabel->text().toLocal8Bit().constData());
- if (isDevice != other->isDevice()) {
- if (isDevice)
- break;
- continue;
- }
if (w->compareTo(other) < 0) {
done = true;
printf("Inserting before that (%d)!\n", idx);
@@ -98,6 +117,7 @@ void MainWindow::insertItemWidget(SlxOutput* w, bool isDevice)
*/
void MainWindow::mark()
{
+ setUpdatesEnabled(false);
for (auto *w : _widgets) {
w->unused = true;
}
@@ -117,4 +137,5 @@ void MainWindow::sweep()
w->deleteLater();
}
}
+ setUpdatesEnabled(true);
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 6fbe9f2..5eede3f 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -8,9 +8,8 @@
class SlxOutput;
namespace PulseAudioQt {
-class Sink;
+class Device;
class Port;
-class Source;
class Card;
class Profile;
}
@@ -23,8 +22,9 @@ public:
MainWindow();
virtual ~MainWindow();
- SlxOutput* getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Sink *sink, const PulseAudioQt::Port *port);
+ SlxOutput* getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Device *device, const PulseAudioQt::Port *port, bool output);
SlxOutput* getCardProfile(const PulseAudioQt::Card *card, const PulseAudioQt::Profile *profile);
+ SlxOutput* getCardPort(const PulseAudioQt::Card *card, const PulseAudioQt::Port *port);
void insertItemWidget(SlxOutput* w, bool isDevice);
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 80c81d9..af88c18 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -15,7 +15,24 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <layout class="QVBoxLayout" name="container"/>
+ <widget class="QTabWidget" name="inOutTab">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="outputTab">
+ <attribute name="title">
+ <string>Output</string>
+ </attribute>
+ </widget>
+ <widget class="QWidget" name="inputTab">
+ <attribute name="title">
+ <string>Input</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="cards"/>
</item>
<item>
<spacer name="verticalSpacer">
diff --git a/src/slxoutput.cpp b/src/slxoutput.cpp
index 5bc319b..b1da26f 100644
--- a/src/slxoutput.cpp
+++ b/src/slxoutput.cpp
@@ -56,9 +56,11 @@ SlxOutput::SlxOutput(ItemType type, const QString &id,
defaultToggleButton->setChecked(true);
}
if (_type == CardProfileItem) {
- enableCard(_cardId, _profileId);
- } else {
+ enableCard(_cardId, _profileId, _portId);
+ } else if (_type == SinkPortItem) {
enableSink(_deviceId, _portId);
+ } else {
+ enableSource(_deviceId, _portId);
}
});
}
diff --git a/src/slxoutput.h b/src/slxoutput.h
index c175899..4df64fa 100644
--- a/src/slxoutput.h
+++ b/src/slxoutput.h
@@ -28,7 +28,8 @@ public:
void updateCardAndProfile();
const QString &deviceId() const { return _deviceId; }
- const bool isDevice() const { return !_deviceId.isEmpty(); }
+ bool isDevice() const { return !_deviceId.isEmpty(); }
+ ItemType type() const { return _type; }
int compareTo(SlxOutput* other) const
{