diff --git a/messagecomposer/src/CMakeLists.txt b/messagecomposer/src/CMakeLists.txt --- a/messagecomposer/src/CMakeLists.txt +++ b/messagecomposer/src/CMakeLists.txt @@ -101,6 +101,12 @@ set(messagecomposer_followupreminder_SRCS followupreminder/followupreminderselectdatedialog.cpp followupreminder/followupremindercreatejob.cpp + followupreminder/followupreminder.cpp + ) + +qt5_add_dbus_interface(messagecomposer_followupreminder_SRCS + followupreminder/org.freedesktop.Akonadi.FollowUpReminder.xml + followupreminderinterface ) set(messagecomposer_richtextcomposerng_SRCS @@ -218,7 +224,6 @@ Grantlee5::TextDocument KF5::CalendarCore # for KCalendarCore/Todo KF5::SendLater - KF5::FollowupReminder KF5::Archive KF5::Contacts KF5::SonnetCore @@ -395,6 +400,7 @@ HEADER_NAMES FollowupReminderCreateJob FollowUpReminderSelectDateDialog + FollowupReminder REQUIRED_HEADERS MessageComposer_followupreminder_HEADERS PREFIX MessageComposer RELATIVE followupreminder diff --git a/messagecomposer/src/followupreminder/followupreminder.h b/messagecomposer/src/followupreminder/followupreminder.h new file mode 100644 --- /dev/null +++ b/messagecomposer/src/followupreminder/followupreminder.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2020 Daniel Vrátil + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MESSAGECOMPOSER_FOLLOWUPREMINDER_H_ +#define MESSAGECOMPOSER_FOLLOWUPREMINDER_H_ + +#include "messagecomposer_export.h" + +#include + +namespace MessageComposer +{ + +namespace FollowUpReminder +{ + +Q_REQUIRED_RESULT MESSAGECOMPOSER_EXPORT bool isAvailableAndEnabled(); + +} + +} + +#endif diff --git a/messagecomposer/src/followupreminder/followupreminder.cpp b/messagecomposer/src/followupreminder/followupreminder.cpp new file mode 100644 --- /dev/null +++ b/messagecomposer/src/followupreminder/followupreminder.cpp @@ -0,0 +1,40 @@ +/* + Copyright (C) 2020 Daniel Vrátil + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "followupreminder.h" +#include "followupreminderinterface.h" + +#include +#include + +using namespace MessageComposer; + + +bool FollowUpReminder::isAvailableAndEnabled() +{ + using Akonadi::ServerManager; + org::freedesktop::Akonadi::FollowUpReminderAgent iface{ + ServerManager::agentServiceName(ServerManager::Agent, QStringLiteral("akonadi_followupreminder_agent")), + QStringLiteral("/FollowUpReminder"), + QDBusConnection::sessionBus() + }; + + return iface.isValid() && iface.enabledAgent(); +} + diff --git a/messagecomposer/src/followupreminder/followupremindercreatejob.h b/messagecomposer/src/followupreminder/followupremindercreatejob.h --- a/messagecomposer/src/followupreminder/followupremindercreatejob.h +++ b/messagecomposer/src/followupreminder/followupremindercreatejob.h @@ -24,9 +24,12 @@ #include #include #include -#include #include + #include "messagecomposer_export.h" + +#include + namespace MessageComposer { class FollowupReminderCreateJobPrivate; /** @@ -56,9 +59,11 @@ private Q_SLOTS: void slotCreateNewTodo(KJob *job); + private: void writeFollowupReminderInfo(); - FollowupReminderCreateJobPrivate *const d; + + std::unique_ptr const d; }; } diff --git a/messagecomposer/src/followupreminder/followupremindercreatejob.cpp b/messagecomposer/src/followupreminder/followupremindercreatejob.cpp --- a/messagecomposer/src/followupreminder/followupremindercreatejob.cpp +++ b/messagecomposer/src/followupreminder/followupremindercreatejob.cpp @@ -18,64 +18,63 @@ */ #include "followupremindercreatejob.h" +#include "followupreminderinterface.h" #include "messagecomposer_debug.h" -#include + #include #include #include +#include + +#include +#include +#include +#include using namespace MessageComposer; class MessageComposer::FollowupReminderCreateJobPrivate { public: - FollowupReminderCreateJobPrivate() - : mInfo(new FollowUpReminder::FollowUpReminderInfo) - { - } - - ~FollowupReminderCreateJobPrivate() - { - delete mInfo; - } - Akonadi::Collection mCollection; - FollowUpReminder::FollowUpReminderInfo *mInfo = nullptr; + QDate mFollowupDate; + Akonadi::Item::Id mOriginalMessageItemId = -1; + Akonadi::Item::Id mTodoId = -1; + QString mMessageId; + QString mSubject; + QString mTo; }; FollowupReminderCreateJob::FollowupReminderCreateJob(QObject *parent) : KJob(parent) , d(new MessageComposer::FollowupReminderCreateJobPrivate) { } -FollowupReminderCreateJob::~FollowupReminderCreateJob() -{ - delete d; -} +FollowupReminderCreateJob::~FollowupReminderCreateJob() = default; void FollowupReminderCreateJob::setFollowUpReminderDate(const QDate &date) { - d->mInfo->setFollowUpReminderDate(date); + d->mFollowupDate = date; } void FollowupReminderCreateJob::setOriginalMessageItemId(Akonadi::Item::Id value) { - d->mInfo->setOriginalMessageItemId(value); + d->mOriginalMessageItemId = value; } void FollowupReminderCreateJob::setMessageId(const QString &messageId) { - d->mInfo->setMessageId(messageId); + d->mMessageId = messageId; } void FollowupReminderCreateJob::setTo(const QString &to) { - d->mInfo->setTo(to); + d->mTo = to; } void FollowupReminderCreateJob::setSubject(const QString &subject) { - d->mInfo->setSubject(subject); + d->mSubject = subject; } void FollowupReminderCreateJob::setCollectionToDo(const Akonadi::Collection &collection) @@ -85,11 +84,11 @@ void FollowupReminderCreateJob::start() { - if (d->mInfo->isValid()) { + if (!d->mMessageId.isEmpty() && d->mFollowupDate.isValid() && !d->mTo.isEmpty()) { if (d->mCollection.isValid()) { KCalendarCore::Todo::Ptr todo(new KCalendarCore::Todo); - todo->setSummary(i18n("Wait answer from \"%1\" send to \"%2\"", d->mInfo->subject(), d->mInfo->to())); - todo->setDtDue(QDateTime(d->mInfo->followUpReminderDate(), QTime(0, 0, 0))); + todo->setSummary(i18n("Wait answer from \"%1\" send to \"%2\"", d->mSubject, d->mTo)); + todo->setDtDue(QDateTime(d->mFollowupDate, QTime(0, 0, 0))); Akonadi::Item newTodoItem; newTodoItem.setMimeType(KCalendarCore::Todo::todoMimeType()); newTodoItem.setPayload(todo); @@ -100,25 +99,55 @@ writeFollowupReminderInfo(); } } else { - qCDebug(MESSAGECOMPOSER_LOG) << "FollowupReminderCreateJob info not valid " << *d->mInfo; + qCWarning(MESSAGECOMPOSER_LOG) << "FollowupReminderCreateJob info not valid!"; emitResult(); return; } } void FollowupReminderCreateJob::slotCreateNewTodo(KJob *job) { if (job->error()) { - qCDebug(MESSAGECOMPOSER_LOG) << "Error during create new Todo " << job->errorString(); - } else { - Akonadi::ItemCreateJob *createJob = qobject_cast(job); - d->mInfo->setTodoId(createJob->item().id()); + qCWarning(MESSAGECOMPOSER_LOG) << "Error during create new Todo " << job->errorString(); + setError(job->error()); + setErrorText(i18n("Failed to store a new reminder: an error occured while trying to create a new Todo in your calendar: %1", job->errorString())); + emitResult(); + return; } + + Akonadi::ItemCreateJob *createJob = qobject_cast(job); + d->mTodoId = createJob->item().id(); writeFollowupReminderInfo(); } void FollowupReminderCreateJob::writeFollowupReminderInfo() { - FollowUpReminder::FollowUpReminderUtil::writeFollowupReminderInfo(FollowUpReminder::FollowUpReminderUtil::defaultConfig(), d->mInfo, true); - emitResult(); + std::unique_ptr iface{ + new org::freedesktop::Akonadi::FollowUpReminderAgent{ + Akonadi::ServerManager::agentServiceName(Akonadi::ServerManager::Agent, QStringLiteral("akonadi_followupreminder_agent")), + QStringLiteral("/FollowUpReminder"), + QDBusConnection::sessionBus() + }}; + + if (!iface->isValid()) { + qCWarning(MESSAGECOMPOSER_LOG) << "The FollowUpReminder agent is not running!"; + return; + } + + auto call = iface->addReminder(d->mMessageId, d->mOriginalMessageItemId, d->mTo, d->mSubject, d->mFollowupDate, d->mTodoId); + auto wait = new QDBusPendingCallWatcher{call, this}; + connect(wait, &QDBusPendingCallWatcher::finished, + this, [this, iface_ = std::move(iface)](QDBusPendingCallWatcher *watcher) mutable { + auto iface = std::move(iface_); + watcher->deleteLater(); + + const QDBusPendingReply reply = *watcher; + if (reply.isError()) { + qCWarning(MESSAGECOMPOSER_LOG) << "Failed to write the new reminder, agent replied" << reply.error().message(); + setError(KJob::UserDefinedError); + setErrorText(i18n("Failed to store a new reminder: %1", reply.error().message())); + } + + emitResult(); + }); } diff --git a/messagecomposer/src/followupreminder/followupreminderselectdatedialog.h b/messagecomposer/src/followupreminder/followupreminderselectdatedialog.h --- a/messagecomposer/src/followupreminder/followupreminderselectdatedialog.h +++ b/messagecomposer/src/followupreminder/followupreminderselectdatedialog.h @@ -44,11 +44,13 @@ void accept() override; Akonadi::Collection collection() const; + private Q_SLOTS: void slotDateChanged(); void updateOkButton(); + private: - FollowUpReminderSelectDateDialogPrivate *const d; + std::unique_ptr const d; }; } diff --git a/messagecomposer/src/followupreminder/followupreminderselectdatedialog.cpp b/messagecomposer/src/followupreminder/followupreminderselectdatedialog.cpp --- a/messagecomposer/src/followupreminder/followupreminderselectdatedialog.cpp +++ b/messagecomposer/src/followupreminder/followupreminderselectdatedialog.cpp @@ -37,10 +37,6 @@ class MessageComposer::FollowUpReminderSelectDateDialogPrivate { public: - FollowUpReminderSelectDateDialogPrivate() - { - } - KDateComboBox *mDateComboBox = nullptr; Akonadi::CollectionComboBox *mCollectionCombobox = nullptr; QPushButton *mOkButton = nullptr; @@ -93,10 +89,7 @@ updateOkButton(); } -FollowUpReminderSelectDateDialog::~FollowUpReminderSelectDateDialog() -{ - delete d; -} +FollowUpReminderSelectDateDialog::~FollowUpReminderSelectDateDialog() = default; void FollowUpReminderSelectDateDialog::updateOkButton() { diff --git a/messagecomposer/src/followupreminder/org.freedesktop.Akonadi.FollowUpReminder.xml b/messagecomposer/src/followupreminder/org.freedesktop.Akonadi.FollowUpReminder.xml new file mode 100644 --- /dev/null +++ b/messagecomposer/src/followupreminder/org.freedesktop.Akonadi.FollowUpReminder.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + +