#include "trayicon.h" #include #include #include #include #include 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); }