diff --git a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp @@ -104,7 +104,7 @@ if (auto context = previousContext()) { const QString link = createLink(context->name(), context->name(), NavigationAction(context)); - modifyHtml() += navigationHighlight(i18n("Back to %1
", link)); + modifyHtml() += theme().navigationHighlight(i18n("Back to %1
", link)); } QExplicitlySharedDataPointer doc; @@ -121,7 +121,7 @@ } else if (d->m_declaration->isTypeAlias() || d->m_declaration->type() || d->m_declaration->kind() == Declaration::Instance) { if (d->m_declaration->isTypeAlias()) - modifyHtml() += importantHighlight(QStringLiteral("typedef ")); + modifyHtml() += theme().importantHighlight(QStringLiteral("typedef ")); if (d->m_declaration->type()) modifyHtml() += i18n("enumerator "); @@ -210,9 +210,9 @@ if (showType && showType.cast()) { showType = showType.cast()->returnType(); if (showType) - modifyHtml() += labelHighlight(i18n("Returns: ")); + modifyHtml() += theme().labelHighlight(i18n("Returns: ")); } else if (showType) { - modifyHtml() += labelHighlight(i18n("Type: ")); + modifyHtml() += theme().labelHighlight(i18n("Type: ")); } if (showType) { @@ -231,17 +231,17 @@ decl = definition->declaration(); if (decl->abstractType().cast()) - modifyHtml() += labelHighlight(i18n("Enum: ")); + modifyHtml() += theme().labelHighlight(i18n("Enum: ")); else - modifyHtml() += labelHighlight(i18n("Container: ")); + modifyHtml() += theme().labelHighlight(i18n("Container: ")); makeLink(declarationName(DeclarationPointer(decl)), DeclarationPointer( decl), NavigationAction::NavigateDeclaration); modifyHtml() += QStringLiteral(" "); } else { QualifiedIdentifier parent = identifier; parent.pop(); - modifyHtml() += labelHighlight(i18n("Scope: %1 ", typeHighlight(parent.toString().toHtmlEscaped()))); + modifyHtml() += theme().labelHighlight(i18n("Scope: %1 ", theme().typeHighlight(parent.toString().toHtmlEscaped()))); } } @@ -254,12 +254,12 @@ comment.replace(QLatin1Char('\n'), QLatin1Char(' ')); comment.replace(QLatin1String("
"), QLatin1String(" ")); comment.replace(QLatin1String("
"), QLatin1String(" ")); - modifyHtml() += commentHighlight(comment.toHtmlEscaped()) + QLatin1String(" "); + modifyHtml() += theme().commentHighlight(comment.toHtmlEscaped()) + QLatin1String(" "); } QString access = stringFromAccess(d->m_declaration); if (!access.isEmpty()) - modifyHtml() += labelHighlight(i18n("Access: %1 ", propertyHighlight(access.toHtmlEscaped()))); + modifyHtml() += theme().labelHighlight(i18n("Access: %1 ", theme().propertyHighlight(access.toHtmlEscaped()))); ///@todo Enumerations @@ -271,20 +271,20 @@ if (!first) detailsHtml += QLatin1String(", "); first = false; - detailsHtml += propertyHighlight(str); + detailsHtml += theme().propertyHighlight(str); } } QString kind = declarationKind(d->m_declaration); if (!kind.isEmpty()) { if (!detailsHtml.isEmpty()) - modifyHtml() += labelHighlight(i18n("Kind: %1 %2 ", importantHighlight(kind.toHtmlEscaped()), detailsHtml)); + modifyHtml() += theme().labelHighlight(i18n("Kind: %1 %2 ", theme().importantHighlight(kind.toHtmlEscaped()), detailsHtml)); else - modifyHtml() += labelHighlight(i18n("Kind: %1 ", importantHighlight(kind.toHtmlEscaped()))); + modifyHtml() += theme().labelHighlight(i18n("Kind: %1 ", theme().importantHighlight(kind.toHtmlEscaped()))); } if (d->m_declaration->isDeprecated()) { - modifyHtml() += labelHighlight(i18n("Status: %1 ", propertyHighlight(i18n("Deprecated")))); + modifyHtml() += theme().labelHighlight(i18n("Status: %1 ", theme().propertyHighlight(i18n("Deprecated")))); } modifyHtml() += QStringLiteral("
"); @@ -294,9 +294,9 @@ if (!shorten) { if (dynamic_cast(d->m_declaration.data())) - modifyHtml() += labelHighlight(i18n("Def.: ")); + modifyHtml() += theme().labelHighlight(i18n("Def.: ")); else - modifyHtml() += labelHighlight(i18n("Decl.: ")); + modifyHtml() += theme().labelHighlight(i18n("Decl.: ")); makeLink(QStringLiteral("%1 :%2").arg(d->m_declaration->url().toUrl().fileName()).arg(d->m_declaration-> rangeInCurrentRevision(). @@ -306,7 +306,7 @@ //modifyHtml() += "
"; if (!dynamic_cast(d->m_declaration.data())) { if (FunctionDefinition* definition = FunctionDefinition::definition(d->m_declaration.data())) { - modifyHtml() += labelHighlight(i18n(" Def.: ")); + modifyHtml() += theme().labelHighlight(i18n(" Def.: ")); makeLink(QStringLiteral("%1 :%2").arg(definition->url().toUrl().fileName()).arg(definition-> rangeInCurrentRevision() .start().line() + 1), DeclarationPointer( @@ -316,7 +316,7 @@ if (auto* definition = dynamic_cast(d->m_declaration.data())) { if (definition->declaration()) { - modifyHtml() += labelHighlight(i18n(" Decl.: ")); + modifyHtml() += theme().labelHighlight(i18n(" Decl.: ")); makeLink(QStringLiteral("%1 :%2").arg(definition->declaration()->url().toUrl().fileName()).arg( definition->declaration()->rangeInCurrentRevision().start().line() + 1), DeclarationPointer(definition->declaration()), NavigationAction::JumpToSource); @@ -339,7 +339,7 @@ &AbstractDeclarationNavigationContext::contentsChanged); if (!comment.isEmpty()) { - modifyHtml() += QLatin1String("

") + commentHighlight(comment) + QLatin1String("

"); + modifyHtml() += QLatin1String("

") + theme().commentHighlight(comment) + QLatin1String("

"); } } @@ -353,7 +353,7 @@ comment = comment.toHtmlEscaped(); comment.replace(QLatin1Char('\n'), QLatin1String("
")); //Replicate newlines in html } - modifyHtml() += QLatin1String("

") + commentHighlight(comment) + QLatin1String("

"); + modifyHtml() += QLatin1String("

") + theme().commentHighlight(comment) + QLatin1String("

"); } } @@ -390,7 +390,7 @@ dynamic_cast(d->m_declaration.data()); const FunctionType::Ptr type = d->m_declaration->abstractType().cast(); if (!type) { - modifyHtml() += errorHighlight(QStringLiteral("Invalid type
")); + modifyHtml() += theme().errorHighlight(QStringLiteral("Invalid type
")); return; } @@ -651,15 +651,15 @@ if (!idType) { qCDebug(LANGUAGE) << "no identified type for" << type->toString(); - modifyHtml() += typeHighlight(type->toString().toHtmlEscaped()); + modifyHtml() += theme().typeHighlight(type->toString().toHtmlEscaped()); return; } auto* decl = idType->declaration(topContext().data()); if (!decl) { qCDebug(LANGUAGE) << "could not resolve declaration:" << idType->declarationId().isDirect() << idType->qualifiedIdentifier().toString() << "in top-context" << topContext()->url().str(); - modifyHtml() += typeHighlight(type->toString().toHtmlEscaped()); + modifyHtml() += theme().typeHighlight(type->toString().toHtmlEscaped()); return; } @@ -693,7 +693,7 @@ type = typeToShow(type); if (!type) { - modifyHtml() += typeHighlight(QStringLiteral("").toHtmlEscaped()); + modifyHtml() += theme().typeHighlight(QStringLiteral("").toHtmlEscaped()); return; } @@ -706,7 +706,7 @@ ///@todo This is C++ specific, move into subclass if (target->modifiers() & AbstractType::ConstModifier) - modifyHtml() += typeHighlight(QStringLiteral("const ")); + modifyHtml() += theme().typeHighlight(QStringLiteral("const ")); htmlIdentifiedType(target, idType); @@ -720,14 +720,14 @@ QRegExp suffixExp(QStringLiteral("\\&|\\*")); int suffixPos = typeSuffixString.indexOf(suffixExp); if (suffixPos != -1) - modifyHtml() += typeHighlight(typeSuffixString.mid(suffixPos)); + modifyHtml() += theme().typeHighlight(typeSuffixString.mid(suffixPos)); } } else { if (idType) { qCDebug(LANGUAGE) << "identified type could not be resolved:" << idType->qualifiedIdentifier() << idType->declarationId().isValid() << idType->declarationId().isDirect(); } - modifyHtml() += typeHighlight(type->toString().toHtmlEscaped()); + modifyHtml() += theme().typeHighlight(type->toString().toHtmlEscaped()); } } @@ -741,7 +741,7 @@ QString AbstractDeclarationNavigationContext::identifierHighlight(const QString& identifier, const DeclarationPointer& decl) const { - QString ret = nameHighlight(identifier); + QString ret = theme().nameHighlight(identifier); if (!decl) { return ret; } diff --git a/kdevplatform/language/duchain/navigation/abstractincludenavigationcontext.cpp b/kdevplatform/language/duchain/navigation/abstractincludenavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/abstractincludenavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/abstractincludenavigationcontext.cpp @@ -96,7 +96,7 @@ if (duchain) { getFileInfo(duchain); if (!shorten) { - modifyHtml() += labelHighlight(i18n("Declarations:")) + QLatin1String("
"); + modifyHtml() += theme().labelHighlight(i18n("Declarations:")) + QLatin1String("
"); bool first = true; QVector decs; addDeclarationsFromContext(duchain, first, decs); @@ -112,8 +112,8 @@ void AbstractIncludeNavigationContext::getFileInfo(TopDUContext* duchain) { modifyHtml() += - QStringLiteral("%1: %2 %3: %4").arg(labelHighlight(i18nc("Files included into this file", "Includes"))).arg( - duchain->importedParentContexts().count()).arg(labelHighlight(i18nc( + QStringLiteral("%1: %2 %3: %4").arg(theme().labelHighlight(i18nc("Files included into this file", "Includes"))).arg( + duchain->importedParentContexts().count()).arg(theme().labelHighlight(i18nc( "Count of files this file was included into", "Included by"))).arg( duchain->importers().count()); diff --git a/kdevplatform/language/duchain/navigation/abstractnavigationcontext.h b/kdevplatform/language/duchain/navigation/abstractnavigationcontext.h --- a/kdevplatform/language/duchain/navigation/abstractnavigationcontext.h +++ b/kdevplatform/language/duchain/navigation/abstractnavigationcontext.h @@ -25,6 +25,8 @@ #include "../indexeddeclaration.h" #include "navigationaction.h" +#include + namespace KDevelop { class AbstractNavigationContextPrivate; @@ -48,12 +50,42 @@ { } + explicit Colorizer() = default; + QString operator()(const QString& str) const; QString m_color; Formatting m_formatting; }; +/** Theme for color used in HTML navigation widget. + */ +class KDEVPLATFORMLANGUAGE_EXPORT ColorizerTheme +{ +private: + /** Obtain foreground color. + * @param scheme UI color scheme. + * @param role Foreground type. + * @return foreground color. + */ + static QString foreground(const KColorScheme& scheme, KColorScheme::ForegroundRole role); + +public: + explicit ColorizerTheme(const KColorScheme& scheme); + explicit ColorizerTheme() = default; + + Colorizer typeHighlight; + Colorizer positionHighlight; + Colorizer errorHighlight; + Colorizer labelHighlight; + Colorizer codeHighlight; + Colorizer propertyHighlight; + Colorizer navigationHighlight; + Colorizer importantHighlight; + Colorizer commentHighlight; + Colorizer nameHighlight; +}; + class AbstractNavigationContext; using NavigationContextPointer = QExplicitlySharedDataPointer; @@ -155,15 +187,8 @@ virtual QString declarationKind(const DeclarationPointer& decl); - static const Colorizer typeHighlight; - static const Colorizer errorHighlight; - static const Colorizer labelHighlight; - static const Colorizer codeHighlight; - static const Colorizer propertyHighlight; - static const Colorizer navigationHighlight; - static const Colorizer importantHighlight; - static const Colorizer commentHighlight; - static const Colorizer nameHighlight; + /// Color theme used for HTML. + const ColorizerTheme& theme() const; private: const QScopedPointer d_ptr; diff --git a/kdevplatform/language/duchain/navigation/abstractnavigationcontext.cpp b/kdevplatform/language/duchain/navigation/abstractnavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/abstractnavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/abstractnavigationcontext.cpp @@ -36,6 +36,8 @@ #include #include +#include + namespace KDevelop { class AbstractNavigationContextPrivate { @@ -59,6 +61,8 @@ TopDUContextPointer m_topContext; QString m_currentText; //Here the text is built + + ColorizerTheme m_theme; }; void AbstractNavigationContext::setTopContext(const TopDUContextPointer& context) @@ -83,6 +87,8 @@ d->m_previousContext = previousContext; d->m_topContext = topContext; + const KColorScheme scheme(QPalette::Normal, KColorScheme::View); + d->m_theme = ColorizerTheme(scheme); qRegisterMetaType("KTextEditor::Cursor"); qRegisterMetaType("IDocumentation::Ptr"); @@ -105,7 +111,7 @@ if (d->m_shorten) { //Do not create links in shortened mode, it's only for viewing - return typeHighlight(name.toHtmlEscaped()); + return theme().typeHighlight(name.toHtmlEscaped()); } // NOTE: Since the by definition in the HTML standard some uri components @@ -124,8 +130,7 @@ QString str = name.toHtmlEscaped(); if (d->m_linkCount == d->m_selectedLink) - str = QLatin1String("") + str + QLatin1String( - ""); + str = theme().positionHighlight(str); QString ret = QLatin1String("m_linkCount == d->m_selectedLink && @@ -579,8 +584,8 @@ if (line.indexOf(newLineRegExp) != -1) { ++d->m_currentLine; if (d->m_currentLine == d->m_currentPositionLine) { - d->m_currentText += QStringLiteral( - " <-> "); // ><-> is <-> + d->m_currentText += theme().positionHighlight( + QStringLiteral("<->")); // ><-> is <-> } } } @@ -593,9 +598,16 @@ return d->m_currentText; } +const ColorizerTheme& AbstractNavigationContext::theme() const +{ + Q_D(const AbstractNavigationContext); + + return d->m_theme; +} + QString Colorizer::operator()(const QString& str) const { - QString ret = QLatin1String("") + str + QLatin1String(""); + QString ret = QLatin1String("") + str + QLatin1String(""); if (m_formatting & Fixed) ret = QLatin1String("") + ret + QLatin1String(""); @@ -607,14 +619,23 @@ return ret; } -const Colorizer AbstractNavigationContext::typeHighlight(QStringLiteral("006000")); -const Colorizer AbstractNavigationContext::errorHighlight(QStringLiteral("990000")); -const Colorizer AbstractNavigationContext::labelHighlight(QStringLiteral("000000")); -const Colorizer AbstractNavigationContext::codeHighlight(QStringLiteral("005000")); -const Colorizer AbstractNavigationContext::propertyHighlight(QStringLiteral("009900")); -const Colorizer AbstractNavigationContext::navigationHighlight(QStringLiteral("000099")); -const Colorizer AbstractNavigationContext::importantHighlight(QStringLiteral( - "000000"), Colorizer::Bold | Colorizer::Italic); -const Colorizer AbstractNavigationContext::commentHighlight(QStringLiteral("303030")); -const Colorizer AbstractNavigationContext::nameHighlight(QStringLiteral("000000"), Colorizer::Bold); +QString ColorizerTheme::foreground(const KColorScheme& scheme, KColorScheme::ForegroundRole role) +{ + return scheme.foreground(role).color().name(); +} + +ColorizerTheme::ColorizerTheme(const KColorScheme& scheme) + : typeHighlight(foreground(scheme, KColorScheme::LinkText)) + , positionHighlight(foreground(scheme, KColorScheme::LinkText)) + , errorHighlight(foreground(scheme, KColorScheme::NegativeText)) + , labelHighlight(foreground(scheme, KColorScheme::NormalText)) + , codeHighlight(foreground(scheme, KColorScheme::PositiveText)) + , propertyHighlight(foreground(scheme, KColorScheme::NeutralText)) + , navigationHighlight(foreground(scheme, KColorScheme::NormalText)) + , importantHighlight(foreground(scheme, KColorScheme::ActiveText), Colorizer::Bold | Colorizer::Italic) + , commentHighlight(foreground(scheme, KColorScheme::InactiveText)) + , nameHighlight(foreground(scheme, KColorScheme::ActiveText), Colorizer::Bold) +{ +} + } diff --git a/kdevplatform/language/duchain/navigation/abstractnavigationwidget.cpp b/kdevplatform/language/duchain/navigation/abstractnavigationwidget.cpp --- a/kdevplatform/language/duchain/navigation/abstractnavigationwidget.cpp +++ b/kdevplatform/language/duchain/navigation/abstractnavigationwidget.cpp @@ -96,14 +96,6 @@ Q_ASSERT(!d->m_browser); Q_UNUSED(height); d->m_browser = new QTextBrowser; - - // since we can embed arbitrary HTML we have to make sure it stays readable by forcing a black-white palette - QPalette p; - p.setColor(QPalette::AlternateBase, Qt::white); - p.setColor(QPalette::Base, Qt::white); - p.setColor(QPalette::Text, Qt::black); - d->m_browser->setPalette(p); - d->m_browser->setOpenLinks(false); d->m_browser->setOpenExternalLinks(false); diff --git a/kdevplatform/language/duchain/navigation/problemnavigationcontext.cpp b/kdevplatform/language/duchain/navigation/problemnavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/problemnavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/problemnavigationcontext.cpp @@ -135,7 +135,7 @@ modifyHtml() += QStringLiteral("
"); if (m_flags & ShowLocation) { - modifyHtml() += labelHighlight(i18n("Location: ")); + modifyHtml() += theme().labelHighlight(i18n("Location: ")); makeLink(QStringLiteral("%1 :%2") .arg(problem->finalLocation().document.toUrl().fileName()) .arg(problem->finalLocation().start().line() + 1), @@ -167,7 +167,7 @@ DUChainReadLocker lock; for (auto diagnostic : diagnostics) { modifyHtml() += QStringLiteral("

"); - modifyHtml() += labelHighlight(QStringLiteral("%1: ").arg(diagnostic->severityString())); + modifyHtml() += theme().labelHighlight(QStringLiteral("%1: ").arg(diagnostic->severityString())); modifyHtml() += escapedHtml(diagnostic->description()); const DocumentRange range = diagnostic->finalLocation(); diff --git a/kdevplatform/language/duchain/navigation/usesnavigationcontext.cpp b/kdevplatform/language/duchain/navigation/usesnavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/usesnavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/usesnavigationcontext.cpp @@ -50,7 +50,7 @@ modifyHtml() += QLatin1String("

"); if (auto context = previousContext()) { - modifyHtml() += navigationHighlight(i18n("Uses of ")); + modifyHtml() += theme().navigationHighlight(i18n("Uses of ")); makeLink(context->name(), context->name(), NavigationAction(context)); } else { KDevelop::DUChainReadLocker lock(DUChain::lock()); diff --git a/plugins/clang/duchain/macronavigationcontext.cpp b/plugins/clang/duchain/macronavigationcontext.cpp --- a/plugins/clang/duchain/macronavigationcontext.cpp +++ b/plugins/clang/duchain/macronavigationcontext.cpp @@ -66,7 +66,7 @@ "%2: the macro name and arguments", "%1: %2", (m_macro->isFunctionLike() ? i18n("Function macro") : i18n("Macro")), - importantHighlight(name()) + parameters); + theme().importantHighlight(name()) + parameters); modifyHtml() += QStringLiteral("
"); modifyHtml() += i18nc("%1: the link to the definition", "Defined in: %1", createLink(QStringLiteral("%1 :%2").arg(url.fileName()).arg(cursor.line()+1), path, action)); diff --git a/plugins/qmljs/duchain/navigation/declarationnavigationcontext.cpp b/plugins/qmljs/duchain/navigation/declarationnavigationcontext.cpp --- a/plugins/qmljs/duchain/navigation/declarationnavigationcontext.cpp +++ b/plugins/qmljs/duchain/navigation/declarationnavigationcontext.cpp @@ -61,7 +61,7 @@ if (funcType) { // Don't let eventuallyMakeTypeLinks cast funcType to an identified type // and try to print it! The function most of the time has no name. - modifyHtml() += typeHighlight(type->toString().toHtmlEscaped()); + modifyHtml() += theme().m_typeHighlight(type->toString().toHtmlEscaped()); } else { KDevelop::AbstractDeclarationNavigationContext::eventuallyMakeTypeLinks(type); }