diff --git a/CMakeLists.txt b/CMakeLists.txt index de2f1953..9239b777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ set_package_properties(CURL PROPERTIES DESCRIPTION "Command line tool and library for transferring data with URLs" URL "https://curl.se/" TYPE REQUIRED - PURPOSE "KIO HTTP(S) slave" + PURPOSE "E-mail library and KIO HTTP(S) slave" ) # optional features diff --git a/cmake/modules/FindKDE4Internal.cmake b/cmake/modules/FindKDE4Internal.cmake index c053edfc..e298bbba 100644 --- a/cmake/modules/FindKDE4Internal.cmake +++ b/cmake/modules/FindKDE4Internal.cmake @@ -245,6 +245,7 @@ set(_kde_libraries khttp kspeech karchive + kemail kfile kidletime kio diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index 2dfce102..38a455d2 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -111,6 +111,8 @@ install( KDiskFreeSpaceInfo KDoubleNumInput KDoubleValidator + KEMail + KEMailDialog KEMailSettings KEditListWidget KEditToolBar diff --git a/includes/KEMail b/includes/KEMail new file mode 100644 index 00000000..53094ccf --- /dev/null +++ b/includes/KEMail @@ -0,0 +1 @@ +#include "../kemail.h" diff --git a/includes/KEMailDialog b/includes/KEMailDialog new file mode 100644 index 00000000..a5564845 --- /dev/null +++ b/includes/KEMailDialog @@ -0,0 +1 @@ +#include "../kemaildialog.h" diff --git a/interfaces/ktexteditor/CMakeLists.txt b/interfaces/ktexteditor/CMakeLists.txt index 285532bd..c546d283 100644 --- a/interfaces/ktexteditor/CMakeLists.txt +++ b/interfaces/ktexteditor/CMakeLists.txt @@ -2,6 +2,8 @@ include_directories( ${KDE4_KPARTS_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.. + ${CMAKE_SOURCE_DIR}/kutils/kemail + ${CMAKE_BINARY_DIR}/kutils/kemail ) ########### next target ############### @@ -36,6 +38,7 @@ add_library(ktexteditor ${LIBRARY_TYPE} ${ktexteditor_LIB_SRCS}) target_link_libraries(ktexteditor ${KDE4_KDECORE_LIBS} ${KDE4_KPARTS_LIBS} + ${KDE4_KEMAIL_LIBS} ${QT_QTDBUS_LIBRARY} ) diff --git a/kdecore/kdebug.areas b/kdecore/kdebug.areas index 3b730da2..efbafb7e 100644 --- a/kdecore/kdebug.areas +++ b/kdecore/kdebug.areas @@ -193,6 +193,9 @@ # karchive 51009 karchive +# kemail +51010 kemail + # kdemultimedia 67100 kmix diff --git a/kdecore/kernel/ktoolinvocation_x11.cpp b/kdecore/kernel/ktoolinvocation_x11.cpp index dd94f7d2..c1421a0b 100644 --- a/kdecore/kernel/ktoolinvocation_x11.cpp +++ b/kdecore/kernel/ktoolinvocation_x11.cpp @@ -120,11 +120,8 @@ void KToolInvocation::invokeMailer(const QString &_to, const QString &_cc, const return; KConfig config(QString::fromLatin1("emaildefaults")); - KConfigGroup defaultsGrp(&config, "Defaults"); + KConfigGroup profileGrp(&config, "General"); - QString group = defaultsGrp.readEntry("Profile","Default"); - - KConfigGroup profileGrp(&config, QString::fromLatin1("PROFILE_%1").arg(group) ); QString command = profileGrp.readPathEntry("EmailClient", QString()); QString to, cc, bcc; diff --git a/kio/CMakeLists.txt b/kio/CMakeLists.txt index b3fc270a..dd31d38b 100644 --- a/kio/CMakeLists.txt +++ b/kio/CMakeLists.txt @@ -46,7 +46,6 @@ set(kiocore_STAT_SRCS kio/kdirmodel.cpp kio/kdirnotify.cpp kio/kdynamicjobtracker.cpp - kio/kemailsettings.cpp kio/kfileitem.cpp kio/kfileitemlistproperties.cpp kio/kfileitemactions.cpp @@ -221,7 +220,6 @@ install( kio/kdirlister.h kio/kdirmodel.h kio/kdirnotify.h - kio/kemailsettings.h kio/kfileitem.h kio/kfileitemlistproperties.h kio/kfileitemactions.h diff --git a/kio/kio/kemailsettings.cpp b/kio/kio/kemailsettings.cpp deleted file mode 100644 index 2b973231..00000000 --- a/kio/kio/kemailsettings.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2000 Alex Zepeda - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "kemailsettings.h" - -#include -#include -#include -#include - -class KEMailSettingsPrivate { -public: - KEMailSettingsPrivate() : m_pConfig( 0 ) {} - ~KEMailSettingsPrivate() { delete m_pConfig; } - KConfig *m_pConfig; - QStringList profiles; - QString m_sDefaultProfile, m_sCurrentProfile; -}; - -QString KEMailSettings::defaultProfileName() const -{ - return p->m_sDefaultProfile; -} - -QString KEMailSettings::getSetting(KEMailSettings::Setting s) const -{ - KConfigGroup cg( p->m_pConfig, QString("PROFILE_")+p->m_sCurrentProfile); - switch (s) { - case ClientProgram: { - return cg.readEntry("EmailClient"); - break; - } - case ClientTerminal: { - return cg.readEntry("TerminalClient", QVariant(false)).toString(); - break; - } - case RealName: { - return cg.readEntry("FullName"); - break; - } - case EmailAddress: { - return cg.readEntry("EmailAddress"); - break; - } - case ReplyToAddress: { - return cg.readEntry("ReplyAddr"); - break; - } - case Organization: { - return cg.readEntry("Organization"); - break; - } - case OutServer: { - return cg.readEntry("OutgoingServer"); - break; - } - case OutServerLogin: { - return cg.readEntry("OutgoingUserName"); - break; - } - case OutServerPass: { - return cg.readEntry("OutgoingPassword"); - break; - } - case OutServerType: { - return cg.readEntry("OutgoingServerType"); - break; - } - case OutServerCommand: { - return cg.readEntry("OutgoingCommand"); - break; - } - case OutServerTLS: { - return cg.readEntry("OutgoingServerTLS", QVariant(false)).toString(); - break; - } - case InServer: { - return cg.readEntry("IncomingServer"); - break; - } - case InServerLogin: { - return cg.readEntry("IncomingUserName"); - break; - } - case InServerPass: { - return cg.readEntry("IncomingPassword"); - break; - } - case InServerType: { - return cg.readEntry("IncomingServerType"); - break; - } - case InServerMBXType: { - return cg.readEntry("IncomingServerMBXType"); - break; - } - case InServerTLS: { - return cg.readEntry("IncomingServerTLS", QVariant(false)).toString(); - break; - } - }; - return QString(); -} -void KEMailSettings::setSetting(KEMailSettings::Setting s, const QString &v) -{ - KConfigGroup cg( p->m_pConfig, QString("PROFILE_")+p->m_sCurrentProfile); - switch (s) { - case ClientProgram: { - cg.writePathEntry("EmailClient", v); - break; - } - case ClientTerminal: { - cg.writeEntry("TerminalClient", (v == "true") ); - break; - } - case RealName: { - cg.writeEntry("FullName", v); - break; - } - case EmailAddress: { - cg.writeEntry("EmailAddress", v); - break; - } - case ReplyToAddress: { - cg.writeEntry("ReplyAddr", v); - break; - } - case Organization: { - cg.writeEntry("Organization", v); - break; - } - case OutServer: { - cg.writeEntry("OutgoingServer", v); - break; - } - case OutServerLogin: { - cg.writeEntry("OutgoingUserName", v); - break; - } - case OutServerPass: { - cg.writeEntry("OutgoingPassword", v); - break; - } - case OutServerType: { - cg.writeEntry("OutgoingServerType", v); - break; - } - case OutServerCommand: { - cg.writeEntry("OutgoingCommand", v); - break; - } - case OutServerTLS: { - cg.writeEntry("OutgoingServerTLS", (v == "true") ); - break; - } - case InServer: { - cg.writeEntry("IncomingServer", v); - break; - } - case InServerLogin: { - cg.writeEntry("IncomingUserName", v); - break; - } - case InServerPass: { - cg.writeEntry("IncomingPassword", v); - break; - } - case InServerType: { - cg.writeEntry("IncomingServerType", v); - break; - } - case InServerMBXType: { - cg.writeEntry("IncomingServerMBXType", v); - break; - } - case InServerTLS: { - cg.writeEntry("IncomingServerTLS", (v == "true") ); - break; - } - }; - cg.sync(); -} - -void KEMailSettings::setDefault(const QString &s) -{ - p->m_pConfig->group("Defaults").writeEntry("Profile", s); - p->m_pConfig->sync(); - p->m_sDefaultProfile=s; - -} - -void KEMailSettings::setProfile (const QString &s) -{ - QString groupname="PROFILE_"; - groupname.append(s); - p->m_sCurrentProfile=s; - if (!p->m_pConfig->hasGroup(groupname)) { // Create a group if it doesn't exist - KConfigGroup cg(p->m_pConfig, groupname); - cg.writeEntry("ServerType", QString()); - p->profiles+=s; - } -} - -QString KEMailSettings::currentProfileName() const -{ - return p->m_sCurrentProfile; -} - -QStringList KEMailSettings::profiles() const -{ - return p->profiles; -} - -KEMailSettings::KEMailSettings() - :p(new KEMailSettingsPrivate()) -{ - p->m_sCurrentProfile.clear(); - - p->m_pConfig = new KConfig("emaildefaults"); - - const QStringList groups = p->m_pConfig->groupList(); - for (QStringList::ConstIterator it = groups.begin(); it != groups.end(); ++it) { - if ( (*it).startsWith( QLatin1String( "PROFILE_" ) ) ) - p->profiles+= (*it).mid(8, (*it).length()); - } - - KConfigGroup cg( p->m_pConfig, "Defaults"); - p->m_sDefaultProfile = cg.readEntry("Profile", i18n("Default")); - if (!p->m_sDefaultProfile.isNull()) { - if (!p->m_pConfig->hasGroup(QString("PROFILE_")+p->m_sDefaultProfile)) - setDefault(i18n("Default")); - else - setDefault(p->m_sDefaultProfile); - } else { - if (p->profiles.count()) { - setDefault(p->profiles[0]); - } else - setDefault(i18n("Default")); - } - setProfile(defaultProfileName()); -} - -KEMailSettings::~KEMailSettings() -{ - delete p; -} diff --git a/kio/kio/kemailsettings.h b/kio/kio/kemailsettings.h deleted file mode 100644 index dbc3bea9..00000000 --- a/kio/kio/kemailsettings.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2000 Alex Zepeda - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef KEMAILSETTINGS_H -#define KEMAILSETTINGS_H - -#include -#include - -#include - -class KEMailSettingsPrivate; - - -/** - * This is just a small class to facilitate accessing e-mail settings in - * a sane way, and allowing any program to manage multiple e-mail - * profiles effortlessly - * - * @author Alex Zepeda zipzippy@sonic.net - **/ -class KIO_EXPORT KEMailSettings { -public: - /** - * The list of settings that I thought of when I wrote this - * class. Any extra settings thought of later can be accessed - * easily with getExtendedSetting and setExtendedSetting. - * @see getSetting() - * @see setSetting() - * @see getExtendedSetting() - * @see setExtendedSetting() - **/ - enum Setting { - ClientProgram, - ClientTerminal, - RealName, - EmailAddress, - ReplyToAddress, - Organization, - OutServer, - OutServerLogin, - OutServerPass, - OutServerType, - OutServerCommand, - OutServerTLS, - InServer, - InServerLogin, - InServerPass, - InServerType, - InServerMBXType, - InServerTLS - }; - - /** - * The various extensions allowed. - **/ - enum Extension { - POP3, - SMTP, - OTHER - }; - - /** - * Default constructor, just sets things up. - **/ - KEMailSettings(); - - /** - * Default destructor, nothing to see here. - **/ - ~KEMailSettings(); - - /** - * List of profiles available. - * @return the list of profiles - **/ - QStringList profiles() const; - - /** - * Returns the name of the current profile. - * @returns what profile we're currently using - **/ - QString currentProfileName() const; - - /** - * Change the current profile. - * @param s the name of the new profile - **/ - void setProfile (const QString &s); - - /** - * Returns the name of the default profile. - * @returns the name of the one that's currently default QString() if none - **/ - QString defaultProfileName() const; - - /** - * Sets a new default. - * @param def the new default - **/ - void setDefault(const QString &def); - - /** - * Get one of the predefined "basic" settings. - * @param s the setting to get - * @return the value of the setting, or QString() if not - * set - **/ - QString getSetting(KEMailSettings::Setting s) const; - - /** - * Set one of the predefined "basic" settings. - * @param s the setting to set - * @param v the new value of the setting, or QString() to - * unset - **/ - void setSetting(KEMailSettings::Setting s, const QString &v); - -private: - KEMailSettingsPrivate* const p; -}; - -#endif diff --git a/kutils/CMakeLists.txt b/kutils/CMakeLists.txt index 685197d6..22e71035 100644 --- a/kutils/CMakeLists.txt +++ b/kutils/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(kdnssd) add_subdirectory(khttp) add_subdirectory(kspeech) add_subdirectory(karchive) +add_subdirectory(kemail) ######## kidletime #################### diff --git a/kutils/kemail/CMakeLists.txt b/kutils/kemail/CMakeLists.txt new file mode 100644 index 00000000..8f788c45 --- /dev/null +++ b/kutils/kemail/CMakeLists.txt @@ -0,0 +1,40 @@ +include_directories(${CURL_INCLUDE_DIRS}) + +add_definitions(-DKDE_DEFAULT_DEBUG_AREA=51010) + +set(kemail_LIB_SRCS + kemailsettings.cpp + kemail.cpp + kemaildialog.cpp +) + +add_library(kemail ${LIBRARY_TYPE} ${kemail_LIB_SRCS}) + +target_link_libraries(kemail PUBLIC + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} +) +target_link_libraries(kemail PRIVATE ${CURL_LIBRARIES}) + +set_target_properties(kemail PROPERTIES + VERSION ${GENERIC_LIB_VERSION} + SOVERSION ${GENERIC_LIB_SOVERSION} +) + +generate_export_header(kemail) + +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/kemail_export.h + kemail.h + kemaildialog.h + kemailsettings.h + DESTINATION ${KDE4_INCLUDE_INSTALL_DIR} + COMPONENT Devel +) + +install( + TARGETS kemail + EXPORT kdelibsLibraryTargets + ${INSTALL_TARGETS_DEFAULT_ARGS} +) diff --git a/kutils/kemail/kemail.cpp b/kutils/kemail/kemail.cpp new file mode 100644 index 00000000..f9900573 --- /dev/null +++ b/kutils/kemail/kemail.cpp @@ -0,0 +1,252 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kemail.h" +#include "klocale.h" +#include "kemailsettings.h" +#include "kdebug.h" + +#include +#include + +class KEMailPrivate +{ +public: + KEMailPrivate(); + ~KEMailPrivate(); + + static QByteArray makeData(const QString &subject, const QString &message, const KUrl::List &attach); + + static size_t curlReadCallback(char *ptr, size_t size, size_t nmemb, void *userdata); + + CURL* m_curl; + struct curl_slist *m_curlrcpt; + KUrl m_server; + QString m_user; + QString m_password; + QString m_from; + QStringList m_to; + QByteArray m_data; + QString m_errorstring; +}; + +KEMailPrivate::KEMailPrivate() + : m_curl(nullptr), + m_curlrcpt(nullptr) +{ +} + +KEMailPrivate::~KEMailPrivate() +{ + if (m_curlrcpt) { + curl_slist_free_all(m_curlrcpt); + } + if (m_curl) { + curl_easy_cleanup(m_curl); + } +} + +QByteArray KEMailPrivate::makeData(const QString &subject, const QString &message, const KUrl::List &attach) +{ + // TODO: + Q_UNUSED(attach); + + QByteArray subjectbytes("Subject: "); + subjectbytes.append(subject.toAscii()); + subjectbytes.append("\r\n\r\n"); + + QByteArray result = subjectbytes; + result.append(message.toAscii()); + result.replace('\n', "\r\n"); + result.append("\r\n"); + return result; +} + +size_t KEMailPrivate::curlReadCallback(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + KEMailPrivate* kemailprivate = static_cast(userdata); + Q_ASSERT(kemailprivate); + Q_ASSERT(size == 1); + QByteArray kemailmessage = kemailprivate->m_data.left(qMin(int(nmemb), kemailprivate->m_data.size())); + if (kemailmessage.size() <= 0) { + kDebug() << "Message has been sent"; + return 0; + } + ::memcpy(ptr, kemailmessage.constData(), kemailmessage.size() * sizeof(char)); + kemailprivate->m_data = kemailprivate->m_data.mid(kemailmessage.size(), kemailprivate->m_data.size() - kemailmessage.size()); + return kemailmessage.size(); +} + +KEMail::KEMail(QObject *parent) + : QObject(parent), + d(new KEMailPrivate()) +{ + KEMailSettings kemailsettings; + setServer(KUrl(kemailsettings.getSetting(KEMailSettings::OutServer))); + setFrom(kemailsettings.getSetting(KEMailSettings::EmailAddress)); + setUser(kemailsettings.getSetting(KEMailSettings::OutServerLogin)); + setPassword(kemailsettings.getSetting(KEMailSettings::OutServerPass)); +} + +KEMail::~KEMail() +{ + delete d; +} + +KUrl KEMail::server() const +{ + return d->m_server; +} + +bool KEMail::setServer(const KUrl &server) +{ + d->m_errorstring.clear(); + QString serverurl = server.url(); + if (serverurl.isEmpty()) { + d->m_errorstring = i18n("Invalid server URL: %1", serverurl); + return false; + } + if (!serverurl.startsWith("smtp://")) { + serverurl.prepend(QLatin1String("smtp://")); + } + d->m_server = serverurl; + return true; +} + +QString KEMail::user() const +{ + return d->m_user; +} + +bool KEMail::setUser(const QString &user) +{ + d->m_errorstring.clear(); + if (user.isEmpty()) { + d->m_errorstring = i18n("Invalid user: %1", user); + return false; + } + d->m_user = user; + return true; +} + +QString KEMail::password() const +{ + return d->m_password; +} + +bool KEMail::setPassword(const QString &password) +{ + d->m_errorstring.clear(); + if (password.isEmpty()) { + d->m_errorstring = i18n("Invalid password: %1", password); + return false; + } + d->m_password = password; + return true; +} + +QString KEMail::from() const +{ + return d->m_from; +} + +bool KEMail::setFrom(const QString &from) +{ + d->m_errorstring.clear(); + if (from.isEmpty()) { + d->m_errorstring = i18n("Invalid sender: %1", from); + return false; + } + d->m_from = from; + return true; +} + +QStringList KEMail::to() const +{ + return d->m_to; +} + +bool KEMail::setTo(const QStringList &to) +{ + d->m_errorstring.clear(); + if (to.isEmpty()) { + d->m_errorstring = i18n("Invalid receivers: %1", to.join(QLatin1String(", "))); + return false; + } + d->m_to = to; + return true; +} + +bool KEMail::send(const QString &subject, const QString &message, const KUrl::List &attach) +{ + d->m_errorstring.clear(); + if (message.isEmpty()) { + d->m_errorstring = i18n("Invalid message: %1", message); + return false; + } + d->m_data = KEMailPrivate::makeData(subject, message, attach); + d->m_curl = curl_easy_init(); + if (!d->m_curl) { + d->m_errorstring = i18n("Could not create context"); + return false; + } + if (d->m_curlrcpt) { + curl_slist_free_all(d->m_curlrcpt); + d->m_curlrcpt = nullptr; + } + + const QByteArray serverbytes = d->m_server.url().toAscii(); + const QByteArray userbytes = d->m_user.toAscii(); + const QByteArray passwordbytes = d->m_password.toAscii(); + const QByteArray frombytes = d->m_from.toAscii(); + curl_easy_setopt(d->m_curl, CURLOPT_URL, serverbytes.constData()); + curl_easy_setopt(d->m_curl, CURLOPT_USERNAME, userbytes.constData()); + curl_easy_setopt(d->m_curl, CURLOPT_PASSWORD, passwordbytes.constData()); + curl_easy_setopt(d->m_curl, CURLOPT_MAIL_FROM, frombytes.constData()); + foreach (const QString &to, d->m_to) { + const QByteArray tobytes = to.toAscii(); + d->m_curlrcpt = curl_slist_append(d->m_curlrcpt, tobytes.constData()); + } + curl_easy_setopt(d->m_curl, CURLOPT_MAIL_RCPT, d->m_curlrcpt); + curl_easy_setopt(d->m_curl, CURLOPT_READFUNCTION, KEMailPrivate::curlReadCallback); + curl_easy_setopt(d->m_curl, CURLOPT_READDATA, d); + curl_easy_setopt(d->m_curl, CURLOPT_UPLOAD, 1L); + // curl_easy_setopt(d->m_curl, CURLOPT_VERBOSE, 1L); + // TODO: option for these and add setting to KEMailSettings + curl_easy_setopt(d->m_curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN"); + curl_easy_setopt(d->m_curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY); + + bool result = true; + CURLcode curlresult = curl_easy_perform(d->m_curl); + if (curlresult != CURLE_OK) { + d->m_errorstring = curl_easy_strerror(curlresult); + kWarning() << d->m_errorstring; + result = false; + } + + curl_slist_free_all(d->m_curlrcpt); + d->m_curlrcpt = nullptr; + curl_easy_cleanup(d->m_curl); + d->m_curl = nullptr; + return result; +} + +QString KEMail::errorString() const +{ + return d->m_errorstring; +} diff --git a/kutils/kemail/kemail.h b/kutils/kemail/kemail.h new file mode 100644 index 00000000..3a30caea --- /dev/null +++ b/kutils/kemail/kemail.h @@ -0,0 +1,80 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEMAIL_H +#define KEMAIL_H + +#include "kemail_export.h" + +#include +#include +#include + +class KEMailPrivate; + +/*! + Class to send mail. + Example: + \code + KEMail kemail; + kemail.setServer(KUrl("smtp://myuser@myhost.com:123")); + kemail.setUser("myuser"); + kemail.setPassword("mypass"); + kemail.setFrom("myuser@myhost.com"); + kemail.setTo(QStringList() << "otheruser@otherhost.com"); + qDebug() << kemail.send("hello"); + \endcode + + @since 4.22 + @warning the API is subject to change + + @see KEMailSettings +*/ +class KEMAIL_EXPORT KEMail : public QObject +{ + Q_OBJECT +public: + /*! + @brief Contructs object with @p parent + */ + KEMail(QObject *parent = nullptr); + ~KEMail(); + + KUrl server() const; + bool setServer(const KUrl &server); + QString user() const; + bool setUser(const QString &user); + QString password() const; + bool setPassword(const QString &password); + + QString from() const; + bool setFrom(const QString &from); + QStringList to() const; + bool setTo(const QStringList &to); + + bool send(const QString &subject, const QString &message, const KUrl::List &attach = KUrl::List()); + + //! @brief Returns human-readable description of the error that occured + QString errorString() const; + +private: + Q_DISABLE_COPY(KEMail); + KEMailPrivate *d; +}; + +#endif // KEMAIL_H diff --git a/kutils/kemail/kemaildialog.cpp b/kutils/kemail/kemaildialog.cpp new file mode 100644 index 00000000..f1927f05 --- /dev/null +++ b/kutils/kemail/kemaildialog.cpp @@ -0,0 +1,102 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kemaildialog.h" +#include "klocale.h" +#include "kmessagebox.h" +#include "kdebug.h" + +#include "ui_kemaildialog.h" + +class KEMailDialogPrivate +{ +public: + KEMailDialogPrivate(); + ~KEMailDialogPrivate(); + + KEMail* m_kemail; + Ui::KEMailDialogUI ui; +}; + +KEMailDialogPrivate::KEMailDialogPrivate() + : m_kemail(nullptr) +{ + m_kemail = new KEMail(); +} + +KEMailDialogPrivate::~KEMailDialogPrivate() +{ + delete m_kemail; +} + +KEMailDialog::KEMailDialog(QWidget *parent, Qt::WindowFlags flags) + : KDialog(parent, flags), + d(new KEMailDialogPrivate()) +{ + d->ui.setupUi(mainWidget()); + d->ui.fromlineedit->setText(d->m_kemail->from()); + d->ui.userlineedit->setText(d->m_kemail->user()); + d->ui.passlineedit->setText(d->m_kemail->password()); + // TODO: connect(d->ui.settingslabel) +} + +KEMailDialog::~KEMailDialog() +{ + delete d; +} + +KEMail* KEMailDialog::kemail() const +{ + return d->m_kemail; +} + +void KEMailDialog::slotButtonClicked(int button) +{ + if (button == KDialog::Ok) { + d->m_kemail->setFrom(d->ui.fromlineedit->text()); + d->m_kemail->setUser(d->ui.userlineedit->text()); + d->m_kemail->setPassword(d->ui.passlineedit->text()); + d->m_kemail->setTo(d->ui.recipientslistwidget->items()); + if (!d->m_kemail->server().isValid()) { + KMessageBox::error(this, i18n("No server specified")); + return; + } else if (d->m_kemail->from().isEmpty()) { + KMessageBox::error(this, i18n("No Sender specified")); + return; + } else if (d->m_kemail->to().isEmpty()) { + KMessageBox::error(this, i18n("No recipients specified")); + return; + } else if (d->ui.sibjectlineedit->text().isEmpty()) { + KMessageBox::error(this, i18n("No subject specified")); + return; + } else if (d->ui.messagetextedit->textOrHtml().isEmpty()) { + KMessageBox::error(this, i18n("No message specified")); + return; + } + const bool result = d->m_kemail->send( + d->ui.sibjectlineedit->text(), + d->ui.messagetextedit->textOrHtml(), + d->ui.attachlistwidget->items() + ); + if (!result) { + KMessageBox::error(this, d->m_kemail->errorString()); + return; + } + } + KDialog::slotButtonClicked(button); +} diff --git a/kutils/kemail/kemaildialog.h b/kutils/kemail/kemaildialog.h new file mode 100644 index 00000000..6c20558b --- /dev/null +++ b/kutils/kemail/kemaildialog.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEMAILDIALOG_H +#define KEMAILDIALOG_H + +#include "kemail_export.h" + +#include +#include + +class KEMailDialogPrivate; + +/*! + Class to send mail via convenience dialog. + Example: + \code + KEMailDialog kemaildialog; + kemaildialog.show(); + qDebug() << kemaildialog.exec(); + \endcode + + @since 4.22 + @warning the API is subject to change +*/ +class KEMAIL_EXPORT KEMailDialog : public KDialog +{ + Q_OBJECT +public: + /*! + @brief Contructs object with @p parent and @p flags + */ + KEMailDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = 0); + ~KEMailDialog(); + + KEMail* kemail() const; + +protected Q_SLOTS: + virtual void slotButtonClicked(int button); + +private: + Q_DISABLE_COPY(KEMailDialog); + KEMailDialogPrivate *d; +}; + +#endif // KEMAILDIALOG_H diff --git a/kutils/kemail/kemaildialog.ui b/kutils/kemail/kemaildialog.ui new file mode 100644 index 00000000..20eeea7e --- /dev/null +++ b/kutils/kemail/kemaildialog.ui @@ -0,0 +1,157 @@ + + + KEMailDialogUI + + + + 0 + 0 + 805 + 382 + + + + KPasswdRouletteDialogUI + + + + + + Message + + + + + + + + + Subject: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + From + + + + + + + + + + + + User: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + From: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Password: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QLineEdit::Password + + + + + + + Settings + + + Qt::AlignCenter + + + + + + + + + + + + Attachments + + + + + + Recipients + + + + + + + + + + + + + + + + + + + + + KRichTextEdit + +
krichtextedit.h
+
+ + KLineEdit + +
klineedit.h
+
+ + KUrlLabel + +
kurllabel.h
+
+ + KEditListWidget + +
keditlistwidget.h
+
+
+ +
diff --git a/kutils/kemail/kemailsettings.cpp b/kutils/kemail/kemailsettings.cpp new file mode 100644 index 00000000..8c66374d --- /dev/null +++ b/kutils/kemail/kemailsettings.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000 Alex Zepeda + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kemailsettings.h" + +#include +#include +#include +#include + +class KEMailSettingsPrivate { +public: + KEMailSettingsPrivate(); + ~KEMailSettingsPrivate(); + + KConfig *m_config; +}; + +KEMailSettingsPrivate::KEMailSettingsPrivate() + : m_config(nullptr) +{ + m_config = new KConfig("emaildefaults"); +} + +KEMailSettingsPrivate::~KEMailSettingsPrivate() +{ + delete m_config; +} + +QString KEMailSettings::getSetting(KEMailSettings::Setting s) const +{ + KConfigGroup cg(d->m_config, QString("General")); + switch (s) { + case ClientProgram: { + return cg.readEntry("EmailClient"); + } + case ClientTerminal: { + return cg.readEntry("TerminalClient", QVariant(false)).toString(); + } + case RealName: { + return cg.readEntry("FullName"); + } + case EmailAddress: { + return cg.readEntry("EmailAddress"); + } + case Organization: { + return cg.readEntry("Organization"); + } + case OutServer: { + return cg.readEntry("OutgoingServer"); + break; + } + case OutServerLogin: { + return cg.readEntry("OutgoingUserName"); + } + case OutServerPass: { + return cg.readEntry("OutgoingPassword"); + } + }; + return QString(); +} +void KEMailSettings::setSetting(KEMailSettings::Setting s, const QString &v) +{ + KConfigGroup cg(d->m_config, QString("General")); + switch (s) { + case ClientProgram: { + cg.writePathEntry("EmailClient", v); + break; + } + case ClientTerminal: { + cg.writeEntry("TerminalClient", (v == "true") ); + break; + } + case RealName: { + cg.writeEntry("FullName", v); + break; + } + case EmailAddress: { + cg.writeEntry("EmailAddress", v); + break; + } + case Organization: { + cg.writeEntry("Organization", v); + break; + } + case OutServer: { + cg.writeEntry("OutgoingServer", v); + break; + } + case OutServerLogin: { + cg.writeEntry("OutgoingUserName", v); + break; + } + case OutServerPass: { + cg.writeEntry("OutgoingPassword", v); + break; + } + }; + cg.sync(); +} + +KEMailSettings::KEMailSettings() + : d(new KEMailSettingsPrivate()) +{ +} + +KEMailSettings::~KEMailSettings() +{ + delete d; +} diff --git a/kutils/kemail/kemailsettings.h b/kutils/kemail/kemailsettings.h new file mode 100644 index 00000000..90542904 --- /dev/null +++ b/kutils/kemail/kemailsettings.h @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2000 Alex Zepeda + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef KEMAILSETTINGS_H +#define KEMAILSETTINGS_H + +#include + +#include + +class KEMailSettingsPrivate; + +/** + * This is just a small class to facilitate accessing e-mail settings in + * a sane way, and allowing any program to manage multiple e-mail + * profiles effortlessly + * + * @author Alex Zepeda zipzippy@sonic.net + **/ +class KEMAIL_EXPORT KEMailSettings { +public: + /** + * The list of settings that I thought of when I wrote this + * class. Any extra settings thought of later can be accessed + * easily with getExtendedSetting and setExtendedSetting. + * @see getSetting() + * @see setSetting() + **/ + enum Setting { + ClientProgram, + ClientTerminal, + RealName, + EmailAddress, + Organization, + OutServer, + OutServerLogin, + OutServerPass + }; + + /** + * Default constructor, just sets things up. + **/ + KEMailSettings(); + + /** + * Default destructor, nothing to see here. + **/ + ~KEMailSettings(); + + /** + * Get one of the predefined "basic" settings. + * @param setting the setting to get + * @return the value of the setting, or QString() if not set + **/ + QString getSetting(const KEMailSettings::Setting ssetting) const; + + /** + * Set one of the predefined "basic" settings. + * @param setting the setting to set + * @param value the new value of the setting, or QString() to unset + **/ + void setSetting(KEMailSettings::Setting setting, const QString &value); + +private: + KEMailSettingsPrivate* const d; +}; + +#endif // KEMAILSETTINGS_H