diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ include(ECMQtDeclareLoggingCategory) include(CheckSymbolExists) include(ECMCoverageOption) +include(KDEPackageAppTemplates) include(AkonadiMacros) @@ -257,6 +258,8 @@ add_subdirectory(src) add_subdirectory(icons) +add_subdirectory(templates) + if(BUILD_TOOLS) # add testrunner (application for managing a self-contained # test environment) diff --git a/ExtraDesktop.sh b/ExtraDesktop.sh new file mode 100644 --- /dev/null +++ b/ExtraDesktop.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +#This file outputs in a separate line each file with a .desktop syntax +#that needs to be translated but has a non .desktop extension +find -name \*.kdevtemplate -print diff --git a/templates/CMakeLists.txt b/templates/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/CMakeLists.txt @@ -0,0 +1,6 @@ +set(apptemplate_DIRS + akonadiresource + akonadiserializer +) + +kde_package_app_templates(TEMPLATES ${apptemplate_DIRS} INSTALL_DIR ${KDE_INSTALL_KTEMPLATESDIR}) diff --git a/templates/akonadiresource/CMakeLists.txt b/templates/akonadiresource/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.1) + +project(%{APPNAMELC}) + +set(ECM_MIN_VERSION "5.22.0") +find_package(ECM ${ECM_MIN_VERSION} CONFIG REQUIRED) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) + +include(FeatureSummary) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) +include(ECMQtDeclareLoggingCategory) + +set(QT_MIN_VERSION "5.6.0") +find_package(Qt5 ${QT_MIN_VERSION} REQUIRED Core DBus Gui) + +set(KF5_MIN_VERSION "5.22.0") +find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED) + +set(AKONADI_MIN_VERSION "5.2") +find_package(KF5Akonadi ${AKONADI_MIN_VERSION} CONFIG REQUIRED) + +find_package(Xsltproc REQUIRED) +set_package_properties(Xsltproc PROPERTIES + DESCRIPTION "XSLT processor from libxslt" + TYPE REQUIRED + PURPOSE "Required to generate a D-Bus interface for the resource." +) + +add_subdirectory(src) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/akonadiresource/README b/templates/akonadiresource/README new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/README @@ -0,0 +1,89 @@ +How To Build This Template +-=-=-=-=-=-=-=-=-=-=-=-=-= + +--- On Linux & similar: + +cd +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=$MY_PREFIX -DCMAKE_BUILD_TYPE=Debug +make +make install or su -c 'make install' + +(MY_PREFIX is where you install your Akonadi setup, replace it accordingly) + +to uninstall the project: +make uninstall or su -c 'make uninstall' + +Note: you can use another build path. Then cd in your build dir and: +export MY_SRC=path_to_your_src +cmake $MY_SRC -DCMAKE_INSTALL_PREFIX=$MY_PREFIX -DCMAKE_BUILD_TYPE=Debug + +--- On Windows: + +cd +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=%MY_PREFIX% -DCMAKE_BUILD_TYPE=Debug +[n]make +[n]make install + +(MY_PREFIX is where you install your Akonadi setup, replace it accordingly) + +to uninstall the project: +[n]make uninstall + +Note: use nmake if you're building with the Visual Studio compiler, or make +if you're using the minGW compiler + + +Implementation hints +-=-=-=-=-=-=-=-=-=-= + +The code generated by the template can be compiled without any further +changes, so you can start with your own code right away. + +However, there are a couple of things you will need to change outside the +resource's code, i.e. in the resource's .desktop file: + +- Name field: the name of the resource with which it will be displayed in + system settings and applications which can add resources on their own. + E.g. MyBackend Resource + +- Comment field: short description of the resource, also used to be + displayed, e.g. For calendars and contacts stored in MyBackend + +- Icon field: if you are not writing a contact (addressbook) resource, you have + to change this to either an icon for the respective MIME type you are going + to provide or use a resource specific icon which you provide yourself + +- X-Akonadi-MimeTypes field: if you are not writing a contact (addressbook) + resource, you have to change this to either a known MIME type or one you + install together with the resource. + If your resource can provide data of more than one MIME type, you can + specific all possible ones as a comma separate list. + + Common MIME types are: + * text/directory: for contact data + * text/calendar: for calendar data (there are Akonadi defined subtypes + available, e.g. application/x-vnd.akonadi.calendar.event) + * message/rfc822: for e-mails and usenet news + +The template comes with an input file for KDE's KConfigXT framework +for improved configuration file handling. The generated class is called +"Settings", so access to its data is provided through its singleton +instance method Settings::self(). +See https://techbase.kde.org/Development/Tutorials/Using_KConfig_XT + + +Documentation +-=-=-=-=-=-=- + +The Akonadi-KDE API documentation can be found here: +https://api.kde.org/kdepim/akonadi/html/index.html + +General developer information, e.g. tutorials can be found here: +https://techbase.kde.org/KDE_PIM/Akonadi + +The contact site can be found here: +https://community.kde.org/KDE_PIM/Contact diff --git a/templates/akonadiresource/akonadiresource.kdevtemplate b/templates/akonadiresource/akonadiresource.kdevtemplate new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/akonadiresource.kdevtemplate @@ -0,0 +1,6 @@ +[General] +Name=C++ +Comment=Akonadi Resource Template. A template for an Akonadi PIM data resource +Category=Akonadi/Resource +Icon=akonadiresource.png +ShowFilesAfterGeneration=src/akonadi_serializer_%{APPNAMELC}.cpp diff --git a/templates/akonadiresource/akonadiresource.png b/templates/akonadiresource/akonadiresource.png new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + DEPENDS + ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + ) + endmacro() +endif() diff --git a/templates/akonadiresource/src/%{APPNAMELC}resource.h b/templates/akonadiresource/src/%{APPNAMELC}resource.h new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/%{APPNAMELC}resource.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) %{CURRENT_YEAR} by %{AUTHOR} <%{EMAIL}> + * + * 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. If not, see . + */ + +#ifndef %{APPNAMEUC}RESOURCE_H +#define %{APPNAMEUC}RESOURCE_H + +#include + +class %{APPNAME}Resource : public Akonadi::ResourceBase, + public Akonadi::AgentBase::Observer +{ + Q_OBJECT + +public: + explicit %{APPNAME}Resource(const QString &id); + ~%{APPNAME}Resource() override; + +public Q_SLOTS: + void configure(WId windowId) override; + +protected Q_SLOTS: + void retrieveCollections() override; + void retrieveItems(const Akonadi::Collection &col) override; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) override; + +protected: + void aboutToQuit() override; + + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) override; + void itemChanged(const Akonadi::Item &item, const QSet &parts) override; + void itemRemoved(const Akonadi::Item &item) override; +}; + +#endif diff --git a/templates/akonadiresource/src/%{APPNAMELC}resource.cpp b/templates/akonadiresource/src/%{APPNAMELC}resource.cpp new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/%{APPNAMELC}resource.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) %{CURRENT_YEAR} by %{AUTHOR} <%{EMAIL}> + * + * 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. If not, see . + */ + +#include "%{APPNAMELC}resource.h" + +#include "settings.h" +#include "settingsadaptor.h" +#include "debug.h" + +#include + +using namespace Akonadi; + +%{APPNAME}Resource::%{APPNAME}Resource(const QString &id) + : ResourceBase(id) +{ + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), + QDBusConnection::ExportAdaptors); + + // TODO: you can put any resource specific initialization code here. + qCDebug(log_%{APPNAMELC}resource) << "Resource started"; +} + +%{APPNAME}Resource::~%{APPNAME}Resource() +{ +} + +void %{APPNAME}Resource::retrieveCollections() +{ + // TODO: this method is called when Akonadi wants to have all the + // collections your resource provides. + // Be sure to set the remote ID and the content MIME types +} + +void %{APPNAME}Resource::retrieveItems(const Akonadi::Collection &collection) +{ + // TODO: this method is called when Akonadi wants to know about all the + // items in the given collection. You can but don't have to provide all the + // data for each item, remote ID and MIME type are enough at this stage. + // Depending on how your resource accesses the data, there are several + // different ways to tell Akonadi when you are done. +} + +bool %{APPNAME}Resource::retrieveItem(const Akonadi::Item &item, const QSet &parts) +{ + // TODO: this method is called when Akonadi wants more data for a given item. + // You can only provide the parts that have been requested but you are allowed + // to provide all in one go + + return true; +} + +void %{APPNAME}Resource::aboutToQuit() +{ + // TODO: any cleanup you need to do while there is still an active + // event loop. The resource will terminate after this method returns +} + +void %{APPNAME}Resource::configure(WId windowId) +{ + // TODO: this method is usually called when a new resource is being + // added to the Akonadi setup. You can do any kind of user interaction here, + // e.g. showing dialogs. + // The given window ID is usually useful to get the correct + // "on top of parent" behavior if the running window manager applies any kind + // of focus stealing prevention technique + // + // If the configuration dialog has been accepted by the user by clicking Ok, + // the signal configurationDialogAccepted() has to be emitted, otherwise, if + // the user canceled the dialog, configurationDialogRejected() has to be emitted. +} + +void %{APPNAME}Resource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) +{ + // TODO: this method is called when somebody else, e.g. a client application, + // has created an item in a collection managed by your resource. + + // NOTE: There is an equivalent method for collections, but it isn't part + // of this template code to keep it simple +} + +void %{APPNAME}Resource::itemChanged(const Akonadi::Item &item, const QSet &parts) +{ + // TODO: this method is called when somebody else, e.g. a client application, + // has changed an item managed by your resource. + + // NOTE: There is an equivalent method for collections, but it isn't part + // of this template code to keep it simple +} + +void %{APPNAME}Resource::itemRemoved(const Akonadi::Item &item) +{ + // TODO: this method is called when somebody else, e.g. a client application, + // has deleted an item managed by your resource. + + // NOTE: There is an equivalent method for collections, but it isn't part + // of this template code to keep it simple +} + +AKONADI_RESOURCE_MAIN(%{APPNAME}Resource) diff --git a/templates/akonadiresource/src/%{APPNAMELC}resource.desktop b/templates/akonadiresource/src/%{APPNAMELC}resource.desktop new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/%{APPNAMELC}resource.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=%{APPNAME} Resource +Comment=An Akonadi resource plugin for %{APPNAME} +Type=AkonadiResource +Exec=akonadi_%{APPNAMELC}_resource +Icon=text-directory + +X-Akonadi-MimeTypes=text/directory +X-Akonadi-Capabilities=Resource +X-Akonadi-Identifier=akonadi_%{APPNAMELC}_resource diff --git a/templates/akonadiresource/src/CMakeLists.txt b/templates/akonadiresource/src/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/CMakeLists.txt @@ -0,0 +1,38 @@ +set(%{APPNAMELC}resource_SRCS + %{APPNAMELC}resource.cpp +) + +ecm_qt_declare_logging_category(%{APPNAMELC}resource_SRCS + HEADER debug.h + IDENTIFIER log_%{APPNAMELC}resource + CATEGORY_NAME log_%{APPNAMELC}resource +) + +kconfig_add_kcfg_files(%{APPNAMELC}resource_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/settings.kcfgc +) + +kcfg_generate_dbus_interface( + ${CMAKE_CURRENT_SOURCE_DIR}/settings.kcfg + org.kde.Akonadi.%{APPNAME}.Settings +) + +qt5_add_dbus_adaptor(%{APPNAMELC}resource_SRCS + ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.%{APPNAME}.Settings.xml + ${CMAKE_CURRENT_BINARY_DIR}/settings.h + Settings +) + +add_executable(akonadi_%{APPNAMELC}_resource ${%{APPNAMELC}resource_SRCS}) + +target_link_libraries(akonadi_%{APPNAMELC}_resource + Qt5::DBus + KF5::AkonadiAgentBase + KF5::ConfigCore +) + +install(TARGETS akonadi_%{APPNAMELC}_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +install(FILES %{APPNAMELC}resource.desktop + DESTINATION ${KDE_INSTALL_DATAROOTDIR}/akonadi/agents +) diff --git a/templates/akonadiresource/src/settings.kcfg b/templates/akonadiresource/src/settings.kcfg new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/settings.kcfg @@ -0,0 +1,14 @@ + + + + + + + false + + + diff --git a/templates/akonadiresource/src/settings.kcfgc b/templates/akonadiresource/src/settings.kcfgc new file mode 100644 --- /dev/null +++ b/templates/akonadiresource/src/settings.kcfgc @@ -0,0 +1,8 @@ +File=settings.kcfg +ClassName=Settings +Mutators=true +ItemAccessors=true +SetUserTexts=true +Singleton=true +#IncludeFiles= +GlobalEnums=true diff --git a/templates/akonadiserializer/CMakeLists.txt b/templates/akonadiserializer/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/akonadiserializer/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.1) + +project(%{APPNAMELC}) + +set(ECM_MIN_VERSION "5.22.0") +find_package(ECM ${ECM_MIN_VERSION} CONFIG REQUIRED) + +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) + +include(FeatureSummary) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) + +set(QT_MIN_VERSION "5.6.0") +find_package(Qt5 ${QT_MIN_VERSION} REQUIRED Core Network Gui) + +set(KF5_MIN_VERSION "5.22.0") +find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED) + +set(AKONADI_MIN_VERSION "5.2") +find_package(KF5Akonadi ${AKONADI_MIN_VERSION} CONFIG REQUIRED) + +add_subdirectory(src) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/akonadiserializer/README b/templates/akonadiserializer/README new file mode 100644 --- /dev/null +++ b/templates/akonadiserializer/README @@ -0,0 +1,66 @@ +How To Build This Template +-=-=-=-=-=-=-=-=-=-=-=-=-= + +--- On Linux & similar: + +cd +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=$MY_PREFIX -DCMAKE_BUILD_TYPE=Debug +make +make install or su -c 'make install' + +(MY_PREFIX is where you install your Akonadi setup, replace it accordingly) + +to uninstall the project: +make uninstall or su -c 'make uninstall' + +Note: you can use another build path. Then cd in your build dir and: +export MY_SRC=path_to_your_src +cmake $MY_SRC -DCMAKE_INSTALL_PREFIX=$MY_PREFIX -DCMAKE_BUILD_TYPE=Debug + +--- On Windows: + +cd +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=%MY_PREFIX% -DCMAKE_BUILD_TYPE=Debug +[n]make +[n]make install + +(MY_PREFIX is where you install your Akonadi setup, replace it accordingly) + +to uninstall the project: +[n]make uninstall + +Note: use nmake if you're building with the Visual Studio compiler, or make +if you're using the minGW compiler + + +Implementation hints +-=-=-=-=-=-=-=-=-=-= + +The code generated by the template can be compiled without any further +changes, so you can start with your own code right away. + +However, there are a couple of things you will need to change outside the +serialzer's code, i.e. in the serializer's .desktop file: + +- Name field + +- Comment field + +- Type field: MIME type of your data type + + +Documentation +-=-=-=-=-=-=- + +The Akonadi-KDE API documentation can be found here: +https://api.kde.org/kdepim/akonadi/html/index.html + +General developer information, e.g. tutorials can be found here: +https://techbase.kde.org/KDE_PIM/Akonadi + +The contact site can be found here: +https://community.kde.org/KDE_PIM/Contact diff --git a/templates/akonadiserializer/akonadiserializer.kdevtemplate b/templates/akonadiserializer/akonadiserializer.kdevtemplate new file mode 100644 --- /dev/null +++ b/templates/akonadiserializer/akonadiserializer.kdevtemplate @@ -0,0 +1,6 @@ +[General] +Name=C++ +Comment=Akonadi Serializer Template. A template for an Akonadi data serializer plugin +Category=Akonadi/Serializer +Icon=akonadiserializer.png +ShowFilesAfterGeneration=src/%{APPNAMELC}resource.cpp diff --git a/templates/akonadiserializer/akonadiserializer.png b/templates/akonadiserializer/akonadiserializer.png new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ + * + * 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. If not, see . + */ + +#ifndef AKONADI_SERIALIZER_%{APPNAMEUC}_H +#define AKONADI_SERIALIZER_%{APPNAMEUC}_H + +#include + +#include + +namespace Akonadi +{ + +class SerializerPlugin%{APPNAME} : public QObject + , public ItemSerializerPlugin +{ + Q_OBJECT + Q_INTERFACES(Akonadi::ItemSerializerPlugin) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPlugin%{APPNAME}") + +public: + bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) override; + void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) override; + + QSet parts(const Item &item) const; +}; + +} + +#endif diff --git a/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.cpp b/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.cpp new file mode 100644 --- /dev/null +++ b/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) %{CURRENT_YEAR} by %{AUTHOR} <%{EMAIL}> + * + * 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. If not, see . + */ + +#include "akonadi_serializer_%{APPNAMELC}.h" + +#include + +using namespace Akonadi; + +bool SerializerPlugin%{APPNAME}::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) +{ + Q_UNUSED(item); + Q_UNUSED(label); + Q_UNUSED(data); + Q_UNUSED(version); + + // TODO Implement this + + return false; +} + +void SerializerPlugin%{APPNAME}::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) +{ + Q_UNUSED(item); + Q_UNUSED(label); + Q_UNUSED(data); + Q_UNUSED(version); + + // TODO Implement this +} + +QSet SerializerPlugin%{APPNAME}::parts(const Item &item) const +{ + // only need to reimplement this when implementing partial serialization + // i.e. when using the "label" parameter of the other two methods + return ItemSerializerPlugin::parts(item); +} diff --git a/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.desktop b/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.desktop new file mode 100644 --- /dev/null +++ b/templates/akonadiserializer/src/akonadi_serializer_%{APPNAMELC}.desktop @@ -0,0 +1,7 @@ +[Misc] +Name=%{APPNAME} Serializer +Comment=An Akonadi serializer plugin for %{APPNAMELC} + +[Plugin] +Type=application/x-vnd.kde.%{APPNAMELC} +X-KDE-Library=akonadi_serializer_%{APPNAMELC}