diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 0ee70102db2fed8da4ab8f4dde68854cde324c4b..3d81c84bf36005ef7c2f65121441598066b211c8 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -2097,6 +2097,7 @@ void BaseTextEditor::paintEvent(QPaintEvent *e) TextEditorOverlay *overlay = new TextEditorOverlay(this); overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120), d->m_searchScopeFormat.background().color()); + overlay->setAlpha(false); overlay->paint(&painter, e->rect()); delete overlay; } diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp index 183db1140d22263a561629e4dd107525f1575571..de8c0b88013c69fe4939a0a31bd4f7a151004fe8 100644 --- a/src/plugins/texteditor/texteditoroverlay.cpp +++ b/src/plugins/texteditor/texteditoroverlay.cpp @@ -42,6 +42,7 @@ TextEditorOverlay::TextEditorOverlay(BaseTextEditor *editor) m_borderWidth = 1; m_dropShadowWidth = 2; m_editor = editor; + m_alpha = true; m_viewport = editor->viewport(); } @@ -118,7 +119,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co if (begin.isNull() || end.isNull() || begin.position() > end.position()) return QPainterPath(); - QPointF offset = m_editor->contentOffset(); QRect viewportRect = rect(); QTextDocument *document = m_editor->document(); @@ -134,65 +134,78 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co QVector<QRectF> selection; - for (; block.isValid() && block.blockNumber() <= end.blockNumber(); block = block.next()) { - if (! block.isVisible()) - continue; - + if (begin.position() == end.position()) { + // special case empty selections const QRectF blockGeometry = m_editor->blockBoundingGeometry(block); QTextLayout *blockLayout = block.layout(); + int pos = begin.position() - begin.block().position(); + QTextLine line = blockLayout->lineForTextPosition(pos); + QRectF lineRect = line.naturalTextRect(); + int x = line.cursorToX(pos); + lineRect.setLeft(x - m_borderWidth); + lineRect.setRight(x + m_borderWidth); + selection += lineRect.translated(blockGeometry.topLeft()); + } else { + for (; block.isValid() && block.blockNumber() <= end.blockNumber(); block = block.next()) { + if (! block.isVisible()) + continue; + + const QRectF blockGeometry = m_editor->blockBoundingGeometry(block); + QTextLayout *blockLayout = block.layout(); + + QTextLine line = blockLayout->lineAt(0); + + int beginChar = 0; + if (!inSelection) { + beginChar = begin.position() - begin.block().position(); + line = blockLayout->lineForTextPosition(beginChar); + inSelection = true; + } else { + while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace()) + ++beginChar; + if (beginChar == block.length()) + beginChar = 0; + } - QTextLine line = blockLayout->lineAt(0); - - int beginChar = 0; - if (!inSelection) { - beginChar = begin.position() - begin.block().position(); - line = blockLayout->lineForTextPosition(beginChar); - inSelection = true; - } else { - while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace()) - ++beginChar; - if (beginChar == block.length()) - beginChar = 0; - } - - int lastLine = blockLayout->lineCount()-1; - int endChar = -1; - if (block == end.block()) { - endChar = end.position() - end.block().position(); - lastLine = blockLayout->lineForTextPosition(endChar).lineNumber(); - inSelection = false; - } else { - endChar = block.length(); - while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace()) - --endChar; - } + int lastLine = blockLayout->lineCount()-1; + int endChar = -1; + if (block == end.block()) { + endChar = end.position() - end.block().position(); + lastLine = blockLayout->lineForTextPosition(endChar).lineNumber(); + inSelection = false; + } else { + endChar = block.length(); + while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace()) + --endChar; + } - QRectF lineRect = line.naturalTextRect(); - if (beginChar < endChar) { - lineRect.setLeft(line.cursorToX(beginChar)); - if (line.lineNumber() == lastLine) - lineRect.setRight(line.cursorToX(endChar)); - selection += lineRect.translated(blockGeometry.topLeft()); - - for (int lineIndex = line.lineNumber()+1; lineIndex <= lastLine; ++lineIndex) { - line = blockLayout->lineAt(lineIndex); - lineRect = line.naturalTextRect(); - if (lineIndex == lastLine) + QRectF lineRect = line.naturalTextRect(); + if (beginChar < endChar) { + lineRect.setLeft(line.cursorToX(beginChar)); + if (line.lineNumber() == lastLine) lineRect.setRight(line.cursorToX(endChar)); selection += lineRect.translated(blockGeometry.topLeft()); + + for (int lineIndex = line.lineNumber()+1; lineIndex <= lastLine; ++lineIndex) { + line = blockLayout->lineAt(lineIndex); + lineRect = line.naturalTextRect(); + if (lineIndex == lastLine) + lineRect.setRight(line.cursorToX(endChar)); + selection += lineRect.translated(blockGeometry.topLeft()); + } + } else { // empty lines + if (!selection.isEmpty()) + lineRect.setLeft(selection.last().left()); + lineRect.setRight(lineRect.left() + 16); + selection += lineRect.translated(blockGeometry.topLeft()); } - } else { // empty lines - if (!selection.isEmpty()) - lineRect.setLeft(selection.last().left()); - lineRect.setRight(lineRect.left() + 16); - selection += lineRect.translated(blockGeometry.topLeft()); - } - if (!inSelection) - break; + if (!inSelection) + break; - if (blockGeometry.translated(offset).y() > 2*viewportRect.height()) - break; + if (blockGeometry.translated(offset).y() > 2*viewportRect.height()) + break; + } } @@ -288,21 +301,30 @@ void TextEditorOverlay::paintSelection(QPainter *painter, painter->save(); QColor penColor = fg; - penColor.setAlpha(220); + if (m_alpha) + penColor.setAlpha(220); QPen pen(penColor, m_borderWidth); painter->translate(-.5, -.5); QRectF pathRect = path.controlPointRect(); if (bg.isValid()) { - QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft()); - QColor col1 = fg.lighter(150); - col1.setAlpha(20); - QColor col2 = fg; - col2.setAlpha(80); - linearGrad.setColorAt(0, col1); - linearGrad.setColorAt(1, col2); - painter->setBrush(QBrush(linearGrad)); + if (!m_alpha || begin.blockNumber() != end.blockNumber()) { + // gradients are too slow for larger selections :( + QColor col = bg; + if (m_alpha) + col.setAlpha(50); + painter->setBrush(col); + } else { + QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft()); + QColor col1 = fg.lighter(150); + col1.setAlpha(20); + QColor col2 = fg; + col2.setAlpha(80); + linearGrad.setColorAt(0, col1); + linearGrad.setColorAt(1, col2); + painter->setBrush(QBrush(linearGrad)); + } } else { painter->setBrush(QBrush()); } @@ -311,12 +333,10 @@ void TextEditorOverlay::paintSelection(QPainter *painter, if (selection.m_dropShadow) { painter->save(); - painter->translate(m_dropShadowWidth, m_dropShadowWidth); - - QPainterPath clip = path; - clip.translate(-m_dropShadowWidth, -m_dropShadowWidth); - painter->setClipPath(clip.intersected(path)); - painter->fillPath(path, QColor(0, 0, 0, 100)); + QPainterPath shadow = path; + shadow.translate(m_dropShadowWidth, m_dropShadowWidth); + painter->setClipPath(shadow.intersected(path)); + painter->fillPath(shadow, QColor(0, 0, 0, 100)); painter->restore(); } diff --git a/src/plugins/texteditor/texteditoroverlay.h b/src/plugins/texteditor/texteditoroverlay.h index 26e45b0755e0339596b6334940c7fb6fb89a107e..19aa0a3fa68e152a17e42e4674515f7e543db7eb 100644 --- a/src/plugins/texteditor/texteditoroverlay.h +++ b/src/plugins/texteditor/texteditoroverlay.h @@ -59,6 +59,7 @@ private: bool m_visible; int m_borderWidth; int m_dropShadowWidth; +bool m_alpha; public: TextEditorOverlay(BaseTextEditor *editor); @@ -74,6 +75,8 @@ public: void update(); + void setAlpha(bool enabled) { m_alpha = enabled; } + void clear(); void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg, bool lockSize = false); void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg, bool lockSize = false, bool dropShadow = false);