diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ include(FeatureSummary) include(ECMOptionalAddSubdirectory) include(ECMQtDeclareLoggingCategory) +include(KDEPackageAppTemplates) find_package(KF5Activities ${KF5_MIN_VERSION}) set_package_properties(KF5Activities PROPERTIES DESCRIPTION "management of Plasma activities" @@ -164,4 +165,7 @@ ecm_optional_add_subdirectory(xembed-sni-proxy) add_subdirectory(soliduiserver) + +add_subdirectory(templates) + feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/CMakeLists.txt b/templates/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/CMakeLists.txt @@ -0,0 +1,5 @@ +set(apptemplate_DIRS + ion-dataengine +) + +kde_package_app_templates(TEMPLATES ${apptemplate_DIRS} INSTALL_DIR ${KDE_INSTALL_KTEMPLATESDIR}) diff --git a/templates/ion-dataengine/CMakeLists.txt b/templates/ion-dataengine/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) + +project(plasma-%{APPNAMEID}) + +set(QT_MIN_VERSION "5.5.0") +set(KF5_MIN_VERSION "5.18.0") + +find_package(ECM 1.8.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) + +find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED + COMPONENTS + Gui + Network +) + +find_package(KF5 ${KF5_MIN_VERSION} REQUIRED + COMPONENTS + Plasma + UnitConversion +) + +find_package(PlasmaWeatherIon REQUIRED) +set_package_properties(PlasmaWeatherIon PROPERTIES + DESCRIPTION "Plasma Weather Ion library" + TYPE REQUIRED +) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) + +add_subdirectory(src) diff --git a/templates/ion-dataengine/Messages.sh b/templates/ion-dataengine/Messages.sh new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp` -o $podir/plasma_engine_ion_%{APPNAMELC}.pot diff --git a/templates/ion-dataengine/README b/templates/ion-dataengine/README new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/README @@ -0,0 +1,50 @@ +Plasma Weather Ion Dataengine +----------------------------- + +-- Note -- + +Remember that this dataengine relies on a semi-public API, +as exposed by the "plasma/weather/ion.h" header. +While this API has been the same for some time, there is no guarantee +that it will be stable for all future versions of the weather dataengine +as part of Plasma Workspace. + +The main purpose of having this interface semi-public is to allow everyone +to easily develop adapters to more weather data providers, +without needing to work directly in the module plasma-workspace. + +Once your ion dataengine is nicely working, please consider to merge +it into the KDE module plasma-workspace with the existing ion dataengines. +Looking forward to cover another weather data providers with your help :) + + +-- Build instructions -- + +cd /where/your/ion/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + + +-- Test instructions -- + +Test your ion dataengine with +plasmaengineexplorer --engine weather +where you should see your ion listed in the default data "ions". +You then can test the ion itself by entering into the field for "Source name" e.g. +%{APPNAMELC}|weather|foo +or +%{APPNAMELC}|validate|foo +with "foo" being some location term which makes sense for your ion dataengine, +and triggering the button "Request Source". + + +Or try to use it from the Plasma Addons Weather widget. +Start the widget in a test window with +plasmawindowed org.kde.plasma.weather +and then see to use your ion dataengine by configuring the widget to use +a weatherstation provided via your ion dataengine diff --git a/templates/ion-dataengine/cmake/FindPlasmaWeatherIon.cmake b/templates/ion-dataengine/cmake/FindPlasmaWeatherIon.cmake new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/cmake/FindPlasmaWeatherIon.cmake @@ -0,0 +1,31 @@ +# - Try to find the Plasma Weather Ion library +# Once done this will define +# +# PlasmaWeatherIon_FOUND - system has Plasma Weather Ion +# PlasmaWeatherIon_INCLUDE_DIR - the Plasma Weather Ion include directory +# PlasmaWeatherIon_LIBRARIES - Plasma Weather Ion library + +if (PlasmaWeatherIon_INCLUDE_DIR AND PlasmaWeatherIon_LIBRARY) + # Already in cache, be silent + set(PlasmaWeatherIon_FIND_QUIETLY TRUE) +endif (PlasmaWeatherIon_INCLUDE_DIR AND PlasmaWeatherIon_LIBRARY) + +find_path(PlasmaWeatherIon_INCLUDE_DIR NAMES plasma/weather/ion.h) +find_library(PlasmaWeatherIon_LIBRARY weather_ion) + +if (PlasmaWeatherIon_INCLUDE_DIR AND PlasmaWeatherIon_LIBRARY) + set(PlasmaWeatherIon_FOUND TRUE) + set(PlasmaWeatherIon_LIBRARIES ${PlasmaWeatherIon_LIBRARY}) +endif (PlasmaWeatherIon_INCLUDE_DIR AND PlasmaWeatherIon_LIBRARY) + +if (PlasmaWeatherIon_FOUND) + if (NOT PlasmaWeatherIon_FIND_QUIETLY) + message(STATUS "Found Plasma Weather Ion library: ${PlasmaWeatherIon_LIBRARIES}") + endif (NOT PlasmaWeatherIon_FIND_QUIETLY) +else (PlasmaWeatherIon_FOUND) + if (PlasmaWeatherIon_FIND_REQUIRED) + message(FATAL_ERROR "Plasma Weather Ion library was not found") + endif(PlasmaWeatherIon_FIND_REQUIRED) +endif (PlasmaWeatherIon_FOUND) + +mark_as_advanced(PlasmaWeatherIon_INCLUDE_DIR PlasmaWeatherIon_LIBRARY) diff --git a/templates/ion-dataengine/ion-dataengine.kdevtemplate b/templates/ion-dataengine/ion-dataengine.kdevtemplate new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/ion-dataengine.kdevtemplate @@ -0,0 +1,6 @@ +# KDE Config File +[General] +Name=Plasma Weather Ion Dataengine +Comment=A special Plasma sub-dataengine for the Plasma Weather dataengine, providing access to one weather data service provider. +ShowFilesAfterGeneration=%{PROJECTDIR}/src/ion-%{APPNAMELC}.cpp +Category=KDE/Plasma Dataengine diff --git a/templates/ion-dataengine/src/CMakeLists.txt b/templates/ion-dataengine/src/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/src/CMakeLists.txt @@ -0,0 +1,15 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_engine_ion_%{APPNAMELC}\") + +add_library(ion_%{APPNAMELC} MODULE ion-%{APPNAMELC}.cpp) + +target_link_libraries (ion_%{APPNAMELC} + ${PlasmaWeatherIon_LIBRARIES} + KF5::Plasma + KF5::UnitConversion +) + +kcoreaddons_desktop_to_json(ion_%{APPNAMELC} ion-%{APPNAMELC}.desktop) + +install (FILES ion-%{APPNAMELC}.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) + +install (TARGETS ion_%{APPNAMELC} DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/dataengine) diff --git a/templates/ion-dataengine/src/ion-%{APPNAMELC}.h b/templates/ion-dataengine/src/ion-%{APPNAMELC}.h new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/src/ion-%{APPNAMELC}.h @@ -0,0 +1,45 @@ +/* + * 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 Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ION%{APPNAMEUC}_H +#define ION%{APPNAMEUC}_H + +#include + +class Q_DECL_EXPORT %{APPNAME}Ion : public IonInterface +{ + Q_OBJECT + +public: + %{APPNAME}Ion(QObject *parent, const QVariantList &args); + ~%{APPNAME}Ion(); + +public: // IonInterface API + bool updateIonSource(const QString& source) override; + void reset() override; + +private: + void fetchValidateData(const QString &source); + void fetchWeatherData(const QString &source); + + void onValidateReport(const QString &source); + void onWeatherDataReport(const QString &source); + +}; + +#endif diff --git a/templates/ion-dataengine/src/ion-%{APPNAMELC}.cpp b/templates/ion-dataengine/src/ion-%{APPNAMELC}.cpp new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/src/ion-%{APPNAMELC}.cpp @@ -0,0 +1,127 @@ +/* + * 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 Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ion-%{APPNAMELC}.h" + +#include + + +%{APPNAME}Ion::%{APPNAME}Ion(QObject *parent, const QVariantList &args) + : IonInterface(parent, args) +{ + // call whenever the ion is ready + setInitialized(true); +} + +%{APPNAME}Ion::~%{APPNAME}Ion() +{ +} + +bool %{APPNAME}Ion::updateIonSource(const QString& source) +{ + // We expect the applet to send the source in the following tokenization: + // ionname:validate:place_name - Triggers validation of place + // ionname:weather:place_name - Triggers receiving weather of place + + const QStringList sourceAction = source.split(QLatin1Char('|')); + + // Guard: if the size of array is not 2 then we have bad data, return an error + if (sourceAction.size() < 2) { + setData(source, QStringLiteral("validate"), "%{APPNAMELC}|malformed"); + return true; + } + + if (sourceAction.at(1) == QLatin1String("validate") && sourceAction.size() > 2) { + fetchValidateData(source); + return true; + } + + if (sourceAction.at(1) == QLatin1String("weather") && sourceAction.size() > 2) { + fetchWeatherData(source); + return true; + } + + setData(source, QStringLiteral("validate"), "%{APPNAMELC}|malformed"); + return true; +} + +void %{APPNAME}Ion::reset() +{ +} + +// purpose: fetch/use data from provider and trigger processing of returned data in a handler +void %{APPNAME}Ion::fetchValidateData(const QString &source) +{ + + // here called directly for a start + onValidateReport(source); +} + +// purpose: process data from provider and turn into DataEngine data +void %{APPNAME}Ion::onValidateReport(const QString &source) +{ + + const QStringList sourceAction = source.split(QLatin1Char('|')); + + QStringList placeList; + placeList.append(QStringLiteral("place|").append(QStringLiteral("Some example place"))); + + if (placeList.size() == 1) { + setData(source, QStringLiteral("validate"), QStringLiteral("%{APPNAMELC}|valid|single|").append(placeList.at(0))); + return; + } + if (placeList.size() > 1) { + setData(source, QStringLiteral("validate"), QStringLiteral("%{APPNAMELC}|valid|multiple|").append(placeList.join(QLatin1Char('|')))); + return; + } + if (placeList.size() == 0) { + setData(source, QStringLiteral("validate"), QStringLiteral("%{APPNAMELC}|invalid|single|").append(sourceAction.at(2))); + return; + } +} + +// purpose: fetch data from provider and trigger processing of returned data in a handler +void %{APPNAME}Ion::fetchWeatherData(const QString &source) +{ + // here called directly for a start + onWeatherDataReport(source); +} + + +// purpose: process data from provider and turn into DataEngine data for the given source key +void %{APPNAME}Ion::onWeatherDataReport(const QString &source) +{ + Plasma::DataEngine::Data data; + + // examples, see the existing ion dataengines for other keys in use: + // plasma-workspace/dataengines/weather/ions/ + // an overview document with all common keys and value types is yet to be written + data.insert(QStringLiteral("Place"), "Some %{APPNAME} place"); + data.insert(QStringLiteral("Station"), "Some %{APPNAME} station"); + data.insert(QStringLiteral("Credit"), "%{APPNAME} weather data provider"); + data.insert(QStringLiteral("Temperature"), "23.4"); + data.insert(QStringLiteral("Temperature Unit"), QString::number(KUnitConversion::Celsius)); + + // finally set the created data for the given source key, so it will be pushed out to all consumers + setData(source, data); +} + + +K_EXPORT_PLASMA_DATAENGINE_WITH_JSON(%{APPNAMELC}, %{APPNAME}Ion, "ion-%{APPNAMELC}.json") + +#include "ion-%{APPNAMELC}.moc" diff --git a/templates/ion-dataengine/src/ion-%{APPNAMELC}.desktop b/templates/ion-dataengine/src/ion-%{APPNAMELC}.desktop new file mode 100644 --- /dev/null +++ b/templates/ion-dataengine/src/ion-%{APPNAMELC}.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=%{APPNAME} Weather Data Provider +Comment=Access to the weather data provider %{APPNAME} +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-ParentApp=weatherengine +Type=Service +Icon=noneyet +X-KDE-Library=ion_%{APPNAMELC} +X-KDE-PluginInfo-Name=%{APPNAMELC}