1
/***************************************************************************
5
Copyright 2001-2009 Otto Bruggeman <bruggie@gmail.com>
6
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
7
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
8
Copyright 2007-2012 Kevin Kofler <kevin.kofler@chello.at>
9
****************************************************************************/
11
/***************************************************************************
13
** This program is free software; you can redistribute it and/or modify
14
** it under the terms of the GNU General Public License as published by
15
** the Free Software Foundation; either version 2 of the License, or
16
** (at your option) any later version.
18
***************************************************************************/
20
#include "komparelistview.h"
26
#include <QResizeEvent>
27
#include <QMouseEvent>
28
#include <QWheelEvent>
31
#include <KSharedConfig>
33
#include <libkomparediff2/diffmodel.h>
34
#include <libkomparediff2/diffhunk.h>
35
#include <libkomparediff2/difference.h>
36
#include <libkomparediff2/komparemodellist.h>
38
#include <komparepartdebug.h>
39
#include "viewsettings.h"
40
#include "komparesplitter.h"
45
#define BLANK_LINE_HEIGHT 3
46
#define HUNK_LINE_HEIGHT 5
50
using namespace Diff2;
52
KompareListViewFrame::KompareListViewFrame(bool isSource,
53
ViewSettings* settings,
54
KompareSplitter* parent,
57
m_view(isSource, settings, this, name),
58
m_label(isSource ? QStringLiteral("Source") : QStringLiteral("Dest"), this),
61
setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
62
m_label.setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
63
QFrame* bottomLine = new QFrame(this);
64
bottomLine->setFrameShape(QFrame::HLine);
65
bottomLine->setFrameShadow(QFrame::Plain);
66
bottomLine->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
67
bottomLine->setFixedHeight(1);
69
m_layout.setSpacing(0);
70
m_layout.setContentsMargins(0, 0, 0, 0);
71
m_layout.addWidget(&m_label);
72
m_layout.addWidget(bottomLine);
73
m_layout.addWidget(&m_view);
75
connect(&m_view, &KompareListView::differenceClicked,
76
parent, &KompareSplitter::slotDifferenceClicked);
78
connect(parent, &KompareSplitter::scrollViewsToId, &m_view, &KompareListView::scrollToId);
79
connect(parent, &KompareSplitter::setXOffset, &m_view, &KompareListView::setXOffset);
80
connect(&m_view, &KompareListView::resized, parent, &KompareSplitter::slotUpdateScrollBars);
83
void KompareListViewFrame::slotSetModel(const DiffModel* model)
87
if (view()->isSource()) {
88
if (!model->sourceRevision().isEmpty())
89
m_label.setText(model->sourceFile() + QLatin1String(" (") + model->sourceRevision() + QLatin1Char(')'));
91
m_label.setText(model->sourceFile());
93
if (!model->destinationRevision().isEmpty())
94
m_label.setText(model->destinationFile() + QLatin1String(" (") + model->destinationRevision() + QLatin1Char(')'));
96
m_label.setText(model->destinationFile());
99
m_label.setText(QString());
103
KompareListView::KompareListView(bool isSource,
104
ViewSettings* settings,
105
QWidget* parent, const char* name) :
107
m_isSource(isSource),
108
m_settings(settings),
110
m_selectedModel(nullptr),
111
m_selectedDifference(nullptr)
113
setObjectName(QLatin1String(name));
114
setItemDelegate(new KompareListViewItemDelegate(this));
115
setHeaderHidden(true);
116
setColumnCount(3); // Line Number, Main, Blank
117
setAllColumnsShowFocus(true);
118
setRootIsDecorated(false);
120
setFrameStyle(QFrame::NoFrame);
121
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
122
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
123
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
124
setFocusPolicy(Qt::NoFocus);
125
setFont(m_settings->m_font);
126
setFocusProxy(parent->parentWidget());
129
KompareListView::~KompareListView()
131
m_settings = nullptr;
132
m_selectedModel = nullptr;
133
m_selectedDifference = nullptr;
136
KompareListViewItem* KompareListView::itemAtIndex(int i)
141
int KompareListView::firstVisibleDifference()
143
QTreeWidgetItem* item = itemAt(QPoint(0, 0));
147
qCDebug(KOMPAREPART) << "no item at viewport coordinates (0,0)" ;
151
KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
152
if (lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged)
154
item = itemBelow(item);
158
return m_items.indexOf(((KompareListViewLineItem*)item)->diffItemParent());
163
int KompareListView::lastVisibleDifference()
165
QTreeWidgetItem* item = itemAt(QPoint(0, visibleHeight() - 1));
169
qCDebug(KOMPAREPART) << "no item at viewport coordinates (0," << visibleHeight() - 1 << ")" ;
171
item = itemAt(QPoint(0, 0));
173
QTreeWidgetItem* nextItem = item;
176
nextItem = itemBelow(item);
182
KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
183
if (lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged)
185
item = itemAbove(item);
189
return m_items.indexOf(((KompareListViewLineItem*)item)->diffItemParent());
194
QRect KompareListView::totalVisualItemRect(QTreeWidgetItem* item)
196
QRect total = visualItemRect(item);
197
int n = item->childCount();
198
for (int i = 0; i < n; ++i) {
199
QTreeWidgetItem* child = item->child(i);
200
if (!child->isHidden())
201
total = total.united(totalVisualItemRect(child));
206
QRect KompareListView::itemRect(int i)
208
QTreeWidgetItem* item = itemAtIndex(i);
209
return totalVisualItemRect(item);
212
int KompareListView::minScrollId()
214
return visibleHeight() / 2;
217
int KompareListView::maxScrollId()
219
int n = topLevelItemCount();
221
KompareListViewItem* item = (KompareListViewItem*)topLevelItem(n - 1);
222
int maxId = item->scrollId() + item->maxHeight() - minScrollId();
223
qCDebug(KOMPAREPART) << "Max ID = " << maxId ;
227
int KompareListView::contentsHeight()
229
return verticalScrollBar()->maximum() + viewport()->height() - style()->pixelMetric(QStyle::PM_ScrollBarExtent);
232
int KompareListView::contentsWidth()
234
return (columnWidth(COL_LINE_NO) + columnWidth(COL_MAIN));
237
int KompareListView::visibleHeight()
239
return viewport()->height();
242
int KompareListView::visibleWidth()
244
return viewport()->width();
247
int KompareListView::contentsX()
249
return horizontalOffset();
252
int KompareListView::contentsY()
254
return verticalOffset();
257
int KompareListView::nextPaintOffset() const
259
return m_nextPaintOffset;
262
void KompareListView::setNextPaintOffset(int offset)
264
m_nextPaintOffset = offset;
267
void KompareListView::setXOffset(int x)
269
qCDebug(KOMPAREPART) << "SetXOffset : Scroll to x position: " << x ;
270
horizontalScrollBar()->setValue(x);
273
void KompareListView::scrollToId(int id)
275
// qCDebug(KOMPAREPART) << "ScrollToID : Scroll to id : " << id ;
276
int n = topLevelItemCount();
277
KompareListViewItem* item = nullptr;
281
if (((KompareListViewItem*)topLevelItem(i))->scrollId() > id)
284
item = (KompareListViewItem*)topLevelItem(i - 1);
288
QRect rect = totalVisualItemRect(item);
289
int pos = rect.top() + verticalOffset();
290
int itemId = item->scrollId();
291
int height = rect.height();
292
double r = (double)(id - itemId) / (double)item->maxHeight();
293
int y = pos + (int)(r * (double)height) - minScrollId();
294
// qCDebug(KOMPAREPART) << "scrollToID: " ;
295
// qCDebug(KOMPAREPART) << " id = " << id ;
296
// qCDebug(KOMPAREPART) << " pos = " << pos ;
297
// qCDebug(KOMPAREPART) << " itemId = " << itemId ;
298
// qCDebug(KOMPAREPART) << " r = " << r ;
299
// qCDebug(KOMPAREPART) << " height = " << height ;
300
// qCDebug(KOMPAREPART) << " minID = " << minScrollId() ;
301
// qCDebug(KOMPAREPART) << " y = " << y ;
302
// qCDebug(KOMPAREPART) << "contentsHeight = " << contentsHeight() ;
303
// qCDebug(KOMPAREPART) << " c - y = " << contentsHeight() - y ;
304
verticalScrollBar()->setValue(y);
310
int KompareListView::scrollId()
313
m_scrollId = minScrollId();
317
void KompareListView::setSelectedDifference(const Difference* diff, bool scroll)
319
qCDebug(KOMPAREPART) << "KompareListView::setSelectedDifference(" << diff << ", " << scroll << ")" ;
321
// When something other than a click causes this function to be called,
322
// it'll only get called once, and all is simple.
324
// When the user clicks on a diff, this function will get called once when
325
// komparesplitter::slotDifferenceClicked runs, and again when the
326
// setSelection signal from the modelcontroller arrives.
328
// the first call (which will always be from the splitter) will have
329
// scroll==false, and the second call will bail out here.
330
// Which is why clicking on a difference does not cause the listviews to
332
if (m_selectedDifference == diff)
335
m_selectedDifference = diff;
337
KompareListViewItem* item = m_itemDict[ diff ];
339
qCDebug(KOMPAREPART) << "KompareListView::slotSetSelection(): couldn't find our selection!" ;
343
// why does this not happen when the user clicks on a diff? see the comment above.
345
scrollToId(item->scrollId());
346
setUpdatesEnabled(false);
347
int x = horizontalScrollBar()->value();
348
int y = verticalScrollBar()->value();
349
setCurrentItem(item);
350
horizontalScrollBar()->setValue(x);
351
verticalScrollBar()->setValue(y);
352
setUpdatesEnabled(true);
355
void KompareListView::slotSetSelection(const Difference* diff)
357
qCDebug(KOMPAREPART) << "KompareListView::slotSetSelection( const Difference* diff )" ;
359
setSelectedDifference(diff, true);
362
void KompareListView::slotSetSelection(const DiffModel* model, const Difference* diff)
364
qCDebug(KOMPAREPART) << "KompareListView::slotSetSelection( const DiffModel* model, const Difference* diff )" ;
366
if (m_selectedModel && m_selectedModel == model) {
367
slotSetSelection(diff);
374
m_selectedModel = model;
376
DiffHunkListConstIterator hunkIt = model->hunks()->begin();
377
DiffHunkListConstIterator hEnd = model->hunks()->end();
379
KompareListViewItem* item = nullptr;
380
m_nextPaintOffset = 0;
382
for (; hunkIt != hEnd; ++hunkIt)
385
item = new KompareListViewHunkItem(this, item, *hunkIt, model->isBlended());
387
item = new KompareListViewHunkItem(this, *hunkIt, model->isBlended());
389
DifferenceListConstIterator diffIt = (*hunkIt)->differences().begin();
390
DifferenceListConstIterator dEnd = (*hunkIt)->differences().end();
392
for (; diffIt != dEnd; ++diffIt)
394
item = new KompareListViewDiffItem(this, item, *diffIt);
396
int type = (*diffIt)->type();
398
if (type != Difference::Unchanged)
400
m_items.append((KompareListViewDiffItem*)item);
401
m_itemDict.insert(*diffIt, (KompareListViewDiffItem*)item);
406
resizeColumnToContents(COL_LINE_NO);
407
resizeColumnToContents(COL_MAIN);
409
slotSetSelection(diff);
412
KompareListViewDiffItem* KompareListView::diffItemAt(const QPoint& pos)
414
KompareListViewItem* item = static_cast<KompareListViewItem*>(itemAt(pos));
417
switch (item->type()) {
418
case KompareListViewItem::Hunk:
419
if (item->paintHeight()) return nullptr; // no diff item here
420
// zero height (fake 1 pixel height), so a diff item shines through
421
return static_cast<KompareListViewDiffItem*>(itemBelow(item));
422
case KompareListViewItem::Line:
423
case KompareListViewItem::Blank:
424
return static_cast<KompareListViewLineItem*>(item)->diffItemParent();
425
case KompareListViewItem::Container:
426
return static_cast<KompareListViewLineContainerItem*>(item)->diffItemParent();
427
case KompareListViewItem::Diff:
428
return static_cast<KompareListViewDiffItem*>(item);
434
void KompareListView::mousePressEvent(QMouseEvent* e)
436
QPoint vp = e->pos();
437
KompareListViewDiffItem* diffItem = diffItemAt(vp);
438
if (diffItem && diffItem->difference()->type() != Difference::Unchanged) {
439
Q_EMIT differenceClicked(diffItem->difference());
443
void KompareListView::mouseDoubleClickEvent(QMouseEvent* e)
445
QPoint vp = e->pos();
446
KompareListViewDiffItem* diffItem = diffItemAt(vp);
447
if (diffItem && diffItem->difference()->type() != Difference::Unchanged) {
448
// FIXME: make a new signal that does both
449
Q_EMIT differenceClicked(diffItem->difference());
450
Q_EMIT applyDifference(!diffItem->difference()->applied());
454
void KompareListView::renumberLines()
456
// qCDebug(KOMPAREPART) << "Begin" ;
457
unsigned int newLineNo = 1;
458
if (!topLevelItemCount()) return;
459
KompareListViewItem* item = (KompareListViewItem*)topLevelItem(0);
461
// qCDebug(KOMPAREPART) << "type: " << item->type() ;
462
if (item->type() != KompareListViewItem::Container
463
&& item->type() != KompareListViewItem::Blank
464
&& item->type() != KompareListViewItem::Hunk)
466
// qCDebug(KOMPAREPART) << QString::number( newLineNo ) ;
467
item->setText(COL_LINE_NO, QString::number(newLineNo++));
469
item = (KompareListViewItem*)itemBelow(item);
473
void KompareListView::slotApplyDifference(bool apply)
475
m_itemDict[ m_selectedDifference ]->applyDifference(apply);
476
// now renumber the line column if this is the destination
481
void KompareListView::slotApplyAllDifferences(bool apply)
483
QHash<const Diff2::Difference*, KompareListViewDiffItem*>::ConstIterator it = m_itemDict.constBegin();
484
QHash<const Diff2::Difference*, KompareListViewDiffItem*>::ConstIterator end = m_itemDict.constEnd();
485
for (; it != end; ++it)
486
it.value()->applyDifference(apply);
488
// now renumber the line column if this is the destination
494
void KompareListView::slotApplyDifference(const Difference* diff, bool apply)
496
m_itemDict[ diff ]->applyDifference(apply);
497
// now renumber the line column if this is the destination
502
void KompareListView::wheelEvent(QWheelEvent* e)
504
e->ignore(); // we want the parent to catch wheel events
507
void KompareListView::resizeEvent(QResizeEvent* e)
509
QTreeWidget::resizeEvent(e);
513
KompareListViewItemDelegate::KompareListViewItemDelegate(QObject* parent)
514
: QStyledItemDelegate(parent)
518
KompareListViewItemDelegate::~KompareListViewItemDelegate()
522
void KompareListViewItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
524
int column = index.column();
525
QStyleOptionViewItem changedOption = option;
526
if (column == COL_LINE_NO)
527
changedOption.displayAlignment = Qt::AlignRight;
528
KompareListViewItem* item = static_cast<KompareListViewItem*>(static_cast<KompareListView*>(parent())->itemFromIndex(index));
529
item->paintCell(painter, changedOption, column);
532
QSize KompareListViewItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
534
KompareListViewItem* item = static_cast<KompareListViewItem*>(static_cast<KompareListView*>(parent())->itemFromIndex(index));
535
QSize hint = QStyledItemDelegate::sizeHint(option, index);
536
return QSize(hint.width() + ITEM_MARGIN, item->height());
539
KompareListViewItem::KompareListViewItem(KompareListView* parent, int type)
540
: QTreeWidgetItem(parent, type),
544
m_paintOffset(parent->nextPaintOffset())
546
// qCDebug(KOMPAREPART) << "Created KompareListViewItem with scroll id " << m_scrollId ;
549
KompareListViewItem::KompareListViewItem(KompareListView* parent, KompareListViewItem* after, int type)
550
: QTreeWidgetItem(parent, after, type),
551
m_scrollId(after->scrollId() + after->maxHeight()),
554
m_paintOffset(parent->nextPaintOffset())
556
// qCDebug(KOMPAREPART) << "Created KompareListViewItem with scroll id " << m_scrollId ;
559
KompareListViewItem::KompareListViewItem(KompareListViewItem* parent, int type)
560
: QTreeWidgetItem(parent, type),
564
m_paintOffset(parent->kompareListView()->nextPaintOffset())
568
KompareListViewItem::KompareListViewItem(KompareListViewItem* parent, KompareListViewItem* /*after*/, int type)
569
: QTreeWidgetItem(parent, type),
573
m_paintOffset(parent->kompareListView()->nextPaintOffset())
577
int KompareListViewItem::height() const
582
void KompareListViewItem::setHeight(int h)
584
m_height = m_paintHeight = h;
585
// QTreeWidget doesn't like zero height, fudge around it.
586
m_height -= m_paintOffset;
588
kompareListView()->setNextPaintOffset(1 - m_height);
590
} else kompareListView()->setNextPaintOffset(0);
593
int KompareListViewItem::paintHeight() const
595
return m_paintHeight;
598
int KompareListViewItem::paintOffset() const
600
return m_paintOffset;
603
bool KompareListViewItem::isCurrent() const
605
return treeWidget()->currentItem() == this;
608
KompareListView* KompareListViewItem::kompareListView() const
610
return (KompareListView*)treeWidget();
613
void KompareListViewItem::paintCell(QPainter* p, const QStyleOptionViewItem& option, int column)
615
// Default implementation for zero-height items.
616
// We have to paint the item which shines through or we'll end up with glitches.
617
KompareListViewItem* nextItem = (KompareListViewItem*)kompareListView()->itemBelow(this);
619
QStyleOptionViewItem changedOption = option;
620
changedOption.rect.translate(0, height());
621
nextItem->paintCell(p, changedOption, column);
625
KompareListViewDiffItem::KompareListViewDiffItem(KompareListView* parent, Difference* difference)
626
: KompareListViewItem(parent, Diff),
627
m_difference(difference),
628
m_sourceItem(nullptr),
634
KompareListViewDiffItem::KompareListViewDiffItem(KompareListView* parent, KompareListViewItem* after, Difference* difference)
635
: KompareListViewItem(parent, after, Diff),
636
m_difference(difference),
637
m_sourceItem(nullptr),
643
KompareListViewDiffItem::~KompareListViewDiffItem()
645
m_difference = nullptr;
648
void KompareListViewDiffItem::init()
652
int nextPaintOffset = kompareListView()->nextPaintOffset();
653
m_destItem = new KompareListViewLineContainerItem(this, false);
654
kompareListView()->setNextPaintOffset(nextPaintOffset);
655
m_sourceItem = new KompareListViewLineContainerItem(this, true);
659
void KompareListViewDiffItem::setVisibility()
661
m_sourceItem->setHidden(!(kompareListView()->isSource() || m_difference->applied()));
662
m_destItem->setHidden(!m_sourceItem->isHidden());
665
void KompareListViewDiffItem::applyDifference(bool apply)
667
qCDebug(KOMPAREPART) << "KompareListViewDiffItem::applyDifference( " << apply << " )" ;
671
int KompareListViewDiffItem::maxHeight()
673
int lines = qMax(m_difference->sourceLineCount(), m_difference->destinationLineCount());
675
return BLANK_LINE_HEIGHT;
677
return lines * treeWidget()->fontMetrics().height();
680
KompareListViewLineContainerItem::KompareListViewLineContainerItem(KompareListViewDiffItem* parent, bool isSource)
681
: KompareListViewItem(parent, Container),
682
m_blankLineItem(nullptr),
685
// qCDebug(KOMPAREPART) << "isSource ? " << (isSource ? " Yes!" : " No!") ;
689
int lines = lineCount();
690
int line = lineNumber();
691
// qCDebug(KOMPAREPART) << "LineNumber : " << lineNumber() ;
693
m_blankLineItem = new KompareListViewBlankLineItem(this);
697
for (int i = 0; i < lines; ++i, ++line) {
698
new KompareListViewLineItem(this, line, lineAt(i));
702
KompareListViewLineContainerItem::~KompareListViewLineContainerItem()
706
KompareListViewDiffItem* KompareListViewLineContainerItem::diffItemParent() const
708
return (KompareListViewDiffItem*)parent();
711
int KompareListViewLineContainerItem::lineCount() const
713
return m_isSource ? diffItemParent()->difference()->sourceLineCount() :
714
diffItemParent()->difference()->destinationLineCount();
717
int KompareListViewLineContainerItem::lineNumber() const
719
return m_isSource ? diffItemParent()->difference()->sourceLineNumber() :
720
diffItemParent()->difference()->destinationLineNumber();
723
DifferenceString* KompareListViewLineContainerItem::lineAt(int i) const
725
return m_isSource ? diffItemParent()->difference()->sourceLineAt(i) :
726
diffItemParent()->difference()->destinationLineAt(i);
729
KompareListViewLineItem::KompareListViewLineItem(KompareListViewLineContainerItem* parent, int line, DifferenceString* text)
730
: KompareListViewItem(parent, Line)
735
KompareListViewLineItem::KompareListViewLineItem(KompareListViewLineContainerItem* parent, int line, DifferenceString* text, int type)
736
: KompareListViewItem(parent, type)
741
KompareListViewLineItem::~KompareListViewLineItem()
746
void KompareListViewLineItem::init(int line, DifferenceString* text)
748
setHeight(treeWidget()->fontMetrics().height());
749
setText(COL_LINE_NO, QString::number(line));
750
setText(COL_MAIN, text->string());
754
void KompareListViewLineItem::paintCell(QPainter* p, const QStyleOptionViewItem& option, int column)
756
int width = option.rect.width();
757
Qt::Alignment align = option.displayAlignment;
759
p->setRenderHint(QPainter::Antialiasing);
760
p->translate(option.rect.topLeft());
761
p->translate(0, -paintOffset());
763
QColor bg(Qt::white); // Always make the background white when it is not a real difference
764
if (diffItemParent()->difference()->type() == Difference::Unchanged)
766
if (column == COL_LINE_NO)
768
bg = QColor(Qt::lightGray);
773
bg = kompareListView()->settings()->colorForDifferenceType(
774
diffItemParent()->difference()->type(),
775
diffItemParent()->isCurrent(),
776
diffItemParent()->difference()->applied());
780
p->fillRect(0, 0, width, paintHeight(), bg);
783
if (diffItemParent()->difference()->type() == Difference::Unchanged)
784
p->setPen(QColor(Qt::darkGray)); // always make normal text gray
786
p->setPen(QColor(Qt::black)); // make text with changes black
788
paintText(p, bg, column, width, align);
790
// Paint darker lines around selected item
791
if (diffItemParent()->isCurrent())
793
p->translate(0.5, 0.5);
794
p->setPen(bg.darker(135));
795
QTreeWidgetItem* parentItem = parent();
796
if (this == parentItem->child(0))
797
p->drawLine(0, 0, width, 0);
798
if (this == parentItem->child(parentItem->childCount() - 1))
799
p->drawLine(0, paintHeight() - 1, width, paintHeight() - 1);
805
void KompareListViewLineItem::paintText(QPainter* p, const QColor& bg, int column, int width, int align)
807
if (column == COL_MAIN)
810
int offset = ITEM_MARGIN;
814
QBrush changeBrush(bg, Qt::Dense3Pattern);
815
QBrush normalBrush(bg, Qt::SolidPattern);
818
if (m_text->string().isEmpty())
820
p->fillRect(0, 0, width, paintHeight(), normalBrush);
824
p->fillRect(0, 0, offset, paintHeight(), normalBrush);
826
if (!m_text->markerList().isEmpty())
828
MarkerListConstIterator markerIt = m_text->markerList().begin();
829
MarkerListConstIterator mEnd = m_text->markerList().end();
830
Marker* m = *markerIt;
832
for (; markerIt != mEnd; ++markerIt)
835
textChunk = m_text->string().mid(prevValue, m->offset() - prevValue);
836
// qCDebug(KOMPAREPART) << "TextChunk = \"" << textChunk << "\"" ;
837
// qCDebug(KOMPAREPART) << "c->offset() = " << c->offset() ;
838
// qCDebug(KOMPAREPART) << "prevValue = " << prevValue ;
839
expandTabs(textChunk, kompareListView()->settings()->m_tabToNumberOfSpaces, charsDrawn);
840
charsDrawn += textChunk.length();
841
prevValue = m->offset();
842
if (m->type() == Marker::End)
844
QFont font(p->font());
847
// p->setPen( Qt::blue );
852
QFont font(p->font());
855
// p->setPen( Qt::black );
858
chunkWidth = p->fontMetrics().horizontalAdvance(textChunk);
859
p->fillRect(offset, 0, chunkWidth, paintHeight(), brush);
860
p->drawText(offset, 0,
861
chunkWidth, paintHeight(),
863
offset += chunkWidth;
866
if (prevValue < m_text->string().length())
868
// Still have to draw some string without changes
869
textChunk = m_text->string().mid(prevValue, qMax(1, m_text->string().length() - prevValue));
870
expandTabs(textChunk, kompareListView()->settings()->m_tabToNumberOfSpaces, charsDrawn);
871
// qCDebug(KOMPAREPART) << "TextChunk = \"" << textChunk << "\"" ;
872
QFont font(p->font());
875
chunkWidth = p->fontMetrics().horizontalAdvance(textChunk);
876
p->fillRect(offset, 0, chunkWidth, paintHeight(), normalBrush);
877
p->drawText(offset, 0,
878
chunkWidth, paintHeight(),
880
offset += chunkWidth;
882
p->fillRect(offset, 0, width - offset, paintHeight(), normalBrush);
886
p->fillRect(0, 0, width, paintHeight(), bg);
887
p->drawText(ITEM_MARGIN, 0,
888
width - ITEM_MARGIN, paintHeight(),
889
align, text(column));
893
void KompareListViewLineItem::expandTabs(QString& text, int tabstop, int startPos) const
896
while ((index = text.indexOf(QChar(9))) != -1)
897
text.replace(index, 1, QString(tabstop - ((startPos + index) % tabstop), QLatin1Char(' ')));
900
KompareListViewDiffItem* KompareListViewLineItem::diffItemParent() const
902
KompareListViewLineContainerItem* p = (KompareListViewLineContainerItem*)parent();
903
return p->diffItemParent();
906
KompareListViewBlankLineItem::KompareListViewBlankLineItem(KompareListViewLineContainerItem* parent)
907
: KompareListViewLineItem(parent, 0, new DifferenceString(), Blank)
909
setHeight(BLANK_LINE_HEIGHT);
912
void KompareListViewBlankLineItem::paintText(QPainter* p, const QColor& bg, int column, int width, int /* align */)
914
if (column == COL_MAIN)
916
QBrush normalBrush(bg, Qt::SolidPattern);
917
p->fillRect(0, 0, width, paintHeight(), normalBrush);
921
KompareListViewHunkItem::KompareListViewHunkItem(KompareListView* parent, DiffHunk* hunk, bool zeroHeight)
922
: KompareListViewItem(parent, Hunk),
923
m_zeroHeight(zeroHeight),
926
setHeight(maxHeight());
927
setFlags(flags() & ~Qt::ItemIsSelectable);
930
KompareListViewHunkItem::KompareListViewHunkItem(KompareListView* parent, KompareListViewItem* after, DiffHunk* hunk, bool zeroHeight)
931
: KompareListViewItem(parent, after, Hunk),
932
m_zeroHeight(zeroHeight),
935
setHeight(maxHeight());
936
setFlags(flags() & ~Qt::ItemIsSelectable);
939
KompareListViewHunkItem::~KompareListViewHunkItem()
944
int KompareListViewHunkItem::maxHeight()
948
} else if (m_hunk->function().isEmpty()) {
949
return HUNK_LINE_HEIGHT;
951
return treeWidget()->fontMetrics().height();
955
void KompareListViewHunkItem::paintCell(QPainter* p, const QStyleOptionViewItem& option, int column)
958
KompareListViewItem::paintCell(p, option, column);
960
int x = option.rect.left();
961
int y = option.rect.top() - paintOffset();
962
int width = option.rect.width();
963
Qt::Alignment align = option.displayAlignment;
965
p->fillRect(x, y, width, paintHeight(), QColor(Qt::lightGray)); // Hunk headers should be lightgray
966
p->setPen(QColor(Qt::black)); // Text color in hunk should be black
967
if (column == COL_MAIN) {
968
p->drawText(x + ITEM_MARGIN, y, width - ITEM_MARGIN, paintHeight(),
969
align, m_hunk->function());