Optimize painting of skipped lines, don't paint "..."

Change-Id: I4a803ca899438ea0067c9a6244dffc77bc7109dd
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
jkobus
2013-02-21 17:14:07 +01:00
committed by hjk
parent 95c410f145
commit 4c75dd71ed

View File

@@ -39,7 +39,6 @@
#include <QDebug> #include <QDebug>
#include <texteditor/basetexteditor.h> #include <texteditor/basetexteditor.h>
#include <texteditor/snippets/snippeteditor.h> #include <texteditor/snippets/snippeteditor.h>
#include <texteditor/basetextdocumentlayout.h> #include <texteditor/basetextdocumentlayout.h>
@@ -80,10 +79,10 @@ public:
return const_cast<QTextCodec *>(baseTextDocument()->codec()); return const_cast<QTextCodec *>(baseTextDocument()->codec());
} }
QMap<int, int> skippedLines() const { return m_skippedLines; } QMap<int, QMap<int, int> > skippedLines() const { return m_skippedLines; }
void setLineNumber(int blockNumber, const QString &lineNumber); void setLineNumber(int blockNumber, const QString &lineNumber);
void setSkippedLines(int visualLineNumber, int skippedLines) { m_skippedLines.insert(visualLineNumber, skippedLines); } void setSkippedLines(int blockNumber, int lineInBlock, int skippedLines) { m_skippedLines[blockNumber][lineInBlock] = skippedLines; }
void clearLineNumbers(); void clearLineNumbers();
void clearSkippedLines() { m_skippedLines.clear(); } void clearSkippedLines() { m_skippedLines.clear(); }
@@ -99,7 +98,8 @@ protected:
private: private:
QMap<int, QString> m_lineNumbers; QMap<int, QString> m_lineNumbers;
int m_lineNumberDigits; int m_lineNumberDigits;
QMap<int, int> m_skippedLines; // block number, line in block, skipped lines
QMap<int, QMap<int, int> > m_skippedLines;
}; };
DiffViewEditorWidget::DiffViewEditorWidget(QWidget *parent) DiffViewEditorWidget::DiffViewEditorWidget(QWidget *parent)
@@ -157,41 +157,36 @@ void DiffViewEditorWidget::scrollContentsBy(int dx, int dy)
void DiffViewEditorWidget::paintEvent(QPaintEvent *e) void DiffViewEditorWidget::paintEvent(QPaintEvent *e)
{ {
SnippetEditorWidget::paintEvent(e); SnippetEditorWidget::paintEvent(e);
QPainter painter(viewport()); QPainter painter(viewport());
QPointF offset = contentOffset(); QPointF offset = contentOffset();
QTextBlock firstBlock = firstVisibleBlock(); QTextBlock firstBlock = firstVisibleBlock();
QTextBlock currentBlock = firstBlock;
QMap<int, int> skipped = skippedLines(); QMap<int, QMap<int, int> > skipped = skippedLines();
QMapIterator<int, int> itChunk(skipped);
while (itChunk.hasNext()) {
itChunk.next();
const int line = itChunk.key();
const int skipped = itChunk.value();
QTextCursor cursor = textCursor(); while (currentBlock.isValid()) {
cursor.movePosition(QTextCursor::Start); if (currentBlock.isVisible()) {
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, line); qreal top = blockBoundingGeometry(currentBlock).translated(offset).top();
QTextBlock block = cursor.block(); qreal bottom = top + blockBoundingRect(currentBlock).height();
qreal top = blockBoundingGeometry(block).translated(offset).top();
qreal bottom = top + blockBoundingRect(block).height();
if (block.blockNumber() < firstBlock.blockNumber() if (top > e->rect().bottom())
|| top > e->rect().bottom()) break;
continue;
if (bottom >= e->rect().top()) {
QTextLayout *layout = currentBlock.layout();
QMap<int, int> skippedInBlock = skipped.value(currentBlock.blockNumber());
QMapIterator<int, int> itLines(skippedInBlock);
while (itLines.hasNext()) {
itLines.next();
if (block.isVisible() && bottom >= e->rect().top()) {
QTextLayout *layout = block.layout();
const int blockLine = line - block.firstLineNumber();
const int blockLineCount = layout->lineCount();
if (blockLine < blockLineCount) {
painter.save(); painter.save();
painter.setPen(palette().foreground().color()); painter.setPen(palette().foreground().color());
QTextLine textLine = layout->lineAt(blockLine); QTextLine textLine = layout->lineAt(itLines.key());
// QRectF lineRect = textLine.naturalTextRect().translated(offset.x(), top); // QRectF lineRect = textLine.naturalTextRect().translated(offset.x(), top);
QRectF lineRect = textLine.naturalTextRect().translated(0, top); QRectF lineRect = textLine.naturalTextRect().translated(0, top);
QString skippedRowsText = tr("Skipped %n lines...", 0, skipped); QString skippedRowsText = tr("Skipped %n lines...", 0, itLines.value());
QFontMetrics fm(font()); QFontMetrics fm(font());
const int textWidth = fm.width(skippedRowsText); const int textWidth = fm.width(skippedRowsText);
painter.drawText(QPointF(lineRect.right() painter.drawText(QPointF(lineRect.right()
@@ -202,6 +197,8 @@ void DiffViewEditorWidget::paintEvent(QPaintEvent *e)
} }
} }
} }
currentBlock = currentBlock.next();
}
} }
////////////////// //////////////////
@@ -485,6 +482,19 @@ ChunkData DiffEditorWidget::calculateOriginalData(const QList<Diff> &diffList) c
} }
if (diffList.count() && diffList.last().command == Diff::Equal) { if (diffList.count() && diffList.last().command == Diff::Equal) {
if (currentLeftLine != lastAlignedLeftLine &&
currentRightLine != lastAlignedRightLine) {
// apply line spans before the current lines
if (currentLeftLineOffset < currentRightLineOffset) {
const int spans = currentRightLineOffset - currentLeftLineOffset;
leftLineSpans[currentLeftLine] = spans;
// currentLeftPos += spans;
} else if (currentRightLineOffset < currentLeftLineOffset) {
const int spans = currentLeftLineOffset - currentRightLineOffset;
rightLineSpans[currentRightLine] = spans;
// currentRightPos += spans;
}
}
if (lastLeftLineEqual && lastRightLineEqual) { if (lastLeftLineEqual && lastRightLineEqual) {
leftEqualLines.append(currentLeftLine); leftEqualLines.append(currentLeftLine);
rightEqualLines.append(currentRightLine); rightEqualLines.append(currentRightLine);
@@ -694,8 +704,8 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c
void DiffEditorWidget::showDiff() void DiffEditorWidget::showDiff()
{ {
QTime time; // QTime time;
time.start(); // time.start();
const int verticalValue = m_leftEditor->verticalScrollBar()->value(); const int verticalValue = m_leftEditor->verticalScrollBar()->value();
const int leftHorizontalValue = m_leftEditor->horizontalScrollBar()->value(); const int leftHorizontalValue = m_leftEditor->horizontalScrollBar()->value();
const int rightHorizontalValue = m_rightEditor->horizontalScrollBar()->value(); const int rightHorizontalValue = m_rightEditor->horizontalScrollBar()->value();
@@ -723,7 +733,7 @@ void DiffEditorWidget::showDiff()
m_rightEditor->clearLineNumbers(); m_rightEditor->clearLineNumbers();
m_leftEditor->clearSkippedLines(); m_leftEditor->clearSkippedLines();
m_rightEditor->clearSkippedLines(); m_rightEditor->clearSkippedLines();
int ela1 = time.elapsed(); // int ela1 = time.elapsed();
QString leftText, rightText; QString leftText, rightText;
bool leftStartWithNewLine = false; bool leftStartWithNewLine = false;
@@ -732,39 +742,23 @@ void DiffEditorWidget::showDiff()
int leftBlockNumber = 0; int leftBlockNumber = 0;
int rightLineNumber = 0; int rightLineNumber = 0;
int rightBlockNumber = 0; int rightBlockNumber = 0;
int line = 0;
int leftPos = 0; int leftPos = 0;
int rightPos = 0; int rightPos = 0;
for (int i = 0; i < m_contextFileData.chunks.count(); i++) {
ChunkData chunkData = m_contextFileData.chunks.at(i);
int leftSeparatorCount = 0; int leftSeparatorCount = 0;
int rightSeparatorCount = 0; int rightSeparatorCount = 0;
for (int i = 0; i < m_contextFileData.chunks.count(); i++) {
ChunkData chunkData = m_contextFileData.chunks.at(i);
leftLineNumber += chunkData.skippedLinesBefore; leftLineNumber += chunkData.skippedLinesBefore;
rightLineNumber += chunkData.skippedLinesBefore; rightLineNumber += chunkData.skippedLinesBefore;
if (chunkData.skippedLinesBefore) { if (chunkData.skippedLinesBefore) {
if (leftStartWithNewLine) { m_leftEditor->setSkippedLines(leftBlockNumber, leftSeparatorCount, chunkData.skippedLinesBefore);
leftText += QLatin1Char('\n'); leftSeparatorCount++;
leftStartWithNewLine = false; m_rightEditor->setSkippedLines(rightBlockNumber, rightSeparatorCount, chunkData.skippedLinesBefore);
leftPos++; rightSeparatorCount++;
}
leftText += QChar::LineSeparator; // for chunk description
leftPos++;
m_leftEditor->setSkippedLines(line, chunkData.skippedLinesBefore);
if (rightStartWithNewLine) {
rightText += QLatin1Char('\n');
rightStartWithNewLine = false;
rightPos++;
}
rightText += QChar::LineSeparator; // for chunk description
rightPos++;
m_rightEditor->setSkippedLines(line, chunkData.skippedLinesBefore);
line++;
} }
for (int j = 0; j < chunkData.rows.count(); j++) { for (int j = 0; j < chunkData.rows.count(); j++) {
line++;
RowData rowData = chunkData.rows.at(j); RowData rowData = chunkData.rows.at(j);
TextLineData leftLineData = rowData.leftLine; TextLineData leftLineData = rowData.leftLine;
TextLineData rightLineData = rowData.rightLine; TextLineData rightLineData = rowData.rightLine;
@@ -775,9 +769,7 @@ void DiffEditorWidget::showDiff()
leftPos++; leftPos++;
} }
if (leftSeparatorCount) { if (leftSeparatorCount) {
QString separators; leftText += QString(leftSeparatorCount, QChar::LineSeparator);
separators.fill(QChar::LineSeparator, leftSeparatorCount);
leftText += separators;
leftSeparatorCount = 0; leftSeparatorCount = 0;
leftPos += leftSeparatorCount; leftPos += leftSeparatorCount;
} }
@@ -793,27 +785,13 @@ void DiffEditorWidget::showDiff()
leftSeparatorCount++; leftSeparatorCount++;
} }
if (j == chunkData.rows.count() - 1 && leftSeparatorCount) {
if (leftStartWithNewLine) {
leftText += QLatin1Char('\n');
leftPos++;
}
QString separators;
separators.fill(QChar::LineSeparator, leftSeparatorCount);
leftText += separators;
leftStartWithNewLine = false;
leftPos += leftSeparatorCount;
}
if (rightLineData.textLineType == TextLineData::TextLine) { if (rightLineData.textLineType == TextLineData::TextLine) {
if (rightStartWithNewLine) { if (rightStartWithNewLine) {
rightText += QLatin1Char('\n'); rightText += QLatin1Char('\n');
rightPos++; rightPos++;
} }
if (rightSeparatorCount) { if (rightSeparatorCount) {
QString separators; rightText += QString(rightSeparatorCount, QChar::LineSeparator);
separators.fill(QChar::LineSeparator, rightSeparatorCount);
rightText += separators;
rightSeparatorCount = 0; rightSeparatorCount = 0;
rightPos += rightSeparatorCount; rightPos += rightSeparatorCount;
} }
@@ -829,44 +807,41 @@ void DiffEditorWidget::showDiff()
rightSeparatorCount++; rightSeparatorCount++;
} }
if (j == chunkData.rows.count() - 1 && rightSeparatorCount) { }
if (i == m_contextFileData.chunks.count() - 1) {
if (leftSeparatorCount) {
if (leftStartWithNewLine) {
leftText += QLatin1Char('\n');
leftPos++;
}
leftText += QString(leftSeparatorCount, QChar::LineSeparator);
}
if (rightSeparatorCount) {
if (rightStartWithNewLine) { if (rightStartWithNewLine) {
rightText += QLatin1Char('\n'); rightText += QLatin1Char('\n');
rightPos++; rightPos++;
} }
QString separators; rightText += QString(rightSeparatorCount, QChar::LineSeparator);
separators.fill(QChar::LineSeparator, rightSeparatorCount);
rightText += separators;
rightStartWithNewLine = false;
rightPos += rightSeparatorCount;
} }
} }
} }
int ela2 = time.elapsed(); // int ela2 = time.elapsed();
m_leftEditor->setPlainText(leftText + QLatin1String("\n")); m_leftEditor->setPlainText(leftText);
m_rightEditor->setPlainText(rightText + QLatin1String("\n")); m_rightEditor->setPlainText(rightText);
int ela3 = time.elapsed(); // int ela3 = time.elapsed();
QTextBlock bl; // int ela4 = time.elapsed();
bl = m_leftEditor->document()->lastBlock();
bl.setVisible(false);
bl.setLineCount(0);
bl = m_rightEditor->document()->lastBlock();
bl.setVisible(false);
bl.setLineCount(0);
int ela4 = time.elapsed();
colorDiff(m_contextFileData); colorDiff(m_contextFileData);
int ela5 = time.elapsed(); // int ela5 = time.elapsed();
m_leftEditor->verticalScrollBar()->setValue(verticalValue); m_leftEditor->verticalScrollBar()->setValue(verticalValue);
m_rightEditor->verticalScrollBar()->setValue(verticalValue); m_rightEditor->verticalScrollBar()->setValue(verticalValue);
m_leftEditor->horizontalScrollBar()->setValue(leftHorizontalValue); m_leftEditor->horizontalScrollBar()->setValue(leftHorizontalValue);
m_rightEditor->horizontalScrollBar()->setValue(rightHorizontalValue); m_rightEditor->horizontalScrollBar()->setValue(rightHorizontalValue);
int ela6 = time.elapsed(); // int ela6 = time.elapsed();
qDebug() << ela1 << ela2 << ela3 << ela4 << ela5 << ela6; // qDebug() << ela1 << ela2 << ela3 << ela4 << ela5 << ela6;
} }
QList<QTextEdit::ExtraSelection> DiffEditorWidget::colorPositions( QList<QTextEdit::ExtraSelection> DiffEditorWidget::colorPositions(