File indexing completed on 2024-04-28 15:30:59
0001 /* 0002 SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "katetextpreview.h" 0008 #include "kateconfig.h" 0009 #include "katedocument.h" 0010 #include "katelayoutcache.h" 0011 #include "katepartdebug.h" 0012 #include "katerenderer.h" 0013 #include "kateview.h" 0014 #include "kateviewinternal.h" 0015 0016 #include <QPainter> 0017 0018 #include <cmath> 0019 0020 KateTextPreview::KateTextPreview(KTextEditor::ViewPrivate *view, QWidget *parent) 0021 : QFrame(parent, Qt::ToolTip | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint) 0022 , m_view(view) 0023 , m_line(0) 0024 , m_showFoldedLines(false) 0025 , m_center(true) 0026 , m_scale(1.0) 0027 { 0028 } 0029 0030 KTextEditor::ViewPrivate *KateTextPreview::view() const 0031 { 0032 return m_view; 0033 } 0034 0035 void KateTextPreview::setLine(qreal line) 0036 { 0037 if (m_line != line) { 0038 m_line = qMax(0.0, line); 0039 update(); 0040 } 0041 } 0042 0043 qreal KateTextPreview::line() const 0044 { 0045 return m_line; 0046 } 0047 0048 void KateTextPreview::setCenterView(bool center) 0049 { 0050 if (m_center != center) { 0051 m_center = center; 0052 update(); 0053 } 0054 } 0055 0056 bool KateTextPreview::centerView() const 0057 { 0058 return m_center; 0059 } 0060 0061 void KateTextPreview::setScaleFactor(qreal factor) 0062 { 0063 if (m_scale <= 0.0) { 0064 qCWarning(LOG_KTE) << "Negative scale factors are not supported, ignoring."; 0065 return; 0066 } 0067 0068 if (m_scale != factor) { 0069 m_scale = factor; 0070 update(); 0071 } 0072 } 0073 0074 qreal KateTextPreview::scaleFactor() const 0075 { 0076 return m_scale; 0077 } 0078 0079 void KateTextPreview::setShowFoldedLines(bool on) 0080 { 0081 if (m_showFoldedLines != on) { 0082 m_showFoldedLines = on; 0083 update(); 0084 } 0085 } 0086 0087 bool KateTextPreview::showFoldedLines() const 0088 { 0089 return m_showFoldedLines; 0090 } 0091 0092 void KateTextPreview::paintEvent(QPaintEvent *event) 0093 { 0094 QFrame::paintEvent(event); 0095 0096 KateRenderer *const renderer = view()->renderer(); 0097 const int lastLine = showFoldedLines() ? view()->document()->lines() : view()->textFolding().visibleLines(); 0098 0099 const QRectF r = contentsRect(); // already subtracted QFrame's frame width 0100 const int xStart = 0; 0101 const int xEnd = r.width() / m_scale; 0102 const int lineHeight = qMax(1, renderer->lineHeight()); 0103 const int lineCount = ceil(static_cast<qreal>(r.height()) / (lineHeight * m_scale)); 0104 int startLine = qMax(0.0, m_line - (m_center ? (ceil(lineCount / 2.0)) : 0)); 0105 // at the very end of the document, make sure the preview is filled 0106 if (qMax(0.0, m_line - (m_center ? (ceil(lineCount / 2.0)) : 0)) + lineCount - 1 > lastLine) { 0107 m_line = qMax(0.0, lastLine - static_cast<qreal>(r.height()) / (lineHeight * m_scale) + floor(lineCount / 2.0) - 1); 0108 startLine = qMax(0.0, m_line - (m_center ? (ceil(lineCount / 2.0)) : 0) + 1); 0109 } 0110 const int endLine = startLine + lineCount; 0111 0112 QPainter paint(this); 0113 paint.setClipRect(r); 0114 paint.fillRect(r, renderer->config()->backgroundColor()); 0115 0116 // renderer->setShowTabs(doc()->config()->showTabs()); 0117 // renderer->setShowTrailingSpaces(doc()->config()->showSpaces()); 0118 0119 paint.scale(m_scale, m_scale); 0120 paint.translate(r.topLeft()); 0121 if (m_center && m_line - ceil(lineCount / 2.0) > 0.0) { 0122 paint.translate(0, -lineHeight * (m_line - static_cast<int>(m_line))); 0123 } 0124 0125 for (int line = startLine; line <= endLine; ++line) { 0126 // get real line, skip if invalid! 0127 const int realLine = showFoldedLines() ? line : view()->textFolding().visibleLineToLine(line); 0128 if (realLine < 0 || realLine >= renderer->doc()->lines()) { 0129 continue; 0130 } 0131 0132 // compute layout WITHOUT cache to not poison it + render it 0133 KateLineLayoutPtr lineLayout(new KateLineLayout(*renderer)); 0134 lineLayout->setLine(realLine, -1); 0135 renderer->layoutLine(lineLayout, -1 /* no wrap */, false /* no layout cache */); 0136 renderer->paintTextLine(paint, lineLayout, xStart, xEnd, nullptr, KateRenderer::SkipDrawFirstInvisibleLineUnderlined); 0137 0138 // translate for next line 0139 paint.translate(0, lineHeight); 0140 } 0141 } 0142 0143 #include "moc_katetextpreview.cpp"