diff options
author | Marcus Tillmanns <[email protected]> | 2024-10-10 09:39:00 +0200 |
---|---|---|
committer | Marcus Tillmanns <[email protected]> | 2024-10-14 08:00:59 +0000 |
commit | 7b1734305a787c88ca3a2e77aa42b8789f63019b (patch) | |
tree | 4cadce87b5c0c7335a4ce7b64c485efc506ce2b7 /src/plugins/extensionmanager/extensionmanagerwidget.cpp | |
parent | e21c24dc634f45322d4ebb013b2c98ed181d0e29 (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.cpp | 87 |
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 |