diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_policy(SET CMP0063 NEW) endif() -set(KF5_MIN_VERSION "5.58.0") +set(KF5_MIN_VERSION "5.60.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ ${ECM_MODULE_PATH}) @@ -55,7 +55,7 @@ option(KMAIL_DKIM_CONFIGURE_DIALOG_BUILD "Build dkim-verify configure dialog (experimental)." FALSE) -find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED WebEngine WebEngineWidgets Widgets Test) +find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED DBus WebEngine WebEngineWidgets Widgets Test) find_package(KF5I18n ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED) @@ -69,6 +69,7 @@ find_package(KF5Parts ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Prison ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Holidays ${KF5_MIN_VERSION} CONFIG REQUIRED) +find_package(KF5Service ${KF5_MIN_VERSION} CONFIG REQUIRED) set(MAILCOMMON_LIB_VERSION "5.11.42") set(GRAVATAR_LIB_VERSION "5.11.40") diff --git a/plugins/plasma/pimeventsplugin/CMakeLists.txt b/plugins/plasma/pimeventsplugin/CMakeLists.txt --- a/plugins/plasma/pimeventsplugin/CMakeLists.txt +++ b/plugins/plasma/pimeventsplugin/CMakeLists.txt @@ -45,10 +45,12 @@ add_library(pimcalendarsplugin SHARED ${plasmapimcalendarsplugin_SRCS} ${loggingcategory_SRCS}) target_link_libraries(pimcalendarsplugin Qt5::Core + Qt5::DBus Qt5::Qml KF5::AkonadiCore KF5::CalendarCore KF5::ConfigCore + KF5::Service ) install(TARGETS pimcalendarsplugin diff --git a/plugins/plasma/pimeventsplugin/autotests/CMakeLists.txt b/plugins/plasma/pimeventsplugin/autotests/CMakeLists.txt --- a/plugins/plasma/pimeventsplugin/autotests/CMakeLists.txt +++ b/plugins/plasma/pimeventsplugin/autotests/CMakeLists.txt @@ -11,13 +11,15 @@ ecm_mark_as_test(plasma-pimeventsplugin-${_name}) add_definitions(-DPIMEVENT_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}\") target_link_libraries(${_name} Qt5::Core + Qt5::DBus Qt5::Test KF5::AkonadiCore KF5::AkonadiCalendar KF5::CalendarCore KF5::CalendarEvents KF5::EventViews KF5::ConfigCore + KF5::Service ) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/.. diff --git a/plugins/plasma/pimeventsplugin/pimeventsplugin.h b/plugins/plasma/pimeventsplugin/pimeventsplugin.h --- a/plugins/plasma/pimeventsplugin/pimeventsplugin.h +++ b/plugins/plasma/pimeventsplugin/pimeventsplugin.h @@ -28,10 +28,13 @@ } class PimDataSource; -class PimEventsPlugin : public CalendarEvents::CalendarEventsPlugin, public KCalCore::Calendar::CalendarObserver +class PimEventsPlugin + : public CalendarEvents::CalendarEventsPlugin + , public CalendarEvents::ShowEventInterface + , public KCalCore::Calendar::CalendarObserver { Q_OBJECT - Q_INTERFACES(CalendarEvents::CalendarEventsPlugin) + Q_INTERFACES(CalendarEvents::CalendarEventsPlugin CalendarEvents::ShowEventInterface) Q_PLUGIN_METADATA(IID "org.kde.CalendarEventsPlugin" FILE "pimeventsplugin.json") public: @@ -42,6 +45,9 @@ // CalendarEvents::CalendarEventsPlugin void loadEventsForDateRange(const QDate &startDate, const QDate &endDate) override; + // CalendarEvents::ShowEventInterface + bool showEvent(const QString &uid) override; + // KCalCore::Calendar::CalendarObserver void calendarIncidenceChanged(const KCalCore::Incidence::Ptr &incidence) override; void calendarIncidenceAdded(const KCalCore::Incidence::Ptr &incidence) override; diff --git a/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp b/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp --- a/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp +++ b/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp @@ -22,6 +22,13 @@ #include "akonadipimdatasource.h" #include "pimeventsplugin_debug.h" +#include + +#include +#include +#include +#include + PimEventsPlugin::PimEventsPlugin(QObject *parent) : PimEventsPlugin(new AkonadiPimDataSource(), parent) { @@ -75,6 +82,65 @@ << "TodoData:" << todoDataCount; } +namespace { + +QString parseUid(const QString &uid) +{ + const auto parsed = uid.splitRef(QLatin1Char('-')); + if (parsed.size() < 2) { + return {}; + } + + return parsed[1].toString(); +} + +bool showIncidenceInKOrganizer(const QString &uid) +{ + auto iface = std::make_unique(QStringLiteral("org.kde.korganizer"), QStringLiteral("/Korganizer"), + QStringLiteral("org.kde.korganizer.Korganizer"), QDBusConnection::sessionBus()); + if (!iface->isValid()) { + qCWarning(PIMEVENTSPLUGIN_LOG) << "Failed to acquire DBus interface of KOrganizer"; + return false; + } + + auto pendingCall = iface->asyncCall(QStringLiteral("showIncidence"), uid); + auto watcher = new QDBusPendingCallWatcher(pendingCall); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, + [iface = std::move(iface)](auto watcher) mutable { + QDBusPendingReply<> reply = *watcher; + if (reply.isError()) { + qCWarning(PIMEVENTSPLUGIN_LOG) << "Failed to invoke showIncidence DBus method:" << reply.error().message(); + } + + watcher->deleteLater(); + iface.release()->deleteLater(); + }); + return true; +} + +} + +bool PimEventsPlugin::showEvent(const QString &uid) +{ + if (!uid.startsWith(QLatin1String("Akonadi-"))) { + return false; + } + + const auto incidenceUri = parseUid(uid); + if (incidenceUri.isEmpty()) { + qCWarning(PIMEVENTSPLUGIN_LOG) << "Failed to parse event UID " << uid; + return false; + } + + QString error; + if (KToolInvocation::startServiceByDesktopName(QStringLiteral("org.kde.korganizer"), QStringList{}, &error) != 0) { + qCWarning(PIMEVENTSPLUGIN_LOG) << "Failed to launch KOrganizer:" << error; + return false; + } + + return showIncidenceInKOrganizer(incidenceUri); +} + void PimEventsPlugin::calendarIncidenceAdded(const KCalCore::Incidence::Ptr &incidence) { if (!mStart.isValid() || !mEnd.isValid()) {