Commit 624488cb authored by Volker Krause's avatar Volker Krause
Browse files

Fold NotificationHandler into KalendarAlarmClient

Those two have a 1:1 relation and the separation doesn't really give us
any value but requires additional code to tie things together.

The intended effect of this is that we now have access to the calendar
object when creating notifications, which is necessary for moving beyond
a single string and provide more detailed notifications eventually.
parent 3777dffb
Pipeline #109375 passed with stage
in 4 minutes and 45 seconds
......@@ -5,7 +5,6 @@
set(kalendarac_SRCS
kalendaralarmclient.cpp
alarmnotification.cpp
notificationhandler.cpp
kalendaracmain.cpp
)
......
......@@ -5,7 +5,7 @@
*/
#include "alarmnotification.h"
#include "notificationhandler.h"
#include "kalendaralarmclient.h"
#include <KLocalizedString>
#include <QDebug>
......@@ -22,7 +22,7 @@ AlarmNotification::~AlarmNotification()
m_notification->deleteLater();
}
void AlarmNotification::send(NotificationHandler *handler)
void AlarmNotification::send(KalendarAlarmClient *client)
{
if (m_notification) {
return; // already active
......@@ -35,12 +35,12 @@ void AlarmNotification::send(NotificationHandler *handler)
// dismiss both with the explicit action and just closing the notification
// there is no signal for explicit closing though, we only can observe that
// indirectly from not having received a different signal before closed()
QObject::connect(m_notification, &KNotification::closed, handler, [this, handler]() {
handler->dismiss(this);
QObject::connect(m_notification, &KNotification::closed, client, [this, client]() {
client->dismiss(this);
});
QObject::connect(m_notification, &KNotification::action1Activated, handler, [this, handler]() {
handler->suspend(this);
QObject::disconnect(m_notification, &KNotification::closed, handler, nullptr);
QObject::connect(m_notification, &KNotification::action1Activated, client, [this, client]() {
client->suspend(this);
QObject::disconnect(m_notification, &KNotification::closed, client, nullptr);
});
m_notification->sendEvent();
......
......@@ -10,7 +10,7 @@
#include <QDateTime>
#include <QPointer>
class NotificationHandler;
class KalendarAlarmClient;
/**
* @brief The alarm notification that should be displayed. It is a wrapper of a KNotification enhanced with alarm properties, like uid and remind time
......@@ -25,7 +25,7 @@ public:
/**
* @brief Sends the notification to be displayed
*/
void send(NotificationHandler *handler);
void send(KalendarAlarmClient *client);
/**
* @return The uid of the Incidence of the alarm of the notification
......
......@@ -3,7 +3,6 @@
#include "kalendaralarmclient.h"
#include "alarmnotification.h"
#include "notificationhandler.h"
#include <akonadi-calendar_version.h>
......@@ -20,10 +19,6 @@ using namespace KCalendarCore;
KalendarAlarmClient::KalendarAlarmClient(QObject *parent)
: QObject(parent)
{
m_notificationHandler = new NotificationHandler(this);
connect(m_notificationHandler, &NotificationHandler::notificationUpdated, this, &KalendarAlarmClient::storeNotification);
connect(m_notificationHandler, &NotificationHandler::notificationRemoved, this, &KalendarAlarmClient::removeNotification);
mCheckTimer.setSingleShot(true);
mCheckTimer.setTimerType(Qt::VeryCoarseTimer);
......@@ -107,11 +102,26 @@ void KalendarAlarmClient::restoreSuspendedFromConfig()
qDebug() << "restoreSuspendedFromConfig: Restoring alarm" << uid << "," << txt << "," << remindAt;
if (!uid.isEmpty() && remindAt.isValid() && !txt.isEmpty()) {
m_notificationHandler->addNotification(uid, txt, remindAt);
addNotification(uid, txt, remindAt);
}
}
}
void KalendarAlarmClient::dismiss(AlarmNotification *notification)
{
qDebug() << "Alarm" << notification->uid() << "dismissed";
removeNotification(notification);
m_notifications.remove(notification->uid());
delete notification;
}
void KalendarAlarmClient::suspend(AlarmNotification *notification)
{
qDebug() << "Alarm " << notification->uid() << "suspended";
notification->setRemindAt(QDateTime(QDateTime::currentDateTime()).addSecs(5 * 60)); // 5 minutes is hardcoded in the suspend action text
storeNotification(notification);
}
void KalendarAlarmClient::storeNotification(AlarmNotification *notification)
{
KConfigGroup suspendedGroup(KSharedConfig::openConfig(), "Suspended");
......@@ -130,6 +140,30 @@ void KalendarAlarmClient::removeNotification(AlarmNotification *notification)
KSharedConfig::openConfig()->sync();
}
void KalendarAlarmClient::addNotification(const QString &uid, const QString &text, const QDateTime &remindTime)
{
if (m_notifications.contains(uid)) {
return;
}
qDebug() << "Adding notification, uid:" << uid << "text:" << text << "remindTime:" << remindTime;
AlarmNotification *notification = new AlarmNotification(uid);
notification->setText(text);
notification->setRemindAt(remindTime);
m_notifications[notification->uid()] = notification;
storeNotification(notification);
}
void KalendarAlarmClient::sendNotifications()
{
qDebug() << "Looking for notifications, total:" << m_notifications.count();
for (auto it = m_notifications.begin(); it != m_notifications.end(); ++it) {
if (it.value()->remindAt() <= QDateTime::currentDateTime()) {
qDebug() << "Sending notification for alarm" << it.value()->uid() << ", text is" << it.value()->text();
it.value()->send(this);
}
}
}
bool KalendarAlarmClient::collectionsAvailable() const
{
// The list of collections must be available.
......@@ -178,21 +212,21 @@ void KalendarAlarmClient::checkAlarms()
if (incidence && incidence->type() == KCalendarCore::Incidence::TypeTodo && !incidence->dtStart().isValid()) {
auto todo = incidence.staticCast<KCalendarCore::Todo>();
timeText = i18n("Task due at %1", QLocale::system().toString(todo->dtDue().time(), QLocale::NarrowFormat));
m_notificationHandler->addNotification(uid, QLatin1String("%1\n%2").arg(timeText, incidence->summary()), mLastChecked);
addNotification(uid, QLatin1String("%1\n%2").arg(timeText, incidence->summary()), mLastChecked);
} else if (incidence) {
QString incidenceString = incidence->type() == KCalendarCore::Incidence::TypeTodo ? i18n("Task") : i18n("Event");
timeText = i18nc("Event starts at 10:00",
"%1 starts at %2",
incidenceString,
QLocale::system().toString(incidence->dtStart().time(), QLocale::NarrowFormat));
m_notificationHandler->addNotification(uid, QLatin1String("%1\n%2").arg(timeText, incidence->summary()), mLastChecked);
addNotification(uid, QLatin1String("%1\n%2").arg(timeText, incidence->summary()), mLastChecked);
} else {
QLocale::system().toString(alarm->time(), QLocale::NarrowFormat);
m_notificationHandler->addNotification(uid, QLatin1String("%1\n%2").arg(timeText, alarm->text()), mLastChecked);
addNotification(uid, QLatin1String("%1\n%2").arg(timeText, alarm->text()), mLastChecked);
}
}
m_notificationHandler->sendNotifications();
sendNotifications();
saveLastCheckTime();
// schedule next check for the beginning of the next minute
......
......@@ -4,7 +4,9 @@
#pragma once
#include <QDateTime>
#include <QHash>
#include <QTimer>
#include <akonadi_version.h>
#if AKONADI_VERSION >= QT_VERSION_CHECK(5, 18, 41)
#include <Akonadi/EntityTreeModel>
......@@ -16,7 +18,6 @@
#include <Akonadi/Calendar/ETMCalendar>
class AlarmNotification;
class NotificationHandler;
class KalendarAlarmClient : public QObject
{
......@@ -26,11 +27,18 @@ public:
explicit KalendarAlarmClient(QObject *parent = nullptr);
~KalendarAlarmClient() override;
/** Dismisses any further notification display for the alarm \p notification. */
void dismiss(AlarmNotification *notification);
/** Suspends the display of the alarm \p notification. */
void suspend(AlarmNotification *notification);
private:
void deferredInit();
void restoreSuspendedFromConfig();
void storeNotification(AlarmNotification *notification);
void removeNotification(AlarmNotification *notification);
void addNotification(const QString &uid, const QString &text, const QDateTime &remindTime);
void sendNotifications();
void checkAlarms();
void setupAkonadi();
Q_REQUIRED_RESULT bool collectionsAvailable() const;
......@@ -41,5 +49,5 @@ private:
QDateTime mLastChecked;
QTimer mCheckTimer;
NotificationHandler *m_notificationHandler;
QHash<QString, AlarmNotification *> m_notifications;
};
/*
* SPDX-FileCopyrightText: 2020 Dimitris Kardarakos <dimkard@posteo.net>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "notificationhandler.h"
#include "alarmnotification.h"
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QDebug>
NotificationHandler::NotificationHandler(QObject *parent)
: QObject(parent)
{
KConfigGroup generalGroup(KSharedConfig::openConfig(), "General");
m_suspend_seconds = generalGroup.readEntry("SuspendSeconds", 60 * 5); // 5 minutes
}
NotificationHandler::~NotificationHandler() = default;
void NotificationHandler::addNotification(const QString &uid, const QString &txt, const QDateTime &remindTime)
{
if (m_notifications.contains(uid)) {
return;
}
qDebug() << "Adding notification, uid:" << uid << "text:" << txt << "remindTime:" << remindTime;
AlarmNotification *notification = new AlarmNotification(uid);
notification->setText(txt);
notification->setRemindAt(remindTime);
m_notifications[notification->uid()] = notification;
Q_EMIT notificationUpdated(notification);
}
void NotificationHandler::sendNotifications()
{
qDebug() << "Looking for notifications, total:" << m_notifications.count();
for (auto it = m_notifications.begin(); it != m_notifications.end(); ++it) {
if (it.value()->remindAt() <= QDateTime::currentDateTime()) {
qDebug() << "Sending notification for alarm" << it.value()->uid() << ", text is" << it.value()->text();
it.value()->send(this);
}
}
}
void NotificationHandler::dismiss(AlarmNotification *notification)
{
qDebug() << "Alarm" << notification->uid() << "dismissed";
Q_EMIT notificationRemoved(notification);
m_notifications.remove(notification->uid());
delete notification;
}
void NotificationHandler::suspend(AlarmNotification *notification)
{
qDebug() << ":Alarm " << notification->uid() << "suspended";
notification->setRemindAt(QDateTime(QDateTime::currentDateTime()).addSecs(m_suspend_seconds));
Q_EMIT notificationUpdated(notification);
}
/*
* SPDX-FileCopyrightText: 2019 Dimitris Kardarakos <dimkard@posteo.net>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef NOTIFICATIONHANDLER_H
#define NOTIFICATIONHANDLER_H
#include <QDateTime>
#include <QHash>
#include <QObject>
class AlarmNotification;
/**
* @brief Manages the creation and triggering of event alarm notifications
*
*/
class NotificationHandler : public QObject
{
Q_OBJECT
public:
explicit NotificationHandler(QObject *parent);
~NotificationHandler() override;
/**
* @brief Parses the internal list of active and suspended notifications and triggers their sending
*/
void sendNotifications();
/**
* @brief Creates an alarm notification object for the Incidence with \p uid. It sets the text to be displayed according to \p text.
*/
void addNotification(const QString &uid, const QString &text, const QDateTime &remindTime);
public Q_SLOTS:
/**
* @brief Dismisses any further notification display for the alarm \p notification.
*
*/
void dismiss(AlarmNotification *notification);
/**
* @brief Suspends the display of the alarm \p notification, by removing it from the list of active and putting it to the list of suspended notifications.
* Remind time is set according to configuration.
*/
void suspend(AlarmNotification *notification);
Q_SIGNALS:
/** Store a new or updated notification. */
void notificationUpdated(AlarmNotification *notification);
/** Remove a dismissed notification. */
void notificationRemoved(AlarmNotification *notification);
private:
QHash<QString, AlarmNotification *> m_notifications;
int m_suspend_seconds;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment