Allow notifications via D-Bus
This commit is contained in:
parent
a163c3f046
commit
203370f933
|
@ -8,8 +8,8 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
|||
set(META_APP_DESCRIPTION "Tray application for Syncthing")
|
||||
set(META_APP_CATEGORIES "System;Utility;Network;FileTransfer")
|
||||
set(META_VERSION_MAJOR 0)
|
||||
set(META_VERSION_MINOR 1)
|
||||
set(META_VERSION_PATCH 1)
|
||||
set(META_VERSION_MINOR 2)
|
||||
set(META_VERSION_PATCH 0)
|
||||
set(META_VERSION_EXACT_SONAME ON)
|
||||
|
||||
project(${META_PROJECT_NAME})
|
||||
|
|
|
@ -88,6 +88,7 @@ set(REQUIRED_ICONS
|
|||
media-playback-start
|
||||
network-card
|
||||
network-connect
|
||||
network-disconnect
|
||||
network-server
|
||||
preferences-desktop
|
||||
preferences-desktop-icons
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include "./settings.h"
|
||||
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
# include <qtutilities/misc/dbusnotification.h>
|
||||
#endif
|
||||
|
||||
#include <QStringBuilder>
|
||||
#include <QApplication>
|
||||
|
@ -11,6 +14,9 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace Data;
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
using namespace MiscUtils;
|
||||
#endif
|
||||
|
||||
namespace Settings {
|
||||
|
||||
|
@ -74,6 +80,9 @@ void restore()
|
|||
notifyOn.internalErrors = settings.value(QStringLiteral("notifyOnErrors"), notifyOn.internalErrors).toBool();
|
||||
notifyOn.syncComplete = settings.value(QStringLiteral("notifyOnSyncComplete"), notifyOn.syncComplete).toBool();
|
||||
notifyOn.syncthingErrors = settings.value(QStringLiteral("showSyncthingNotifications"), notifyOn.syncthingErrors).toBool();
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
v.dbusNotifications = settings.value(QStringLiteral("dbusNotifications"), DBusNotification::isAvailable()).toBool();
|
||||
#endif
|
||||
auto &appearance = v.appearance;
|
||||
appearance.showTraffic = settings.value(QStringLiteral("showTraffic"), appearance.showTraffic).toBool();
|
||||
appearance.trayMenuSize = settings.value(QStringLiteral("trayMenuSize"), appearance.trayMenuSize).toSize();
|
||||
|
@ -133,6 +142,9 @@ void save()
|
|||
settings.setValue(QStringLiteral("notifyOnErrors"), notifyOn.internalErrors);
|
||||
settings.setValue(QStringLiteral("notifyOnSyncComplete"), notifyOn.syncComplete);
|
||||
settings.setValue(QStringLiteral("showSyncthingNotifications"), notifyOn.syncthingErrors);
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
settings.setValue(QStringLiteral("dbusNotifications"), v.dbusNotifications);
|
||||
#endif
|
||||
const auto &appearance = v.appearance;
|
||||
settings.setValue(QStringLiteral("showTraffic"), appearance.showTraffic);
|
||||
settings.setValue(QStringLiteral("trayMenuSize"), appearance.trayMenuSize);
|
||||
|
|
|
@ -77,6 +77,9 @@ struct Settings
|
|||
bool firstLaunch = false;
|
||||
Connection connection;
|
||||
NotifyOn notifyOn;
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
bool dbusNotifications = false;
|
||||
#endif
|
||||
Appearance appearance;
|
||||
Launcher launcher;
|
||||
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::NotificationsOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::NotificationsOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>240</width>
|
||||
<height>193</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Notifications</string>
|
||||
</property>
|
||||
|
@ -19,44 +11,63 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="notifyOnLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<widget class="QGroupBox" name="notifyOnGroupBox">
|
||||
<property name="title">
|
||||
<string>Notify on</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnDisconnectCheckBox">
|
||||
<property name="text">
|
||||
<string>disconnect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnErrorsCheckBox">
|
||||
<property name="text">
|
||||
<string>internal errors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showSyncthingNotificationsCheckBox">
|
||||
<property name="text">
|
||||
<string>errors/notifications from Syncthing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnSyncCompleteCheckBox">
|
||||
<property name="text">
|
||||
<string>sync complete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnDisconnectCheckBox">
|
||||
<property name="text">
|
||||
<string>disconnect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnErrorsCheckBox">
|
||||
<property name="text">
|
||||
<string>internal errors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showSyncthingNotificationsCheckBox">
|
||||
<property name="text">
|
||||
<string>errors/notifications from Syncthing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnSyncCompleteCheckBox">
|
||||
<property name="text">
|
||||
<string>sync complete</string>
|
||||
<widget class="QGroupBox" name="apiGroupBox">
|
||||
<property name="title">
|
||||
<string>Notification API</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="dbusRadioButton">
|
||||
<property name="text">
|
||||
<string>D-Bus notifi&cations (org.freedesktop.Notifications)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="qtRadioButton">
|
||||
<property name="text">
|
||||
<string>&Method provided by Qt (might be overridden by QPA plugin)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include <qtutilities/settingsdialog/optioncategory.h>
|
||||
#include <qtutilities/settingsdialog/optioncategorymodel.h>
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
# include <qtutilities/misc/dbusnotification.h>
|
||||
#endif
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
@ -35,6 +38,9 @@ using namespace std::placeholders;
|
|||
using namespace Settings;
|
||||
using namespace Dialogs;
|
||||
using namespace Data;
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
using namespace MiscUtils;
|
||||
#endif
|
||||
|
||||
namespace QtGui {
|
||||
|
||||
|
@ -232,14 +238,21 @@ NotificationsOptionPage::~NotificationsOptionPage()
|
|||
|
||||
bool NotificationsOptionPage::apply()
|
||||
{
|
||||
bool ok = true;
|
||||
if(hasBeenShown()) {
|
||||
auto ¬ifyOn = values().notifyOn;
|
||||
notifyOn.disconnect = ui()->notifyOnDisconnectCheckBox->isChecked();
|
||||
notifyOn.internalErrors = ui()->notifyOnErrorsCheckBox->isChecked();
|
||||
notifyOn.syncComplete = ui()->notifyOnSyncCompleteCheckBox->isChecked();
|
||||
notifyOn.syncthingErrors = ui()->showSyncthingNotificationsCheckBox->isChecked();
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
if((values().dbusNotifications = ui()->dbusRadioButton->isChecked()) && !DBusNotification::isAvailable()) {
|
||||
errors() << QCoreApplication::translate("QtGui::NotificationsOptionPage", "Configured to use D-Bus notifications but D-Bus notification daemon seems unavailabe.");
|
||||
ok = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
return ok;
|
||||
}
|
||||
|
||||
void NotificationsOptionPage::reset()
|
||||
|
@ -250,6 +263,12 @@ void NotificationsOptionPage::reset()
|
|||
ui()->notifyOnErrorsCheckBox->setChecked(notifyOn.internalErrors);
|
||||
ui()->notifyOnSyncCompleteCheckBox->setChecked(notifyOn.syncComplete);
|
||||
ui()->showSyncthingNotificationsCheckBox->setChecked(notifyOn.syncthingErrors);
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
(values().dbusNotifications ? ui()->dbusRadioButton : ui()->qtRadioButton)->setChecked(true);
|
||||
#else
|
||||
ui()->dbusRadioButton->setEnabled(false);
|
||||
ui()->qtRadioButton->setChecked(true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
using namespace std;
|
||||
using namespace Dialogs;
|
||||
using namespace Data;
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
using namespace MiscUtils;
|
||||
#endif
|
||||
|
||||
namespace QtGui {
|
||||
|
||||
|
@ -34,6 +37,13 @@ TrayIcon::TrayIcon(QObject *parent) :
|
|||
m_statusIconErrorSync(QIcon(renderSvgImage(QStringLiteral(":/icons/hicolor/scalable/status/syncthing-error-sync.svg")))),
|
||||
m_trayMenu(this),
|
||||
m_status(SyncthingStatus::Disconnected)
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
,
|
||||
m_disconnectedNotification(QCoreApplication::applicationName(), QStringLiteral("network-disconnect"), 5000),
|
||||
m_internalErrorNotification(QCoreApplication::applicationName() + tr(" - internal error"), NotificationIcon::Critical, 5000),
|
||||
m_syncthingNotification(tr("Syncthing notification"), NotificationIcon::Warning, 10000),
|
||||
m_syncCompleteNotification(QCoreApplication::applicationName(), NotificationIcon::Information, 5000)
|
||||
#endif
|
||||
{
|
||||
// set context menu
|
||||
connect(m_contextMenu.addAction(QIcon::fromTheme(QStringLiteral("internet-web-browser"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/internet-web-browser.svg"))), tr("Web UI")), &QAction::triggered, m_trayMenu.widget(), &TrayWidget::showWebUi);
|
||||
|
@ -45,13 +55,22 @@ TrayIcon::TrayIcon(QObject *parent) :
|
|||
connect(m_contextMenu.addAction(QIcon::fromTheme(QStringLiteral("window-close"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/window-close.svg"))), tr("Close")), &QAction::triggered, this, &TrayIcon::deleteLater);
|
||||
setContextMenu(&m_contextMenu);
|
||||
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
// setup notifications
|
||||
m_disconnectedNotification.setMessage(tr("Disconnected from Syncthing"));
|
||||
m_disconnectedNotification.setActions(QStringList(tr("Try to reconnect")));
|
||||
connect(&m_disconnectedNotification, &DBusNotification::actionInvoked, &(m_trayMenu.widget()->connection()), &SyncthingConnection::connect);
|
||||
m_syncthingNotification.setActions(QStringList({QStringLiteral("show"), tr("Show"), QStringLiteral("dismiss"), tr("Dismiss")}));
|
||||
connect(&m_syncthingNotification, &DBusNotification::actionInvoked, this, &TrayIcon::handleSyncthingNotificationAction);
|
||||
#endif
|
||||
|
||||
// set initial status
|
||||
updateStatusIconAndText(SyncthingStatus::Disconnected);
|
||||
|
||||
// connect signals and slots
|
||||
SyncthingConnection *connection = &(m_trayMenu.widget()->connection());
|
||||
connect(this, &TrayIcon::activated, this, &TrayIcon::handleActivated);
|
||||
connect(this, &TrayIcon::messageClicked, this, &TrayIcon::handleMessageClicked);
|
||||
connect(this, &TrayIcon::messageClicked, m_trayMenu.widget(), &TrayWidget::dismissNotifications);
|
||||
connect(connection, &SyncthingConnection::error, this, &TrayIcon::showInternalError);
|
||||
connect(connection, &SyncthingConnection::newNotification, this, &TrayIcon::showSyncthingNotification);
|
||||
connect(connection, &SyncthingConnection::statusChanged, this, &TrayIcon::updateStatusIconAndText);
|
||||
|
@ -79,23 +98,44 @@ void TrayIcon::handleActivated(QSystemTrayIcon::ActivationReason reason)
|
|||
}
|
||||
}
|
||||
|
||||
void TrayIcon::handleMessageClicked()
|
||||
void TrayIcon::handleSyncthingNotificationAction(const QString &action)
|
||||
{
|
||||
m_trayMenu.widget()->dismissNotifications();
|
||||
if(action == QLatin1String("dismiss")) {
|
||||
m_trayMenu.widget()->dismissNotifications();
|
||||
|
||||
} else if(action == QLatin1String("show")) {
|
||||
m_trayMenu.widget()->showNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
void TrayIcon::showInternalError(const QString &errorMsg)
|
||||
{
|
||||
if(Settings::values().notifyOn.internalErrors) {
|
||||
showMessage(tr("Error"), errorMsg, QSystemTrayIcon::Critical);
|
||||
const auto &settings = Settings::values();
|
||||
if(settings.notifyOn.internalErrors) {
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
if(settings.dbusNotifications) {
|
||||
m_internalErrorNotification.update(errorMsg);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
showMessage(tr("Error"), errorMsg, QSystemTrayIcon::Critical);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrayIcon::showSyncthingNotification(ChronoUtilities::DateTime when, const QString &message)
|
||||
{
|
||||
Q_UNUSED(when)
|
||||
if(Settings::values().notifyOn.syncthingErrors) {
|
||||
showMessage(tr("Syncthing notification - click to dismiss"), message, QSystemTrayIcon::Warning);
|
||||
const auto &settings = Settings::values();
|
||||
if(settings.notifyOn.syncthingErrors) {
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
if(settings.dbusNotifications) {
|
||||
m_syncthingNotification.update(message);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
showMessage(tr("Syncthing notification - click to dismiss"), message, QSystemTrayIcon::Warning);
|
||||
}
|
||||
}
|
||||
updateStatusIconAndText(m_status);
|
||||
}
|
||||
|
@ -103,12 +143,20 @@ void TrayIcon::showSyncthingNotification(ChronoUtilities::DateTime when, const Q
|
|||
void TrayIcon::updateStatusIconAndText(SyncthingStatus status)
|
||||
{
|
||||
const SyncthingConnection &connection = trayMenu().widget()->connection();
|
||||
const auto &settings = Settings::values();
|
||||
switch(status) {
|
||||
case SyncthingStatus::Disconnected:
|
||||
setIcon(m_statusIconDisconnected);
|
||||
setToolTip(tr("Not connected to Syncthing"));
|
||||
if(Settings::values().notifyOn.disconnect) {
|
||||
showMessage(QCoreApplication::applicationName(), tr("Disconnected from Syncthing"), QSystemTrayIcon::Warning);
|
||||
if(settings.notifyOn.disconnect) {
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
if(settings.dbusNotifications) {
|
||||
m_disconnectedNotification.show();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
showMessage(QCoreApplication::applicationName(), tr("Disconnected from Syncthing"), QSystemTrayIcon::Warning);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SyncthingStatus::Reconnecting:
|
||||
|
@ -156,7 +204,7 @@ void TrayIcon::updateStatusIconAndText(SyncthingStatus status)
|
|||
case SyncthingStatus::Synchronizing:
|
||||
break;
|
||||
default:
|
||||
if(m_status == SyncthingStatus::Synchronizing && Settings::values().notifyOn.syncComplete) {
|
||||
if(m_status == SyncthingStatus::Synchronizing && settings.notifyOn.syncComplete) {
|
||||
const vector<SyncthingDir *> &completedDirs = connection.completedDirs();
|
||||
if(!completedDirs.empty()) {
|
||||
QString message;
|
||||
|
@ -170,7 +218,14 @@ void TrayIcon::updateStatusIconAndText(SyncthingStatus status)
|
|||
}
|
||||
message = tr("Synchronization of the following devices complete:\n") + names.join(QStringLiteral(", "));
|
||||
}
|
||||
showMessage(QCoreApplication::applicationName(), message, QSystemTrayIcon::Information);
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
if(settings.dbusNotifications) {
|
||||
m_syncCompleteNotification.update(message);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
showMessage(QCoreApplication::applicationName(), message, QSystemTrayIcon::Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
#include <c++utilities/chrono/datetime.h>
|
||||
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
# include <qtutilities/misc/dbusnotification.h>
|
||||
#endif
|
||||
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QIcon>
|
||||
|
||||
|
@ -31,7 +35,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void handleActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void handleMessageClicked();
|
||||
void handleSyncthingNotificationAction(const QString &action);
|
||||
|
||||
private:
|
||||
QPixmap renderSvgImage(const QString &path);
|
||||
|
@ -48,6 +52,12 @@ private:
|
|||
TrayMenu m_trayMenu;
|
||||
QMenu m_contextMenu;
|
||||
Data::SyncthingStatus m_status;
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
MiscUtils::DBusNotification m_disconnectedNotification;
|
||||
MiscUtils::DBusNotification m_internalErrorNotification;
|
||||
MiscUtils::DBusNotification m_syncthingNotification;
|
||||
MiscUtils::DBusNotification m_syncCompleteNotification;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline TrayMenu &TrayIcon::trayMenu()
|
||||
|
|
Loading…
Reference in New Issue