File indexing completed on 2024-05-12 05:52:05
0001 /* 0002 SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 #pragma once 0006 0007 #include "diffparams.h" 0008 #include <KTextEditor/Range> 0009 #include <QPlainTextEdit> 0010 0011 #include <KSyntaxHighlighting/FoldingRegion> 0012 #include <KSyntaxHighlighting/SyntaxHighlighter> 0013 0014 #include <QTimeLine> 0015 0016 class DiffSyntaxHighlighter final : public KSyntaxHighlighting::SyntaxHighlighter 0017 { 0018 public: 0019 DiffSyntaxHighlighter(QTextDocument *parent, class DiffWidget *diffWidget); 0020 0021 void highlightBlock(const QString &text) override; 0022 void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; 0023 void applyFolding(int, int, KSyntaxHighlighting::FoldingRegion) override 0024 { 0025 // no folding 0026 } 0027 0028 private: 0029 class DiffWidget *const m_diffWidget; 0030 }; 0031 0032 using IntT = qsizetype; 0033 0034 struct Change { 0035 IntT pos; 0036 IntT len; 0037 enum { FullBlock = -2 }; 0038 }; 0039 0040 struct LineHighlight { 0041 std::vector<Change> changes; 0042 IntT line; 0043 bool added; 0044 }; 0045 0046 enum DiffStyle { SideBySide = 0, Unified, Raw }; 0047 0048 class DiffEditor : public QPlainTextEdit 0049 { 0050 Q_OBJECT 0051 friend class LineNumArea; 0052 0053 public: 0054 enum { Line = 0, Hunk = 1 }; 0055 DiffEditor(DiffParams::Flags, QWidget *parent = nullptr); 0056 0057 void clearData() 0058 { 0059 clear(); 0060 m_data.clear(); 0061 setLineNumberData({}, {}, 0); 0062 } 0063 void appendData(const std::vector<LineHighlight> &newData) 0064 { 0065 m_data.insert(m_data.end(), newData.begin(), newData.end()); 0066 } 0067 0068 void setLineNumberData(std::vector<int> lineNosA, std::vector<int> lineNosB, int maxLineNum); 0069 0070 KTextEditor::Range selectionRange() const; 0071 0072 bool isHunkLine(int line) const; 0073 void toggleFoldHunk(int block); 0074 bool isHunkFolded(int blockNumber); 0075 const LineHighlight *highlightingForLine(int line); 0076 0077 QColor removedColor() const 0078 { 0079 return red1; 0080 } 0081 QColor addedColor() const 0082 { 0083 return green1; 0084 } 0085 0086 int firstVisibleBlockNumber() const 0087 { 0088 return QPlainTextEdit::firstVisibleBlock().blockNumber(); 0089 } 0090 0091 void scrollToBlock(int block, bool flashBlock = false); 0092 0093 // Returns the line number that user sees 0094 int firstVisibleLineNumber() const; 0095 void scrollToLineNumber(int lineNo); 0096 0097 protected: 0098 void resizeEvent(QResizeEvent *event) override; 0099 void paintEvent(QPaintEvent *e) override; 0100 void contextMenuEvent(QContextMenuEvent *e) override; 0101 0102 private: 0103 void updateLineNumberArea(const QRect &rect, int dy); 0104 void updateLineNumAreaGeometry(); 0105 void updateLineNumberAreaWidth(int); 0106 void updateDiffColors(bool darkMode); 0107 void onContextMenuRequest(); 0108 void addStageUnstageDiscardActions(QMenu *menu); 0109 0110 std::vector<LineHighlight> m_data; 0111 QColor red1; 0112 QColor red2; 0113 QColor green1; 0114 QColor green2; 0115 QColor hunkSeparatorColor; 0116 class LineNumArea *const m_lineNumArea; 0117 class DiffWidget *const m_diffWidget; 0118 DiffParams::Flags m_flags; 0119 0120 QTimeLine m_timeLine; 0121 QRect m_animateTextRect; 0122 0123 Q_SIGNALS: 0124 void switchStyle(int); 0125 void actionTriggered(DiffEditor *e, int startLine, int endLine, int actionType, DiffParams::Flag); 0126 };