KTextEditor

katecompletiondelegate.cpp
1/*
2 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
3 SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "katecompletiondelegate.h"
9
10#include <ktexteditor/codecompletionmodel.h>
11
12#include "katecompletionmodel.h"
13#include "katepartdebug.h"
14
15#include <QApplication>
16#include <QPainter>
17
18KateCompletionDelegate::KateCompletionDelegate(QObject *parent)
19 : QStyledItemDelegate(parent)
20{
21}
22
23static void paintItemViewText(QPainter *p, const QString &text, const QStyleOptionViewItem &options, QList<QTextLayout::FormatRange> formats)
24{
25 // set formats
26 QTextLayout textLayout(text, options.font, p->device());
27 auto fmts = textLayout.formats();
28 formats.append(fmts);
29 textLayout.setFormats(formats);
30
31 // set alignment, rtls etc
32 QTextOption textOption;
33 textOption.setTextDirection(options.direction);
34 textOption.setAlignment(QStyle::visualAlignment(options.direction, options.displayAlignment));
35 textLayout.setTextOption(textOption);
36
37 // layout the text
38 textLayout.beginLayout();
39
40 QTextLine line = textLayout.createLine();
41 if (!line.isValid())
42 return;
43
44 const int lineWidth = options.rect.width();
45 line.setLineWidth(lineWidth);
46 line.setPosition(QPointF(0, 0));
47
48 textLayout.endLayout();
49
50 int y = QStyle::alignedRect(Qt::LayoutDirectionAuto, options.displayAlignment, textLayout.boundingRect().size().toSize(), options.rect).y();
51
52 // draw the text
53 const auto pos = QPointF(options.rect.x(), y);
54 textLayout.draw(p, pos);
55}
56
57void KateCompletionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o, const QModelIndex &index) const
58{
60 initStyleOption(&opt, index);
61 QString text = opt.text;
62
63 if (text.isEmpty()) {
64 QStyledItemDelegate::paint(painter, o, index);
65 return;
66 }
67
68 auto *style = opt.widget->style() ? opt.widget->style() : qApp->style();
69
70 opt.text.clear();
71
72 style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
73
74 QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &opt, opt.widget);
75
76 const bool isGroup = index.data(KateCompletionModel::IsNonEmptyGroup).toBool();
77 if (!isGroup && !opt.features.testFlag(QStyleOptionViewItem::HasDecoration)) {
78 // 3 because 2 margins for the icon, and one left margin for the text
79 int hMargins = style->pixelMetric(QStyle::PM_FocusFrameHMargin) * 3;
80 textRect.adjust(hMargins + opt.decorationSize.width(), 0, 0, 0);
81 }
82
83#if 0
84 auto p = painter->pen();
85 painter->setPen(Qt::yellow);
86 painter->drawRect(opt.rect);
87
88 painter->setPen(Qt::red);
89 painter->drawRect(textRect);
90 painter->setPen(p);
91#endif
92
93 auto highlightings = createHighlighting(index);
94 opt.rect = textRect;
95 opt.displayAlignment = m_alignTop ? Qt::AlignTop : Qt::AlignVCenter;
96 paintItemViewText(painter, text, opt, std::move(highlightings));
97}
98
99QSize KateCompletionDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
100{
101 if (index.data().toString().isEmpty()) {
102 return QStyledItemDelegate::sizeHint(option, index);
103 }
104
105 QSize size = QStyledItemDelegate::sizeHint(option, index);
106 if (!index.data(Qt::DecorationRole).isNull()) {
107 return size;
108 }
109 const int hMargins = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) * 3;
110 size.rwidth() += option.decorationSize.width() + hMargins;
111 return size;
112}
113
114static QList<QTextLayout::FormatRange> highlightingFromVariantList(const QList<QVariant> &customHighlights)
115{
117
118 for (int i = 0; i + 2 < customHighlights.count(); i += 3) {
119 if (!customHighlights[i].canConvert<int>() || !customHighlights[i + 1].canConvert<int>() || !customHighlights[i + 2].canConvert<QTextFormat>()) {
120 qCWarning(LOG_KTE) << "Unable to convert triple to custom formatting.";
121 continue;
122 }
123
125 format.start = customHighlights[i].toInt();
126 format.length = customHighlights[i + 1].toInt();
127 format.format = customHighlights[i + 2].value<QTextFormat>().toCharFormat();
128
129 if (!format.format.isValid()) {
130 qCWarning(LOG_KTE) << "Format is not valid";
131 }
132
133 ret << format;
134 }
135 return ret;
136}
137
138QList<QTextLayout::FormatRange> KateCompletionDelegate::createHighlighting(const QModelIndex &index)
139{
141
142 // TODO: config enable specifying no highlight as default
143 int highlightMethod = KTextEditor::CodeCompletionModel::InternalHighlighting;
144 if (highlight.canConvert<int>()) {
145 highlightMethod = highlight.toInt();
146 }
147
148 if (highlightMethod & KTextEditor::CodeCompletionModel::CustomHighlighting) {
149 return highlightingFromVariantList(index.data(KTextEditor::CodeCompletionModel::CustomHighlight).toList());
150 }
151
152 return {};
153}
@ HighlightingMethod
Define which highlighting method will be used:
@ CustomHighlight
Allows an item to provide custom highlighting.
void append(QList< T > &&value)
qsizetype count() const const
T value(qsizetype i) const const
QVariant data(int role) const const
QPaintDevice * device() const const
void drawRect(const QRect &rectangle)
const QPen & pen() const const
void setPen(Qt::PenStyle style)
void adjust(int dx1, int dy1, int dx2, int dy2)
int y() const const
int & rwidth()
bool isEmpty() const const
PM_FocusFrameHMargin
SE_ItemViewItemText
QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const const override
AlignTop
DecorationRole
LayoutDirectionAuto
bool isValid() const const
void setLineWidth(qreal width)
void setPosition(const QPointF &pos)
void setAlignment(Qt::Alignment alignment)
void setTextDirection(Qt::LayoutDirection direction)
bool canConvert() const const
bool isNull() const const
bool toBool() const const
int toInt(bool *ok) const const
QList< QVariant > toList() const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:21 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.