diff --git a/plugins/messageviewer/bodypartformatter/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/CMakeLists.txt index ca561b12..44ecc845 100644 --- a/plugins/messageviewer/bodypartformatter/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(autotests) add_subdirectory(ms-tnef) add_subdirectory(vcard) -add_subdirectory(xdiff) +add_subdirectory(highlighter) add_subdirectory(calendar) add_subdirectory(gnupgwks) diff --git a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt index defff42c..2a7ee7bf 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt @@ -1,44 +1,44 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) add_definitions( -DMAIL_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" ) add_definitions( -DDIFF_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/diffdata" ) macro(add_kdepimaddons_unittest _source) set(_test ${_source}) get_filename_component(_name ${_source} NAME_WE) ecm_add_test(${_source} TEST_NAME ${_name} NAME_PREFIX "messageviewerplugins-" LINK_LIBRARIES KF5::MessageViewer Qt5::Test KF5::IconThemes ) endmacro () add_kdepimaddons_unittest(rendertest.cpp) macro(add_messageviewer_bodyformatter_class_unittest _source _additional) set( _test ${_source} ${common_SRCS} ${_additional}) get_filename_component(_name ${_source} NAME_WE) ecm_add_test(${_test} TEST_NAME ${_name} NAME_PREFIX "messageviewerplugins-" LINK_LIBRARIES KF5::MessageViewer Qt5::Test KF5::PimTextEdit KF5::I18n KF5::Completion KF5::LibkdepimAkonadi ) endmacro () add_messageviewer_bodyformatter_class_unittest(reactiontoinvitationdialogtest.cpp "../calendar/reactiontoinvitationdialog.cpp") add_messageviewer_bodyformatter_class_unittest(delegateselectortest.cpp "../calendar/delegateselector.cpp") macro(add_diff_bodyformatter_class_unittest _source _additional) set( _test ${_source} ${common_SRCS} ${_additional}) get_filename_component(_name ${_source} NAME_WE) ecm_add_test(${_test} TEST_NAME ${_name} NAME_PREFIX "messageviewerplugins-" LINK_LIBRARIES KF5::MessageViewer Qt5::Test KF5::PimTextEdit KF5::I18n KF5::SyntaxHighlighting ) endmacro () -add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../xdiff/diffhighlighter.cpp") +add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../highlighter/highlighter.cpp") diff --git a/plugins/messageviewer/bodypartformatter/autotests/diffhighlightertest.cpp b/plugins/messageviewer/bodypartformatter/autotests/diffhighlightertest.cpp index d755a97e..c62fb713 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/diffhighlightertest.cpp +++ b/plugins/messageviewer/bodypartformatter/autotests/diffhighlightertest.cpp @@ -1,86 +1,90 @@ /* Copyright (C) 2017 Montel Laurent 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "diffhighlightertest.h" -#include "../xdiff/diffhighlighter.h" +#include "../highlighter/highlighter.h" + +#include +#include +#include #include #include #include DiffHighlighterTest::DiffHighlighterTest(QObject *parent) : QObject(parent) { QStandardPaths::setTestModeEnabled(true); - // trick the highlighter into using the light color theme - auto pal = QGuiApplication::palette(); - pal.setColor(QPalette::Base, Qt::white); - QGuiApplication::setPalette(pal); } QString readDiffFile(const QString &diffFile) { QFile file(diffFile); file.open(QIODevice::ReadOnly); Q_ASSERT(file.isOpen()); const QString data = QString::fromUtf8(file.readAll()); return data; } void DiffHighlighterTest::shouldGenerateDiff_data() { QTest::addColumn("input"); QTest::newRow("test1") << QStringLiteral("test1"); QTest::newRow("kcontact1") << QStringLiteral("kcontact1"); QTest::newRow("diff-akonadiconsole-16.12-master") << QStringLiteral("diff-akonadiconsole-16.12-master"); } void DiffHighlighterTest::shouldGenerateDiff() { QFETCH(QString, input); const QString originalFile = QStringLiteral(DIFF_DATA_DIR) + QLatin1Char('/') + input + QStringLiteral(".diff"); const QString refFile = QStringLiteral(DIFF_DATA_DIR) + QLatin1Char('/') + input + QStringLiteral("-ref.diff"); const QString generatedFile = QStringLiteral(DIFF_DATA_DIR) + QLatin1Char('/') + input + QStringLiteral("-generated.diff"); QString diff = readDiffFile(originalFile); - DiffHighlighter highLighter; - highLighter.highlightDiff(diff); - const QString html = highLighter.outputDiff(); - //Create generated file QFile f(generatedFile); QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate)); - f.write(html.toUtf8()); + QTextStream s(&f); + + KSyntaxHighlighting::Repository repo; + Highlighter highLighter(&s); + highLighter.setDefinition(repo.definitionForName(QStringLiteral("Diff"))); + highLighter.setTheme(repo.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + highLighter.highlight(diff); + + s.flush(); f.close(); // compare to reference file QStringList args = QStringList() << QStringLiteral("-u") << refFile << generatedFile; QProcess proc; proc.setProcessChannelMode(QProcess::ForwardedChannels); proc.start(QStringLiteral("diff"), args); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); } QTEST_MAIN(DiffHighlighterTest) diff --git a/plugins/messageviewer/bodypartformatter/highlighter/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/highlighter/CMakeLists.txt new file mode 100644 index 00000000..bb9b4a30 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/highlighter/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_definitions(-DTRANSLATION_DOMAIN=\"messageviewer_text_xdiff_plugin\") +set(messageviewer_bodypartformatter_text_highlighter_PART_SRCS texthighlighterplugin.cpp highlighter.cpp) + +add_library(messageviewer_bodypartformatter_text_highlighter MODULE ${messageviewer_bodypartformatter_text_highlighter_PART_SRCS}) + +target_link_libraries(messageviewer_bodypartformatter_text_highlighter + Qt5::Core + KF5::MessageViewer + KF5::SyntaxHighlighting + Grantlee5::Templates +) + +install(TARGETS messageviewer_bodypartformatter_text_highlighter DESTINATION ${KDE_INSTALL_PLUGINDIR}/messageviewer/bodypartformatter) diff --git a/plugins/messageviewer/bodypartformatter/xdiff/Messages.sh b/plugins/messageviewer/bodypartformatter/highlighter/Messages.sh similarity index 100% rename from plugins/messageviewer/bodypartformatter/xdiff/Messages.sh rename to plugins/messageviewer/bodypartformatter/highlighter/Messages.sh diff --git a/plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.cpp b/plugins/messageviewer/bodypartformatter/highlighter/highlighter.cpp similarity index 51% rename from plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.cpp rename to plugins/messageviewer/bodypartformatter/highlighter/highlighter.cpp index d7379f1e..17e37a50 100644 --- a/plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.cpp +++ b/plugins/messageviewer/bodypartformatter/highlighter/highlighter.cpp @@ -1,95 +1,87 @@ /* Copyright (C) 2017 Montel Laurent 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "diffhighlighter.h" +#include "highlighter.h" + #include -#include #include +#include -#include -#include +#include -DiffHighlighter::DiffHighlighter() +Highlighter::Highlighter(QTextStream *stream) + : mStream(stream) { - mDef = mRepo.definitionForName(QStringLiteral("Diff")); - setDefinition(mDef); - - setTheme(QGuiApplication::palette().color(QPalette::Base).lightness() < 128 - ? mRepo.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme) - : mRepo.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); } -DiffHighlighter::~DiffHighlighter() -{ -} +Highlighter::~Highlighter() = default; -void DiffHighlighter::highlightDiff(const QString &str) +void Highlighter::highlight(const QString &str) { - mOutputDiff.clear(); - mOutputDiff = QStringLiteral("
");
+    *mStream << QStringLiteral("
");
 
     KSyntaxHighlighting::State state;
 
     int lineStart = 0;
     int lineEnd = str.indexOf(QLatin1Char('\n'));
 
     for (; lineEnd != -1; lineStart = lineEnd + 1, lineEnd = str.indexOf(QLatin1Char('\n'), lineStart)) {
         mCurrentLine = str.mid(lineStart, lineEnd - lineStart);
         state = highlightLine(mCurrentLine, state);
-        mOutputDiff += QLatin1Char('\n');
+        *mStream << QLatin1Char('\n');
+    }
+    if (lineStart < str.size()) { // remaining content if str isn't ending with a newline
+       mCurrentLine = str.mid(lineStart);
+       state = highlightLine(mCurrentLine, state);
+       *mStream << QLatin1Char('\n');
     }
-    mOutputDiff += QLatin1String("
\n"); + *mStream << QLatin1String("
\n"); } -void DiffHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) +void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) { if (!format.isDefaultTextStyle(theme())) { - mOutputDiff += QStringLiteral(""); + *mStream << QStringLiteral("\">"); } - mOutputDiff += mCurrentLine.mid(offset, length).toHtmlEscaped(); + *mStream << mCurrentLine.mid(offset, length).toHtmlEscaped(); if (!format.isDefaultTextStyle(theme())) { - mOutputDiff += QStringLiteral(""); + *mStream << QStringLiteral(""); } } - -QString DiffHighlighter::outputDiff() const -{ - return mOutputDiff; -} diff --git a/plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.h b/plugins/messageviewer/bodypartformatter/highlighter/highlighter.h similarity index 70% rename from plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.h rename to plugins/messageviewer/bodypartformatter/highlighter/highlighter.h index a10c6737..e91dd347 100644 --- a/plugins/messageviewer/bodypartformatter/xdiff/diffhighlighter.h +++ b/plugins/messageviewer/bodypartformatter/highlighter/highlighter.h @@ -1,46 +1,42 @@ /* Copyright (C) 2017 Montel Laurent 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef DIFFHIGHLIGHTER_H -#define DIFFHIGHLIGHTER_H +#ifndef HIGHLIGHTER_H +#define HIGHLIGHTER_H #include -#include -#include -class DiffHighlighter : public KSyntaxHighlighting::AbstractHighlighter +class QTextStream; + +class Highlighter : public KSyntaxHighlighting::AbstractHighlighter { public: - DiffHighlighter(); - ~DiffHighlighter(); - - void highlightDiff(const QString &str); + Highlighter(QTextStream *stream); + ~Highlighter(); - QString outputDiff() const; + void highlight(const QString &str); protected: void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; private: - KSyntaxHighlighting::Repository mRepo; - KSyntaxHighlighting::Definition mDef; QString mCurrentLine; - QString mOutputDiff; + QTextStream *mStream; }; #endif // DIFFHIGHLIGHTER_H diff --git a/plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.cpp b/plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.cpp similarity index 70% rename from plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.cpp rename to plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.cpp index 5aff1b4e..399ab987 100644 --- a/plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.cpp +++ b/plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.cpp @@ -1,93 +1,111 @@ /* This file is part of kdepim. Copyright (c) 2004 Till Adam 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 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 "diffhighlighter.h" +#include "highlighter.h" #include #include #include #include #include +#include +#include +#include + #include +#include +#include +#include +#include + namespace { -// FIXME: The box should only be as wide as necessary. class Formatter : public MessageViewer::MessagePartRendererBase { public: bool render(const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter, MessageViewer::RenderContext *context) const override { Q_UNUSED(context); auto mp = msgPart.dynamicCast(); if (!mp || mp->isHidden() || mp->text().isEmpty() || mp->asIcon() != MimeTreeParser::NoIcon) return false; - const bool diffMimeType = msgPart->content()->contentType()->mimeType() == "text/x-patch" - || msgPart->content()->contentType()->mimeType() == "text/x-diff"; - const bool diffFileName = msgPart->content()->contentType()->name().endsWith(QLatin1String(".diff")) - || msgPart->content()->contentType()->name().endsWith(QLatin1String(".patch")); - if (!diffMimeType && !diffFileName) + QMimeDatabase db; + auto mt = db.mimeTypeForName(QString::fromLatin1(msgPart->content()->contentType()->mimeType().toLower())); + if (!mt.isValid()) + return false; + if (mt.name() != QLatin1String("text/plain") && !mt.allAncestors().contains(QLatin1String("text/plain"))) + return false; + + const auto def = mRepo.definitionForFileName(mp->label()); + if (!def.isValid()) return false; auto c = MessageViewer::MessagePartRendererManager::self()->createContext(); c.insert(QStringLiteral("block"), msgPart.data()); - c.insert(QStringLiteral("content"), QVariant::fromValue([msgPart](Grantlee::OutputStream *stream) { - DiffHighlighter highLighter; - highLighter.highlightDiff(msgPart->text()); - *stream << highLighter.outputDiff(); + c.insert(QStringLiteral("content"), QVariant::fromValue([=](Grantlee::OutputStream*) { + Highlighter highLighter(htmlWriter->stream()); + highLighter.setDefinition(def); + highLighter.setTheme(QGuiApplication::palette().color(QPalette::Base).lightness() < 128 + ? mRepo.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme) + : mRepo.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + highLighter.highlight(msgPart->text()); })); auto t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(":/textmessagepart.html")); Grantlee::OutputStream s(htmlWriter->stream()); t->render(&s, &c); return true; } + +private: + mutable KSyntaxHighlighting::Repository mRepo; }; class Plugin : public QObject, public MessageViewer::MessagePartRenderPlugin { Q_OBJECT Q_INTERFACES(MessageViewer::MessagePartRenderPlugin) - Q_PLUGIN_METADATA(IID "com.kde.messageviewer.bodypartformatter" FILE "text_xdiff.json") + Q_PLUGIN_METADATA(IID "com.kde.messageviewer.bodypartformatter" FILE "texthighlighterplugin.json") public: MessageViewer::MessagePartRendererBase* renderer(int index) override { if (index == 0) return new Formatter(); return nullptr; } }; } -#include "text_xdiff.moc" +#include "texthighlighterplugin.moc" diff --git a/plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.json b/plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.json similarity index 66% rename from plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.json rename to plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.json index 4d063207..80b6b2f5 100644 --- a/plugins/messageviewer/bodypartformatter/xdiff/text_xdiff.json +++ b/plugins/messageviewer/bodypartformatter/highlighter/texthighlighterplugin.json @@ -1,3 +1,3 @@ { - "renderer": [ { "type": "MimeTreeParser::AttachmentMessagePart" } ] + "renderer": [ { "type": "MimeTreeParser::AttachmentMessagePart", "mimetype": "text/plain" } ] } diff --git a/plugins/messageviewer/bodypartformatter/xdiff/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/xdiff/CMakeLists.txt deleted file mode 100644 index a31dde4b..00000000 --- a/plugins/messageviewer/bodypartformatter/xdiff/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -add_definitions(-DTRANSLATION_DOMAIN=\"messageviewer_text_xdiff_plugin\") -set(messageviewer_bodypartformatter_text_xdiff_PART_SRCS text_xdiff.cpp diffhighlighter.cpp) - -add_library(messageviewer_bodypartformatter_text_xdiff MODULE ${messageviewer_bodypartformatter_text_xdiff_PART_SRCS}) - -target_link_libraries(messageviewer_bodypartformatter_text_xdiff - Qt5::Core - KF5::MessageViewer - KF5::SyntaxHighlighting - Grantlee5::Templates -) - -install(TARGETS messageviewer_bodypartformatter_text_xdiff DESTINATION ${KDE_INSTALL_PLUGINDIR}/messageviewer/bodypartformatter)