File indexing completed on 2024-06-16 04:29:30

0001 #include "trayiconnotifer.h"
0002 #include "libsnore/snore.h"
0003 #include "libsnore/snore_p.h"
0004 #include "libsnore/utils.h"
0005 
0006 #include <QSystemTrayIcon>
0007 #include <QApplication>
0008 
0009 SnorePlugin::Trayicon::Trayicon()
0010 {
0011     connect(this, &Trayicon::enabledChanged, [this](bool) {
0012         m_currentlyDisplaying = false;
0013     });
0014 }
0015 
0016 bool SnorePlugin::Trayicon::canCloseNotification() const
0017 {
0018     return true;
0019 }
0020 
0021 void SnorePlugin::Trayicon::slotNotify(Snore::Notification notification)
0022 {
0023     QSystemTrayIcon *icon = trayIcon(notification.application());
0024     if (icon) {
0025         m_notificationQue.append(notification);
0026         displayNotification(icon);
0027     } else {
0028         closeNotification(notification, Snore::Notification::Closed);
0029         setErrorString(QLatin1String("No tray-icon hint provided for ") + notification.application().name());
0030     }
0031 }
0032 
0033 void SnorePlugin::Trayicon::slotCloseNotification(Snore::Notification n)
0034 {
0035     QSystemTrayIcon *icon = trayIcon(n.application());
0036     if (icon) {
0037         qCDebug(SNORE) << n;
0038         m_currentlyDisplaying = false;
0039         displayNotification(icon);
0040     }
0041 }
0042 
0043 void SnorePlugin::Trayicon::slotRegisterApplication(const Snore::Application &application)
0044 {
0045     QSystemTrayIcon *icon = trayIcon(application);
0046     if (icon) {
0047         connect(icon, &QSystemTrayIcon::messageClicked, this, &Trayicon::actionInvoked);
0048     }
0049 }
0050 
0051 void SnorePlugin::Trayicon::slotDeregisterApplication(const Snore::Application &application)
0052 {
0053     QSystemTrayIcon *icon = trayIcon(application);
0054     if (icon) {
0055         disconnect(icon, &QSystemTrayIcon::messageClicked, this, &Trayicon::actionInvoked);
0056     }
0057 }
0058 
0059 QSystemTrayIcon *SnorePlugin::Trayicon::trayIcon(const Snore::Application &app)
0060 {
0061     if (app.constHints().contains("tray-icon")) {
0062         return app.constHints().value("tray-icon").value<QPointer<QSystemTrayIcon>>();
0063     }
0064     return nullptr;
0065 }
0066 
0067 void SnorePlugin::Trayicon::displayNotification(QSystemTrayIcon *icon)
0068 {
0069     Q_ASSERT(icon);
0070     if (m_currentlyDisplaying) {
0071         return;
0072     }
0073     if (m_notificationQue.isEmpty()) {
0074         m_currentlyDisplaying = false;
0075         return;
0076     }
0077     m_currentlyDisplaying = true;
0078     Snore::Notification notification =  m_notificationQue.takeFirst();
0079     m_displayed = notification;
0080     icon->showMessage(notification.title(), notification.text(), QSystemTrayIcon::NoIcon, notification.timeout() * 1000);
0081     slotNotificationDisplayed(notification);
0082 }
0083 
0084 void SnorePlugin::Trayicon::actionInvoked()
0085 {
0086     Snore::Notification n = m_displayed;
0087     QSystemTrayIcon *icon = trayIcon(n.application());
0088     if (icon && n.isValid()) {
0089         slotNotificationActionInvoked(n);
0090         closeNotification(n, Snore::Notification::Activated);
0091         m_currentlyDisplaying = false;
0092         displayNotification(icon);
0093     }
0094 
0095 }
0096 
0097 bool SnorePlugin::Trayicon::isReady()
0098 {
0099     if (!qobject_cast< QApplication * >(qApp)) {
0100         setErrorString(tr("This plugin only works with QApplication"));
0101         return false;
0102     }
0103     return true;
0104 }
0105