Warning, file /libraries/snorenotify/src/plugins/backends/snoretoast/snoretoast.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 #include "snoretoast.h"
0002 #include "libsnore/snore.h"
0003 #include "libsnore/snore_p.h"
0004 #include "libsnore/utils.h"
0005 
0006 #include "libsnore/plugins/plugins.h"
0007 #include "libsnore/plugins/snorebackend.h"
0008 
0009 #include <QDir>
0010 #include <QGuiApplication>
0011 #include <QSysInfo>
0012 
0013 #include <windows.h>
0014 
0015 bool SnorePlugin::WindowsToast::isReady()
0016 {
0017     if (errorString().isEmpty() && QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8) {
0018         setErrorString(tr("%1 needs at least Windows 8 to run.").arg(name()));
0019         return false;
0020     }
0021     return true;
0022 }
0023 
0024 bool SnorePlugin::WindowsToast::canCloseNotification() const
0025 {
0026     return true;
0027 }
0028 
0029 int SnorePlugin::WindowsToast::maxNumberOfActiveNotifications() const
0030 {
0031     return 1;
0032 }
0033 
0034 void SnorePlugin::WindowsToast::slotNotify(Snore::Notification notification)
0035 {
0036     QProcess *p = createProcess(notification);
0037 
0038     QStringList arguements;
0039     arguements << QLatin1String("-t")
0040                << notification.title()
0041                << QLatin1String("-m")
0042                << notification.text()
0043                << QLatin1String("-p")
0044                << QDir::toNativeSeparators(notification.icon().localUrl(QSize(1024, 1024)))
0045                << QLatin1String("-appID")
0046                << appId(notification.application())
0047                << QLatin1String("-id")
0048                << QString::number(notification.id());
0049     //TODO: could clash with sound backend
0050     if (notification.hints().value("silent").toBool() || notification.hints().value("sound").isValid()) {
0051         arguements << QLatin1String("-silent");
0052     }
0053     qCDebug(SNORE) << "SnoreToast" << arguements;
0054 
0055     connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), [this, notification](int code) {
0056         Snore::Notification::CloseReasons reason = Snore::Notification::None;
0057 
0058         switch (code) {
0059         case 0:
0060             reason = Snore::Notification::Activated;
0061             slotNotificationActionInvoked(notification);
0062             break;
0063         case 1:
0064             //hidden;
0065             break;
0066         case 2:
0067             reason = Snore::Notification::Dismissed;
0068             break;
0069         case 3:
0070             reason = Snore::Notification::TimedOut;
0071             break;
0072         case -1:
0073             //failed
0074             qCWarning(SNORE) << "SnoreToast failed to display " << notification;
0075             break;
0076         }
0077 
0078         closeNotification(notification, reason);
0079     });
0080     p->start(QLatin1String("SnoreToast"), arguements);
0081     slotNotificationDisplayed(notification);
0082 }
0083 
0084 void SnorePlugin::WindowsToast::slotRegisterApplication(const Snore::Application &application)
0085 {
0086     if (!application.constHints().contains("windows-app-id")) {
0087         qCInfo(SNORE) << "No windows-app-id found in hints. Installing default shortcut with appID.";
0088         QProcess *p = createProcess(Snore::Notification());
0089         QStringList arguements;
0090         arguements << QLatin1String("-install")
0091                    << QLatin1String("SnoreNotify\\") + qApp->applicationName()
0092                    << QDir::toNativeSeparators(qApp->applicationFilePath())
0093                    << appId(application);
0094         qCDebug(SNORE) << "SnoreToast" << arguements;
0095         p->start(QLatin1String("SnoreToast"), arguements);
0096     }
0097 }
0098 
0099 void SnorePlugin::WindowsToast::slotCloseNotification(Snore::Notification notification)
0100 {
0101     QProcess *p = createProcess(notification);
0102 
0103     QStringList arguements;
0104     arguements << QLatin1String("-close")
0105                << QString::number(notification.id());
0106     qCDebug(SNORE) << "SnoreToast" << arguements;
0107     p->start(QLatin1String("SnoreToast"), arguements);
0108 }
0109 
0110 QString SnorePlugin::WindowsToast::appId(const Snore::Application &application)
0111 {
0112     QString appID = application.constHints().value("windows-app-id").toString();
0113     if (appID.isEmpty()) {
0114         appID = QString(qApp->organizationName() + QLatin1Char('.') + qApp->applicationName() + QLatin1String(".SnoreToast")).remove(QLatin1Char(' '));
0115     }
0116     return appID;
0117 }
0118 
0119 QProcess *SnorePlugin::WindowsToast::createProcess(Snore::Notification noti)
0120 {
0121     QProcess *p = new QProcess(this);
0122     p->setReadChannelMode(QProcess::MergedChannels);
0123 
0124     connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), [p](int, QProcess::ExitStatus) {
0125         qCDebug(SNORE) << p->readAll();
0126         p->deleteLater();
0127     });
0128 
0129     connect(p, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), [this, p, noti](QProcess::ProcessError) {
0130         setErrorString(name() + p->errorString());
0131         qCDebug(SNORE) << p->readAll();
0132         if (noti.isValid()) {
0133             closeNotification(noti, Snore::Notification::None);
0134         }
0135         p->deleteLater();
0136     });
0137     connect(qApp, &QGuiApplication::aboutToQuit, p, &QProcess::kill);
0138     return p;
0139 }