pa-card-profile-tray/trayicon.cpp
2018-10-01 20:00:27 +13:00

111 lines
3.1 KiB
C++

#include "trayicon.h"
#include <QMenu>
#include <QApplication>
#include <QAction>
#include <QDebug>
#include <pulse/pulseaudio.h>
TrayIcon::TrayIcon(QObject *parent) :
QSystemTrayIcon(QIcon::fromTheme("preferences-desktop-sound"), parent),
pulse(this)
{
this->menu = new QMenu(); // can only be explicitly owned by a QWidget, not any QObject, so we need to
// manually manage its lifecycle in the d'tor
this->quitAction = new QAction("Quit");
connect(this->quitAction, &QAction::triggered, this, &TrayIcon::on_quitAction_triggered);
this->refreshAction = new QAction("Refresh");
connect(this->refreshAction, &QAction::triggered, this, &TrayIcon::onRefreshAction_triggered);
// Set up basic menu only, will be wiped during refresh
this->menu->addAction(refreshAction);
this->menu->addAction(quitAction);
this->setContextMenu(this->menu); // n.b. does not take ownership
connect(&this->pulse, &QPulse::ConnectionStateChanged, [=]() {
if (pulse.ConnectionState() == PA_CONTEXT_READY) {
refreshData();
}
});
connect(&this->pulse, &QPulse::GotCardInfoList, this, &TrayIcon::onGotPulseCardInfo);
refreshData();
}
TrayIcon::~TrayIcon()
{
for (int i = 0; i < cardMenus.length(); ++i) {
delete cardMenus[i];
}
cardMenus.clear();
delete this->quitAction;
delete this->menu;
}
void TrayIcon::refreshData()
{
// Delete existing card menus, but leave the final clearing for later
for (int i = 0; i < cardMenus.length(); ++i) {
delete cardMenus[i];
}
cardMenus.clear();
// Calling delete() should have removed them from the menu, leaving only the separator / refresh / quit options
pulse.RequestCardInfo();
}
void TrayIcon::on_quitAction_triggered()
{
QApplication::exit(0);
}
void TrayIcon::onRefreshAction_triggered()
{
refreshData();
}
void TrayIcon::onGotPulseCardInfo(const pa_card_info *cardInfo, int eol)
{
if (eol) {
// OK - rebuild the menu
this->menu->clear();
for (int i = 0; i < this->cardMenus.length(); ++i) {
this->menu->addMenu(this->cardMenus[i]);
}
this->menu->addSeparator();
this->menu->addAction(refreshAction);
this->menu->addAction(quitAction);
return;
}
/*
QString name; // = pa_proplist_to_string(cardInfo->proplist);; // copy to QString from internally-managed buffers
if (true) { // 0 != pa_proplist_isempty(cardInfo->proplist) && 1 == pa_proplist_contains(cardInfo->proplist, PA_PROP_DEVICE_DESCRIPTION)) {
name = pa_proplist_gets(cardInfo->proplist, PA_PROP_DEVICE_DESCRIPTION);;
} else {
name = cardInfo->name;
}
*/
/*
QString name(cardInfo->name);
if (name.length() == 0) {
name = tr("Default card");
}
*/
QMenu* cardMenu = new QMenu(name);
for (size_t i = 0; i < cardInfo->n_profiles; ++i) {
auto profileAction = new QAction(cardInfo->profiles[i].description, cardMenu);
cardMenu->addAction(profileAction);
}
this->cardMenus.push_back(cardMenu);
}