Improved Makefiles.
[qshowdiff.git] / src / qt / diff_view.cpp
blob200f10c4eda98b3028358d9dc24dee1341dde6dc
1 #include <QVBoxLayout>
2 #include <QScrollBar>
3 #include <QPainter>
4 #include <QScrollArea>
5 #include <vector>
6 using std::vector;
8 #include "../debug.h"
9 #include "../settings.h"
10 #include "diff_view.h"
11 #include "diff_view.moc"
13 DiffViewFrame::DiffViewFrame(QWidget *parent) : QWidget(parent)
15 QVBoxLayout *layout = new QVBoxLayout();
16 QSplitter *splitter = new QSplitter(Qt::Horizontal);
17 _original = new DiffView(true);
18 _modified = new DiffView(false);
19 _orig = new QScrollArea();
20 _modif = new QScrollArea();
23 _orig->setWidget(_original);
24 _orig->setWidgetResizable(true);
25 _orig->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
26 _modif->setWidget(_modified);
27 _modif->setWidgetResizable(true);
29 splitter->addWidget(_orig);
30 splitter->addWidget(_modif);
32 layout->addWidget(splitter);
34 setLayout(layout);
37 QScrollBar *orig_vertical = _orig->verticalScrollBar();
38 QScrollBar *modif_vertical = _modif->verticalScrollBar();
39 QScrollBar *orig_horizontal = _orig->horizontalScrollBar();
40 QScrollBar *modif_horizontal = _modif->horizontalScrollBar();
42 connect(orig_vertical, SIGNAL(valueChanged(int)), modif_vertical,
43 SLOT(setValue(int)));
44 connect(modif_vertical, SIGNAL(valueChanged(int)), orig_vertical,
45 SLOT(setValue(int)));
46 connect(orig_horizontal, SIGNAL(valueChanged(int)), modif_horizontal,
47 SLOT(setValue(int)));
48 connect(modif_horizontal, SIGNAL(valueChanged(int)), orig_horizontal,
49 SLOT(setValue(int)));
52 void DiffViewFrame::changeFile(int num) const
54 if (num != -1){
55 // num - 1 is there because num==0 is for 'All files'
56 _original->setCurrentFile(num - 1);
57 _modified->setCurrentFile(num - 1);
61 void DiffViewFrame::scrollDown(int how_many)
63 QScrollBar *sb = _modif->verticalScrollBar();
64 sb->setValue(sb->value() + how_many);
67 void DiffViewFrame::scrollUp(int how_many)
69 QScrollBar *sb = _modif->verticalScrollBar();
70 sb->setValue(sb->value() - how_many);
73 /* DiffView */
74 void DiffView::paintEvent(QPaintEvent *e)
76 painter = new QPainter(this);
77 offset = 0;
78 max_width = 0;
80 _paintFiles();
82 setFixedHeight(offset);
83 setMinimumWidth(max_width);
84 delete painter;
87 void DiffView::setCurrentFile(int num)
89 _current_file = num;
90 repaint();
96 void DiffView::_paintFiles()
98 if (_current_file == -1){
99 Diff::const_iterator it = Diff::instance()->begin();
100 Diff::const_iterator it_end = Diff::instance()->end();
102 for (;it != it_end; it++){
103 _paintFileHeader((*it)->getFilename());
104 _paintHunks(*it);
106 }else{
107 Diff *diff = Diff::instance();
109 if (diff->numFiles() > _current_file){
110 File const *file = diff->getFile(_current_file);
111 _paintFileHeader(file->getFilename());
112 _paintHunks(file);
113 } // else do nothing
117 void DiffView::_paintHunks(File const *file)
119 File::const_iterator it = file->begin();
120 File::const_iterator it_end = file->end();
122 for (; it != it_end; it++){
123 _paintHunkHeader();
124 _paintSnippets(*it);
128 void DiffView::_paintSnippets(Hunk const *hunk)
130 int from_line;
131 int height = QFontMetrics(Settings::Text::font).height();
132 Hunk::const_iterator it = hunk->begin();
133 Hunk::const_iterator it_end = hunk->end();
134 list_of_ranges_t ranges_default;
136 if (_original)
137 from_line = hunk->originalBeginsAt();
138 else
139 from_line = hunk->modifiedBeginsAt();
141 for (; it != it_end; it++){
142 const ListOfTextSnippets &ts = (_original ? (*it)->getOriginal() :
143 (*it)->getModified());
144 int len = ts.size();
146 _paintSnippetBackground(*it);
148 for (int i=0; i < len; i++){
149 _paintLine(ts[i], from_line);
150 from_line++;
153 if (_original){
154 offset += height * ((*it)->numLines() - (*it)->numOriginalLines());
155 }else{
156 offset += height * ((*it)->numLines() - (*it)->numModifiedLines());
162 void DiffView::_paintLine(const TextSnippets &ts, int from_line)
164 QFontMetrics &metrics = Settings::Text::font_metrics;
165 QFontMetrics &metrics_subs = Settings::Text::font_substitution_metrics;
166 QFontMetrics &metrics_ins = Settings::Text::font_insertion_metrics;
168 int height = std::max(std::max(metrics.height(), metrics_subs.height()),
169 metrics_ins.height());
170 QRect line_rect(0, offset, Settings::Text::line_column_width, height);
171 QRect text_rect(Settings::Text::line_column_width +
172 Settings::Text::line_indentation, offset, 0, height);
173 int left = text_rect.left();
174 int width;
176 painter->setBrush(Qt::NoBrush);
177 painter->setFont(Settings::Text::font);
179 // draw number of line
180 painter->setPen(Settings::Text::font_color);
181 painter->setPen(Settings::Text::font_color);
182 painter->drawText(line_rect, Qt::AlignRight,
183 QString::number(from_line));
185 // draw line
186 TextSnippets::const_iterator it = ts.begin();
187 TextSnippets::const_iterator it_end = ts.end();
188 for (;it != it_end; it++){
189 switch ((*it)->getType()){
190 case range_t::NOCHANGE:
191 // move text_rect to appropriate place
192 width = metrics.width((*it)->getStr());
193 text_rect.setLeft(left);
194 text_rect.setWidth(width);
195 left += width;
197 painter->setFont(Settings::Text::font);
198 painter->setPen(Settings::Text::font_color);
199 break;
201 case range_t::DELETION:
202 case range_t::INSERTION:
203 // move text_rect to appropriate place
204 width = metrics_ins.width((*it)->getStr());
205 text_rect.setLeft(left);
206 text_rect.setWidth(width);
207 left += width;
209 painter->setPen(Settings::Text::background_color_changed);
210 painter->setBrush(Settings::Text::brush_insertion);
211 painter->drawRect(text_rect);
213 painter->setFont(Settings::Text::font_insertion);
214 painter->setPen(Settings::Text::font_color_insertion);
215 break;
217 case range_t::SUBSTITUTION:
218 // move text_rect to appropriate place
219 width = metrics_subs.width((*it)->getStr());
220 text_rect.setLeft(left);
221 text_rect.setWidth(width);
222 left += width;
224 painter->setPen(Settings::Text::background_color_changed);
225 painter->setBrush(Settings::Text::brush_substitution);
226 painter->drawRect(text_rect);
228 painter->setFont(Settings::Text::font_substitution);
229 painter->setPen(Settings::Text::font_color_substitution);
230 break;
232 default:
233 // move text_rect to appropriate place
234 width = metrics.width((*it)->getStr());
235 text_rect.setLeft(left);
236 text_rect.setWidth(width);
237 left += width;
239 painter->setFont(Settings::Text::font);
240 painter->setPen(Settings::Text::font_color);
241 break;
243 painter->drawText(text_rect, Qt::AlignLeft, (*it)->getStr());
246 // increment offset
247 offset += height;
251 void DiffView::_paintFileHeader(const QString &filename)
253 QRect rect(0, offset, painter->window().width(),
254 Settings::File::box_height);
255 QRect text_rect(0 + Settings::File::text_left_indentation, offset,
256 painter->window().width(), Settings::File::box_height);
258 // Rectangle
259 painter->setBrush(QBrush(Settings::File::background_color));
260 painter->setPen(Settings::File::background_color);
261 painter->drawRect(rect);
263 // Text
264 painter->setFont(Settings::File::font);
265 painter->setPen(Settings::File::font_color);
266 painter->drawText(text_rect, Qt::AlignVCenter, "Filename: " + filename);
268 offset += Settings::File::box_height;
271 void DiffView::_paintHunkHeader()
273 painter->setBrush(QBrush(Settings::Hunk::separator_color));
274 painter->setPen(Settings::Hunk::separator_color);
275 painter->drawRect(0, offset, painter->window().width(),
276 Settings::Hunk::separator_height);
278 offset += Settings::Hunk::separator_height;
281 void DiffView::_paintSnippetBackground(Snippet const *snippet)
283 int lines = snippet->numLines();
284 int height = QFontMetrics(Settings::Text::font).height();
285 QColor color;
287 if (snippet->isContext()){
288 color = Settings::Text::background_color;
289 }else if (snippet->isAdded()){
290 color = Settings::Text::background_color_added;
291 }else if (snippet->isDeleted()){
292 color = Settings::Text::background_color_deleted;
293 }else if (snippet->isChanged()){
294 color = Settings::Text::background_color_changed;
297 painter->setBrush(QBrush(color));
298 painter->setPen(color);
299 painter->drawRect(0, offset, painter->window().width(), lines*height);