1 /*
2 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "katecompletiondelegate.h"
8
9 #include <ktexteditor/codecompletionmodel.h>
10
11 #include "katedocument.h"
12 #include "katehighlight.h"
13 #include "katepartdebug.h"
14 #include "katerenderer.h"
15 #include "katerenderrange.h"
16 #include "katetextline.h"
17 #include "kateview.h"
18
19 #include "katecompletionmodel.h"
20 #include "katecompletiontree.h"
21 #include "katecompletionwidget.h"
22
23 // Currently disable because it doesn't work
24 #define DISABLE_INTERNAL_HIGHLIGHTING
25
KateCompletionDelegate(ExpandingWidgetModel * model,KateCompletionWidget * parent)26 KateCompletionDelegate::KateCompletionDelegate(ExpandingWidgetModel *model, KateCompletionWidget *parent)
27 : ExpandingDelegate(model, parent)
28 , m_cachedRow(-1)
29 {
30 }
31
adjustStyle(const QModelIndex & index,QStyleOptionViewItem & option) const32 void KateCompletionDelegate::adjustStyle(const QModelIndex &index, QStyleOptionViewItem &option) const
33 {
34 if (index.column() == 0) {
35 // We always want to use the match-color if available, also for highlighted items.
36 ///@todo Only do this for the "current" item, for others the model is asked for the match color.
37 uint color = model()->matchColor(index);
38 if (color != 0) {
39 QColor match(color);
40
41 for (int a = 0; a <= 2; a++) {
42 option.palette.setColor((QPalette::ColorGroup)a, QPalette::Highlight, match);
43 }
44 }
45 }
46 }
47
renderer() const48 KateRenderer *KateCompletionDelegate::renderer() const
49 {
50 return widget()->view()->renderer();
51 }
52
widget() const53 KateCompletionWidget *KateCompletionDelegate::widget() const
54 {
55 return static_cast<KateCompletionWidget *>(const_cast<QObject *>(parent()));
56 }
57
document() const58 KTextEditor::DocumentPrivate *KateCompletionDelegate::document() const
59 {
60 return widget()->view()->doc();
61 }
62
heightChanged() const63 void KateCompletionDelegate::heightChanged() const
64 {
65 if (parent()) {
66 widget()->updateHeight();
67 }
68 }
69
createHighlighting(const QModelIndex & index,QStyleOptionViewItem & option) const70 QVector<QTextLayout::FormatRange> KateCompletionDelegate::createHighlighting(const QModelIndex &index, QStyleOptionViewItem &option) const
71 {
72 QVariant highlight = model()->data(index, KTextEditor::CodeCompletionModel::HighlightingMethod);
73
74 // TODO: config enable specifying no highlight as default
75 int highlightMethod = KTextEditor::CodeCompletionModel::InternalHighlighting;
76 if (highlight.canConvert(QVariant::Int)) {
77 highlightMethod = highlight.toInt();
78 }
79
80 if (highlightMethod & KTextEditor::CodeCompletionModel::CustomHighlighting) {
81 m_currentColumnStart = 0;
82 return highlightingFromVariantList(model()->data(index, KTextEditor::CodeCompletionModel::CustomHighlight).toList());
83 }
84
85 #ifdef DISABLE_INTERNAL_HIGHLIGHTING
86 return QVector<QTextLayout::FormatRange>();
87 #endif
88
89 if (index.row() == m_cachedRow && highlightMethod & KTextEditor::CodeCompletionModel::InternalHighlighting) {
90 if (index.column() < m_cachedColumnStarts.size()) {
91 m_currentColumnStart = m_cachedColumnStarts[index.column()];
92 } else {
93 qCWarning(LOG_KTE) << "Column-count does not match";
94 }
95
96 return m_cachedHighlights;
97 }
98
99 ///@todo reset the cache when the model changed
100 m_cachedRow = index.row();
101
102 KTextEditor::Cursor completionStart = widget()->completionRange()->start();
103
104 QString startText = document()->text(KTextEditor::Range(completionStart.line(), 0, completionStart.line(), completionStart.column()));
105
106 QString lineContent = startText;
107
108 int len = completionStart.column();
109 m_cachedColumnStarts.clear();
110
111 for (int i = 0; i < KTextEditor::CodeCompletionModel::ColumnCount; ++i) {
112 m_cachedColumnStarts.append(len);
113 QString text = model()->data(model()->index(index.row(), i, index.parent()), Qt::DisplayRole).toString();
114 lineContent += text;
115 len += text.length();
116 }
117
118 Kate::TextLine thisLine = Kate::TextLine(new Kate::TextLineData(lineContent));
119
120 // qCDebug(LOG_KTE) << "About to highlight with mode " << highlightMethod << " text [" << thisLine->string() << "]";
121
122 if (highlightMethod & KTextEditor::CodeCompletionModel::InternalHighlighting) {
123 Kate::TextLine previousLine;
124 if (completionStart.line()) {
125 previousLine = document()->kateTextLine(completionStart.line() - 1);
126 } else {
127 previousLine = Kate::TextLine(new Kate::TextLineData());
128 }
129
130 Kate::TextLine nextLine;
131 if ((completionStart.line() + 1) < document()->lines()) {
132 nextLine = document()->kateTextLine(completionStart.line() + 1);
133 } else {
134 nextLine = Kate::TextLine(new Kate::TextLineData());
135 }
136
137 bool ctxChanged = false;
138 document()->highlight()->doHighlight(previousLine.data(), thisLine.data(), nextLine.data(), ctxChanged);
139 }
140
141 m_currentColumnStart = m_cachedColumnStarts[index.column()];
142
143 QVector<QTextLayout::FormatRange> ret = renderer()->decorationsForLine(thisLine, 0, false, true, option.state & QStyle::State_Selected);
144
145 // Remove background-colors
146 for (QVector<QTextLayout::FormatRange>::iterator it = ret.begin(); it != ret.end(); ++it) {
147 (*it).format.clearBackground();
148 }
149
150 return ret;
151 }
152