1 /*
2     SPDX-FileCopyrightText: 2001-2004, 2009 Otto Bruggeman <bruggie@gmail.com>
3     SPDX-FileCopyrightText: 2001-2003 John Firebaugh <jfirebaugh@kde.org>
4     SPDX-FileCopyrightText: 2004 Jeff Snyder <jeff@caffeinated.me.uk>
5     SPDX-FileCopyrightText: 2011 Kevin Kofler <kevin.kofler@chello.at>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #ifndef KOMPARELISTVIEW_H
11 #define KOMPARELISTVIEW_H
12 
13 #include <QHash>
14 #include <QLabel>
15 #include <QResizeEvent>
16 #include <QWheelEvent>
17 #include <QVBoxLayout>
18 #include <QMouseEvent>
19 #include <QFrame>
20 #include <QTreeWidget>
21 #include <QStyledItemDelegate>
22 
23 namespace Diff2 {
24 class DiffModel;
25 class DiffHunk;
26 class Difference;
27 class DifferenceString;
28 }
29 class ViewSettings;
30 class KompareSplitter;
31 class KompareListView;
32 class KompareListViewItem;
33 class KompareListViewItemDelegate;
34 class KompareListViewDiffItem;
35 class KompareListViewLineContainerItem;
36 
37 class KompareListView : public QTreeWidget
38 {
39     Q_OBJECT
40 
41     friend class KompareListViewItemDelegate;
42 
43 public:
44     KompareListView(bool isSource, ViewSettings* settings, QWidget* parent, const char* name = nullptr);
45     ~KompareListView() override;
46 
47     KompareListViewItem* itemAtIndex(int i);
48     int                  firstVisibleDifference();
49     int                  lastVisibleDifference();
50     QRect                itemRect(int i);
51     int                  minScrollId();
52     int                  maxScrollId();
53     int                  contentsHeight();
54     int                  contentsWidth();
55     int                  visibleHeight();
56     int                  visibleWidth();
57     int                  contentsX();
58     int                  contentsY();
59     int                  nextPaintOffset() const;
60     void                 setNextPaintOffset(int offset);
61 
isSource()62     bool                 isSource() const { return m_isSource; };
settings()63     ViewSettings*        settings() const { return m_settings; };
64 
65     void setSelectedDifference(const Diff2::Difference* diff, bool scroll);
66 
67 public Q_SLOTS:
68     void slotSetSelection(const Diff2::DiffModel* model, const Diff2::Difference* diff);
69     void slotSetSelection(const Diff2::Difference* diff);
70     void setXOffset(int x);
71     void scrollToId(int id);
72     int  scrollId();
73     void slotApplyDifference(bool apply);
74     void slotApplyAllDifferences(bool apply);
75     void slotApplyDifference(const Diff2::Difference* diff, bool apply);
76 
77 Q_SIGNALS:
78     void differenceClicked(const Diff2::Difference* diff);
79     void applyDifference(bool apply);
80     void resized();
81 
82 protected:
83     void wheelEvent(QWheelEvent* e) override;
84     void resizeEvent(QResizeEvent* e) override;
85     void mousePressEvent(QMouseEvent* e) override;
86     void mouseDoubleClickEvent(QMouseEvent*) override;
mouseReleaseEvent(QMouseEvent *)87     void mouseReleaseEvent(QMouseEvent*) override {};
mouseMoveEvent(QMouseEvent *)88     void mouseMoveEvent(QMouseEvent*) override {};
89 
90 private:
91     QRect totalVisualItemRect(QTreeWidgetItem* item);
92     KompareListViewDiffItem* diffItemAt(const QPoint& pos);
93     void renumberLines();
94 
95     QList<KompareListViewDiffItem*> m_items;
96     QHash<const Diff2::Difference*, KompareListViewDiffItem*> m_itemDict;
97     bool                              m_isSource;
98     ViewSettings*                     m_settings;
99     int                               m_scrollId;
100     int                               m_maxMainWidth;
101     const Diff2::DiffModel*           m_selectedModel;
102     const Diff2::Difference*          m_selectedDifference;
103     int                               m_nextPaintOffset;
104 };
105 
106 class KompareListViewFrame : public QFrame
107 {
108     Q_OBJECT
109 
110 public:
111     KompareListViewFrame(bool isSource, ViewSettings* settings, KompareSplitter* parent, const char* name = nullptr);
~KompareListViewFrame()112     ~KompareListViewFrame() override {};
view()113     KompareListView* view() { return &m_view; };
114 
115 public Q_SLOTS:
116     void slotSetModel(const Diff2::DiffModel* model);
117 
118 private:
119     KompareListView      m_view;
120     QLabel               m_label;
121     QVBoxLayout          m_layout;
122 };
123 
124 class KompareListViewItemDelegate : public QStyledItemDelegate
125 {
126     Q_OBJECT
127 
128 public:
129     explicit KompareListViewItemDelegate(QObject* parent);
130     ~KompareListViewItemDelegate() override;
131     void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
132     QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
133 };
134 
135 class KompareListViewItem : public QTreeWidgetItem
136 {
137 public:
138     KompareListViewItem(KompareListView* parent, int type);
139     KompareListViewItem(KompareListView* parent, KompareListViewItem* after, int type);
140     KompareListViewItem(KompareListViewItem* parent, int type);
141     KompareListViewItem(KompareListViewItem* parent, KompareListViewItem* after, int type);
142 
143     virtual void paintCell(QPainter* p, const QStyleOptionViewItem& option, int column);
144 
145     void repaint();
146     int height() const;
147     void setHeight(int h);
148     int paintHeight() const;
149     int paintOffset() const;
150     bool isCurrent() const;
scrollId()151     int scrollId() const { return m_scrollId; };
152 
153     virtual int maxHeight() = 0;
154 
155     KompareListView* kompareListView() const;
156 
157     enum ListViewItemType { Diff = QTreeWidgetItem::UserType + 1, Container = QTreeWidgetItem::UserType + 2, Line = QTreeWidgetItem::UserType + 3, Blank = QTreeWidgetItem::UserType + 4, Hunk = QTreeWidgetItem::UserType + 5 };
158 
159 private:
160     int     m_scrollId;
161     int     m_height;
162     int     m_paintHeight;
163     int     m_paintOffset;
164 };
165 
166 class KompareListViewDiffItem : public KompareListViewItem
167 {
168 public:
169     KompareListViewDiffItem(KompareListView* parent, Diff2::Difference* difference);
170     KompareListViewDiffItem(KompareListView* parent, KompareListViewItem* after, Diff2::Difference* difference);
171     ~KompareListViewDiffItem() override;
172 
173     void applyDifference(bool apply);
174 
difference()175     Diff2::Difference* difference() { return m_difference; };
176 
177     int maxHeight() override;
178 
179 private:
180     void init();
181     void setVisibility();
182 
183 private:
184     Diff2::Difference* m_difference;
185     KompareListViewLineContainerItem* m_sourceItem;
186     KompareListViewLineContainerItem* m_destItem;
187 };
188 
189 class KompareListViewLineItem;
190 class KompareListViewBlankLineItem;
191 
192 class KompareListViewLineContainerItem : public KompareListViewItem
193 {
194 public:
195     KompareListViewLineContainerItem(KompareListViewDiffItem* parent, bool isSource);
196     ~KompareListViewLineContainerItem() override;
197 
maxHeight()198     int maxHeight() override { return 0; }
199 
200     KompareListViewDiffItem* diffItemParent() const;
201 
202 private:
203     int lineCount() const;
204     int lineNumber() const;
205     Diff2::DifferenceString* lineAt(int i) const;
206 
207 private:
208     KompareListViewBlankLineItem* m_blankLineItem;
209     bool m_isSource;
210 };
211 
212 class KompareListViewLineItem : public KompareListViewItem
213 {
214 public:
215     KompareListViewLineItem(KompareListViewLineContainerItem* parent, int line, Diff2::DifferenceString* text);
216     KompareListViewLineItem(KompareListViewLineContainerItem* parent, int line, Diff2::DifferenceString* text, int type);
217     ~KompareListViewLineItem() override;
218 
maxHeight()219     int maxHeight() override { return 0; }
220 
221     void paintCell(QPainter* p, const QStyleOptionViewItem& option, int column) override;
222 
223     KompareListViewDiffItem* diffItemParent() const;
224 
225 protected:
226     virtual void paintText(QPainter* p, const QColor& bg, int column, int width, int align);
227 
228 private:
229     void init(int line, Diff2::DifferenceString* text);
230     void expandTabs(QString& text, int tabstop, int startPos = 0) const;
231 
232 private:
233     Diff2::DifferenceString* m_text;
234 };
235 
236 class KompareListViewBlankLineItem : public KompareListViewLineItem
237 {
238 public:
239     explicit KompareListViewBlankLineItem(KompareListViewLineContainerItem* parent);
240 
241 protected:
242     void paintText(QPainter* p, const QColor& bg, int column, int width, int align) override;
243 };
244 
245 class KompareListViewHunkItem : public KompareListViewItem
246 {
247 public:
248     KompareListViewHunkItem(KompareListView* parent, Diff2::DiffHunk* hunk, bool zeroHeight = false);
249     KompareListViewHunkItem(KompareListView* parent, KompareListViewItem* after, Diff2::DiffHunk* hunk, bool zeroHeight = false);
250     ~KompareListViewHunkItem() override;
251 
252     void paintCell(QPainter* p, const QStyleOptionViewItem& option, int column) override;
253 
254     int maxHeight() override;
255 
256 private:
257     bool             m_zeroHeight;
258     Diff2::DiffHunk* m_hunk;
259 };
260 
261 #endif
262