aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/extensionmanager/extensionmanagerwidget.cpp
diff options
context:
space:
mode:
authorMarcus Tillmanns <[email protected]>2024-10-10 09:39:00 +0200
committerMarcus Tillmanns <[email protected]>2024-10-14 08:00:59 +0000
commit7b1734305a787c88ca3a2e77aa42b8789f63019b (patch)
tree4cadce87b5c0c7335a4ce7b64c485efc506ce2b7 /src/plugins/extensionmanager/extensionmanagerwidget.cpp
parente21c24dc634f45322d4ebb013b2c98ed181d0e29 (diff)
ExtensionManager: Add highlighted code blocks
Change-Id: Id6c8ea7064f4f6b0e4e65c1142ad2787f9f1571d Reviewed-by: Alessandro Portale <[email protected]>
Diffstat (limited to 'src/plugins/extensionmanager/extensionmanagerwidget.cpp')
-rw-r--r--src/plugins/extensionmanager/extensionmanagerwidget.cpp87
1 files changed, 84 insertions, 3 deletions
diff --git a/src/plugins/extensionmanager/extensionmanagerwidget.cpp b/src/plugins/extensionmanager/extensionmanagerwidget.cpp
index 19cf95a63aa..b9ebfbf8c99 100644
--- a/src/plugins/extensionmanager/extensionmanagerwidget.cpp
+++ b/src/plugins/extensionmanager/extensionmanagerwidget.cpp
@@ -29,10 +29,12 @@
#include <utils/icon.h>
#include <utils/infolabel.h>
#include <utils/layoutbuilder.h>
+#include <utils/mimeutils.h>
#include <utils/networkaccessmanager.h>
#include <utils/styledbar.h>
#include <utils/stylehelper.h>
#include <utils/temporarydirectory.h>
+#include <utils/textutils.h>
#include <utils/utilsicons.h>
#include <QAbstractTextDocumentLayout>
@@ -743,6 +745,78 @@ ExtensionManagerWidget::ExtensionManagerWidget()
updateView({});
}
+static QTextDocument *highlightText(const QString &code, const QString &language)
+{
+ auto mimeTypes = mimeTypesForFileName("file." + language);
+
+ QString mimeType = mimeTypes.isEmpty() ? "text/" + language : mimeTypes.first().name();
+
+ auto document = Utils::Text::highlightCode(code, mimeType);
+ if (document.isFinished())
+ return document.result();
+ document.cancel();
+ QTextDocument *doc = new QTextDocument;
+ doc->setPlainText(code);
+ return doc;
+}
+
+static void highlightCodeBlock(QTextDocument *document, QTextBlock &block, const QString &language)
+{
+ int startBlockNumner = block.blockNumber();
+
+ // Find the end of the code block ...
+ QTextBlock curBlock = block;
+ while (curBlock.isValid()) {
+ curBlock = curBlock.next();
+ const auto valid = curBlock.isValid();
+ const auto hasProp = curBlock.blockFormat().hasProperty(QTextFormat::BlockCodeLanguage);
+ const auto prop = curBlock.blockFormat().stringProperty(QTextFormat::BlockCodeLanguage);
+ if (!valid || !hasProp || prop != language)
+ break;
+ }
+ // Get the text of the code block and erase it
+ QTextCursor eraseCursor(document);
+ eraseCursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, startBlockNumner);
+ eraseCursor.movePosition(
+ QTextCursor::NextBlock,
+ QTextCursor::KeepAnchor,
+ curBlock.blockNumber() - startBlockNumner - 1);
+ eraseCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+
+ QString code = eraseCursor.selectedText();
+ eraseCursor.deleteChar();
+
+ // Create a new Frame and insert the highlighted code ...
+ block = document->findBlockByNumber(startBlockNumner);
+
+ QTextCursor cursor(block);
+ QTextFrameFormat format;
+ format.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
+ format.setBackground(creatorColor(Theme::Token_Background_Muted));
+ format.setPadding(SpacingTokens::ExPaddingGapM);
+ format.setLeftMargin(SpacingTokens::VGapM);
+ format.setRightMargin(SpacingTokens::VGapM);
+
+ QTextFrame *frame = cursor.insertFrame(format);
+ QTextCursor frameCursor(frame);
+
+ std::unique_ptr<QTextDocument> codeDocument(highlightText(code, language));
+ bool first = true;
+
+ for (auto block = codeDocument->begin(); block != codeDocument->end(); block = block.next()) {
+ if (!first)
+ frameCursor.insertBlock();
+ first = false;
+ auto formats = block.layout()->formats();
+ frameCursor.insertText(block.text());
+ frameCursor.block().layout()->setFormats(formats);
+ }
+
+ // Leave the frame
+ QTextCursor next = frame->lastCursorPosition();
+ block = next.block();
+}
+
static void setMarkdown(QTextDocument *document, const QString &markdown)
{
document->setMarkdown(markdown);
@@ -754,12 +828,19 @@ static void setMarkdown(QTextDocument *document, const QString &markdown)
if (block.text().contains(QChar::ObjectReplacementCharacter))
continue;
- if (blockFormat.hasProperty(QTextFormat::HeadingLevel))
+ if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
blockFormat.setTopMargin(SpacingTokens::ExVPaddingGapXl);
- else
+ blockFormat.setBottomMargin(SpacingTokens::VGapL);
+ } else
blockFormat.setLineHeight(contentTF.lineHeight(), QTextBlockFormat::FixedHeight);
- blockFormat.setBottomMargin(SpacingTokens::VGapL);
+
QTextCursor cursor(block);
+ if (blockFormat.hasProperty(QTextFormat::BlockCodeLanguage)) {
+ QString language = blockFormat.stringProperty(QTextFormat::BlockCodeLanguage);
+ highlightCodeBlock(document, block, language);
+ continue;
+ }
+
cursor.mergeBlockFormat(blockFormat);
const TextFormat headingTf =
blockFormat.headingLevel() == 1 ? h5TF