diff --git a/CMakeLists.txt b/CMakeLists.txt index ff9a6993..f02241d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,151 +1,151 @@ cmake_minimum_required(VERSION 3.0) -set(PIM_VERSION "5.6.50") +set(PIM_VERSION "5.6.51") if (POLICY CMP0053) cmake_policy(SET CMP0053 NEW) endif() project(Messagelib VERSION ${PIM_VERSION}) option(MIMETREEPARSER_ONLY_BUILD "Build only mimetreeparser" FALSE) option(KDEPIM_ENTERPRISE_BUILD "Enable features specific to the enterprise branch, which are normally disabled. Also, it disables many components not needed for Kontact such as the Kolab client." FALSE) set(KF5_VERSION "5.38.0") find_package(ECM ${KF5_VERSION} CONFIG REQUIRED) set(MESSAGELIB_LIB_VERSION ${PIM_VERSION}) set(AKONADIMIME_LIB_VERSION "5.6.40") set(QT_REQUIRED_VERSION "5.8.0") set(AKONADI_VERSION "5.6.40") set(GRANTLEETHEME_LIB_VERSION "5.6.40") set(GRAVATAR_LIB_VERSION "5.6.41") set(IDENTITYMANAGEMENT_LIB_VERSION "5.6.40") set(KCONTACTS_LIB_VERSION "5.6.40") set(KDEPIM_APPS_LIB_VERSION "5.6.40") set(KLDAP_LIB_VERSION "5.6.40") set(KMAILTRANSPORT_LIB_VERSION "5.6.40") set(KMBOX_LIB_VERSION "5.6.40") set(KMIME_LIB_VERSION "5.6.40") set(KPIMTEXTEDIT_LIB_VERSION "5.6.41") set(LIBKDEPIM_LIB_VERSION "5.6.40") set(LIBKLEO_LIB_VERSION "5.6.40") set(PIMCOMMON_LIB_VERSION "5.6.41") set(GPGME_LIB_VERSION "1.8.0") set(AKONADI_CONTACT_VERSION "5.6.40") if (${MIMETREEPARSER_ONLY_BUILD}) set(ECM_VERSION "5.26.0") set(KMIME_LIB_VERSION "5.1.40") endif() find_package(ECM ${ECM_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${Messagelib_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH}) set(LIBRARY_NAMELINK) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(CMakePackageConfigHelpers) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMQtDeclareLoggingCategory) include(ECMAddTests) include(ECMCoverageOption) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Gui Test) find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) find_package(QGpgme ${GPGME_LIB_VERSION} CONFIG REQUIRED) if (NOT ${MIMETREEPARSER_ONLY_BUILD}) find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Network PrintSupport WebEngine WebEngineWidgets) find_package(KF5Archive ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Completion ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5ConfigWidgets ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5ItemViews ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5JobWidgets ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5KIO ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Service ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Sonnet ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5TextWidgets ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5WidgetsAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5WindowSystem ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5XmlGui ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5SyntaxHighlighting ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5DBusAddons ${KF5_VERSION} CONFIG REQUIRED) find_package(Grantlee5 "5.1" CONFIG REQUIRED) find_package(KF5Akonadi ${AKONADI_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiMime ${AKONADIMIME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Contacts ${KCONTACTS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiContact ${AKONADI_CONTACT_VERSION} CONFIG REQUIRED) find_package(KF5FollowupReminder ${KDEPIM_APPS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5GrantleeTheme ${GRANTLEETHEME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Gravatar ${GRAVATAR_LIB_VERSION} CONFIG REQUIRED) find_package(KF5IdentityManagement ${IDENTITYMANAGEMENT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5KaddressbookGrantlee ${KDEPIM_APPS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Ldap ${KLDAP_LIB_VERSION} CONFIG REQUIRED) find_package(KF5LibkdepimAkonadi ${LIBKDEPIM_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Libkleo ${LIBKLEO_LIB_VERSION} CONFIG REQUIRED) find_package(KF5MailTransportAkonadi ${KMAILTRANSPORT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Mbox ${KMBOX_LIB_VERSION} CONFIG REQUIRED) find_package(KF5PimCommonAkonadi ${PIMCOMMON_LIB_VERSION} CONFIG REQUIRED) find_package(KF5PimTextEdit ${KPIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5SendLater ${KDEPIM_APPS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiSearch "5.6.40" CONFIG REQUIRED) set_package_properties(KF5AkonadiSearch PROPERTIES DESCRIPTION "The Akonadi Search libraries" URL "http://www.kde.org" TYPE REQUIRED PURPOSE "Provides search capabilities in KMail and Akonadi") endif() # Support for the GIT revision number in messagecomposer-version.h if(EXISTS "${Messagelib_SOURCE_DIR}/.git") find_package(Git) if(GIT_FOUND) execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY ${Messagelib_SOURCE_DIR} OUTPUT_VARIABLE messagelib_git_revision) string(REGEX REPLACE "\n" "" messagelib_git_revision "${messagelib_git_revision}") set(messagelib_git_revision "git-${messagelib_git_revision}") execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --oneline --format=%ci WORKING_DIRECTORY ${Messagelib_SOURCE_DIR} OUTPUT_VARIABLE messagelib_git_last_change) string(REGEX REPLACE " [-0-9:+ ]*\n" "" messagelib_git_last_change "${messagelib_git_last_change}") endif() endif () add_definitions(-DQT_NO_URL_CAST_FROM_STRING) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x000000) if(BUILD_TESTING) add_definitions(-DBUILD_TESTING) endif(BUILD_TESTING) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) add_subdirectory(mimetreeparser) if (NOT ${MIMETREEPARSER_ONLY_BUILD}) add_subdirectory(messageviewer) add_subdirectory(templateparser) add_subdirectory(messagecomposer) add_subdirectory(messagecore) add_subdirectory(messagelist) add_subdirectory(webengineviewer) endif() install( FILES messagelib.renamecategories messagelib.categories DESTINATION ${KDE_INSTALL_CONFDIR} ) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/messageviewer/src/CMakeLists.txt b/messageviewer/src/CMakeLists.txt index 0339bb1a..2301d75c 100644 --- a/messageviewer/src/CMakeLists.txt +++ b/messageviewer/src/CMakeLists.txt @@ -1,432 +1,429 @@ add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) add_definitions(-DTRANSLATION_DOMAIN=\"libmessageviewer\") add_subdirectory(messagepartthemes/grantlee) # KCFG files: # The main messageviewer.kcfg is configured by CMake and put in the build directory. if(KDEPIM_ENTERPRISE_BUILD) set(LEGACY_MANGLE_FROM_TO_HEADERS true) set(LEGACY_BODY_INVITES true) set(EXCHANGE_COMPATIBLE_INVITATIONS true) else() set(LEGACY_MANGLE_FROM_TO_HEADERS false) set(LEGACY_BODY_INVITES false) set(EXCHANGE_COMPATIBLE_INVITATIONS false) endif() configure_file(settings/messageviewer.kcfg.cmake ${CMAKE_CURRENT_BINARY_DIR}/messageviewer.kcfg) include(CheckIncludeFiles) find_package(Inotify) set_package_properties(Inotify PROPERTIES PURPOSE "Filesystem alteration notifications using inotify") if(Inotify_FOUND) set(HAVE_SYS_INOTIFY_H 1) else() set(HAVE_SYS_INOTIFY_H 0) endif() configure_file(config-messageviewer.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-messageviewer.h) # target_include_directories does not handle empty include paths include_directories(${GPGME_INCLUDES}) if(BUILD_TESTING) add_subdirectory(scamdetection/autotests) add_subdirectory(scamdetection/tests) add_subdirectory(viewerplugins/tests/) add_subdirectory(htmlwriter/autotests) add_subdirectory(viewer/webengine/tests) add_subdirectory(messagepartthemes/default/autotests) add_subdirectory(viewer/webengine/autotests) endif() add_subdirectory(pics) add_subdirectory(kconf_update) add_subdirectory(about) add_subdirectory(messageviewerheaderplugins) if(DEBUG_SIGNATURE) add_definitions(-DDEBUG_SIGNATURE) endif() set(libmessageviewer_mailviewer_SRCS viewer/webengine/mailwebengineview.cpp viewer/webengine/mailwebenginepage.cpp viewer/webengine/loadexternalreferencesurlinterceptor/loadexternalreferencesurlinterceptor.cpp viewer/webengine/cidreferencesurlinterceptor/cidreferencesurlinterceptor.cpp viewer/webengine/blockexternalresourcesurlinterceptor/blockexternalresourcesurlinterceptor.cpp viewer/webengine/mailwebenginescript.cpp ) set(libmessageviewer_viewer_SRCS - viewer/bodypartformatterfactory.cpp - viewer/bodypartformatterfactorysingleton.cpp viewer/csshelper.cpp viewer/csshelperbase.cpp viewer/editorwatcher.cpp viewer/objecttreeemptysource.cpp viewer/objecttreeviewersource.cpp viewer/viewer.cpp viewer/viewer_p.cpp viewer/messagedisplayformatattribute.cpp viewer/urlhandlermanager.cpp viewer/mimeparttree/mimeparttreeview.cpp viewer/mimeparttree/mimetreemodel.cpp ) set(libmessageviewer_widgets_SRCS widgets/attachmentdialog.cpp widgets/configurewidget.cpp widgets/printingsettings.cpp widgets/htmlstatusbar.cpp widgets/vcardviewer.cpp widgets/invitationsettings.cpp widgets/openattachmentfolderwidget.cpp widgets/mailsourceviewtextbrowserwidget.cpp widgets/submittedformwarningwidget.cpp ) set(libmessageviewer_widgets_webengine_SRCS widgets/mailsourcewebengineviewer.cpp ) set(libmessageviewer_header_SRCS header/contactdisplaymessagememento.cpp header/headerstrategy.cpp header/richheaderstrategy.cpp header/headerstyle.cpp header/grantleeheaderstyle.cpp header/plainheaderstyle.cpp header/headerstyle_util.cpp header/grantleeheaderformatter.cpp header/grantleeheaderteststyle.cpp header/kxface.cpp header/headerstyleplugin.cpp header/headerstylepluginmanager.cpp header/headerstyleinterface.cpp header/headerstylemenumanager.cpp ) set(libmessageviewer_scamdetection_SRCS scamdetection/scamdetectionwarningwidget.cpp scamdetection/scamdetectiondetailsdialog.cpp scamdetection/scamattribute.cpp scamdetection/scamcheckshorturl.cpp scamdetection/scamexpandurljob.cpp scamdetection/scamcheckshorturlmanager.cpp ) set(libmessageviewer_scamdetection_webengine_SRCS scamdetection/scamdetectionwebengine.cpp ) set(libmessageviewer_findbar_SRCS findbar/findbarsourceview.cpp ) set(libmessageviewer_utils_SRCS utils/iconnamecache.cpp utils/markmessagereadhandler.cpp utils/messageviewerutil.cpp utils/mimetype.cpp ) set(libmessageviewer_htmlwriter_webengine_SRCS htmlwriter/webengineparthtmlwriter.cpp htmlwriter/webengineembedpart.cpp ) set(libmessageviewer_antispam_SRCS antispam/spamheaderanalyzer.cpp antispam/antispamconfig.cpp ) set(libmessageviewer_job_SRCS job/attachmenteditjob.cpp job/modifymessagedisplayformatjob.cpp ) set(libmessageviewer_viewerplugins_SRCS viewerplugins/viewerpluginmanager.cpp viewerplugins/viewerplugin.cpp viewerplugins/viewerplugininterface.cpp viewerplugins/viewerplugintoolmanager.cpp ) set(libmessageviewer_messagepartthemes_default_SRCS messagepartthemes/default/converthtmltoplaintext.cpp messagepartthemes/default/defaultrenderer.cpp messagepartthemes/default/htmlblock.cpp messagepartthemes/default/messagepartrenderermanager.cpp messagepartthemes/default/plugins/attachmentmessagepartrenderer.cpp messagepartthemes/default/plugins/messagepartrenderer.cpp messagepartthemes/default/plugins/textmessagepartrenderer.cpp messagepartthemes/default/plugins/quotehtml.cpp messagepartthemes/default/messagepartrenderbase.cpp messagepartthemes/default/messagepartrenderplugin.cpp messagepartthemes/default/messagepartrendererfactory.cpp ) set(libmessageviewer_SRCS ${libmessageviewer_messagepartthemes_default_SRCS} ${libmessageviewer_htmlwriter_webengine_SRCS} ${libmessageviewer_messagepartthemes_SRCS} ${libmessageviewer_scamdetection_webengine_SRCS} ${libmessageviewer_widgets_webengine_SRCS} ${libmessageviewer_viewer_SRCS} ${libmessageviewer_widgets_SRCS} ${libmessageviewer_header_SRCS} ${libmessageviewer_scamdetection_SRCS} ${libmessageviewer_findbar_SRCS} ${libmessageviewer_utils_SRCS} ${libmessageviewer_antispam_SRCS} ${libmessageviewer_job_SRCS} ${libmessageviewer_viewerplugins_SRCS} settings/messageviewersettings.cpp ${libmessageviewer_mailviewer_SRCS} ) qt5_add_resources(libmessageviewer_SRCS messagepartthemes.qrc) ecm_qt_declare_logging_category(libmessageviewer_SRCS HEADER messageviewer_debug.h IDENTIFIER MESSAGEVIEWER_LOG CATEGORY_NAME org.kde.pim.messageviewer) kconfig_add_kcfg_files(libmessageviewer_SRCS settings/globalsettings_messageviewer.kcfgc ) ki18n_wrap_ui(libmessageviewer_SRCS ui/settings.ui ui/invitationsettings.ui ui/printingsettings.ui ) add_library(KF5MessageViewer ${libmessageviewer_SRCS}) generate_export_header(KF5MessageViewer BASE_NAME messageviewer) add_library(KF5::MessageViewer ALIAS KF5MessageViewer) target_include_directories(KF5MessageViewer INTERFACE "$") target_link_libraries(KF5MessageViewer PUBLIC KF5::MessageCore KF5::PimCommon KF5::AkonadiCore KF5::AkonadiMime KF5::Contacts KF5::Libkleo KF5::MimeTreeParser PRIVATE KF5::SyntaxHighlighting KF5::ItemViews Qt5::Network KF5::WebEngineViewer KF5::LibkdepimAkonadi KF5::GrantleeTheme KF5::KaddressbookGrantlee Grantlee5::Templates KF5::MailTransportAkonadi KF5::Mime KF5::Mbox KF5::PimTextEdit KF5::Gravatar KF5::IconThemes KF5::I18n KF5::KIOFileWidgets KF5::KIOWidgets KF5::WindowSystem KF5::XmlGui Grantlee5::TextDocument Grantlee5::Templates Qt5::PrintSupport QGpgme ) set_target_properties(KF5MessageViewer PROPERTIES VERSION ${MESSAGEVIEWER_VERSION_STRING} SOVERSION ${MESSAGEVIEWER_SOVERSION} EXPORT_NAME MessageViewer ) install(TARGETS KF5MessageViewer EXPORT KF5MessageViewerTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} ${LIBRARY_NAMELINK} ) ecm_generate_headers(MessageViewer_Camelcasewebengine_HEADERS HEADER_NAMES MailWebEnginePage MailWebEngineView REQUIRED_HEADERS MessageViewer_webengine_HEADERS PREFIX MessageViewer RELATIVE viewer/webengine ) ecm_generate_headers(MessageViewer_Camelcasescam_HEADERS HEADER_NAMES ScamExpandUrlJob ScamCheckShortUrlManager ScamCheckShortUrl REQUIRED_HEADERS MessageViewer_scam_HEADERS PREFIX MessageViewer RELATIVE scamdetection ) ecm_generate_headers(MessageViewer_Camelcaseviewer_HEADERS HEADER_NAMES Viewer CSSHelperBase CSSHelper ObjectTreeEmptySource EditorWatcher Stl_Util - BodyPartFormatterFactory REQUIRED_HEADERS MessageViewer_viewer_HEADERS PREFIX MessageViewer RELATIVE viewer ) ecm_generate_headers(MessageViewer_Camelcasewidgets_HEADERS HEADER_NAMES InvitationSettings PrintingSettings ConfigureWidget REQUIRED_HEADERS MessageViewer_widgets_HEADERS PREFIX MessageViewer RELATIVE widgets ) ecm_generate_headers(MessageViewer_Camelcaseutils_HEADERS HEADER_NAMES IconNameCache MarkMessageReadHandler MessageViewerUtil MimeType REQUIRED_HEADERS MessageViewer_utils_HEADERS PREFIX MessageViewer RELATIVE utils ) ecm_generate_headers(MessageViewer_Camelcaseantispam_HEADERS HEADER_NAMES SpamHeaderAnalyzer REQUIRED_HEADERS MessageViewer_antispam_HEADERS PREFIX MessageViewer RELATIVE antispam ) ecm_generate_headers(MessageViewer_Camelcaseinterfaces_HEADERS HEADER_NAMES BodyPartURLHandler URLHandler REQUIRED_HEADERS MessageViewer_interfaces_HEADERS PREFIX MessageViewer RELATIVE interfaces ) ecm_generate_headers(MessageViewer_Camelcasesettings_HEADERS HEADER_NAMES MessageViewerSettings REQUIRED_HEADERS MessageViewer_settings_HEADERS PREFIX MessageViewer RELATIVE settings ) ecm_generate_headers(MessageViewer_Camelcaseheader_HEADERS HEADER_NAMES HeaderStrategy GrantleeHeaderTestStyle GrantleeHeaderStyle HeaderStyle KXFace HeaderStyle_Util HeaderStylePlugin HeaderStyleInterface PlainHeaderStyle RichHeaderStrategy HeaderStylePluginManager HeaderStyleMenuManager REQUIRED_HEADERS MessageViewer_header_HEADERS PREFIX MessageViewer RELATIVE header ) ecm_generate_headers(MessageViewer_Camelcaseviewerplugin_HEADERS HEADER_NAMES ViewerPluginManager ViewerPlugin ViewerPluginInterface ViewerPluginToolManager REQUIRED_HEADERS MessageViewer_viewerplugin_HEADERS PREFIX MessageViewer RELATIVE viewerplugins ) ecm_generate_headers(MessageViewer_Camelcaserenderer_HEADERS HEADER_NAMES HtmlBlock MessagePartRendererBase MessagePartRendererManager MessagePartRenderPlugin REQUIRED_HEADERS MessageViewer_renderer_HEADERS PREFIX MessageViewer RELATIVE messagepartthemes/default ) ecm_generate_pri_file(BASE_NAME MessageViewer LIB_NAME KF5MessageViewer DEPS "PimCommon MessageCore AkonadiCore AkonadiMime Contacts Libkleo MimeTreeParser" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/MessageViewer ) install(FILES ${MessageViewer_Camelcasewebengine_HEADERS} ${MessageViewer_Camelcaseheader_HEADERS} ${MessageViewer_Camelcaseviewerplugin_HEADERS} ${MessageViewer_Camelcasesettings_HEADERS} ${MessageViewer_Camelcaseutils_HEADERS} ${MessageViewer_Camelcaseinterfaces_HEADERS} ${MessageViewer_Camelcaseviewer_HEADERS} ${MessageViewer_Camelcasewidgets_HEADERS} ${MessageViewer_Camelcaseantispam_HEADERS} ${MessageViewer_Camelfindbar_HEADERS} ${MessageViewer_Camelcasescam_HEADERS} ${MessageViewer_Camelcaserenderer_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/MessageViewer COMPONENT Devel ) install(FILES ${MessageViewer_webengine_HEADERS} ${MessageViewer_scam_HEADERS} ${MessageViewer_viewerplugin_HEADERS} ${MessageViewer_settings_HEADERS} ${MessageViewer_header_HEADERS} ${MessageViewer_utils_HEADERS} ${MessageViewer_interfaces_HEADERS} ${MessageViewer_HEADERS} ${MessageViewer_viewer_HEADERS} ${MessageViewer_widgets_HEADERS} ${MessageViewer_antispam_HEADERS} ${MessageViewer_findbar_HEADERS} ${MessageViewer_renderer_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/messageviewer_export.h ${CMAKE_CURRENT_BINARY_DIR}/globalsettings_messageviewer.h ${CMAKE_CURRENT_BINARY_DIR}/messageviewer_debug.h ${CMAKE_CURRENT_BINARY_DIR}/config-messageviewer.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/messageviewer COMPONENT Devel ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) install(FILES header/data/messageviewer_header_themes.knsrc DESTINATION ${KDE_INSTALL_CONFDIR} ) install(FILES notify/messageviewer.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} ) install(FILES scamdetection/data/longurlServices.json DESTINATION ${KDE_INSTALL_DATADIR}/messageviewer ) diff --git a/messageviewer/src/interfaces/bodyparturlhandler.h b/messageviewer/src/interfaces/bodyparturlhandler.h index 869a8939..64ae7612 100644 --- a/messageviewer/src/interfaces/bodyparturlhandler.h +++ b/messageviewer/src/interfaces/bodyparturlhandler.h @@ -1,110 +1,110 @@ /* -*- c++ -*- interfaces/bodyparturlhandler.h This file is part of KMail's plugin interface. Copyright (c) 2003, 2004 Marc Mutz KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KMAIL_INTERFACE_BODYPARTURLHANDLER_H__ #define __KMAIL_INTERFACE_BODYPARTURLHANDLER_H__ class QString; class QPoint; namespace MimeTreeParser { namespace Interface { class BodyPart; } } namespace MessageViewer { class Viewer; } -namespace MimeTreeParser { +namespace MessageViewer { namespace Interface { /** * @short An interface to body part reader link handlers * @author Marc Mutz * * This interface is a condensed of variant of the more general * @see URLHandler interface, designed to make bodypart-dependent * link operations possible without exposing KMail-internal * classes. * * Implementation-wise, these handlers are called as a nested * Chain Of Responsibilty by an internal implementation of * URLHandler. * * You can create a link whose handling is passed to this handler * by using BodyPart::makeLink( const QString & path ). \a path is * what * is passed back to the methods of this interface. * * Note that the BodyPart interface does not provide a means of * learning the content type of the body part passed. This is * intentional. It is expected that either separate * BodyPartURLHandlers are created for these purposes or else the * information encoded into the path parameter by the * BodyPartFormatter. */ class BodyPartURLHandler { public: virtual ~BodyPartURLHandler() { } /** Called when LMB-clicking on a link in the reader. Should start processing equivalent to "opening" the link. @return true if the click was handled by this handler, false otherwise. */ virtual bool handleClick(MessageViewer::Viewer *viewerInstance, MimeTreeParser::Interface::BodyPart *part, const QString &path) const = 0; /** Called when RMB-clicking on a link in the reader. Should show a context menu at the specified point with the specified widget as parent. @return true if the right-click was handled by this handler, false otherwise. */ virtual bool handleContextMenuRequest(MimeTreeParser::Interface::BodyPart *part, const QString &path, const QPoint &p) const = 0; /** Called when hovering over a link. @return a string to be shown in the status bar while hovering over this link or QString() if the link was not handled by this handler. */ virtual QString statusBarMessage(MimeTreeParser::Interface::BodyPart *part, const QString &path) const = 0; }; } // namespace Interface } #endif // __KMAIL_INTERFACES_BODYPARTURLHANDLER_H__ diff --git a/messageviewer/src/messagepartthemes/default/autotests/setupenv.h b/messageviewer/src/messagepartthemes/default/autotests/setupenv.h index c78b82f2..3248d8dd 100644 --- a/messageviewer/src/messagepartthemes/default/autotests/setupenv.h +++ b/messageviewer/src/messagepartthemes/default/autotests/setupenv.h @@ -1,186 +1,186 @@ /* Copyright (C) 2010 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Copyright (c) 2010 Leo Franchi This library 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 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 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 __MESSAGEVIEWER_TESTS_SETUPENV_H__ #define __MESSAGEVIEWER_TESTS_SETUPENV_H__ #include #include -#include +#include #include #include namespace MessageViewer { namespace Test { /** * setup a environment variables for tests: * * set LC_ALL to C * * set KDEHOME */ void setupEnv(); // We can't use EmptySource, since we need to control some emelnets of the source for tests to also test // loadExternal and htmlMail. class ObjectTreeSource : public MessageViewer::EmptySource { public: ObjectTreeSource(MimeTreeParser::HtmlWriter *writer, MessageViewer::CSSHelperBase *cssHelper) : mWriter(writer) , mCSSHelper(cssHelper) , mAttachmentStrategy(QStringLiteral("smart")) , mHtmlLoadExternal(false) , mDecryptMessage(false) , mShowSignatureDetails(false) , mShowExpandQuotesMark(false) , mPreferredMode(MimeTreeParser::Util::Html) , mQuoteLevel(1) { } MimeTreeParser::HtmlWriter *htmlWriter() override { return mWriter; } CSSHelperBase *cssHelper() override { return mCSSHelper; } bool htmlLoadExternal() const override { return mHtmlLoadExternal; } void setHtmlLoadExternal(bool loadExternal) { mHtmlLoadExternal = loadExternal; } void setAttachmentStrategy(const QString &strategy) { mAttachmentStrategy = strategy; } const MimeTreeParser::AttachmentStrategy *attachmentStrategy() override { return MimeTreeParser::AttachmentStrategy::create(mAttachmentStrategy); } bool autoImportKeys() const override { return true; } bool showEmoticons() const override { return false; } void setShowExpandQuotesMark(bool b) { mShowExpandQuotesMark = b; } bool showExpandQuotesMark() const override { return mShowExpandQuotesMark; } - const MimeTreeParser::BodyPartFormatterBaseFactory *bodyPartFormatterFactory() override + const MimeTreeParser::BodyPartFormatterFactory *bodyPartFormatterFactory() override { - return &mBodyPartFormatterBaseFactory; + return &mBodyPartFormatterFactory; } bool decryptMessage() const override { return mDecryptMessage; } void setAllowDecryption(bool allowDecryption) { mDecryptMessage = allowDecryption; } void setShowSignatureDetails(bool showSignatureDetails) { mShowSignatureDetails = showSignatureDetails; } bool showSignatureDetails() const override { return mShowSignatureDetails; } void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) override { Q_UNUSED(mode); Q_UNUSED(availableModes); } MimeTreeParser::Util::HtmlMode preferredMode() const override { return mPreferredMode; } void setPreferredMode(MimeTreeParser::Util::HtmlMode mode) { mPreferredMode = mode; } int levelQuote() const override { return mQuoteLevel; } void setLevelQuote(int level) { mQuoteLevel = level; } const QTextCodec *overrideCodec() override { return nullptr; } QString createMessageHeader(KMime::Message *message) override { Q_UNUSED(message); return QString(); //do nothing } private: MimeTreeParser::HtmlWriter *mWriter; MessageViewer::CSSHelperBase *mCSSHelper; QString mAttachmentStrategy; - MimeTreeParser::BodyPartFormatterBaseFactory mBodyPartFormatterBaseFactory; + MimeTreeParser::BodyPartFormatterFactory mBodyPartFormatterFactory; bool mHtmlLoadExternal; bool mDecryptMessage; bool mShowSignatureDetails; bool mShowExpandQuotesMark; MimeTreeParser::Util::HtmlMode mPreferredMode; int mQuoteLevel; }; } } #endif //__MESSAGEVIEWER_TESTS_SETUPENV_H__ diff --git a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp index 785fbeee..986c917b 100644 --- a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp +++ b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp @@ -1,125 +1,131 @@ /* This file is part of KMail, the KDE mail client. Copyright (c) 2017 Sandro Knauß KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "messagepartrendererfactory.h" #include "messagepartrendererfactory_p.h" #include "messagepartrenderplugin.h" +#include "viewer/urlhandlermanager.h" #include "messagepartrendererbase.h" #include "messageviewer_debug.h" #include "plugins/attachmentmessagepartrenderer.h" #include "plugins/messagepartrenderer.h" #include "plugins/textmessagepartrenderer.h" #include #include #include using namespace MessageViewer; void MessagePartRendererFactoryPrivate::setup() { if (mAll.isEmpty()) { initalize_builtin_renderers(); loadPlugins(); } } void MessagePartRendererFactoryPrivate::loadPlugins() { KPluginLoader::forEachPlugin(QStringLiteral("messageviewer/bodypartformatter"), [this](const QString &path) { QPluginLoader loader(path); const auto pluginData = loader.metaData().value(QLatin1String("MetaData")).toObject().value(QLatin1String("renderer")).toArray(); if (pluginData.isEmpty()) { qCWarning(MESSAGEVIEWER_LOG) << "Plugin" << path << "has no meta data."; return; } auto plugin = qobject_cast(loader.instance()); if (!plugin) { qCWarning(MESSAGEVIEWER_LOG) << path << "is not a MessagePartRendererPlugin"; return; } MessagePartRendererBase *renderer = nullptr; for (int i = 0; (renderer = plugin->renderer(i)) && i < pluginData.size(); ++i) { const auto metaData = pluginData.at(i).toObject(); const auto type = metaData.value(QLatin1String("type")).toString(); if (type.isEmpty()) { qCWarning(MESSAGEVIEWER_LOG) << path << "returned empty type specification for index" << i; break; } // TODO add plugin priority like we have for BPFs qCDebug(MESSAGEVIEWER_LOG) << "renderer plugin for " << type; insert(type, renderer /*, priority*/); } + + const Interface::BodyPartURLHandler *handler = nullptr; + for (int i = 0; (handler = plugin->urlHandler(i)); ++i) { + URLHandlerManager::instance()->registerHandler(handler); + } }); } void MessagePartRendererFactoryPrivate::initalize_builtin_renderers() { insert(QStringLiteral("MimeTreeParser::MessagePart"), new MessagePartRenderer()); insert(QStringLiteral("MimeTreeParser::TextMessagePart"), new TextMessagePartRenderer()); insert(QStringLiteral("MimeTreeParser::AttachmentMessagePart"), new AttachmentMessagePartRenderer()); } void MessagePartRendererFactoryPrivate::insert(const QString &type, MessagePartRendererBase *formatter) { if (type.isEmpty() || !formatter) { return; } mAll[type].insert(mAll[type].begin(), formatter); } MessagePartRendererFactory::MessagePartRendererFactory() : d(new MessagePartRendererFactoryPrivate) { } MessagePartRendererFactory::~MessagePartRendererFactory() { } MessagePartRendererFactory *MessagePartRendererFactory::instance() { static std::unique_ptr singeltonRendererFactory(new MessagePartRendererFactory); return singeltonRendererFactory.get(); } std::vector MessagePartRendererFactory::typeRegistry( const QString &type) const { d->setup(); Q_ASSERT(!d->mAll.isEmpty()); return d->mAll.value(type); } diff --git a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.cpp b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.cpp index cdb4a223..e203c174 100644 --- a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.cpp +++ b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.cpp @@ -1,24 +1,32 @@ /* Copyright (c) 2017 Volker Krause This library 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 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 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 "messagepartrenderplugin.h" +#include "interfaces/bodyparturlhandler.h" + using namespace MessageViewer; MessagePartRenderPlugin::~MessagePartRenderPlugin() = default; + +const Interface::BodyPartURLHandler *MessagePartRenderPlugin::urlHandler(int idx) const +{ + Q_UNUSED(idx); + return nullptr; +} diff --git a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h index 9dca23f3..247747f0 100644 --- a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h +++ b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h @@ -1,43 +1,48 @@ /* Copyright (c) 2017 Volker Krause This library 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 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 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 MESSAGEVIEWER_MESSAGEPARTRENDERPLUGIN_H #define MESSAGEVIEWER_MESSAGEPARTRENDERPLUGIN_H #include "messageviewer_export.h" #include + namespace MessageViewer { +namespace Interface { +class BodyPartURLHandler; +} class MessagePartRendererBase; /** * Plugin interface for MessagePartRendererBase instances. */ class MESSAGEVIEWER_EXPORT MessagePartRenderPlugin { public: virtual ~MessagePartRenderPlugin(); virtual MessagePartRendererBase *renderer(int index) = 0; + virtual const Interface::BodyPartURLHandler *urlHandler(int idx) const; }; } Q_DECLARE_INTERFACE(MessageViewer::MessagePartRenderPlugin, "org.kde.messageviewer.messagepartrenderer/1.0") #endif // MESSAGEVIEWER_MESSAGEPARTRENDERPLUGIN_H diff --git a/messageviewer/src/viewer/bodypartformatterfactory.cpp b/messageviewer/src/viewer/bodypartformatterfactory.cpp deleted file mode 100644 index 8ba70b36..00000000 --- a/messageviewer/src/viewer/bodypartformatterfactory.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - bodypartformatterfactory.cpp - - This file is part of KMail, the KDE mail client. - Copyright (c) 2004 Marc Mutz , - Ingo Kloecker - - KMail 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. - - KMail 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - In addition, as a special exception, the copyright holders give - permission to link the code of this program with any edition of - the Qt library by Trolltech AS, Norway (or with modified versions - of Qt that use the same license as Qt), and distribute linked - combinations including the two. You must obey the GNU General - Public License in all respects for all of the code used other than - Qt. If you modify this file, you may extend this exception to - your version of the file, but you are not obligated to do so. If - you do not wish to do so, delete this exception statement from - your version. -*/ - -#include "bodypartformatterfactory.h" -#include "urlhandlermanager.h" -#include "messageviewer_debug.h" - -#include - -#include - -#include -#include - -using namespace MessageViewer; - -BodyPartFormatterFactory::BodyPartFormatterFactory() - : MimeTreeParser::BodyPartFormatterBaseFactory() -{ -} - -BodyPartFormatterFactory::~BodyPartFormatterFactory() -{ -} - -void BodyPartFormatterFactory::loadPlugins() -{ - KPluginLoader::forEachPlugin(QStringLiteral("messageviewer/bodypartformatter"), [this](const QString &path) { - QPluginLoader loader(path); - const auto formatterData = loader.metaData().value(QLatin1String("MetaData")).toObject().value(QLatin1String("formatter")).toArray(); - if (formatterData.isEmpty()) { - qCWarning(MESSAGEVIEWER_LOG) << "Plugin" << path << "has no meta data."; - return; - } - - auto plugin = qobject_cast(loader.instance()); - if (!plugin) { - qCWarning(MESSAGEVIEWER_LOG) << "BodyPartFormatterFactory: plugin" << path - << "is not valid!"; - return; - } - - const MimeTreeParser::Interface::BodyPartFormatter *bfp = nullptr; - for (int i = 0; (bfp = plugin->bodyPartFormatter(i)) && i < formatterData.size(); ++i) { - const auto metaData = formatterData.at(i).toObject(); - const auto mimetype = metaData.value(QLatin1String("mimetype")).toString(); - if (mimetype.isEmpty()) { - qCWarning(MESSAGEVIEWER_LOG) << "BodyPartFormatterFactory: plugin" << path - << "returned empty mimetype specification for index" - << i; - break; - } - // priority should always be higher than the built-in ones, otherwise what's the point? - const auto priority = metaData.value(QLatin1String("priority")).toInt() + 100; - qCDebug(MESSAGEVIEWER_LOG) << "plugin for " << mimetype << priority; - insert(mimetype, bfp, priority); - } - - const MimeTreeParser::Interface::BodyPartURLHandler *handler = nullptr; - for (int i = 0; (handler = plugin->urlHandler(i)); ++i) { - URLHandlerManager::instance()->registerHandler(handler); - } - }); -} diff --git a/messageviewer/src/viewer/bodypartformatterfactory.h b/messageviewer/src/viewer/bodypartformatterfactory.h deleted file mode 100644 index eb7bfb3f..00000000 --- a/messageviewer/src/viewer/bodypartformatterfactory.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - bodypartformatterfactory.h - - This file is part of KMail, the KDE mail client. - Copyright (c) 2004 Marc Mutz , - Ingo Kloecker - - KMail 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. - - KMail 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - In addition, as a special exception, the copyright holders give - permission to link the code of this program with any edition of - the Qt library by Trolltech AS, Norway (or with modified versions - of Qt that use the same license as Qt), and distribute linked - combinations including the two. You must obey the GNU General - Public License in all respects for all of the code used other than - Qt. If you modify this file, you may extend this exception to - your version of the file, but you are not obligated to do so. If - you do not wish to do so, delete this exception statement from - your version. -*/ - -#ifndef __MESSAGEVIEWER_BODYPARTFORMATTERFACTORY_H__ -#define __MESSAGEVIEWER_BODYPARTFORMATTERFACTORY_H__ - -#include "messageviewer_export.h" - -#include - -namespace MessageViewer { -class MESSAGEVIEWER_EXPORT BodyPartFormatterFactory : public MimeTreeParser:: - BodyPartFormatterBaseFactory -{ -public: - BodyPartFormatterFactory(); - ~BodyPartFormatterFactory(); - -protected: - void loadPlugins() override; -}; -} - -#endif // __MESSAGEVIEWER_BODYPARTFORMATTERFACTORY_H__ diff --git a/messageviewer/src/viewer/bodypartformatterfactorysingleton.cpp b/messageviewer/src/viewer/bodypartformatterfactorysingleton.cpp deleted file mode 100644 index cb8baea1..00000000 --- a/messageviewer/src/viewer/bodypartformatterfactorysingleton.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2016 Sandro Knauß - - KMail 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. - - KMail 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - In addition, as a special exception, the copyright holders give - permission to link the code of this program with any edition of - the Qt library by Trolltech AS, Norway (or with modified versions - of Qt that use the same license as Qt), and distribute linked - combinations including the two. You must obey the GNU General - Public License in all respects for all of the code used other than - Qt. If you modify this file, you may extend this exception to - your version of the file, but you are not obligated to do so. If - you do not wish to do so, delete this exception statement from - your version. -*/ - -#include "bodypartformatterfactorysingleton.h" -#include "bodypartformatterfactory.h" - -#include - -using namespace MessageViewer; - -static QSharedPointer singleton; - -const MimeTreeParser::BodyPartFormatterBaseFactory *MessageViewer:: -bodyPartFormatterBaseFactoryInstance() -{ - if (!singleton) { - singleton = QSharedPointer( - new BodyPartFormatterFactory()); - } - - return singleton.data(); -} diff --git a/messageviewer/src/viewer/bodypartformatterfactorysingleton.h b/messageviewer/src/viewer/bodypartformatterfactorysingleton.h deleted file mode 100644 index 9caba2b0..00000000 --- a/messageviewer/src/viewer/bodypartformatterfactorysingleton.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (c) 2016 Sandro Knauß - - KMail 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. - - KMail 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - In addition, as a special exception, the copyright holders give - permission to link the code of this program with any edition of - the Qt library by Trolltech AS, Norway (or with modified versions - of Qt that use the same license as Qt), and distribute linked - combinations including the two. You must obey the GNU General - Public License in all respects for all of the code used other than - Qt. If you modify this file, you may extend this exception to - your version of the file, but you are not obligated to do so. If - you do not wish to do so, delete this exception statement from - your version. -*/ - -#ifndef __MESSAGEVIEWER_BODYPARTFORMATTERFACTORYSIGNLETON_P_H__ -#define __MESSAGEVIEWER_BODYPARTFORMATTERFACTORYSIGNLETON_P_H__ - -namespace MimeTreeParser { -class BodyPartFormatterBaseFactory; -} - -namespace MessageViewer { -const MimeTreeParser::BodyPartFormatterBaseFactory *bodyPartFormatterBaseFactoryInstance(); -} -#endif diff --git a/messageviewer/src/viewer/objecttreeemptysource.cpp b/messageviewer/src/viewer/objecttreeemptysource.cpp index 53cb32c6..b1eff831 100644 --- a/messageviewer/src/viewer/objecttreeemptysource.cpp +++ b/messageviewer/src/viewer/objecttreeemptysource.cpp @@ -1,147 +1,146 @@ /* Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "objecttreeemptysource.h" #include "viewer/viewer_p.h" #include "viewer/csshelperbase.h" #include #include +#include #include "messagepartthemes/default/defaultrenderer.h" -#include "bodypartformatterfactorysingleton.h" - using namespace MessageViewer; namespace MessageViewer { class EmptySourcePrivate { public: EmptySourcePrivate() : mAllowDecryption(false) { } bool mAllowDecryption; }; } EmptySource::EmptySource() : MimeTreeParser::Interface::ObjectTreeSource() , d(new MessageViewer::EmptySourcePrivate) { } EmptySource::~EmptySource() { delete d; } bool EmptySource::decryptMessage() const { return d->mAllowDecryption; } bool EmptySource::htmlLoadExternal() const { return false; } bool EmptySource::showSignatureDetails() const { return false; } void EmptySource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) { Q_UNUSED(mode); Q_UNUSED(availableModes); } MimeTreeParser::Util::HtmlMode EmptySource::preferredMode() const { return MimeTreeParser::Util::Html; } void EmptySource::setAllowDecryption(bool allowDecryption) { d->mAllowDecryption = allowDecryption; } int EmptySource::levelQuote() const { return 1; } const QTextCodec *EmptySource::overrideCodec() { return nullptr; } QString EmptySource::createMessageHeader(KMime::Message *message) { Q_UNUSED(message); return QString(); //do nothing } const MimeTreeParser::AttachmentStrategy *EmptySource::attachmentStrategy() { return MimeTreeParser::AttachmentStrategy::smart(); } MimeTreeParser::HtmlWriter *EmptySource::htmlWriter() { return nullptr; } CSSHelperBase *EmptySource::cssHelper() { return nullptr; } bool EmptySource::autoImportKeys() const { return true; } bool EmptySource::showEmoticons() const { return false; } bool EmptySource::showExpandQuotesMark() const { return false; } -const MimeTreeParser::BodyPartFormatterBaseFactory *EmptySource::bodyPartFormatterFactory() +const MimeTreeParser::BodyPartFormatterFactory *EmptySource::bodyPartFormatterFactory() { - return bodyPartFormatterBaseFactoryInstance(); + return MimeTreeParser::BodyPartFormatterFactory::instance(); } bool EmptySource::isPrinting() const { return false; } void EmptySource::render(const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) { DefaultRenderer(msgPart, cssHelper(), htmlWriter); } diff --git a/messageviewer/src/viewer/objecttreeemptysource.h b/messageviewer/src/viewer/objecttreeemptysource.h index 35df9d30..5df9671e 100644 --- a/messageviewer/src/viewer/objecttreeemptysource.h +++ b/messageviewer/src/viewer/objecttreeemptysource.h @@ -1,61 +1,61 @@ /* Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILVIEWER_OBJECTTREEEMPTYSOURCE_H #define MAILVIEWER_OBJECTTREEEMPTYSOURCE_H #include #include "messageviewer_export.h" class QString; namespace MessageViewer { class CSSHelperBase; /** An ObjectTreeSource that does not work on anything */ class EmptySourcePrivate; class MESSAGEVIEWER_EXPORT EmptySource : public MimeTreeParser::Interface::ObjectTreeSource { public: EmptySource(); ~EmptySource(); bool decryptMessage() const override; bool htmlLoadExternal() const override; bool showSignatureDetails() const override; void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) override; MimeTreeParser::Util::HtmlMode preferredMode() const override; void setAllowDecryption(bool allowDecryption); int levelQuote() const override; const QTextCodec *overrideCodec() override; QString createMessageHeader(KMime::Message *message) override; const MimeTreeParser::AttachmentStrategy *attachmentStrategy() override; MimeTreeParser::HtmlWriter *htmlWriter() override; virtual CSSHelperBase *cssHelper(); bool autoImportKeys() const override; bool showEmoticons() const override; bool showExpandQuotesMark() const override; - const MimeTreeParser::BodyPartFormatterBaseFactory *bodyPartFormatterFactory() override; + const MimeTreeParser::BodyPartFormatterFactory *bodyPartFormatterFactory() override; void render(const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) override; bool isPrinting() const override; private: EmptySourcePrivate *const d; }; } #endif diff --git a/messageviewer/src/viewer/objecttreeviewersource.cpp b/messageviewer/src/viewer/objecttreeviewersource.cpp index d2293f51..dbb36d7c 100644 --- a/messageviewer/src/viewer/objecttreeviewersource.cpp +++ b/messageviewer/src/viewer/objecttreeviewersource.cpp @@ -1,135 +1,135 @@ /* Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "objecttreeviewersource.h" #include "csshelper.h" -#include "bodypartformatterfactorysingleton.h" +#include #include #include "messagepartthemes/default/defaultrenderer.h" #include "viewer/viewer_p.h" #include "widgets/htmlstatusbar.h" #include "settings/messageviewersettings.h" using namespace MessageViewer; MailViewerSource::MailViewerSource(ViewerPrivate *viewer) : MimeTreeParser::Interface::ObjectTreeSource() , mViewer(viewer) { } MailViewerSource::~MailViewerSource() { } bool MailViewerSource::decryptMessage() const { return mViewer->decryptMessage(); } bool MailViewerSource::htmlLoadExternal() const { return mViewer->htmlLoadExternal(); } bool MailViewerSource::showSignatureDetails() const { return mViewer->mShowSignatureDetails; } void MailViewerSource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) { mViewer->mColorBar->setAvailableModes(availableModes); mViewer->mColorBar->setMode(mode); } MimeTreeParser::Util::HtmlMode MailViewerSource::preferredMode() const { switch (mViewer->displayFormatMessageOverwrite()) { case MessageViewer::Viewer::UseGlobalSetting: case MessageViewer::Viewer::Unknown: return mViewer->htmlMailGlobalSetting() ? MimeTreeParser::Util::Html : MimeTreeParser::Util ::Normal; case MessageViewer::Viewer::Html: return MimeTreeParser::Util::MultipartHtml; case MessageViewer::Viewer::Text: return MimeTreeParser::Util::MultipartPlain; case MessageViewer::Viewer::ICal: return MimeTreeParser::Util::MultipartIcal; } Q_ASSERT(true); return MimeTreeParser::Util::Html; } int MailViewerSource::levelQuote() const { return mViewer->mLevelQuote; } const QTextCodec *MailViewerSource::overrideCodec() { return mViewer->overrideCodec(); } QString MailViewerSource::createMessageHeader(KMime::Message *message) { return mViewer->writeMsgHeader(message); } const MimeTreeParser::AttachmentStrategy *MailViewerSource::attachmentStrategy() { return mViewer->attachmentStrategy(); } MimeTreeParser::HtmlWriter *MailViewerSource::htmlWriter() { return mViewer->htmlWriter(); } bool MailViewerSource::autoImportKeys() const { return MessageViewer::MessageViewerSettings::self()->autoImportKeys(); } bool MailViewerSource::showEmoticons() const { return mViewer->showEmoticons(); } bool MailViewerSource::showExpandQuotesMark() const { return MessageViewer::MessageViewerSettings::self()->showExpandQuotesMark(); } -const MimeTreeParser::BodyPartFormatterBaseFactory *MailViewerSource::bodyPartFormatterFactory() +const MimeTreeParser::BodyPartFormatterFactory *MailViewerSource::bodyPartFormatterFactory() { - return bodyPartFormatterBaseFactoryInstance(); + return MimeTreeParser::BodyPartFormatterFactory::instance(); } bool MailViewerSource::isPrinting() const { return mViewer->mPrinting; } void MailViewerSource::render(const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) { DefaultRenderer(msgPart, mViewer->cssHelper(), htmlWriter); } diff --git a/messageviewer/src/viewer/objecttreeviewersource.h b/messageviewer/src/viewer/objecttreeviewersource.h index 9415052a..726b848b 100644 --- a/messageviewer/src/viewer/objecttreeviewersource.h +++ b/messageviewer/src/viewer/objecttreeviewersource.h @@ -1,58 +1,58 @@ /* Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILVIEWER_OBJECTTREEVIEWERSOURCE_H #define MAILVIEWER_OBJECTTREEVIEWERSOURCE_H #include class QString; namespace MessageViewer { class ViewerPrivate; /** An ObjectTreeParser source working on a MailViewer object */ class MailViewerSource : public MimeTreeParser::Interface::ObjectTreeSource { public: explicit MailViewerSource(ViewerPrivate *viewer); ~MailViewerSource(); bool decryptMessage() const override; bool htmlLoadExternal() const override; bool showSignatureDetails() const override; void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) override; MimeTreeParser::Util::HtmlMode preferredMode() const override; int levelQuote() const override; const QTextCodec *overrideCodec() override; QString createMessageHeader(KMime::Message *message) override; const MimeTreeParser::AttachmentStrategy *attachmentStrategy() override; MimeTreeParser::HtmlWriter *htmlWriter() override; bool autoImportKeys() const override; bool showEmoticons() const override; bool showExpandQuotesMark() const override; - const MimeTreeParser::BodyPartFormatterBaseFactory *bodyPartFormatterFactory() override; + const MimeTreeParser::BodyPartFormatterFactory *bodyPartFormatterFactory() override; void render(const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) override; bool isPrinting() const override; private: ViewerPrivate *mViewer = nullptr; }; } #endif diff --git a/messageviewer/src/viewer/urlhandlermanager.cpp b/messageviewer/src/viewer/urlhandlermanager.cpp index e524ba25..3480cbfc 100644 --- a/messageviewer/src/viewer/urlhandlermanager.cpp +++ b/messageviewer/src/viewer/urlhandlermanager.cpp @@ -1,1169 +1,1168 @@ /* -*- c++ -*- urlhandlermanager.cpp This file is part of KMail, the KDE mail client. Copyright (c) 2003 Marc Mutz Copyright (C) 2002-2003, 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia KMail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "urlhandlermanager.h" #include "messageviewer_debug.h" #include "messageviewer/urlhandler.h" #include "interfaces/bodyparturlhandler.h" #include "utils/mimetype.h" #include "viewer/viewer_p.h" #include "messageviewer/messageviewerutil.h" #include "../utils/messageviewerutil_p.h" #include "stl_util.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using std::for_each; using std::remove; using std::find; using namespace MessageViewer; using namespace MessageCore; URLHandlerManager *URLHandlerManager::self = nullptr; namespace { class KMailProtocolURLHandler : public MimeTreeParser::URLHandler { public: KMailProtocolURLHandler() : MimeTreeParser::URLHandler() { } ~KMailProtocolURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &url, const QPoint &, ViewerPrivate *) const override { return url.scheme() == QLatin1String("kmail"); } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; }; class ExpandCollapseQuoteURLManager : public MimeTreeParser::URLHandler { public: ExpandCollapseQuoteURLManager() : MimeTreeParser::URLHandler() { } ~ExpandCollapseQuoteURLManager() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleDrag(const QUrl &url, ViewerPrivate *window) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; }; class SMimeURLHandler : public MimeTreeParser::URLHandler { public: SMimeURLHandler() : MimeTreeParser::URLHandler() { } ~SMimeURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; }; class MailToURLHandler : public MimeTreeParser::URLHandler { public: MailToURLHandler() : MimeTreeParser::URLHandler() { } ~MailToURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override { return false; } bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; }; class ContactUidURLHandler : public MimeTreeParser::URLHandler { public: ContactUidURLHandler() : MimeTreeParser::URLHandler() { } ~ContactUidURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *) const override; QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; }; class HtmlAnchorHandler : public MimeTreeParser::URLHandler { public: HtmlAnchorHandler() : MimeTreeParser::URLHandler() { } ~HtmlAnchorHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override { return QString(); } }; class AttachmentURLHandler : public MimeTreeParser::URLHandler { public: AttachmentURLHandler() : MimeTreeParser::URLHandler() { } ~AttachmentURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleShiftClick(const QUrl &, ViewerPrivate *window) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override; bool handleDrag(const QUrl &url, ViewerPrivate *window) const override; bool willHandleDrag(const QUrl &url, ViewerPrivate *window) const override; QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; private: KMime::Content *nodeForUrl(const QUrl &url, ViewerPrivate *w) const; bool attachmentIsInHeader(const QUrl &url) const; }; class ShowAuditLogURLHandler : public MimeTreeParser::URLHandler { public: ShowAuditLogURLHandler() : MimeTreeParser::URLHandler() { } ~ShowAuditLogURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override; QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; bool handleDrag(const QUrl &url, ViewerPrivate *window) const override; }; // Handler that prevents dragging of internal images added by KMail, such as the envelope image // in the enterprise header class InternalImageURLHandler : public MimeTreeParser::URLHandler { public: InternalImageURLHandler() : MimeTreeParser::URLHandler() { } ~InternalImageURLHandler() { } bool handleDrag(const QUrl &url, ViewerPrivate *window) const override; bool willHandleDrag(const QUrl &url, ViewerPrivate *window) const override; bool handleClick(const QUrl &, ViewerPrivate *) const override { return false; } bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override { return QString(); } }; class EmbeddedImageURLHandler : public MimeTreeParser::URLHandler { public: EmbeddedImageURLHandler() : MimeTreeParser::URLHandler() { } ~EmbeddedImageURLHandler() { } bool handleDrag(const QUrl &url, ViewerPrivate *window) const override; bool willHandleDrag(const QUrl &url, ViewerPrivate *window) const override; bool handleClick(const QUrl &, ViewerPrivate *) const override { return false; } bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &url, ViewerPrivate *) const override { Q_UNUSED(url); return QString(); } }; class KRunURLHandler : public MimeTreeParser::URLHandler { public: KRunURLHandler() : MimeTreeParser::URLHandler() { } ~KRunURLHandler() { } bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override { return false; } QString statusBarMessage(const QUrl &, ViewerPrivate *) const override { return QString(); } }; } // anon namespace // // // BodyPartURLHandlerManager // // class URLHandlerManager::BodyPartURLHandlerManager : public MimeTreeParser::URLHandler { public: BodyPartURLHandlerManager() : MimeTreeParser::URLHandler() { } ~BodyPartURLHandlerManager(); bool handleClick(const QUrl &, ViewerPrivate *) const override; bool handleContextMenuRequest(const QUrl &, const QPoint &, ViewerPrivate *) const override; QString statusBarMessage(const QUrl &, ViewerPrivate *) const override; - void registerHandler(const MimeTreeParser::Interface::BodyPartURLHandler *handler); - void unregisterHandler(const MimeTreeParser::Interface::BodyPartURLHandler *handler); + void registerHandler(const Interface::BodyPartURLHandler *handler); + void unregisterHandler(const Interface::BodyPartURLHandler *handler); private: - typedef QVector BodyPartHandlerList; + typedef QVector BodyPartHandlerList; BodyPartHandlerList mHandlers; }; URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() { for_each(mHandlers.begin(), mHandlers.end(), - DeleteAndSetToZero()); + DeleteAndSetToZero()); } void URLHandlerManager::BodyPartURLHandlerManager::registerHandler( - const MimeTreeParser::Interface::BodyPartURLHandler *handler) + const Interface::BodyPartURLHandler *handler) { if (!handler) { return; } unregisterHandler(handler); // don't produce duplicates mHandlers.push_back(handler); } void URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( - const MimeTreeParser::Interface::BodyPartURLHandler *handler) + const Interface::BodyPartURLHandler *handler) { // don't delete them, only remove them from the list! mHandlers.erase(remove(mHandlers.begin(), mHandlers.end(), handler), mHandlers.end()); } static KMime::Content *partNodeFromXKMailUrl(const QUrl &url, ViewerPrivate *w, QString *path) { Q_ASSERT(path); if (!w || url.scheme() != QLatin1String("x-kmail")) { return nullptr; } const QString urlPath = url.path(); // urlPath format is: /bodypart/// qCDebug(MESSAGEVIEWER_LOG) << "BodyPartURLHandler: urlPath ==" << urlPath; if (!urlPath.startsWith(QStringLiteral("/bodypart/"))) { return nullptr; } const QStringList urlParts = urlPath.mid(10).split(QLatin1Char('/')); if (urlParts.size() != 3) { return nullptr; } //KMime::ContentIndex index( urlParts[1] ); *path = QUrl::fromPercentEncoding(urlParts.at(2).toLatin1()); return w->nodeFromUrl(QUrl(urlParts.at(1))); } bool URLHandlerManager::BodyPartURLHandlerManager::handleClick(const QUrl &url, ViewerPrivate *w) const { QString path; KMime::Content *node = partNodeFromXKMailUrl(url, w, &path); if (!node) { return false; } MimeTreeParser::PartNodeBodyPart part(nullptr, nullptr, w->message().data(), node, w->nodeHelper()); BodyPartHandlerList::const_iterator end(mHandlers.constEnd()); for (BodyPartHandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleClick(w->viewer(), &part, path)) { return true; } } return false; } bool URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *w) const { QString path; KMime::Content *node = partNodeFromXKMailUrl(url, w, &path); if (!node) { return false; } MimeTreeParser::PartNodeBodyPart part(nullptr, nullptr, w->message().data(), node, w->nodeHelper()); BodyPartHandlerList::const_iterator end(mHandlers.constEnd()); for (BodyPartHandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleContextMenuRequest(&part, path, p)) { return true; } } return false; } QString URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage(const QUrl &url, ViewerPrivate *w) const { QString path; KMime::Content *node = partNodeFromXKMailUrl(url, w, &path); if (!node) { return QString(); } MimeTreeParser::PartNodeBodyPart part(nullptr, nullptr, w->message().data(), node, w->nodeHelper()); BodyPartHandlerList::const_iterator end(mHandlers.constEnd()); for (BodyPartHandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { const QString msg = (*it)->statusBarMessage(&part, path); if (!msg.isEmpty()) { return msg; } } return QString(); } // // // URLHandlerManager // // URLHandlerManager::URLHandlerManager() { registerHandler(new KMailProtocolURLHandler()); registerHandler(new ExpandCollapseQuoteURLManager()); registerHandler(new SMimeURLHandler()); registerHandler(new MailToURLHandler()); registerHandler(new ContactUidURLHandler()); registerHandler(new HtmlAnchorHandler()); registerHandler(new AttachmentURLHandler()); registerHandler(mBodyPartURLHandlerManager = new BodyPartURLHandlerManager()); registerHandler(new ShowAuditLogURLHandler()); registerHandler(new InternalImageURLHandler); registerHandler(new KRunURLHandler()); //registerHandler(new EmbeddedImageURLHandler()); } URLHandlerManager::~URLHandlerManager() { for_each(mHandlers.begin(), mHandlers.end(), DeleteAndSetToZero()); } URLHandlerManager *URLHandlerManager::instance() { if (!self) { self = new URLHandlerManager(); } return self; } void URLHandlerManager::registerHandler(const MimeTreeParser::URLHandler *handler) { if (!handler) { return; } unregisterHandler(handler); // don't produce duplicates mHandlers.push_back(handler); } void URLHandlerManager::unregisterHandler(const MimeTreeParser::URLHandler *handler) { // don't delete them, only remove them from the list! mHandlers.erase(remove(mHandlers.begin(), mHandlers.end(), handler), mHandlers.end()); } -void URLHandlerManager::registerHandler(const MimeTreeParser::Interface::BodyPartURLHandler *handler) +void URLHandlerManager::registerHandler(const Interface::BodyPartURLHandler *handler) { if (mBodyPartURLHandlerManager) { mBodyPartURLHandlerManager->registerHandler(handler); } } -void URLHandlerManager::unregisterHandler( - const MimeTreeParser::Interface::BodyPartURLHandler *handler) +void URLHandlerManager::unregisterHandler(const Interface::BodyPartURLHandler *handler) { if (mBodyPartURLHandlerManager) { mBodyPartURLHandlerManager->unregisterHandler(handler); } } bool URLHandlerManager::handleClick(const QUrl &url, ViewerPrivate *w) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleClick(url, w)) { return true; } } return false; } bool URLHandlerManager::handleShiftClick(const QUrl &url, ViewerPrivate *window) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleShiftClick(url, window)) { return true; } } return false; } bool URLHandlerManager::willHandleDrag(const QUrl &url, ViewerPrivate *window) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->willHandleDrag(url, window)) { return true; } } return false; } bool URLHandlerManager::handleDrag(const QUrl &url, ViewerPrivate *window) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleDrag(url, window)) { return true; } } return false; } bool URLHandlerManager::handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *w) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { if ((*it)->handleContextMenuRequest(url, p, w)) { return true; } } return false; } QString URLHandlerManager::statusBarMessage(const QUrl &url, ViewerPrivate *w) const { HandlerList::const_iterator end(mHandlers.constEnd()); for (HandlerList::const_iterator it = mHandlers.constBegin(); it != end; ++it) { const QString msg = (*it)->statusBarMessage(url, w); if (!msg.isEmpty()) { return msg; } } return QString(); } // // // URLHandler // // namespace { bool KMailProtocolURLHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { if (url.scheme() == QLatin1String("kmail")) { if (!w) { return false; } const QString urlPath(url.path()); if (urlPath == QLatin1String("showHTML")) { w->setDisplayFormatMessageOverwrite(MessageViewer::Viewer::Html); w->update(MimeTreeParser::Force); return true; } else if (urlPath == QLatin1String("goOnline")) { w->goOnline(); return true; } else if (urlPath == QLatin1String("goResourceOnline")) { w->goResourceOnline(); return true; } else if (urlPath == QLatin1String("loadExternal")) { w->setHtmlLoadExtOverride(!w->htmlLoadExtOverride()); w->update(MimeTreeParser::Force); return true; } else if (urlPath == QLatin1String("decryptMessage")) { w->setDecryptMessageOverwrite(true); w->update(MimeTreeParser::Force); return true; } else if (urlPath == QLatin1String("showSignatureDetails")) { w->setShowSignatureDetails(true); w->update(MimeTreeParser::Force); return true; } else if (urlPath == QLatin1String("hideSignatureDetails")) { w->setShowSignatureDetails(false); w->update(MimeTreeParser::Force); return true; } else if (urlPath == QLatin1String("showAttachmentQuicklist")) { w->setShowAttachmentQuicklist(false); return true; } else if (urlPath == QLatin1String("hideAttachmentQuicklist")) { w->setShowAttachmentQuicklist(true); return true; } else if (urlPath == QLatin1String("showFullToAddressList")) { w->setFullToAddressList(false); return true; } else if (urlPath == QLatin1String("hideFullToAddressList")) { w->setFullToAddressList(true); return true; } else if (urlPath == QLatin1String("showFullCcAddressList")) { w->setFullCcAddressList(false); return true; } else if (urlPath == QLatin1String("hideFullCcAddressList")) { w->setFullCcAddressList(true); return true; } } return false; } QString KMailProtocolURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *) const { if (url.scheme() == QLatin1String("kmail")) { const QString urlPath(url.path()); if (urlPath == QLatin1String("showHTML")) { return i18n("Turn on HTML rendering for this message."); } else if (urlPath == QLatin1String("loadExternal")) { return i18n("Load external references from the Internet for this message."); } else if (urlPath == QLatin1String("goOnline")) { return i18n("Work online."); } else if (urlPath == QLatin1String("goResourceOnline")) { return i18n("Make account online."); } else if (urlPath == QLatin1String("decryptMessage")) { return i18n("Decrypt message."); } else if (urlPath == QLatin1String("showSignatureDetails")) { return i18n("Show signature details."); } else if (urlPath == QLatin1String("hideSignatureDetails")) { return i18n("Hide signature details."); } else if (urlPath == QLatin1String("showAttachmentQuicklist")) { return i18n("Hide attachment list."); } else if (urlPath == QLatin1String("hideAttachmentQuicklist")) { return i18n("Show attachment list."); } else if (urlPath == QLatin1String("showFullToAddressList")) { return i18n("Hide full \"To\" list"); } else if (urlPath == QLatin1String("hideFullToAddressList")) { return i18n("Show full \"To\" list"); } else if (urlPath == QLatin1String("showFullCcAddressList")) { return i18n("Hide full \"Cc\" list"); } else if (urlPath == QLatin1String("hideFullCcAddressList")) { return i18n("Show full \"Cc\" list"); } else { return QString(); } } else if (url.scheme() == QLatin1String("help")) { return i18n("Open Documentation"); } return QString(); } } namespace { bool ExpandCollapseQuoteURLManager::handleClick(const QUrl &url, ViewerPrivate *w) const { // kmail:levelquote/?num -> the level quote to collapse. // kmail:levelquote/?-num -> expand all levels quote. if (url.scheme() == QLatin1String("kmail") && url.path() == QLatin1String("levelquote")) { const QString levelStr = url.query(); bool isNumber = false; const int levelQuote = levelStr.toInt(&isNumber); if (isNumber) { w->slotLevelQuote(levelQuote); } return true; } return false; } bool ExpandCollapseQuoteURLManager::handleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(url); Q_UNUSED(window); return false; } QString ExpandCollapseQuoteURLManager::statusBarMessage(const QUrl &url, ViewerPrivate *) const { if (url.scheme() == QLatin1String("kmail") && url.path() == QLatin1String("levelquote")) { const QString query = url.query(); if (query.length() >= 1) { if (query[ 0 ] == QLatin1Char('-')) { return i18n("Expand all quoted text."); } else { return i18n("Collapse quoted text."); } } } return QString(); } } bool foundSMIMEData(const QString &aUrl, QString &displayName, QString &libName, QString &keyId) { static QString showCertMan(QStringLiteral("showCertificate#")); displayName.clear(); libName.clear(); keyId.clear(); int i1 = aUrl.indexOf(showCertMan); if (-1 < i1) { i1 += showCertMan.length(); int i2 = aUrl.indexOf(QLatin1String(" ### "), i1); if (i1 < i2) { displayName = aUrl.mid(i1, i2 - i1); i1 = i2 + 5; i2 = aUrl.indexOf(QLatin1String(" ### "), i1); if (i1 < i2) { libName = aUrl.mid(i1, i2 - i1); i2 += 5; keyId = aUrl.mid(i2); /* int len = aUrl.length(); if( len > i2+1 ) { keyId = aUrl.mid( i2, 2 ); i2 += 2; while( len > i2+1 ) { keyId += ':'; keyId += aUrl.mid( i2, 2 ); i2 += 2; } } */ } } } return !keyId.isEmpty(); } namespace { bool SMimeURLHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { if (!url.hasFragment()) { return false; } QString displayName, libName, keyId; if (!foundSMIMEData(url.path() + QLatin1Char('#') +QUrl::fromPercentEncoding(url.fragment().toLatin1()), displayName, libName, keyId)) { return false; } QStringList lst; lst << QStringLiteral("--parent-windowid") << QString::number((qlonglong)w->viewer()->mainWindow()->winId()) << QStringLiteral("--query") << keyId; if (!QProcess::startDetached(QStringLiteral("kleopatra"), lst)) { KMessageBox::error(w->mMainWindow, i18n("Could not start certificate manager. " "Please check your installation."), i18n("KMail Error")); } return true; } QString SMimeURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *) const { QString displayName, libName, keyId; if (!foundSMIMEData(url.path() + QLatin1Char('#') +QUrl::fromPercentEncoding(url.fragment().toLatin1()), displayName, libName, keyId)) { return QString(); } return i18n("Show certificate 0x%1", keyId); } } namespace { bool HtmlAnchorHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { if (!url.host().isEmpty() || !url.hasFragment()) { return false; } w->scrollToAnchor(url.fragment()); return true; } } namespace { QString MailToURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *) const { if (url.scheme() == QLatin1String("mailto")) { return KEmailAddress::decodeMailtoUrl(url); } return QString(); } } namespace { static QString searchFullEmailByUid(const QString &uid) { QString fullEmail; Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); job->setLimit(1); job->setQuery(Akonadi::ContactSearchJob::ContactUid, uid, Akonadi::ContactSearchJob::ExactMatch); job->exec(); const KContacts::Addressee::List res = job->contacts(); if (!res.isEmpty()) { KContacts::Addressee addr = res.at(0); fullEmail = addr.fullEmail(); } return fullEmail; } static void runKAddressBook(const QUrl &url) { KPIM::OpenEmailAddressJob *job = new KPIM::OpenEmailAddressJob(url.path(), nullptr); job->start(); } bool ContactUidURLHandler::handleClick(const QUrl &url, ViewerPrivate *) const { if (url.scheme() == QLatin1String("uid")) { runKAddressBook(url); return true; } else { return false; } } bool ContactUidURLHandler::handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *) const { if (url.scheme() != QLatin1String("uid") || url.path().isEmpty()) { return false; } QMenu *menu = new QMenu(); QAction *open = menu->addAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")), i18n("&Open in Address Book")); #ifndef QT_NO_CLIPBOARD QAction *copy = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("&Copy Email Address")); #endif QAction *a = menu->exec(p); if (a == open) { runKAddressBook(url); #ifndef QT_NO_CLIPBOARD } else if (a == copy) { const QString fullEmail = searchFullEmailByUid(url.path()); if (!fullEmail.isEmpty()) { QClipboard *clip = QApplication::clipboard(); clip->setText(fullEmail, QClipboard::Clipboard); clip->setText(fullEmail, QClipboard::Selection); KPIM::BroadcastStatus::instance()->setStatusMsg(i18n("Address copied to clipboard.")); } #endif } delete menu; return true; } QString ContactUidURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *) const { if (url.scheme() == QLatin1String("uid")) { return i18n("Lookup the contact in KAddressbook"); } else { return QString(); } } } namespace { KMime::Content *AttachmentURLHandler::nodeForUrl(const QUrl &url, ViewerPrivate *w) const { if (!w || !w->mMessage) { return nullptr; } if (url.scheme() == QLatin1String("attachment")) { KMime::Content *node = w->nodeFromUrl(url); return node; } return nullptr; } bool AttachmentURLHandler::attachmentIsInHeader(const QUrl &url) const { bool inHeader = false; QUrlQuery query(url); const QString place = query.queryItemValue(QStringLiteral("place")).toLower(); if (!place.isNull()) { inHeader = (place == QLatin1String("header")); } return inHeader; } bool AttachmentURLHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { KMime::Content *node = nodeForUrl(url, w); if (!node) { return false; } const bool inHeader = attachmentIsInHeader(url); const bool shouldShowDialog = !w->nodeHelper()->isNodeDisplayedEmbedded(node) || !inHeader; if (inHeader) { w->scrollToAttachment(node); } if (shouldShowDialog) { w->openAttachment(node, w->nodeHelper()->tempFileUrlFromNode(node)); } return true; } bool AttachmentURLHandler::handleShiftClick(const QUrl &url, ViewerPrivate *window) const { KMime::Content *node = nodeForUrl(url, window); if (!node) { return false; } if (!window) { return false; } QUrl currentUrl; if (Util::saveContents(window->viewer(), KMime::Content::List() << node, currentUrl)) { window->viewer()->showOpenAttachmentFolderWidget(currentUrl); } return true; } bool AttachmentURLHandler::willHandleDrag(const QUrl &url, ViewerPrivate *window) const { return nodeForUrl(url, window) != nullptr; } bool AttachmentURLHandler::handleDrag(const QUrl &url, ViewerPrivate *window) const { #ifndef QT_NO_DRAGANDDROP KMime::Content *node = nodeForUrl(url, window); if (!node) { return false; } if (node->header()) { if (!node->contents().isEmpty()) { node = node->contents().constFirst(); window->nodeHelper()->writeNodeToTempFile(node); } } const QUrl tUrl = window->nodeHelper()->tempFileUrlFromNode(node); const QString fileName = tUrl.path(); if (!fileName.isEmpty()) { QFile f(fileName); f.setPermissions( QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther); const QString icon = Util::iconPathForContent(node, KIconLoader::Small); QDrag *drag = new QDrag(window->viewer()); QMimeData *mimeData = new QMimeData(); mimeData->setUrls(QList() << tUrl); drag->setMimeData(mimeData); if (!icon.isEmpty()) { drag->setPixmap(QIcon::fromTheme(icon).pixmap(16, 16)); } drag->start(); return true; } else #endif return false; } bool AttachmentURLHandler::handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *w) const { KMime::Content *node = nodeForUrl(url, w); if (!node) { return false; } // PENDING(romain_kdab) : replace with toLocalFile() ? w->showAttachmentPopup(node, w->nodeHelper()->tempFileUrlFromNode(node).path(), p); return true; } QString AttachmentURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *w) const { KMime::Content *node = nodeForUrl(url, w); if (!node) { return QString(); } const QString name = MimeTreeParser::NodeHelper::fileName(node); if (!name.isEmpty()) { return i18n("Attachment: %1", name); } else if (dynamic_cast(node)) { if (node->header()) { return i18n("Encapsulated Message (Subject: %1)", node->header()->asUnicodeString()); } else { return i18n("Encapsulated Message"); } } return i18n("Unnamed attachment"); } } namespace { static QString extractAuditLog(const QUrl &url) { if (url.scheme() != QLatin1String("kmail") || url.path() != QLatin1String("showAuditLog")) { return QString(); } QUrlQuery query(url); Q_ASSERT(!query.queryItemValue(QStringLiteral("log")).isEmpty()); return query.queryItemValue(QStringLiteral("log")); } bool ShowAuditLogURLHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { const QString auditLog = extractAuditLog(url); if (auditLog.isEmpty()) { return false; } Kleo::MessageBox::auditLog(w->mMainWindow, auditLog); return true; } bool ShowAuditLogURLHandler::handleContextMenuRequest(const QUrl &url, const QPoint &, ViewerPrivate *w) const { Q_UNUSED(w); // disable RMB for my own links: return !extractAuditLog(url).isEmpty(); } QString ShowAuditLogURLHandler::statusBarMessage(const QUrl &url, ViewerPrivate *) const { if (extractAuditLog(url).isEmpty()) { return QString(); } else { return i18n("Show GnuPG Audit Log for this operation"); } } bool ShowAuditLogURLHandler::handleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(url); Q_UNUSED(window); return true; } } namespace { bool InternalImageURLHandler::handleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(window); Q_UNUSED(url); // This will only be called when willHandleDrag() was true. Return false here, that will // notify ViewerPrivate::eventFilter() that no drag was started. return false; } bool InternalImageURLHandler::willHandleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(window); if (url.scheme() == QLatin1String("data") && url.path().startsWith(QStringLiteral("image"))) { return true; } const QString imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral( "libmessageviewer/pics/"), QStandardPaths::LocateDirectory); return url.path().contains(imagePath); } } namespace { bool KRunURLHandler::handleClick(const QUrl &url, ViewerPrivate *w) const { const QString scheme(url.scheme()); if ((scheme == QLatin1String("http")) || (scheme == QLatin1String("https")) || (scheme == QLatin1String("ftp")) || (scheme == QLatin1String("file")) || (scheme == QLatin1String("ftps")) || (scheme == QLatin1String("sftp")) || (scheme == QLatin1String("help")) || (scheme == QLatin1String("vnc")) || (scheme == QLatin1String("smb")) || (scheme == QLatin1String("fish")) || (scheme == QLatin1String("news"))) { KPIM::BroadcastStatus::instance()->setTransientStatusMsg(i18n("Opening URL...")); QTimer::singleShot(2000, KPIM::BroadcastStatus::instance(), &KPIM::BroadcastStatus::reset); QMimeDatabase mimeDb; auto mime = mimeDb.mimeTypeForUrl(url); if (mime.name() == QLatin1String("application/x-desktop") || mime.name() == QLatin1String("application/x-executable") || mime.name() == QLatin1String("application/x-ms-dos-executable") || mime.name() == QLatin1String("application/x-shellscript")) { if (KMessageBox::warningYesNo(nullptr, xi18nc("@info", "Do you really want to execute %1?", url.toDisplayString(QUrl::PreferLocalFile)), QString(), KGuiItem(i18n("Execute")), KStandardGuiItem::cancel()) != KMessageBox::Yes) { return true; } } w->checkPhishingUrl(); return true; } else { return false; } } } bool EmbeddedImageURLHandler::handleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(url); Q_UNUSED(window); return false; } bool EmbeddedImageURLHandler::willHandleDrag(const QUrl &url, ViewerPrivate *window) const { Q_UNUSED(window); return url.scheme() == QLatin1String("cid"); } diff --git a/messageviewer/src/viewer/urlhandlermanager.h b/messageviewer/src/viewer/urlhandlermanager.h index 05f11430..9923b03f 100644 --- a/messageviewer/src/viewer/urlhandlermanager.h +++ b/messageviewer/src/viewer/urlhandlermanager.h @@ -1,90 +1,88 @@ /* -*- c++ -*- urlhandlermanager.h This file is part of KMail, the KDE mail client. Copyright (c) 2003 Marc Mutz Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia KMail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __MESSAGEVIEWER_URLHANDLERMANAGER_H__ #define __MESSAGEVIEWER_URLHANDLERMANAGER_H__ #include class QUrl; class QString; class QPoint; -namespace MessageViewer { -class ViewerPrivate; +namespace MimeTreeParser { +class URLHandler; } -namespace MimeTreeParser { +namespace MessageViewer { namespace Interface { class BodyPartURLHandler; } -class URLHandler; -} +class ViewerPrivate; -namespace MessageViewer { /** * @short Singleton to manage the list of URLHandlers * @author Marc Mutz */ class URLHandlerManager { static URLHandlerManager *self; URLHandlerManager(); public: ~URLHandlerManager(); static URLHandlerManager *instance(); void registerHandler(const MimeTreeParser::URLHandler *handler); void unregisterHandler(const MimeTreeParser::URLHandler *handler); - void registerHandler(const MimeTreeParser::Interface::BodyPartURLHandler *handler); - void unregisterHandler(const MimeTreeParser::Interface::BodyPartURLHandler *handler); + void registerHandler(const Interface::BodyPartURLHandler *handler); + void unregisterHandler(const Interface::BodyPartURLHandler *handler); bool handleClick(const QUrl &url, ViewerPrivate *w = nullptr) const; bool handleShiftClick(const QUrl &url, ViewerPrivate *window = nullptr) const; bool handleContextMenuRequest(const QUrl &url, const QPoint &p, ViewerPrivate *w = nullptr) const; bool willHandleDrag(const QUrl &url, ViewerPrivate *window = nullptr) const; bool handleDrag(const QUrl &url, ViewerPrivate *window = nullptr) const; QString statusBarMessage(const QUrl &url, ViewerPrivate *w = nullptr) const; private: typedef QVector HandlerList; HandlerList mHandlers; class BodyPartURLHandlerManager; BodyPartURLHandlerManager *mBodyPartURLHandlerManager = nullptr; }; } #endif // __MESSAGEVIEWER_URLHANDLERMANAGER_H__ diff --git a/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp b/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp index a7bcea67..b36b1a5f 100644 --- a/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp +++ b/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp @@ -1,134 +1,134 @@ /* Copyright (c) 2017 Volker Krause This library 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 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 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 "viewer/bodypartformatterbasefactory.h" +#include "viewer/bodypartformatterfactory.h" #include "interfaces/bodypartformatter.h" #include using namespace MimeTreeParser; class DummyFormatter : public Interface::BodyPartFormatter { }; -class TestFactory : public BodyPartFormatterBaseFactory +class TestFactory : public BodyPartFormatterFactory { public: void loadPlugins() override { textCalFormatter = new DummyFormatter; insert(QStringLiteral("TEXT/CALENDAR"), textCalFormatter, 100); } DummyFormatter *textCalFormatter = nullptr; }; using namespace MimeTreeParser; class BodyPartFormatterBaseFactoryTest : public QObject { Q_OBJECT private Q_SLOTS: void testFactory() { TestFactory fac; auto l = fac.formattersForType(QStringLiteral("application/octet-stream")); QCOMPARE(l.size(), 2); const auto application_octet_stream_f = l.at(1); QVERIFY(application_octet_stream_f); l = fac.formattersForType(QStringLiteral("application/pgp-encrypted")); QCOMPARE(l.size(), 5); QVERIFY(l.at(0) != application_octet_stream_f); QCOMPARE(l.at(4), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("application/unknown")); QCOMPARE(l.size(), 2); QCOMPARE(l.at(1), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("text/plain")); QCOMPARE(l.size(), 4); const auto text_plain_f1 = l.at(0); const auto text_plain_f2 = l.at(1); QVERIFY(text_plain_f1); QVERIFY(text_plain_f2); QVERIFY(text_plain_f1 != text_plain_f2); QCOMPARE(l.at(3), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("text/calendar")); QCOMPARE(l.size(), 5); QVERIFY(fac.textCalFormatter); QCOMPARE(l.at(0), fac.textCalFormatter); QCOMPARE(l.at(1), text_plain_f1); QCOMPARE(l.at(2), text_plain_f2); QCOMPARE(l.at(4), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("text/x-vcalendar")); QCOMPARE(l.size(), 5); QCOMPARE(l.at(0), fac.textCalFormatter); l = fac.formattersForType(QStringLiteral("TEXT/X-VCALENDAR")); QCOMPARE(l.size(), 5); QCOMPARE(l.at(0), fac.textCalFormatter); l = fac.formattersForType(QStringLiteral("text/html")); QCOMPARE(l.size(), 5); QCOMPARE(l.at(1), text_plain_f1); QCOMPARE(l.at(2), text_plain_f2); QCOMPARE(l.at(4), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("text/rtf")); QCOMPARE(l.size(), 5); QCOMPARE(l.at(0), application_octet_stream_f); QCOMPARE(l.at(4), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("multipart/mixed")); QCOMPARE(l.size(), 1); const auto multipart_mixed_f = l.at(0); QVERIFY(multipart_mixed_f); l = fac.formattersForType(QStringLiteral("multipart/random")); QCOMPARE(l.size(), 1); QCOMPARE(l.at(0), multipart_mixed_f); l = fac.formattersForType(QStringLiteral("multipart/encrypted")); QCOMPARE(l.size(), 2); QVERIFY(l.at(0) != multipart_mixed_f); QCOMPARE(l.at(1), multipart_mixed_f); l = fac.formattersForType(QStringLiteral("image/png")); QCOMPARE(l.size(), 3); QCOMPARE(l.at(2), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("vendor/random")); QCOMPARE(l.size(), 2); QCOMPARE(l.at(1), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("message/rfc822")); QCOMPARE(l.size(), 5); QCOMPARE(l.at(4), application_octet_stream_f); l = fac.formattersForType(QStringLiteral("message/news")); QCOMPARE(l.size(), 4); // ### news does not inherit rfc822 } }; QTEST_MAIN(BodyPartFormatterBaseFactoryTest) #include "bodypartformatterbasefactorytest.moc" diff --git a/mimetreeparser/autotests/setupenv.h b/mimetreeparser/autotests/setupenv.h index 5f5f7dae..02803ce4 100644 --- a/mimetreeparser/autotests/setupenv.h +++ b/mimetreeparser/autotests/setupenv.h @@ -1,174 +1,174 @@ /* Copyright (C) 2010 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Copyright (c) 2010 Leo Franchi This library 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 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 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 MESSAGECORE_TESTS_UTIL_H #define MESSAGECORE_TESTS_UTIL_H #include #include #include -#include +#include #include #include namespace MimeTreeParser { namespace Test { /** * setup a environment variables for tests: * * set LC_ALL to C * * set KDEHOME */ void setupEnv(); // We can't use EmptySource, since we need to control some emelnets of the source for tests to also test // loadExternal and htmlMail. class TestObjectTreeSource : public MimeTreeParser::Interface::ObjectTreeSource { public: TestObjectTreeSource(MimeTreeParser::HtmlWriter *writer) : mWriter(writer) , mAttachmentStrategy(QStringLiteral("smart")) , mPreferredMode(Util::Html) , mHtmlLoadExternal(false) , mDecryptMessage(false) { } MimeTreeParser::HtmlWriter *htmlWriter() override { return mWriter; } bool htmlLoadExternal() const override { return mHtmlLoadExternal; } void setHtmlLoadExternal(bool loadExternal) { mHtmlLoadExternal = loadExternal; } void setAttachmentStrategy(QString strategy) { mAttachmentStrategy = strategy; } const AttachmentStrategy *attachmentStrategy() override { return AttachmentStrategy::create(mAttachmentStrategy); } bool autoImportKeys() const override { return true; } bool showEmoticons() const override { return false; } bool showExpandQuotesMark() const override { return false; } - const BodyPartFormatterBaseFactory *bodyPartFormatterFactory() override + const BodyPartFormatterFactory *bodyPartFormatterFactory() override { - return &mBodyPartFormatterBaseFactory; + return &mBodyPartFormatterFactory; } bool decryptMessage() const override { return mDecryptMessage; } void setAllowDecryption(bool allowDecryption) { mDecryptMessage = allowDecryption; } void setShowSignatureDetails(bool showSignatureDetails) { mShowSignatureDetails = showSignatureDetails; } bool showSignatureDetails() const override { return mShowSignatureDetails; } void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) override { Q_UNUSED(mode); Q_UNUSED(availableModes); } MimeTreeParser::Util::HtmlMode preferredMode() const override { return mPreferredMode; } void setPreferredMode(MimeTreeParser::Util::HtmlMode mode) { mPreferredMode = mode; } int levelQuote() const override { return 1; } const QTextCodec *overrideCodec() override { return nullptr; } QString createMessageHeader(KMime::Message *message) override { Q_UNUSED(message); return QString(); //do nothing } void render(const MessagePart::Ptr &msgPart, HtmlWriter *htmlWriter) override { Q_UNUSED(msgPart); Q_UNUSED(htmlWriter); } bool isPrinting() const override { return false; } private: MimeTreeParser::HtmlWriter *mWriter = nullptr; QString mAttachmentStrategy; - BodyPartFormatterBaseFactory mBodyPartFormatterBaseFactory; + BodyPartFormatterFactory mBodyPartFormatterFactory; MimeTreeParser::Util::HtmlMode mPreferredMode; bool mHtmlLoadExternal = false; bool mDecryptMessage = false; bool mShowSignatureDetails = false; }; } } #endif diff --git a/mimetreeparser/src/CMakeLists.txt b/mimetreeparser/src/CMakeLists.txt index d9f03e47..f479bae6 100644 --- a/mimetreeparser/src/CMakeLists.txt +++ b/mimetreeparser/src/CMakeLists.txt @@ -1,175 +1,176 @@ add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) add_definitions(-DTRANSLATION_DOMAIN=\"libmimetreeparser\") # target_include_directories does not handle empty include paths include_directories(${GPGME_INCLUDES}) set(libmimetreeparser_main_SRCS bodyformatter/applicationpgpencrypted.cpp bodyformatter/applicationpkcs7mime.cpp bodyformatter/mailman.cpp bodyformatter/multipartalternative.cpp bodyformatter/multipartencrypted.cpp bodyformatter/multipartmixed.cpp bodyformatter/multipartsigned.cpp bodyformatter/textplain.cpp bodyformatter/texthtml.cpp bodyformatter/utils.cpp interfaces/bodypartformatter.cpp interfaces/objecttreesource.cpp interfaces/bodypart.cpp interfaces/htmlwriter.cpp job/qgpgmejobexecutor.cpp utils/util.cpp viewer/attachmentstrategy.cpp viewer/bodypartformatter.cpp - viewer/bodypartformatterbasefactory.cpp + viewer/bodypartformatterfactory.cpp viewer/cryptohelper.cpp viewer/nodehelper.cpp viewer/objecttreeparser.cpp viewer/messagepart.cpp viewer/partnodebodypart.cpp viewer/memento/cryptobodypartmemento.cpp viewer/memento/decryptverifybodypartmemento.cpp viewer/memento/verifydetachedbodypartmemento.cpp viewer/memento/verifyopaquebodypartmemento.cpp ) set(libmimetreeparser_extra_SRCS #HTML Writer htmlwriter/bufferedhtmlwriter.cpp htmlwriter/filehtmlwriter.cpp ) set(mimetreeparser_temporaryfile_SRCS temporaryfile/attachmenttemporaryfilesdirs.cpp ) ecm_generate_headers(MimeTreeParser_Camelcaseviewer_HEADERS HEADER_NAMES AttachmentStrategy - BodyPartFormatterBaseFactory + BodyPartFormatterFactory Enums MessagePart NodeHelper ObjectTreeParser PartMetaData PartNodeBodyPart REQUIRED_HEADERS MimeTreeParser_viewer_HEADERS PREFIX MimeTreeParser RELATIVE viewer ) ecm_generate_headers(MimeTreeParser_Camelcaseutils_HEADERS HEADER_NAMES Util REQUIRED_HEADERS MimeTreeParser_utils_HEADERS PREFIX MimeTreeParser RELATIVE utils ) ecm_generate_headers(MimeTreeParser_Camelcaseinterfaces_HEADERS HEADER_NAMES BodyPartFormatter BodyPart HtmlWriter ObjectTreeSource REQUIRED_HEADERS MimeTreeParser_interfaces_HEADERS PREFIX MimeTreeParser RELATIVE interfaces ) ecm_generate_headers(MimeTreeParser_Camelcasehtmlwriter_HEADERS HEADER_NAMES BufferedHtmlWriter FileHtmlWriter REQUIRED_HEADERS MimeTreeParser_htmlwriter_HEADERS PREFIX MimeTreeParser RELATIVE htmlwriter ) ecm_generate_headers(MimeTreeParser_Camelcasetemporaryfile_HEADERS HEADER_NAMES AttachmentTemporaryFilesDirs REQUIRED_HEADERS MimeTreeParser_temporaryfile_HEADERS PREFIX MimeTreeParser RELATIVE temporaryfile ) install(FILES ${MimeTreeParser_Camelcasehtmlwriter_HEADERS} ${MimeTreeParser_Camelcaseutils_HEADERS} ${MimeTreeParser_Camelcaseinterfaces_HEADERS} ${MimeTreeParser_Camelcaseviewer_HEADERS} ${MimeTreeParser_Camelcasetemporaryfile_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/MimeTreeParser COMPONENT Devel ) install(FILES ${MimeTreeParser_htmlwriter_HEADERS} ${MimeTreeParser_utils_HEADERS} ${MimeTreeParser_interfaces_HEADERS} ${MimeTreeParser_viewer_HEADERS} ${MimeTreeParser_temporaryfile_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/mimetreeparser_export.h ${CMAKE_CURRENT_BINARY_DIR}/mimetreeparser_debug.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/mimetreeparser COMPONENT Devel ) ecm_generate_pri_file(BASE_NAME MimeTreeParser LIB_NAME KF5MimeTreeParser FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/MimeTreeParser ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR} ) set(libmimetreeparser_SRCS ${libmimetreeparser_main_SRCS} ${libmimetreeparser_extra_SRCS} ${mimetreeparser_temporaryfile_SRCS} ) ecm_qt_declare_logging_category(libmimetreeparser_SRCS HEADER mimetreeparser_debug.h IDENTIFIER MIMETREEPARSER_LOG CATEGORY_NAME org.kde.pim.mimetreeparser) add_library(KF5MimeTreeParser ${libmimetreeparser_SRCS} ) generate_export_header(KF5MimeTreeParser BASE_NAME mimetreeparser) add_library(KF5::MimeTreeParser ALIAS KF5MimeTreeParser) set(mimetreeparser_LINK_LIBRARIES ) target_link_libraries(KF5MimeTreeParser PRIVATE QGpgme KF5::Codecs KF5::I18n + KF5::CoreAddons KF5::Mime Qt5::Gui ) install(TARGETS KF5MimeTreeParser EXPORT KF5MimeTreeParserTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} ${LIBRARY_NAMELINK} ) set_target_properties(KF5MimeTreeParser PROPERTIES VERSION ${MIMETREEPARSER_VERSION_STRING} SOVERSION ${MIMETREEPARSER_SOVERSION} EXPORT_NAME MimeTreeParser ) target_include_directories(KF5MimeTreeParser INTERFACE "$") diff --git a/mimetreeparser/src/interfaces/bodypartformatter.cpp b/mimetreeparser/src/interfaces/bodypartformatter.cpp index 3d7383b7..434a7aa0 100644 --- a/mimetreeparser/src/interfaces/bodypartformatter.cpp +++ b/mimetreeparser/src/interfaces/bodypartformatter.cpp @@ -1,62 +1,56 @@ /* -*- mode: C++; c-file-style: "gnu" -*- bodypartformatter.cpp This file is part of KMail's plugin interface. Copyright (c) 2016 Sandro Knauß KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "bodypartformatter.h" #include "bodypart.h" #include "viewer/messagepart.h" #include "viewer/objecttreeparser.h" using namespace MimeTreeParser::Interface; BodyPartFormatter::Result BodyPartFormatter::format(BodyPart *part, MimeTreeParser::HtmlWriter *writer) const { Q_UNUSED(part); Q_UNUSED(writer); return Failed; } MimeTreeParser::MessagePart::Ptr BodyPartFormatter::process(BodyPart &part) const { auto mp = MimeTreeParser::MessagePart::Ptr(new LegacyPluginMessagePart(part.objectTreeParser())); return mp; } BodyPartFormatterPlugin::~BodyPartFormatterPlugin() { } - -const BodyPartURLHandler *BodyPartFormatterPlugin::urlHandler(int idx) const -{ - Q_UNUSED(idx); - return nullptr; -} diff --git a/mimetreeparser/src/interfaces/bodypartformatter.h b/mimetreeparser/src/interfaces/bodypartformatter.h index d55dec6d..ea04d809 100644 --- a/mimetreeparser/src/interfaces/bodypartformatter.h +++ b/mimetreeparser/src/interfaces/bodypartformatter.h @@ -1,110 +1,109 @@ /* -*- mode: C++; c-file-style: "gnu" -*- bodypartformatter.h This file is part of KMail's plugin interface. Copyright (c) 2004 Marc Mutz , Ingo Kloecker KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __MIMETREEPARSER_INTERFACE_BODYPARTFORMATTER_H__ #define __MIMETREEPARSER_INTERFACE_BODYPARTFORMATTER_H__ #include "mimetreeparser_export.h" #include #include #include "mimetreeparser/objecttreeparser.h" namespace MimeTreeParser { class HtmlWriter; class MessagePart; typedef QSharedPointer MessagePartPtr; namespace Interface { class BodyPartURLHandler; class BodyPart; class MIMETREEPARSER_EXPORT BodyPartFormatter { public: virtual ~BodyPartFormatter() { } /** @li Ok returned when format() generated some HTML @li NeedContent returned when format() needs the body of the part @li AsIcon returned when the part should be shown iconified @li Failed returned when formatting failed. Currently equivalent to Ok */ enum Result { Ok, NeedContent, AsIcon, Failed }; /** Format body part \a part by generating some HTML and writing that to \a writer. If you a async process and need to send an update information you can use MimeTreeParser::NodeHelper::Update signal with the corresponding instance of BodyPart::nodeHelper() @return the result code (see above) */ virtual Result format(BodyPart *part, MimeTreeParser::HtmlWriter *writer) const; virtual MimeTreeParser::MessagePartPtr process(BodyPart &part) const; }; /** @short interface for BodyPartFormatter plugins The interface is queried by for types, subtypes, and the corresponding bodypart formatter, and the result inserted into the bodypart formatter factory. Subtype alone or both type and subtype may be "*", which is taken as a wildcard, so that e.g. type=text subtype=* matches any text subtype, but with lesser specificity than a concrete mimetype such as text/plain. type=* is only allowed when subtype=*, too. */ class MIMETREEPARSER_EXPORT BodyPartFormatterPlugin { public: virtual ~BodyPartFormatterPlugin(); virtual const BodyPartFormatter *bodyPartFormatter(int idx) const = 0; - virtual const BodyPartURLHandler *urlHandler(int idx) const; }; } // namespace Interface } Q_DECLARE_INTERFACE(MimeTreeParser::Interface::BodyPartFormatterPlugin, "org.kde.messageviewer.bodypartformatter/1.0") #endif // __MIMETREEPARSER_INTERFACE_BODYPARTFORMATTER_H__ diff --git a/mimetreeparser/src/interfaces/objecttreesource.h b/mimetreeparser/src/interfaces/objecttreesource.h index 8c0ccd9d..96cde1a8 100644 --- a/mimetreeparser/src/interfaces/objecttreesource.h +++ b/mimetreeparser/src/interfaces/objecttreesource.h @@ -1,101 +1,101 @@ /* Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __MIMETREEPARSER_OBJECTTREESOURCE_IF_H__ #define __MIMETREEPARSER_OBJECTTREESOURCE_IF_H__ #include "mimetreeparser_export.h" #include #include #include class QTextCodec; namespace MimeTreeParser { class HtmlWriter; class AttachmentStrategy; -class BodyPartFormatterBaseFactory; +class BodyPartFormatterFactory; class MessagePart; typedef QSharedPointer MessagePartPtr; } namespace MimeTreeParser { namespace Interface { /** * Interface for object tree sources. * @author Andras Mantia */ class MIMETREEPARSER_EXPORT ObjectTreeSource { public: ObjectTreeSource(); virtual ~ObjectTreeSource(); /** * Sets the type of mail that is currently displayed. Applications can display this * information to the user, for example KMail displays a HTML status bar. * Note: This is not called when the mode is "Normal". */ virtual void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) = 0; /** Return the mode that is the preferred to display */ virtual MimeTreeParser::Util::HtmlMode preferredMode() const = 0; /** Return true if an encrypted mail should be decrypted */ virtual bool decryptMessage() const = 0; /** Return true if external sources should be loaded in a html mail */ virtual bool htmlLoadExternal() const = 0; /** Return true to include the signature details in the generated html */ virtual bool showSignatureDetails() const = 0; virtual int levelQuote() const = 0; /** The override codec that should be used for the mail */ virtual const QTextCodec *overrideCodec() = 0; virtual QString createMessageHeader(KMime::Message *message) = 0; /** Return the wanted attachment startegy */ virtual const AttachmentStrategy *attachmentStrategy() = 0; /** Return the html write object */ virtual HtmlWriter *htmlWriter() = 0; /** should keys be imported automatically **/ virtual bool autoImportKeys() const = 0; virtual bool showEmoticons() const = 0; virtual bool showExpandQuotesMark() const = 0; - virtual const BodyPartFormatterBaseFactory *bodyPartFormatterFactory() = 0; + virtual const BodyPartFormatterFactory *bodyPartFormatterFactory() = 0; virtual void render(const MessagePartPtr &msgPart, HtmlWriter *htmlWriter) = 0; virtual bool isPrinting() const = 0; private: Q_DISABLE_COPY(ObjectTreeSource) }; } } #endif diff --git a/mimetreeparser/src/viewer/bodypartformatter.cpp b/mimetreeparser/src/viewer/bodypartformatter.cpp index fb4debf5..affbf178 100644 --- a/mimetreeparser/src/viewer/bodypartformatter.cpp +++ b/mimetreeparser/src/viewer/bodypartformatter.cpp @@ -1,187 +1,187 @@ /* -*- c++ -*- bodypartformatter.cpp This file is part of KMail, the KDE mail client. Copyright (c) 2003 Marc Mutz KMail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "mimetreeparser_debug.h" #include "bodyformatter/applicationpgpencrypted.h" #include "bodyformatter/applicationpkcs7mime.h" #include "bodyformatter/mailman.h" #include "bodyformatter/multipartalternative.h" #include "bodyformatter/multipartmixed.h" #include "bodyformatter/multipartencrypted.h" #include "bodyformatter/multipartsigned.h" #include "bodyformatter/texthtml.h" #include "bodyformatter/textplain.h" #include "interfaces/bodypartformatter.h" #include "interfaces/bodypart.h" #include "interfaces/htmlwriter.h" -#include "viewer/bodypartformatterbasefactory.h" -#include "viewer/bodypartformatterbasefactory_p.h" +#include "viewer/bodypartformatterfactory.h" +#include "viewer/bodypartformatterfactory_p.h" #include "viewer/attachmentstrategy.h" #include "viewer/objecttreeparser.h" #include "viewer/messagepart.h" #include #include using namespace MimeTreeParser; namespace { class AnyTypeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { static const AnyTypeBodyPartFormatter *self; public: MessagePart::Ptr process(Interface::BodyPart &part) const override { KMime::Content *node = part.content(); const auto mp = AttachmentMessagePart::Ptr(new AttachmentMessagePart(part.objectTreeParser(), node, false, part.source()->decryptMessage())); part.processResult()->setInlineSignatureState(mp->signatureState()); part.processResult()->setInlineEncryptionState(mp->encryptionState()); part.processResult()->setNeverDisplayInline(true); mp->setNeverDisplayInline(true); mp->setIsImage(false); return mp; } static const MimeTreeParser::Interface::BodyPartFormatter *create() { if (!self) { self = new AnyTypeBodyPartFormatter(); } return self; } }; const AnyTypeBodyPartFormatter *AnyTypeBodyPartFormatter::self = nullptr; class ImageTypeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { static const ImageTypeBodyPartFormatter *self; public: static const MimeTreeParser::Interface::BodyPartFormatter *create() { if (!self) { self = new ImageTypeBodyPartFormatter(); } return self; } MessagePart::Ptr process(Interface::BodyPart &part) const override { KMime::Content *node = part.content(); auto mp = AttachmentMessagePart::Ptr(new AttachmentMessagePart(part.objectTreeParser(), node, false, part.source()->decryptMessage())); mp->setIsImage(true); part.processResult()->setInlineSignatureState(mp->signatureState()); part.processResult()->setInlineEncryptionState(mp->encryptionState()); auto preferredMode = part.source()->preferredMode(); bool isHtmlPreferred = (preferredMode == Util::Html) || (preferredMode == Util::MultipartHtml); if (node->parent() && node->parent()->contentType()->subType() == "related" && isHtmlPreferred && !part.objectTreeParser()->showOnlyOneMimePart()) { QString fileName = mp->temporaryFilePath(); QString href = QUrl::fromLocalFile(fileName).url(); QByteArray cid = node->contentID()->identifier(); if (part.objectTreeParser()->htmlWriter()) { part.objectTreeParser()->htmlWriter()->embedPart(cid, href); } part.nodeHelper()->setNodeDisplayedEmbedded(node, true); part.nodeHelper()->setNodeDisplayedHidden(node, true); return mp; } // Show it inline if showOnlyOneMimePart(), which means the user clicked the image // in the message structure viewer manually, and therefore wants to see the full image if (part.objectTreeParser()->showOnlyOneMimePart() && !part.processResult()->neverDisplayInline()) { part.nodeHelper()->setNodeDisplayedEmbedded(node, true); } return mp; } }; const ImageTypeBodyPartFormatter *ImageTypeBodyPartFormatter::self = nullptr; class MessageRfc822BodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { static const MessageRfc822BodyPartFormatter *self; public: MessagePart::Ptr process(Interface::BodyPart &) const override; static const MimeTreeParser::Interface::BodyPartFormatter *create(); }; const MessageRfc822BodyPartFormatter *MessageRfc822BodyPartFormatter::self; const MimeTreeParser::Interface::BodyPartFormatter *MessageRfc822BodyPartFormatter::create() { if (!self) { self = new MessageRfc822BodyPartFormatter(); } return self; } MessagePart::Ptr MessageRfc822BodyPartFormatter::process(Interface::BodyPart &part) const { const KMime::Message::Ptr message = part.content()->bodyAsMessage(); return MessagePart::Ptr(new EncapsulatedRfc822MessagePart(part.objectTreeParser(), part.content(), message)); } } // anon namespace -void BodyPartFormatterBaseFactoryPrivate::messageviewer_create_builtin_bodypart_formatters() +void BodyPartFormatterFactoryPrivate::messageviewer_create_builtin_bodypart_formatters() { insert(QStringLiteral("application/pkcs7-mime"), ApplicationPkcs7MimeBodyPartFormatter::create()); insert(QStringLiteral("application/x-pkcs7-mime"), ApplicationPkcs7MimeBodyPartFormatter::create()); insert(QStringLiteral("application/pgp-encrypted"), ApplicationPGPEncryptedBodyPartFormatter::create()); insert(QStringLiteral("application/octet-stream"), ApplicationPkcs7MimeBodyPartFormatter::create()); insert(QStringLiteral("application/octet-stream"), AnyTypeBodyPartFormatter::create()); insert(QStringLiteral("text/html"), TextHtmlBodyPartFormatter::create()); insert(QStringLiteral("text/rtf"), AnyTypeBodyPartFormatter::create()); insert(QStringLiteral("text/plain"), MailmanBodyPartFormatter::create()); insert(QStringLiteral("text/plain"), TextPlainBodyPartFormatter::create()); insert(QStringLiteral("image/png"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("image/jpeg"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("image/gif"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("image/svg+xml"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("image/bmp"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("image/vnd.microsoft.icon"), ImageTypeBodyPartFormatter::create()); insert(QStringLiteral("message/rfc822"), MessageRfc822BodyPartFormatter::create()); insert(QStringLiteral("multipart/alternative"), MultiPartAlternativeBodyPartFormatter::create()); insert(QStringLiteral("multipart/encrypted"), MultiPartEncryptedBodyPartFormatter::create()); insert(QStringLiteral("multipart/signed"), MultiPartSignedBodyPartFormatter::create()); insert(QStringLiteral("multipart/mixed"), MultiPartMixedBodyPartFormatter::create()); } diff --git a/mimetreeparser/src/viewer/bodypartformatterbasefactory.cpp b/mimetreeparser/src/viewer/bodypartformatterfactory.cpp similarity index 57% rename from mimetreeparser/src/viewer/bodypartformatterbasefactory.cpp rename to mimetreeparser/src/viewer/bodypartformatterfactory.cpp index c5b7be95..229b3500 100644 --- a/mimetreeparser/src/viewer/bodypartformatterbasefactory.cpp +++ b/mimetreeparser/src/viewer/bodypartformatterfactory.cpp @@ -1,148 +1,189 @@ /* bodypartformatterfactory.cpp This file is part of KMail, the KDE mail client. Copyright (c) 2004 Marc Mutz , Ingo Kloecker KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "bodypartformatterbasefactory.h" -#include "bodypartformatterbasefactory_p.h" +#include "bodypartformatterfactory.h" +#include "bodypartformatterfactory_p.h" +#include "interfaces/bodypartformatter.h" #include "mimetreeparser_debug.h" +#include + +#include +#include #include #include #include using namespace MimeTreeParser; -BodyPartFormatterBaseFactoryPrivate::BodyPartFormatterBaseFactoryPrivate(BodyPartFormatterBaseFactory *factory) +BodyPartFormatterFactoryPrivate::BodyPartFormatterFactoryPrivate(BodyPartFormatterFactory *factory) : q(factory) { } -void BodyPartFormatterBaseFactoryPrivate::setup() +void BodyPartFormatterFactoryPrivate::setup() { if (registry.empty()) { messageviewer_create_builtin_bodypart_formatters(); q->loadPlugins(); } assert(!registry.empty()); } -void BodyPartFormatterBaseFactoryPrivate::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority) +void BodyPartFormatterFactoryPrivate::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority) { if (mimeType.isEmpty() || !formatter) { return; } QMimeDatabase db; const auto mt = db.mimeTypeForName(mimeType); FormatterInfo info; info.formatter = formatter; info.priority = priority; auto &v = registry[mt.isValid() ? mt.name() : mimeType]; v.push_back(info); std::stable_sort(v.begin(), v.end(), [](const FormatterInfo &lhs, const FormatterInfo &rhs) { return lhs.priority > rhs.priority; }); } -void BodyPartFormatterBaseFactoryPrivate::appendFormattersForType(const QString &mimeType, QVector &formatters) +void BodyPartFormatterFactoryPrivate::appendFormattersForType(const QString &mimeType, QVector &formatters) { const auto it = registry.constFind(mimeType); if (it == registry.constEnd()) { return; } for (const auto &f : it.value()) { formatters.push_back(f.formatter); } } -BodyPartFormatterBaseFactory::BodyPartFormatterBaseFactory() - : d(new BodyPartFormatterBaseFactoryPrivate(this)) +BodyPartFormatterFactory::BodyPartFormatterFactory() + : d(new BodyPartFormatterFactoryPrivate(this)) { } -BodyPartFormatterBaseFactory::~BodyPartFormatterBaseFactory() +BodyPartFormatterFactory::~BodyPartFormatterFactory() { delete d; } -void BodyPartFormatterBaseFactory::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority) +BodyPartFormatterFactory* BodyPartFormatterFactory::instance() +{ + static BodyPartFormatterFactory s_instance; + return &s_instance; +} + +void BodyPartFormatterFactory::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority) { d->insert(mimeType.toLower(), formatter, priority); } -QVector BodyPartFormatterBaseFactory::formattersForType(const QString &mimeType) const +QVector BodyPartFormatterFactory::formattersForType(const QString &mimeType) const { QVector r; d->setup(); QMimeDatabase db; std::vector processedTypes; processedTypes.push_back(mimeType.toLower()); // add all formatters we have along the mimetype hierarchy for (std::size_t i = 0; i < processedTypes.size(); ++i) { const auto mt = db.mimeTypeForName(processedTypes[i]); if (mt.isValid()) { processedTypes[i] = mt.name(); // resolve alias if necessary } if (processedTypes[i] == QLatin1String("application/octet-stream")) { // we'll deal with that later continue; } d->appendFormattersForType(processedTypes[i], r); const auto parentTypes = mt.parentMimeTypes(); for (const auto &parentType : parentTypes) { if (std::find(processedTypes.begin(), processedTypes.end(), parentType) != processedTypes.end()) { continue; } processedTypes.push_back(parentType); } } // make sure we always have a suitable fallback formatter if (mimeType.startsWith(QLatin1String("multipart/"))) { if (mimeType != QLatin1String("multipart/mixed")) { d->appendFormattersForType(QStringLiteral("multipart/mixed"), r); } } else { d->appendFormattersForType(QStringLiteral("application/octet-stream"), r); } assert(!r.empty()); return r; } -void BodyPartFormatterBaseFactory::loadPlugins() +void BodyPartFormatterFactory::loadPlugins() { - qCDebug(MIMETREEPARSER_LOG) << "plugin loading is not enabled in libmimetreeparser"; + KPluginLoader::forEachPlugin(QStringLiteral("messageviewer/bodypartformatter"), [this](const QString &path) { + QPluginLoader loader(path); + const auto formatterData = loader.metaData().value(QLatin1String("MetaData")).toObject().value(QLatin1String("formatter")).toArray(); + if (formatterData.isEmpty()) { + qCWarning(MIMETREEPARSER_LOG) << "Plugin" << path << "has no meta data."; + return; + } + + auto plugin = qobject_cast(loader.instance()); + if (!plugin) { + qCWarning(MIMETREEPARSER_LOG) << "BodyPartFormatterFactory: plugin" << path + << "is not valid!"; + return; + } + + const MimeTreeParser::Interface::BodyPartFormatter *bfp = nullptr; + for (int i = 0; (bfp = plugin->bodyPartFormatter(i)) && i < formatterData.size(); ++i) { + const auto metaData = formatterData.at(i).toObject(); + const auto mimetype = metaData.value(QLatin1String("mimetype")).toString(); + if (mimetype.isEmpty()) { + qCWarning(MIMETREEPARSER_LOG) << "BodyPartFormatterFactory: plugin" << path + << "returned empty mimetype specification for index" + << i; + break; + } + // priority should always be higher than the built-in ones, otherwise what's the point? + const auto priority = metaData.value(QLatin1String("priority")).toInt() + 100; + qCDebug(MIMETREEPARSER_LOG) << "plugin for " << mimetype << priority; + insert(mimetype, bfp, priority); + } + }); } diff --git a/mimetreeparser/src/viewer/bodypartformatterbasefactory.h b/mimetreeparser/src/viewer/bodypartformatterfactory.h similarity index 83% rename from mimetreeparser/src/viewer/bodypartformatterbasefactory.h rename to mimetreeparser/src/viewer/bodypartformatterfactory.h index 93879d54..bcaa8a9f 100644 --- a/mimetreeparser/src/viewer/bodypartformatterbasefactory.h +++ b/mimetreeparser/src/viewer/bodypartformatterfactory.h @@ -1,74 +1,76 @@ /* bodypartformatterfactory.h This file is part of KMail, the KDE mail client. Copyright (c) 2004 Marc Mutz , Ingo Kloecker KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __MIMETREEPARSER_BODYPARTFORMATTERBASEFACTORY_H__ -#define __MIMETREEPARSER_BODYPARTFORMATTERBASEFACTORY_H__ +#ifndef __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_H__ +#define __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_H__ #include "mimetreeparser_export.h" #include #include namespace MimeTreeParser { namespace Interface { class BodyPartFormatter; } -class BodyPartFormatterBaseFactoryPrivate; +class BodyPartFormatterFactoryPrivate; /** The place to obtain BodyPartFormatter candidates for a given mime type. */ -class MIMETREEPARSER_EXPORT BodyPartFormatterBaseFactory +class MIMETREEPARSER_EXPORT BodyPartFormatterFactory { public: - BodyPartFormatterBaseFactory(); - virtual ~BodyPartFormatterBaseFactory(); + BodyPartFormatterFactory(); + virtual ~BodyPartFormatterFactory(); + + static BodyPartFormatterFactory* instance(); /** * Returns all suitable formatters for the given mimetype. * The candidates are ordered by priority, with the catch-call * formatter coming last. */ QVector formattersForType(const QString &mimeType) const; protected: void insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority); virtual void loadPlugins(); private: - Q_DISABLE_COPY(BodyPartFormatterBaseFactory) - BodyPartFormatterBaseFactoryPrivate *d; - friend class BodyPartFormatterBaseFactoryPrivate; + Q_DISABLE_COPY(BodyPartFormatterFactory) + BodyPartFormatterFactoryPrivate *d; + friend class BodyPartFormatterFactoryPrivate; }; } #endif // __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_H__ diff --git a/mimetreeparser/src/viewer/bodypartformatterbasefactory_p.h b/mimetreeparser/src/viewer/bodypartformatterfactory_p.h similarity index 85% rename from mimetreeparser/src/viewer/bodypartformatterbasefactory_p.h rename to mimetreeparser/src/viewer/bodypartformatterfactory_p.h index b5ecdd56..79219d20 100644 --- a/mimetreeparser/src/viewer/bodypartformatterbasefactory_p.h +++ b/mimetreeparser/src/viewer/bodypartformatterfactory_p.h @@ -1,63 +1,63 @@ /* -*- mode: C++; c-file-style: "gnu" -*- bodypartformatterfactory.h This file is part of KMail, the KDE mail client. Copyright (c) 2004 Marc Mutz , Ingo Kloecker KMail 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. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __MIMETREEPARSER_BODYPARTFORMATTERBASEFACTORY_P_H__ -#define __MIMETREEPARSER_BODYPARTFORMATTERBASEFACTORY_P_H__ +#ifndef __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_P_H__ +#define __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_P_H__ #include #include namespace MimeTreeParser { -class BodyPartFormatterBaseFactory; +class BodyPartFormatterFactory; -class BodyPartFormatterBaseFactoryPrivate +class BodyPartFormatterFactoryPrivate { public: - BodyPartFormatterBaseFactoryPrivate(BodyPartFormatterBaseFactory *factory); - ~BodyPartFormatterBaseFactoryPrivate() = default; + BodyPartFormatterFactoryPrivate(BodyPartFormatterFactory *factory); + ~BodyPartFormatterFactoryPrivate() = default; void setup(); void messageviewer_create_builtin_bodypart_formatters(); //defined in bodypartformatter.cpp void insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority = 0); void appendFormattersForType(const QString &mimeType, QVector &formatters); - BodyPartFormatterBaseFactory *q; + BodyPartFormatterFactory *q; struct FormatterInfo { const Interface::BodyPartFormatter *formatter = nullptr; int priority = 0; }; QHash > registry; }; } #endif // __MIMETREEPARSER_BODYPARTFORMATTERFACTORY_P_H__ diff --git a/mimetreeparser/src/viewer/objecttreeparser.cpp b/mimetreeparser/src/viewer/objecttreeparser.cpp index 56c922f7..5e51cc85 100644 --- a/mimetreeparser/src/viewer/objecttreeparser.cpp +++ b/mimetreeparser/src/viewer/objecttreeparser.cpp @@ -1,395 +1,395 @@ /* objecttreeparser.cpp This file is part of KMail, the KDE mail client. Copyright (c) 2003 Marc Mutz Copyright (C) 2002-2004 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net Copyright (c) 2009 Andras Mantia Copyright (c) 2015 Sandro Knauß KMail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. KMail 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ // MessageViewer includes #include "objecttreeparser.h" #include "attachmentstrategy.h" -#include "bodypartformatterbasefactory.h" +#include "bodypartformatterfactory.h" #include "nodehelper.h" #include "messagepart.h" #include "partnodebodypart.h" #include "mimetreeparser_debug.h" #include "bodyformatter/utils.h" #include "interfaces/bodypartformatter.h" #include "interfaces/htmlwriter.h" #include "utils/util.h" #include #include // KDE includes // Qt includes #include #include #include using namespace MimeTreeParser; ObjectTreeParser::ObjectTreeParser(const ObjectTreeParser *topLevelParser, bool showOnlyOneMimePart, const AttachmentStrategy *strategy) : mSource(topLevelParser->mSource) , mNodeHelper(topLevelParser->mNodeHelper) , mHtmlWriter(topLevelParser->mHtmlWriter) , mTopLevelContent(topLevelParser->mTopLevelContent) , mShowOnlyOneMimePart(showOnlyOneMimePart) , mHasPendingAsyncJobs(false) , mAllowAsync(topLevelParser->mAllowAsync) , mAttachmentStrategy(strategy) { init(); } ObjectTreeParser::ObjectTreeParser(Interface::ObjectTreeSource *source, MimeTreeParser::NodeHelper *nodeHelper, bool showOnlyOneMimePart, const AttachmentStrategy *strategy) : mSource(source) , mNodeHelper(nodeHelper) , mHtmlWriter(nullptr) , mTopLevelContent(nullptr) , mShowOnlyOneMimePart(showOnlyOneMimePart) , mHasPendingAsyncJobs(false) , mAllowAsync(false) , mAttachmentStrategy(strategy) { init(); } void ObjectTreeParser::init() { Q_ASSERT(mSource); if (!attachmentStrategy()) { mAttachmentStrategy = mSource->attachmentStrategy(); } if (!mNodeHelper) { mNodeHelper = new NodeHelper(); mDeleteNodeHelper = true; } else { mDeleteNodeHelper = false; } } ObjectTreeParser::ObjectTreeParser(const ObjectTreeParser &other) : mSource(other.mSource) , mNodeHelper(other.nodeHelper()) , //TODO(Andras) hm, review what happens if mDeleteNodeHelper was true in the source mHtmlWriter(other.mHtmlWriter) , mTopLevelContent(other.mTopLevelContent) , mShowOnlyOneMimePart(other.showOnlyOneMimePart()) , mHasPendingAsyncJobs(other.hasPendingAsyncJobs()) , mAllowAsync(other.allowAsync()) , mAttachmentStrategy(other.attachmentStrategy()) , mDeleteNodeHelper(false) { } ObjectTreeParser::~ObjectTreeParser() { if (mDeleteNodeHelper) { delete mNodeHelper; mNodeHelper = nullptr; } } void ObjectTreeParser::setAllowAsync(bool allow) { Q_ASSERT(!mHasPendingAsyncJobs); mAllowAsync = allow; } bool ObjectTreeParser::allowAsync() const { return mAllowAsync; } bool ObjectTreeParser::hasPendingAsyncJobs() const { return mHasPendingAsyncJobs; } QString ObjectTreeParser::plainTextContent() const { return mPlainTextContent; } QString ObjectTreeParser::htmlContent() const { return mHtmlContent; } void ObjectTreeParser::copyContentFrom(const ObjectTreeParser *other) { mPlainTextContent += other->plainTextContent(); mHtmlContent += other->htmlContent(); if (!other->plainTextContentCharset().isEmpty()) { mPlainTextContentCharset = other->plainTextContentCharset(); } if (!other->htmlContentCharset().isEmpty()) { mHtmlContentCharset = other->htmlContentCharset(); } } //----------------------------------------------------------------------------- void ObjectTreeParser::parseObjectTree(KMime::Content *node) { mTopLevelContent = node; mParsedPart = parseObjectTreeInternal(node, showOnlyOneMimePart()); if (mParsedPart) { mParsedPart->fix(); if (auto mp = toplevelTextNode(mParsedPart)) { if (auto _mp = mp.dynamicCast()) { extractNodeInfos(_mp->content(), true); } else if (auto _mp = mp.dynamicCast()) { if (_mp->mChildNodes.contains(Util::MultipartPlain)) { extractNodeInfos(_mp->mChildNodes[Util::MultipartPlain], true); } } setPlainTextContent(mp->text()); } if (htmlWriter()) { mSource->render(mParsedPart, htmlWriter()); } } } MessagePartPtr ObjectTreeParser::parsedPart() const { return mParsedPart; } MessagePartPtr ObjectTreeParser::processType(KMime::Content *node, ProcessResult &processResult, const QByteArray &mimeType, bool onlyOneMimePart) { const auto formatters = mSource->bodyPartFormatterFactory()->formattersForType(QString::fromUtf8(mimeType)); Q_ASSERT(!formatters.empty()); for (auto formatter : formatters) { PartNodeBodyPart part(this, &processResult, mTopLevelContent, node, mNodeHelper); // Set the default display strategy for this body part relying on the // identity of Interface::BodyPart::Display and AttachmentStrategy::Display part.setDefaultDisplay((Interface::BodyPart::Display)attachmentStrategy()->defaultDisplay(node)); mNodeHelper->setNodeDisplayedEmbedded(node, true); const MessagePart::Ptr result = formatter->process(part); if (!result) { continue; } // ### legacy BFP::format() handling, can be removed once all plugins are ported away from that if (const auto legacyPart = result.dynamicCast()) { const auto r = formatter->format(&part, legacyPart->htmlWriter()); if (r == Interface::BodyPartFormatter::AsIcon) { processResult.setNeverDisplayInline(true); mNodeHelper->setNodeDisplayedEmbedded(node, false); auto mp = processType(node, processResult, QByteArrayLiteral("application/octet-stream"), onlyOneMimePart); mp->setAttachmentContent(node); return mp; } else if (r == Interface::BodyPartFormatter::Ok) { processResult.setNeverDisplayInline(true); return result; } } else { result->setAttachmentContent(node); return result; } } Q_UNREACHABLE(); return {}; } MessagePart::Ptr ObjectTreeParser::parseObjectTreeInternal(KMime::Content *node, bool onlyOneMimePart) { if (!node) { return MessagePart::Ptr(); } // reset pending async jobs state (we'll rediscover pending jobs as we go) mHasPendingAsyncJobs = false; // reset "processed" flags for... if (onlyOneMimePart) { // ... this node and all descendants mNodeHelper->setNodeUnprocessed(node, false); if (!node->contents().isEmpty()) { mNodeHelper->setNodeUnprocessed(node, true); } } else if (!node->parent()) { // ...this node and all it's siblings and descendants mNodeHelper->setNodeUnprocessed(node, true); } const bool isRoot = node->isTopLevel(); auto parsedPart = MessagePart::Ptr(new MessagePartList(this)); parsedPart->setIsRoot(isRoot); KMime::Content *parent = node->parent(); auto contents = parent ? parent->contents() : KMime::Content::List(); if (contents.isEmpty()) { contents.append(node); } int i = contents.indexOf(node); if (i < 0) { return parsedPart; } else { for (; i < contents.size(); ++i) { node = contents.at(i); if (mNodeHelper->nodeProcessed(node)) { continue; } ProcessResult processResult(mNodeHelper); QByteArray mimeType("text/plain"); if (node->contentType(false) && !node->contentType()->mimeType().isEmpty()) { mimeType = node->contentType()->mimeType(); } const auto mp = processType(node, processResult, mimeType, onlyOneMimePart); Q_ASSERT(mp); parsedPart->appendSubPart(mp); mNodeHelper->setNodeProcessed(node, false); // adjust signed/encrypted flags if inline PGP was found processResult.adjustCryptoStatesOfNode(node); if (onlyOneMimePart) { break; } } } return parsedPart; } KMMsgSignatureState ProcessResult::inlineSignatureState() const { return mInlineSignatureState; } void ProcessResult::setInlineSignatureState(KMMsgSignatureState state) { mInlineSignatureState = state; } KMMsgEncryptionState ProcessResult::inlineEncryptionState() const { return mInlineEncryptionState; } void ProcessResult::setInlineEncryptionState(KMMsgEncryptionState state) { mInlineEncryptionState = state; } bool ProcessResult::neverDisplayInline() const { return mNeverDisplayInline; } void ProcessResult::setNeverDisplayInline(bool display) { mNeverDisplayInline = display; } void ProcessResult::adjustCryptoStatesOfNode(const KMime::Content *node) const { if ((inlineSignatureState() != KMMsgNotSigned) || (inlineEncryptionState() != KMMsgNotEncrypted)) { mNodeHelper->setSignatureState(node, inlineSignatureState()); mNodeHelper->setEncryptionState(node, inlineEncryptionState()); } } void ObjectTreeParser::extractNodeInfos(KMime::Content *curNode, bool isFirstTextPart) { if (isFirstTextPart) { mPlainTextContent += curNode->decodedText(); mPlainTextContentCharset += NodeHelper::charset(curNode); } } void ObjectTreeParser::setPlainTextContent(const QString &plainTextContent) { mPlainTextContent = plainTextContent; } const QTextCodec *ObjectTreeParser::codecFor(KMime::Content *node) const { Q_ASSERT(node); if (mSource->overrideCodec()) { return mSource->overrideCodec(); } return mNodeHelper->codec(node); } QByteArray ObjectTreeParser::plainTextContentCharset() const { return mPlainTextContentCharset; } QByteArray ObjectTreeParser::htmlContentCharset() const { return mHtmlContentCharset; } bool ObjectTreeParser::showOnlyOneMimePart() const { return mShowOnlyOneMimePart; } void ObjectTreeParser::setShowOnlyOneMimePart(bool show) { mShowOnlyOneMimePart = show; } const AttachmentStrategy *ObjectTreeParser::attachmentStrategy() const { return mAttachmentStrategy; } HtmlWriter *ObjectTreeParser::htmlWriter() const { if (mHtmlWriter) { return mHtmlWriter; } return mSource->htmlWriter(); } MimeTreeParser::NodeHelper *ObjectTreeParser::nodeHelper() const { return mNodeHelper; }