Commit 1ac1a5a7 authored by Volker Krause's avatar Volker Krause

Turn the diff plugin into a generic syntax highlighting plugin

Reviewers: knauss

Reviewed By: knauss

Subscribers: #kde_pim

Tags: #kde_pim

Differential Revision: https://phabricator.kde.org/D8192
parent b50a0817
......@@ -2,6 +2,6 @@
add_subdirectory(autotests)
add_subdirectory(ms-tnef)
add_subdirectory(vcard)
add_subdirectory(xdiff)
add_subdirectory(highlighter)
add_subdirectory(calendar)
add_subdirectory(gnupgwks)
......@@ -41,4 +41,4 @@ macro(add_diff_bodyformatter_class_unittest _source _additional)
)
endmacro ()
add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../xdiff/diffhighlighter.cpp")
add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../highlighter/highlighter.cpp")
......@@ -18,7 +18,11 @@
*/
#include "diffhighlightertest.h"
#include "../xdiff/diffhighlighter.h"
#include "../highlighter/highlighter.h"
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
#include <QProcess>
#include <QStandardPaths>
......@@ -28,10 +32,6 @@ 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)
......@@ -60,14 +60,18 @@ void DiffHighlighterTest::shouldGenerateDiff()
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
......
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)
......@@ -17,32 +17,24 @@
Boston, MA 02110-1301, USA.
*/
#include "diffhighlighter.h"
#include "highlighter.h"
#include <KSyntaxHighlighting/Format>
#include <KSyntaxHighlighting/Theme>
#include <KSyntaxHighlighting/State>
#include <KSyntaxHighlighting/Theme>
#include <QGuiApplication>
#include <QPalette>
#include <QTextStream>
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("<pre>");
*mStream << QStringLiteral("<pre>");
KSyntaxHighlighting::State state;
......@@ -52,44 +44,44 @@ void DiffHighlighter::highlightDiff(const QString &str)
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("</pre>\n");
*mStream << QLatin1String("</pre>\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("<span style=\"");
*mStream << QStringLiteral("<span style=\"");
if (format.hasTextColor(theme())) {
mOutputDiff += QStringLiteral("color:") + format.textColor(theme()).name() + QStringLiteral(";");
*mStream << QStringLiteral("color:") << format.textColor(theme()).name() << QStringLiteral(";");
}
if (format.hasBackgroundColor(theme())) {
mOutputDiff += QStringLiteral("background-color:") + format.backgroundColor(theme()).name() + QStringLiteral(";");
*mStream << QStringLiteral("background-color:") << format.backgroundColor(theme()).name() << QStringLiteral(";");
}
if (format.isBold(theme())) {
mOutputDiff += QStringLiteral("font-weight:bold;");
*mStream << QStringLiteral("font-weight:bold;");
}
if (format.isItalic(theme())) {
mOutputDiff += QStringLiteral("font-style:italic;");
*mStream << QStringLiteral("font-style:italic;");
}
if (format.isUnderline(theme())) {
mOutputDiff += QStringLiteral("text-decoration:underline;");
*mStream << QStringLiteral("text-decoration:underline;");
}
if (format.isStrikeThrough(theme())) {
mOutputDiff += QStringLiteral("text-decoration:line-through;");
*mStream << QStringLiteral("text-decoration:line-through;");
}
mOutputDiff += QStringLiteral("\">");
*mStream << QStringLiteral("\">");
}
mOutputDiff += mCurrentLine.mid(offset, length).toHtmlEscaped();
*mStream << mCurrentLine.mid(offset, length).toHtmlEscaped();
if (!format.isDefaultTextStyle(theme())) {
mOutputDiff += QStringLiteral("</span>");
*mStream << QStringLiteral("</span>");
}
}
QString DiffHighlighter::outputDiff() const
{
return mOutputDiff;
}
......@@ -17,30 +17,26 @@
Boston, MA 02110-1301, USA.
*/
#ifndef DIFFHIGHLIGHTER_H
#define DIFFHIGHLIGHTER_H
#ifndef HIGHLIGHTER_H
#define HIGHLIGHTER_H
#include <KSyntaxHighlighting/AbstractHighlighter>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Definition>
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
......@@ -29,7 +29,7 @@
your version.
*/
#include "diffhighlighter.h"
#include "highlighter.h"
#include <MessageViewer/MessagePartRendererBase>
#include <MessageViewer/MessagePartRendererManager>
......@@ -38,10 +38,18 @@
#include <MimeTreeParser/MessagePart>
#include <MimeTreeParser/HtmlWriter>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
#include <grantlee/template.h>
#include <QGuiApplication>
#include <QMimeDatabase>
#include <QMimeType>
#include <QPalette>
namespace {
// FIXME: The box should only be as wide as necessary.
class Formatter : public MessageViewer::MessagePartRendererBase
{
......@@ -53,19 +61,26 @@ public:
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<MessageViewer::GrantleeCallback>([msgPart](Grantlee::OutputStream *stream) {
DiffHighlighter highLighter;
highLighter.highlightDiff(msgPart->text());
*stream << highLighter.outputDiff();
c.insert(QStringLiteral("content"), QVariant::fromValue<MessageViewer::GrantleeCallback>([=](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"));
......@@ -73,13 +88,16 @@ public:
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
{
......@@ -90,4 +108,4 @@ public:
};
}
#include "text_xdiff.moc"
#include "texthighlighterplugin.moc"
{
"renderer": [ { "type": "MimeTreeParser::AttachmentMessagePart" } ]
"renderer": [ { "type": "MimeTreeParser::AttachmentMessagePart", "mimetype": "text/plain" } ]
}
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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment