Home
Phabricator
Search
Log In
Files
F6192639
inline-problems.diff
brauch (Sven Brauch)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Author
brauch
Created
Aug 14 2018, 11:43 AM
Size
6 KB
Mime Type
text/x-diff
Engine
blob
Format
Raw Data
Handle
3858010
Attached To
D14826: inline note interface wip #2
inline-problems.diff
View Options
diff --git a/plugins/problemreporter/problemhighlighter.cpp b/plugins/problemreporter/problemhighlighter.cpp
index a4f3718e9e..bf0b341daf 100644
--- a/plugins/problemreporter/problemhighlighter.cpp
+++ b/plugins/problemreporter/problemhighlighter.cpp
@@ -24,6 +24,7 @@
#include <KTextEditor/Document>
#include <KTextEditor/MarkInterface>
+#include <KTextEditor/InlineNoteInterface>
#include <ktexteditor/view.h>
#include <ktexteditor/movinginterface.h>
@@ -39,12 +40,16 @@
#include <language/editor/documentrange.h>
#include <kcolorscheme.h>
+#include <QPainter>
+#include <QRegularExpression>
#include <shell/problem.h>
using namespace KTextEditor;
using namespace KDevelop;
+const int margin = 4;
+
namespace
{
@@ -61,6 +66,7 @@ QColor colorForSeverity(IProblem::Severity severity)
return scheme.foreground(KColorScheme::PositiveText).color();
}
}
+
}
ProblemHighlighter::ProblemHighlighter(KTextEditor::Document* document)
@@ -78,6 +84,22 @@ ProblemHighlighter::ProblemHighlighter(KTextEditor::Document* document)
}
connect(m_document, SIGNAL(aboutToRemoveText(KTextEditor::Range)), this,
SLOT(aboutToRemoveText(KTextEditor::Range)));
+ connect(m_document, &KTextEditor::Document::viewCreated,
+ this, &ProblemHighlighter::highlightProblemsInView);
+
+ for ( auto view: m_document->views() ) {
+ highlightProblemsInView(m_document, view);
+ }
+}
+
+void ProblemHighlighter::highlightProblemsInView(KTextEditor::Document* /*document*/, KTextEditor::View* view)
+{
+ auto iface = qobject_cast<KTextEditor::InlineNoteInterface*>(view);
+ if (!iface) {
+ return;
+ }
+ iface->registerInlineNoteProvider(this);
+ Q_EMIT reset();
}
void ProblemHighlighter::settingsChanged()
@@ -94,12 +116,82 @@ ProblemHighlighter::~ProblemHighlighter()
qDeleteAll(m_topHLRanges);
}
+namespace {
+ QFont scaledFont(const QFont& font) {
+ QFont small = font;
+ small.setPointSizeF(font.pointSizeF() * 0.80);
+ return small;
+ }
+
+ QString shortTextForProblem(const IProblem::Ptr& problem) {
+ auto expr = QRegularExpression("(.*?)(\\[\\-W.*\\])?$");
+ return expr.match(problem->description()).captured(1);
+ }
+}
+
+int ProblemHighlighter::problemIndexForLine(int line) const
+{
+ for ( int i = 0; i < m_problems.size(); i++ ) {
+ auto location = m_topHLRanges.at(i)->end().line();
+ if ( location == line ) {
+ return i; // only one note per line
+ }
+ }
+ return -1;
+}
+
+QVector<int> ProblemHighlighter::inlineNotes(int line) const
+{
+ auto index = problemIndexForLine(line);
+ if ( index == -1 ) {
+ return {};
+ }
+ auto range = m_topHLRanges.at(index);
+ if ( range->isEmpty() ) {
+ // it disappeared
+ return {};
+ }
+ return {m_document->lineLength(range->end().line()) + 1};
+}
+
+QSize ProblemHighlighter::inlineNoteSize(const KTextEditor::InlineNote& note, qreal /*height*/, QFont font) const
+{
+ auto index = problemIndexForLine(note.location.line());
+ if ( index == -1 ) {
+ return {};
+ }
+ const auto problem = m_problems.at(index);
+ const auto text = shortTextForProblem(problem);
+ return QFontMetrics(scaledFont(font)).boundingRect(text).adjusted(-margin/2, 0, margin/2, 0).size();
+}
+
+void ProblemHighlighter::paintInlineNote(const KTextEditor::InlineNote& note, qreal height, QFont font, QPainter& painter) const
+{
+ auto index = problemIndexForLine(note.location.line());
+ if ( index == -1 ) {
+ return;
+ }
+ auto problem = m_problems.at(index);
+
+ qreal textWidth = inlineNoteSize(note, height, font).width();
+
+ QRectF rectangle(margin / 2.0, 0.5, textWidth, height - 1);
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(colorForSeverity(problem->severity()));
+ painter.drawRoundedRect(rectangle, 2, 2);
+ painter.setPen(Qt::white);
+
+ painter.setFont(scaledFont(font));
+ QFontMetrics metrics(font);
+ painter.drawText(margin, metrics.ascent(), shortTextForProblem(problem));
+}
+
void ProblemHighlighter::setProblems(const QVector<IProblem::Ptr>& problems)
{
if (!m_document)
return;
- if (m_problems == problems)
+ if (problems == m_problems)
return;
const bool hadProblems = !m_problems.isEmpty();
@@ -137,6 +229,7 @@ void ProblemHighlighter::setProblems(const QVector<IProblem::Ptr>& problems)
KTextEditor::MovingInterface* iface = dynamic_cast<KTextEditor::MovingInterface*>(m_document.data());
Q_ASSERT(iface);
+ QSet<int> seenLines;
foreach (const IProblem::Ptr& problem, problems) {
if (problem->finalLocation().document != url || !problem->finalLocation().isValid())
continue;
@@ -203,23 +296,8 @@ void ProblemHighlighter::setProblems(const QVector<IProblem::Ptr>& problems)
markIface->addMark(problem->finalLocation().start().line(), mark);
}
}
-}
-
-void ProblemHighlighter::aboutToRemoveText(const KTextEditor::Range& range)
-{
- if (range.onSingleLine()) { // no need to optimize this
- return;
- }
- QList<MovingRange*>::iterator it = m_topHLRanges.begin();
- while (it != m_topHLRanges.end()) {
- if (range.contains((*it)->toRange())) {
- delete (*it);
- it = m_topHLRanges.erase(it);
- } else {
- ++it;
- }
- }
+ Q_EMIT reset();
}
void ProblemHighlighter::clearProblems()
diff --git a/plugins/problemreporter/problemhighlighter.h b/plugins/problemreporter/problemhighlighter.h
index 21f7cb3f31..107c5ca4a4 100644
--- a/plugins/problemreporter/problemhighlighter.h
+++ b/plugins/problemreporter/problemhighlighter.h
@@ -28,19 +28,30 @@
#include <ktexteditor/movingrange.h>
#include <interfaces/iproblem.h>
-class ProblemHighlighter : public QObject
+#include <KTextEditor/InlineNoteInterface>
+
+class ProblemHighlighter : public KTextEditor::InlineNoteProvider
{
Q_OBJECT
public:
+
explicit ProblemHighlighter(KTextEditor::Document* document);
~ProblemHighlighter() override;
void setProblems(const QVector<KDevelop::IProblem::Ptr>& problems);
+ QVector<int> inlineNotes(int line) const override;
+ QSize inlineNoteSize(const KTextEditor::InlineNote& note, qreal height, QFont font) const override;
+ void paintInlineNote(const KTextEditor::InlineNote& note, qreal height, QFont font, QPainter& painter) const override;
+
private Q_SLOTS:
- void aboutToRemoveText(const KTextEditor::Range& range);
void clearProblems();
+ void highlightProblemsInView(KTextEditor::Document*, KTextEditor::View* view);
+
+private:
+ int problemIndexForLine(int line) const;
+
private:
QPointer<KTextEditor::Document> m_document;
QList<KTextEditor::MovingRange*> m_topHLRanges;
Log In to Comment