File indexing completed on 2025-01-05 05:14:51

0001 /*
0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com>
0003 
0004 SPDX-License-Identifier: GPL-3.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <KSyntaxHighlighting/Repository>
0010 #include <QMap>
0011 #include <QPlainTextEdit>
0012 #include <QTextBlockFormat>
0013 #include <diff.h>
0014 
0015 #include "libkommitwidgets_export.h"
0016 
0017 class QLabel;
0018 
0019 namespace KSyntaxHighlighting
0020 {
0021 class SyntaxHighlighter;
0022 }
0023 
0024 class CodeEditorSidebar;
0025 
0026 class LIBKOMMITWIDGETS_EXPORT CodeEditor : public QPlainTextEdit
0027 {
0028     Q_OBJECT
0029 public:
0030     enum BlockType { Unchanged, Added, Removed, Edited, HighLight, Odd, Even, Empty };
0031     struct BlockData {
0032         int lineNumber;
0033         Diff::Segment *segment;
0034         BlockType type;
0035         QString extraText;
0036         void *data;
0037 
0038         BlockData(int lineNumber, Diff::Segment *segment, CodeEditor::BlockType type);
0039     };
0040 
0041     explicit CodeEditor(QWidget *parent = nullptr);
0042     ~CodeEditor() override;
0043 
0044     void setHighlighting(const QString &fileName);
0045 
0046     void append(const QString &code, CodeEditor::BlockType type = Unchanged, Diff::Segment *segment = nullptr);
0047     int append(const QString &code, const QColor &backgroundColor);
0048     void append(const QStringList &code, CodeEditor::BlockType type = Unchanged, Diff::Segment *segment = nullptr, int size = -1);
0049     int append(const QString &code, CodeEditor::BlockType type, BlockData *data);
0050 
0051     QPair<int, int> blockArea(int from, int to);
0052     QPair<int, int> visibleLines() const;
0053 
0054     int currentLineNumber() const;
0055     void gotoLineNumber(int lineNumber);
0056     void gotoSegment(Diff::Segment *segment);
0057 
0058     Diff::Segment *currentSegment() const;
0059     void highlightSegment(Diff::Segment *segment);
0060 
0061     void clearAll();
0062 
0063     bool showTitleBar() const;
0064     void setShowTitleBar(bool newShowTitleBar);
0065 
0066     QString title() const;
0067     void setTitle(const QString &title);
0068 
0069     int titlebarHeight() const;
0070 
0071     bool showFoldMarks() const;
0072     void setShowFoldMarks(bool newShowFoldMarks);
0073 
0074     BlockData *currentBlockData() const;
0075 
0076 Q_SIGNALS:
0077     void blockSelected();
0078 
0079 protected:
0080     void resizeEvent(QResizeEvent *event) override;
0081     void mousePressEvent(QMouseEvent *event) override;
0082     void mouseReleaseEvent(QMouseEvent *event) override;
0083     int sidebarWidth() const;
0084     void sidebarPaintEvent(QPaintEvent *event);
0085     KSyntaxHighlighting::SyntaxHighlighter *const mHighlighter;
0086     CodeEditorSidebar *const mSideBar;
0087 
0088 protected:
0089     void paintEvent(QPaintEvent *e) override;
0090 
0091 private:
0092     int lineNumberOfBlock(const QTextBlock &block) const;
0093 
0094     QMap<BlockType, QTextBlockFormat> mFormats;
0095     void setTheme(const KSyntaxHighlighting::Theme &theme);
0096 
0097     void updateViewPortGeometry();
0098     void updateSidebarArea(const QRect &rect, int dy);
0099     void highlightCurrentLine();
0100 
0101     QTextBlock blockAtPosition(int y) const;
0102     bool isFoldable(const QTextBlock &block) const;
0103     bool isFolded(const QTextBlock &block) const;
0104     void toggleFold(const QTextBlock &block);
0105 
0106     KSyntaxHighlighting::Repository mRepository;
0107     QMap<int, Diff::Segment *> mSegments;
0108     QMap<QTextBlock, BlockData *> mBlocksData;
0109     QPair<int, int> mCurrentSegment{-1, -1};
0110 
0111     QLabel *mTitleBar = nullptr;
0112     bool mShowTitlebar = true;
0113     int mTitlebarDefaultHeight;
0114 
0115     int mLastLineNumber{0};
0116     bool mShowFoldMarks{false};
0117     bool mLastOddEven{false};
0118 
0119     friend class CodeEditorSidebar;
0120 };