diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 29534bd..d354b1a 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -1,53 +1,54 @@ function(add_share_plugin name) kcoreaddons_add_plugin(${name} SOURCES ${ARGN} JSON "${name}.json" INSTALL_NAMESPACE "purpose") target_link_libraries(${name} Qt5::Core KF5::Purpose) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${name}_config.qml") install(FILES "${name}_config.qml" DESTINATION ${DATA_INSTALL_DIR}/purpose) endif() endfunction() set(KPACKAGE_RELATIVE_DATA_INSTALL_DIR "kpackage") function(kpackage_install_package dir component root) set(install_dir ${ARGV3}) if(NOT install_dir) set(install_dir ${KPACKAGE_RELATIVE_DATA_INSTALL_DIR}) endif() install(DIRECTORY ${dir}/ USE_SOURCE_PERMISSIONS DESTINATION ${DATA_INSTALL_DIR}/${install_dir}/${root}/${component} PATTERN Messages.sh EXCLUDE) endfunction() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) include(QMLModules) find_qmlmodule(Ubuntu.OnlineAccounts 0.1) find_qmlmodule(org.kde.kdeconnect 1.0) find_qmlmodule(org.kde.kquickcontrolsaddons 2.0) find_package(KAccounts) find_package(KF5KIO ${KF5_DEP_VERSION} REQUIRED) set_package_properties(KAccounts PROPERTIES PURPOSE "Used to find your system-wide defined, for now only for YouTube." TYPE OPTIONAL ) set_package_properties(KF5KIO PROPERTIES TYPE REQUIRED) add_subdirectory(saveas) add_subdirectory(imgur) add_subdirectory(pastebin) add_subdirectory(ktp-sendfile) if (KAccounts_FOUND) add_subdirectory(youtube) file(COPY twitter DESTINATION ${CMAKE_CURRENT_BINARY_DIR} PATTERN "main.js.in" EXCLUDE) configure_file(twitter/contents/code/main.js.in ${CMAKE_CURRENT_BINARY_DIR}/twitter/contents/code/main.js @ONLY) kpackage_install_package(${CMAKE_CURRENT_BINARY_DIR}/twitter Twitter Purpose) kaccounts_add_service(${CMAKE_CURRENT_SOURCE_DIR}/twitter-microblog.service.in) add_subdirectory(nextcloud) endif() add_subdirectory(kdeconnect) add_subdirectory(reviewboard) add_subdirectory(phabricator) +add_subdirectory(email) install(FILES ExportPluginType.json DESTINATION ${DATA_INSTALL_DIR}/purpose/types) diff --git a/src/plugins/email/CMakeLists.txt b/src/plugins/email/CMakeLists.txt new file mode 100644 index 0000000..86bd6cb --- /dev/null +++ b/src/plugins/email/CMakeLists.txt @@ -0,0 +1,2 @@ +add_share_plugin(emailplugin emailplugin.cpp) +target_link_libraries(emailplugin KF5::I18n) diff --git a/src/plugins/email/Messages.sh b/src/plugins/email/Messages.sh new file mode 100644 index 0000000..fced46b --- /dev/null +++ b/src/plugins/email/Messages.sh @@ -0,0 +1,4 @@ +#!/bin/sh +$EXTRACTRC `find . -name \*.rc` `find . -name \*.ui` >> rc.cpp +$XGETTEXT `find . -not -path \*/tests/\* -name \*.cpp -o -name \*.cc -o -name \*.h` -o $podir/purpose_email.pot +rm -f rc.cpp diff --git a/src/plugins/email/emailplugin.cpp b/src/plugins/email/emailplugin.cpp new file mode 100644 index 0000000..730a42e --- /dev/null +++ b/src/plugins/email/emailplugin.cpp @@ -0,0 +1,143 @@ +/* + Copyright 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com + Author: Daniel Vrátil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +EXPORT_SHARE_VERSION + +namespace { + +class EmailJob : public Purpose::Job +{ + Q_OBJECT +public: + EmailJob(QObject *parent = nullptr) + : Purpose::Job(parent) + {} + + void start() override + { + // Use xdg-mime to figure out what is the user's default email client + const auto xdgmime = QStandardPaths::findExecutable(QStringLiteral("xdg-mime")); + if (xdgmime.isEmpty()) { + // xdg-utils not available, let Qt figure what to do for us... + launchMailto(); + return; + } + + auto xdgmimeProc = new QProcess(this); + xdgmimeProc->setProgram(xdgmime); + xdgmimeProc->setArguments({ QStringLiteral("query"), QStringLiteral("default"), + QStringLiteral("x-scheme-handler/mailto") }); + connect(xdgmimeProc, static_cast(&QProcess::finished), + this, &EmailJob::xdgMimeFinished); + xdgmimeProc->start(); + } + + void xdgMimeFinished(int code, QProcess::ExitStatus status) + { + if (code != 0 || status != QProcess::NormalExit) { + // Something went wrong, fallback to QDesktopServices + launchMailto(); + return; + } + + const auto proc = qobject_cast(sender()); + const auto mailService = proc->readAllStandardOutput(); + qDebug() << "Default mailto handler:" << mailService; + // Thunderbird is a special snowflake and cannot handle attachments via + // the mailto schema, so we need to handle it ourselves + if (mailService.contains("thunderbird")) { + launchThunderbird(); + } else { + launchMailto(); + } + } + + void launchMailto() + { + const auto urls = data().value(QStringLiteral("urls")).toArray(); + + QUrlQuery query; + for (const auto &att : urls) { + query.addQueryItem(QStringLiteral("attachment"), att.toString()); + } + QUrl url; + url.setScheme(QStringLiteral("mailto")); + url.setQuery(query); + if (!QDesktopServices::openUrl(url)) { + setError(KJob::UserDefinedError); + setErrorText(i18n("Failed to launch email client")); + } + emitResult(); + } + + void launchThunderbird() + { + // thunderbird -compose "attachment='file:///att1','file:///att2'" + + const auto tb = QStandardPaths::findExecutable(QStringLiteral("thunderbird")); + if (tb.isEmpty()) { + launchMailto(); + return; + } + + const auto urls = data().value(QStringLiteral("urls")).toArray(); + QStringList attachments; + for (const auto &att : urls) { + attachments.push_back(att.toString()); + } + const auto args = QStringList{ QStringLiteral("-compose"), + QStringLiteral("attachment='%1'").arg(attachments.join(QStringLiteral(","))) }; + if (!QProcess::startDetached(tb, args)) { + setError(KJob::UserDefinedError); + setErrorText(i18n("Failed to launch email client")); + } + emitResult(); + } + +}; + +} + +class Q_DECL_EXPORT EmailPlugin : public Purpose::PluginBase +{ + Q_OBJECT +public: + EmailPlugin(QObject *p, const QVariantList &) + : Purpose::PluginBase(p) + {} + + Purpose::Job *createJob() const override + { + return new EmailJob(nullptr); + } +}; + +K_PLUGIN_FACTORY_WITH_JSON(Email, "emailplugin.json", registerPlugin();) + +#include "emailplugin.moc" diff --git a/src/plugins/email/emailplugin.json b/src/plugins/email/emailplugin.json new file mode 100644 index 0000000..7dbb04c --- /dev/null +++ b/src/plugins/email/emailplugin.json @@ -0,0 +1,19 @@ +{ + "KPlugin": { + "Authors": [ + { + "Name": "Daniel Vrátil" + } + ], + "Category": "Utilities", + "Description": "Send via Email", + "Icon": "mail-message", + "License": "GPL", + "Name": "Send via Email..." + }, + "X-Purpose-Configuration": [], + "X-Purpose-Constraints": [], + "X-Purpose-PluginTypes": [ + "Export" + ] +}