forked from francescmm/GitQlient
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FileDiffView.cpp
98 lines (78 loc) · 2.5 KB
/
FileDiffView.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "FileDiffView.h"
#include <QPainter>
#include <QTextBlock>
FileDiffView::FileDiffView(QWidget *parent)
: QPlainTextEdit(parent)
, mLineNumberArea(new LineNumberArea(this))
{
setReadOnly(true);
connect(this, &FileDiffView::blockCountChanged, this, &FileDiffView::updateLineNumberAreaWidth);
connect(this, &FileDiffView::updateRequest, this, &FileDiffView::updateLineNumberArea);
updateLineNumberAreaWidth(0);
}
int FileDiffView::lineNumberAreaWidth()
{
auto digits = 1;
auto max = std::max(1, blockCount());
while (max >= 10)
{
max /= 10;
++digits;
}
return 8 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
}
void FileDiffView::updateLineNumberAreaWidth(int /* newBlockCount */)
{
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}
void FileDiffView::updateLineNumberArea(const QRect &rect, int dy)
{
if (dy != 0)
mLineNumberArea->scroll(0, dy);
else
mLineNumberArea->update(0, rect.y(), mLineNumberArea->width(), rect.height());
if (rect.contains(viewport()->rect()))
updateLineNumberAreaWidth(0);
}
void FileDiffView::resizeEvent(QResizeEvent *e)
{
QPlainTextEdit::resizeEvent(e);
const auto cr = contentsRect();
mLineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}
void FileDiffView::lineNumberAreaPaintEvent(QPaintEvent *event)
{
QPainter painter(mLineNumberArea);
painter.fillRect(event->rect(), QColor("#202122"));
auto block = firstVisibleBlock();
auto blockNumber = block.blockNumber();
auto top = blockBoundingGeometry(block).translated(contentOffset()).top();
auto bottom = top + blockBoundingRect(block).height();
while (block.isValid() && top <= event->rect().bottom())
{
if (block.isVisible() && bottom >= event->rect().top())
{
const auto number = QString::number(blockNumber + 1);
painter.setPen(Qt::white);
painter.drawText(0, static_cast<int>(top), mLineNumberArea->width() - 3, fontMetrics().height(),
Qt::AlignRight, number);
}
block = block.next();
top = bottom;
bottom = top + blockBoundingRect(block).height();
++blockNumber;
}
}
LineNumberArea::LineNumberArea(FileDiffView *editor)
: QWidget(editor)
{
fileDiffWidget = editor;
}
QSize LineNumberArea::sizeHint() const
{
return { fileDiffWidget->lineNumberAreaWidth(), 0 };
}
void LineNumberArea::paintEvent(QPaintEvent *event)
{
fileDiffWidget->lineNumberAreaPaintEvent(event);
}