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 "expandingwidgetmodel.h"
8
9#include <QApplication>
10#include <QBrush>
11#include <QModelIndex>
12#include <QTextEdit>
13#include <QTreeView>
14
15#include <KColorUtils>
16#include <ktexteditor/codecompletionmodel.h>
17
18#include "katepartdebug.h"
19
20using namespace KTextEditor;
21
22inline QModelIndex firstColumn(const QModelIndex &index)
23{
24 return index.sibling(arow: index.row(), acolumn: 0);
25}
26
27ExpandingWidgetModel::ExpandingWidgetModel(QWidget *parent)
28 : QAbstractItemModel(parent)
29{
30}
31
32ExpandingWidgetModel::~ExpandingWidgetModel()
33{
34}
35
36static QColor doAlternate(const QColor &color)
37{
38 QColor background = QApplication::palette().window().color();
39 return KColorUtils::mix(c1: color, c2: background, bias: 0.15);
40}
41
42uint ExpandingWidgetModel::matchColor(const QModelIndex &index) const
43{
44 int matchQuality = contextMatchQuality(index: index.sibling(arow: index.row(), acolumn: 0));
45
46 if (matchQuality > 0) {
47 bool alternate = index.row() & 1;
48
49 QColor badMatchColor(0xff00aa44); // Blue-ish green
50 QColor goodMatchColor(0xff00ff00); // Green
51
52 QColor background = treeView()->palette().light().color();
53
54 QColor totalColor = KColorUtils::mix(c1: badMatchColor, c2: goodMatchColor, bias: ((float)matchQuality) / 10.0);
55
56 if (alternate) {
57 totalColor = doAlternate(color: totalColor);
58 }
59
60 const qreal dynamicTint = 0.2;
61 const qreal minimumTint = 0.2;
62 qreal tintStrength = (dynamicTint * matchQuality) / 10;
63 if (tintStrength != 0.0) {
64 tintStrength += minimumTint; // Some minimum tinting strength, else it's not visible any more
65 }
66
67 return KColorUtils::tint(base: background, color: totalColor, amount: tintStrength).rgb();
68 } else {
69 return 0;
70 }
71}
72
73QVariant ExpandingWidgetModel::data(const QModelIndex &index, int role) const
74{
75 switch (role) {
76 case Qt::BackgroundRole: {
77 if (index.column() == 0) {
78 // Highlight by match-quality
79 uint color = matchColor(index);
80 if (color) {
81 return QBrush(color);
82 }
83 }
84 }
85 }
86 return QVariant();
87}
88
89QList<QVariant> mergeCustomHighlighting(int leftSize, const QList<QVariant> &left, int rightSize, const QList<QVariant> &right)
90{
91 QList<QVariant> ret = left;
92 if (left.isEmpty()) {
93 ret << QVariant(0);
94 ret << QVariant(leftSize);
95 ret << QTextFormat(QTextFormat::CharFormat);
96 }
97
98 if (right.isEmpty()) {
99 ret << QVariant(leftSize);
100 ret << QVariant(rightSize);
101 ret << QTextFormat(QTextFormat::CharFormat);
102 } else {
103 QList<QVariant>::const_iterator it = right.constBegin();
104 while (it != right.constEnd()) {
105 {
106 QList<QVariant>::const_iterator testIt = it;
107 for (int a = 0; a < 2; a++) {
108 ++testIt;
109 if (testIt == right.constEnd()) {
110 qCWarning(LOG_KTE) << "Length of input is not multiple of 3";
111 break;
112 }
113 }
114 }
115
116 ret << QVariant((*it).toInt() + leftSize);
117 ++it;
118 ret << QVariant((*it).toInt());
119 ++it;
120 ret << *it;
121 if (!(*it).value<QTextFormat>().isValid()) {
122 qCDebug(LOG_KTE) << "Text-format is invalid";
123 }
124 ++it;
125 }
126 }
127 return ret;
128}
129
130// It is assumed that between each two strings, one space is inserted
131QList<QVariant> mergeCustomHighlighting(QStringList strings, QList<QVariantList> highlights, int grapBetweenStrings)
132{
133 if (strings.isEmpty()) {
134 qCWarning(LOG_KTE) << "List of strings is empty";
135 return QList<QVariant>();
136 }
137
138 if (highlights.isEmpty()) {
139 qCWarning(LOG_KTE) << "List of highlightings is empty";
140 return QList<QVariant>();
141 }
142
143 if (strings.count() != highlights.count()) {
144 qCWarning(LOG_KTE) << "Length of string-list is " << strings.count() << " while count of highlightings is " << highlights.count() << ", should be same";
145 return QList<QVariant>();
146 }
147
148 // Merge them together
149 QString totalString = strings[0];
150 QVariantList totalHighlighting = highlights[0];
151
152 strings.pop_front();
153 highlights.pop_front();
154
155 while (!strings.isEmpty()) {
156 totalHighlighting = mergeCustomHighlighting(leftSize: totalString.length(), left: totalHighlighting, rightSize: strings[0].length(), right: highlights[0]);
157 totalString += strings[0];
158
159 for (int a = 0; a < grapBetweenStrings; a++) {
160 totalString += QLatin1Char(' ');
161 }
162
163 strings.pop_front();
164 highlights.pop_front();
165 }
166 // Combine the custom-highlightings
167 return totalHighlighting;
168}
169

source code of ktexteditor/src/completion/expandingtree/expandingwidgetmodel.cpp