aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/extensionmanager/extensionmanagerwidget.cpp
diff options
context:
space:
mode:
authorAlessandro Portale <[email protected]>2024-07-17 13:12:29 +0200
committerAlessandro Portale <[email protected]>2024-07-17 13:36:45 +0000
commit3ea8c7808e1ae155b6e13438d907c865afc4baa0 (patch)
treefc24e8ed737e7ef63c970fc1e85dcf75c72f0e2b /src/plugins/extensionmanager/extensionmanagerwidget.cpp
parent3fd60717ebd513154c8de5c6276aa4cd4fb67540 (diff)
ExtensionManager: Interpret description text as MarkDown
Task-number: QTCREATORBUG-31199 Fixes: QTCREATORBUG-31182 Change-Id: Iff0ec94db67b3afcad024b2fec4797805f1123e8 Reviewed-by: Cristian Adam <[email protected]>
Diffstat (limited to 'src/plugins/extensionmanager/extensionmanagerwidget.cpp')
-rw-r--r--src/plugins/extensionmanager/extensionmanagerwidget.cpp73
1 files changed, 52 insertions, 21 deletions
diff --git a/src/plugins/extensionmanager/extensionmanagerwidget.cpp b/src/plugins/extensionmanager/extensionmanagerwidget.cpp
index d9fb281e1d2..493f8ebe40d 100644
--- a/src/plugins/extensionmanager/extensionmanagerwidget.cpp
+++ b/src/plugins/extensionmanager/extensionmanagerwidget.cpp
@@ -46,6 +46,8 @@
#include <QProgressDialog>
#include <QScrollArea>
#include <QSignalMapper>
+#include <QTextDocument>
+#include <QTextBlock>
using namespace Core;
using namespace Utils;
@@ -421,8 +423,9 @@ ExtensionManagerWidget::ExtensionManagerWidget()
m_secondaryDescriptionWidget = new CollapsingWidget;
m_headingWidget = new HeadingWidget;
- m_description = tfLabel(contentTF, false);
+ m_description = new QLabel;
m_description->setWordWrap(true);
+ m_description->setTextInteractionFlags(Qt::TextBrowserInteraction);
m_linksTitle = sectionTitle(h6CapitalTF, Tr::tr("More information"));
m_links = tfLabel(contentTF, false);
m_links->setOpenExternalLinks(true);
@@ -528,6 +531,47 @@ ExtensionManagerWidget::ExtensionManagerWidget()
updateView({});
}
+static QString markdownToHtml(const QString &markdown)
+{
+ QTextDocument doc;
+ doc.setMarkdown(markdown);
+ doc.setDefaultFont(contentTF.font());
+
+ for (QTextBlock block = doc.begin(); block != doc.end(); block = block.next()) {
+ QTextBlockFormat blockFormat = block.blockFormat();
+ if (blockFormat.hasProperty(QTextFormat::HeadingLevel))
+ blockFormat.setTopMargin(SpacingTokens::ExVPaddingGapXl);
+ else
+ blockFormat.setLineHeight(contentTF.lineHeight(), QTextBlockFormat::FixedHeight);
+ blockFormat.setBottomMargin(SpacingTokens::VGapL);
+ QTextCursor cursor(block);
+ cursor.mergeBlockFormat(blockFormat);
+ const TextFormat headingTf = blockFormat.headingLevel() == 1 ? h5TF : h6TF;
+ const QFont headingFont = headingTf.font();
+ for (auto it = block.begin(); !(it.atEnd()); ++it) {
+ QTextFragment fragment = it.fragment();
+ if (fragment.isValid()) {
+ QTextCharFormat charFormat = fragment.charFormat();
+ cursor.setPosition(fragment.position());
+ cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
+ if (blockFormat.hasProperty(QTextFormat::HeadingLevel)) {
+ charFormat.setFontFamilies(headingFont.families());
+ charFormat.setFontWeight(headingFont.weight());
+ charFormat.setFontPointSize(headingFont.pointSizeF());
+ charFormat.setForeground(headingTf.color());
+ } else if (charFormat.isAnchor()) {
+ charFormat.setForeground(creatorColor(Theme::Token_Text_Accent));
+ } else {
+ charFormat.setForeground(contentTF.color());
+ }
+ cursor.setCharFormat(charFormat);
+ }
+ }
+ }
+
+ return doc.toHtml();
+}
+
void ExtensionManagerWidget::updateView(const QModelIndex &current)
{
m_headingWidget->update(current);
@@ -556,28 +600,15 @@ void ExtensionManagerWidget::updateView(const QModelIndex &current)
const TextData textData = current.data(RoleDescriptionText).value<TextData>();
const bool hasDescription = !textData.isEmpty();
if (hasDescription) {
- const QString headerCssTemplate =
- ";margin-top:%1;margin-bottom:%2;padding-top:0;padding-bottom:0;";
- const QString h4Css = fontToCssProperties(uiFont(UiElementH4))
- + headerCssTemplate.arg(0).arg(SpacingTokens::VGapL);
- const QString h5Css = fontToCssProperties(uiFont(UiElementH5))
- + headerCssTemplate.arg(SpacingTokens::ExVPaddingGapXl)
- .arg(SpacingTokens::VGapL);
- QString descriptionHtml;
+ QString descriptionMarkdown;
for (const TextData::Type &text : textData) {
- if (text.second.isEmpty())
- continue;
- const QString paragraph =
- QString::fromLatin1("<div style=\"%1\">%2</div>%3")
- .arg(descriptionHtml.isEmpty() ? h4Css : h5Css)
- .arg(text.first)
- .arg(toContentParagraph(text.second.join("<br/>")));
- descriptionHtml.append(paragraph);
+ if (!text.first.isEmpty()) {
+ const QLatin1String headingMark(descriptionMarkdown.isEmpty() ? "#" : "\n\n##");
+ descriptionMarkdown.append(headingMark + " " + text.first + "\n");
+ }
+ descriptionMarkdown.append(text.second.join("\n"));
}
- descriptionHtml.prepend(QString::fromLatin1("<body style=\"color:%1;\">")
- .arg(creatorColor(Theme::Token_Text_Default).name()));
- descriptionHtml.append("</body>");
- m_description->setText(descriptionHtml);
+ m_description->setText(markdownToHtml(descriptionMarkdown));
}
m_description->setVisible(hasDescription);