summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cardwidget.cc137
-rw-r--r--src/cardwidget.h27
-rw-r--r--src/cardwidget.ui53
-rw-r--r--src/mainwindow.cc21
4 files changed, 162 insertions, 76 deletions
diff --git a/src/cardwidget.cc b/src/cardwidget.cc
index d5b4e63..3b4c8b3 100644
--- a/src/cardwidget.cc
+++ b/src/cardwidget.cc
@@ -24,46 +24,59 @@
#include "cardwidget.h"
+#include <QDebug>
+#include <QHash>
+#include <QSet>
+
/*** CardWidget ***/
CardWidget::CardWidget(QWidget* parent) :
QWidget(parent) {
setupUi(this);
connect(profileList, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CardWidget::onProfileChange);
- connect(profileCB, &QAbstractButton::toggled, this, &CardWidget::onProfileCheck);
+ connect(profileFlavorList, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CardWidget::onProfileFlavorChange);
}
void CardWidget::prepareMenu() {
int idx = 0;
- const bool off = activeProfile == noInOutProfile;
profileList->clear();
/* Fill the ComboBox */
- for (const auto & profile : profiles) {
- QByteArray name = profile.first;
- // skip the "off" profile
- if (name == noInOutProfile)
- continue;
- QString desc = QString::fromUtf8(profile.second);
- profileList->addItem(desc, name);
- if (profile.first == activeProfile
- || (off && profile.first == lastActiveProfile)
- )
- {
+ for (auto k : profiles.keys()) {
+ auto & profile = profiles[k];
+ auto desc = profile.getProfileName();
+ profileList->addItem(desc, k);
+ if (profile.containsProfile(activeProfile)) {
profileList->setCurrentIndex(idx);
- lastActiveProfile = profile.first;
+ changeProfile(k);
}
++idx;
}
-
- profileCB->setChecked(!off);
}
-void CardWidget::changeProfile(const QByteArray & name)
+void CardWidget::changeProfile(const QString & name)
{
+ auto &profile = profiles[name];
+ auto old = profileFlavorList->currentText();
+ profileFlavorList->clear();
+ int idx = 0;
+ for (auto & entry : profile.entries) {
+ auto name = entry.getName();
+ profileFlavorList->addItem(name, entry.id);
+ if (name == old || entry.id == activeProfile) {
+ profileFlavorList->setCurrentIndex(idx);
+ }
+ ++idx;
+ }
+ if (profileFlavorList->currentIndex() == -1) {
+ profileFlavorList->setCurrentIndex(0);
+ }
+}
+
+void CardWidget::changeProfileFlavor(const QByteArray & id) {
pa_operation* o;
- if (!(o = pa_context_set_card_profile_by_index(get_context(), index, name.constData(), nullptr, nullptr))) {
+ if (!(o = pa_context_set_card_profile_by_index(get_context(), index, id.constData(), nullptr, nullptr))) {
show_error(tr("pa_context_set_card_profile_by_index() failed").toUtf8().constData());
return;
}
@@ -76,17 +89,91 @@ void CardWidget::onProfileChange(int active) {
return;
if (active != -1)
- changeProfile(profileList->itemData(active).toByteArray());
+ changeProfile(profileList->itemData(active).toString());
}
-void CardWidget::onProfileCheck(bool on)
-{
+void CardWidget::onProfileFlavorChange(int active) {
if (updating)
return;
- if (on)
- onProfileChange(profileList->currentIndex());
- else
- changeProfile(noInOutProfile);
+ if (active != -1)
+ changeProfileFlavor(profileFlavorList->itemData(active).toByteArray());
+}
+
+QString ProfileGroup::getProfileName() {
+ if (!name.isEmpty())
+ return name;
+ // TODO
+ QHash<QString, int> counts;
+ qDebug() << "Entries" << this;
+ for (auto n : entries) {
+ qDebug() << n.tokens;
+ QSet<QString> tmp = n.tokens.toSet(); //(n.tokens.begin(), n.tokens.end());
+ for (auto t : tmp) {
+ counts[t]++;
+ }
+ }
+ qDebug() << counts;
+ QSet<QString> todo = counts.keys().toSet();
+ for (auto &pe : entries) {
+ QMutableListIterator<QString> it(pe.tokens);
+ while (it.hasNext()) {
+ auto s = it.next();
+ if (counts[s] == entries.size()) {
+ it.remove();
+ if (todo.remove(s)) {
+ if (!name.isEmpty()) {
+ name.append(QLatin1Char(' '));
+ }
+ name.append(s);
+ }
+ }
+ }
+ }
+ return name;
+}
+
+void ProfileGroup::addEntry(const char *id, const char *name) {
+ auto *pe = new ProfileEntry;
+ bool paren = false;
+ const char *pos = name, *tokenStart = name;
+ qDebug() << name << "is" << id;
+ while (*pos != '\0') {
+ if (!paren && isspace(*pos)) {
+ if (pos > tokenStart) {
+ qDebug() << tokenStart;
+ pe->tokens.append(QString::fromUtf8(tokenStart, pos - tokenStart));
+ }
+ tokenStart = pos + 1;
+ }
+ if (paren && *pos == ')') {
+ qDebug() << tokenStart;
+ pe->tokens.append(QString::fromUtf8(tokenStart, pos - tokenStart + 1));
+ paren = false;
+ tokenStart = pos + 1;
+ }
+ if (tokenStart == pos && *pos == '(') {
+ paren = true;
+ }
+ pos++;
+ }
+ if (pos > tokenStart) {
+ qDebug() << tokenStart;
+ pe->tokens.append(QString::fromUtf8(tokenStart, pos - tokenStart));
+ }
+ pe->id = id;
+ this->entries.append(*pe);
+ delete pe;
+}
+
+QString ProfileEntry::getName() const {
+ return tokens.join(QLatin1String(" "));
+}
+bool ProfileGroup::containsProfile(const QByteArray &pro) const {
+ for (const auto &e : this->entries) {
+ if (e.id == pro)
+ return true;
+ }
+ return false;
}
diff --git a/src/cardwidget.h b/src/cardwidget.h
index 71f6ebc..7bd87d2 100644
--- a/src/cardwidget.h
+++ b/src/cardwidget.h
@@ -24,6 +24,23 @@
#include "pavucontrol.h"
#include "ui_cardwidget.h"
#include <QWidget>
+#include <QMap>
+#include <QString>
+#include <QList>
+
+struct ProfileEntry {
+ QByteArray id;
+ QStringList tokens;
+ QString getName() const;
+};
+
+struct ProfileGroup {
+ QString name;
+ QList<ProfileEntry> entries;
+ QString getProfileName();
+ void addEntry(const char* id, const char* name);
+ bool containsProfile(const QByteArray &pro) const;
+};
class PortInfo {
public:
@@ -45,20 +62,20 @@ public:
uint32_t index;
bool updating;
- std::vector< std::pair<QByteArray,QByteArray> > profiles;
+
+ QMap<QString, ProfileGroup> profiles;
std::map<QByteArray, PortInfo> ports;
QByteArray activeProfile;
- QByteArray noInOutProfile;
- QByteArray lastActiveProfile;
bool hasSinks;
bool hasSources;
void prepareMenu();
protected:
- void changeProfile(const QByteArray & name);
+ void changeProfile(const QString & name);
+ void changeProfileFlavor(const QByteArray & id);
void onProfileChange(int active);
- void onProfileCheck(bool on);
+ void onProfileFlavorChange(int active);
};
diff --git a/src/cardwidget.ui b/src/cardwidget.ui
index 28ea7ab..a75654b 100644
--- a/src/cardwidget.ui
+++ b/src/cardwidget.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>368</width>
- <height>79</height>
+ <height>106</height>
</rect>
</property>
<property name="windowTitle">
@@ -33,14 +33,7 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="profileHLayout" stretch="0,0,1">
- <item>
- <widget class="QCheckBox" name="profileCB">
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
+ <layout class="QHBoxLayout" name="profileHLayout" stretch="0,1">
<item>
<widget class="QLabel" name="profileLabel">
<property name="text">
@@ -54,6 +47,13 @@
</layout>
</item>
<item>
+ <layout class="QHBoxLayout" name="variantHLayout">
+ <item>
+ <widget class="QComboBox" name="profileFlavorList"/>
+ </item>
+ </layout>
+ </item>
+ <item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -63,38 +63,5 @@
</layout>
</widget>
<resources/>
- <connections>
- <connection>
- <sender>profileCB</sender>
- <signal>toggled(bool)</signal>
- <receiver>profileLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>137</x>
- <y>47</y>
- </hint>
- <hint type="destinationlabel">
- <x>147</x>
- <y>47</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>profileCB</sender>
- <signal>toggled(bool)</signal>
- <receiver>profileList</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>137</x>
- <y>47</y>
- </hint>
- <hint type="destinationlabel">
- <x>315</x>
- <y>47</y>
- </hint>
- </hints>
- </connection>
- </connections>
+ <connections/>
</ui>
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 76e81bf..66c0ac4 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include <QDebug>
#include <set>
#include "mainwindow.h"
@@ -258,9 +259,23 @@ void MainWindow::updateCard(const pa_card_info &info) {
if (!p_profile->available)
desc += tr(" (unavailable)").toUtf8().constData();
- w->profiles.push_back(std::pair<QByteArray,QByteArray>(p_profile->name, desc));
- if (p_profile->n_sinks == 0 && p_profile->n_sources == 0)
- w->noInOutProfile = p_profile->name;
+ QString parseId = QString::fromUtf8(p_profile->name);
+ int plus = parseId.indexOf(QLatin1Char('+'));
+ if (plus != -1) {
+ parseId = parseId.left(plus);
+ }
+ auto list = parseId.split(QRegularExpression(QLatin1String("[:\\-]")));
+ parseId.clear();
+ for (auto p : list) {
+ if (p == QLatin1String("input") || p == QLatin1String("output"))
+ continue;
+ if (parseId.isEmpty() || p.startsWith(QLatin1String("extra"))) {
+ parseId.append(p);
+ }
+ }
+ qDebug() << "ParseID:" << parseId;
+ ProfileGroup &group = w->profiles[parseId];
+ group.addEntry(p_profile->name, desc.constData());
}
w->activeProfile = info.active_profile ? info.active_profile->name : "";