summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authormae <qt-info@nokia.com>2009-12-01 14:47:10 +0100
committermae <qt-info@nokia.com>2009-12-01 14:47:40 +0100
commite2a899e354ce579597feed2d79d9df9cdc3daf57 (patch)
treea2ba8f4082131fbc17dd034d44f30ec56005b094 /src/plugins
parentc4737c1fdf5ab3d950adaa5002367797c993ed37 (diff)
downloadqt-creator-e2a899e354ce579597feed2d79d9df9cdc3daf57.tar.gz
improved search result selection with over and underlay
done with thorbjorn
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/texteditor/basetexteditor.cpp52
-rw-r--r--src/plugins/texteditor/basetexteditor_p.h6
-rw-r--r--src/plugins/texteditor/displaysettings.cpp4
-rw-r--r--src/plugins/texteditor/texteditoroverlay.cpp155
-rw-r--r--src/plugins/texteditor/texteditoroverlay.h18
5 files changed, 195 insertions, 40 deletions
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 2a20ed857c..3a8c5e9437 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -177,6 +177,7 @@ BaseTextEditor::BaseTextEditor(QWidget *parent)
d->m_overlay = new TextEditorOverlay(this);
d->m_searchResultOverlay = new TextEditorOverlay(this);
+ d->m_searchResultUnderlay = new TextEditorOverlay(this);
d->setupDocumentSignals(d->m_document);
d->setupDocumentSignals(d->m_document);
@@ -230,6 +231,10 @@ BaseTextEditor::BaseTextEditor(QWidget *parent)
slotCursorPositionChanged();
setFrameStyle(QFrame::NoFrame);
+ d->m_delayedUpdateTimer = new QTimer(this);
+ d->m_delayedUpdateTimer->setSingleShot(true);
+ connect(d->m_delayedUpdateTimer, SIGNAL(timeout()), viewport(), SLOT(update()));
+
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(currentEditorChanged(Core::IEditor*)));
}
@@ -1822,7 +1827,9 @@ QTextBlock BaseTextEditor::collapsedBlockAt(const QPoint &pos, QRect *box) const
return QTextBlock();
}
-void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block)
+void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
+ TextEditorOverlay *overlay,
+ QVector<QTextLayout::FormatRange> *selections )
{
if (m_searchExpr.isEmpty())
return;
@@ -1843,9 +1850,19 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block)
if (m_findScope.isNull()
|| (block.position() + idx >= m_findScope.selectionStart()
&& block.position() + idx + l <= m_findScope.selectionEnd())) {
- m_searchResultOverlay->addOverlaySelection(block.position() + idx,
- block.position() + idx + l,
- m_searchResultFormat.background().color());
+ if (selections) {
+ QTextLayout::FormatRange selection;
+ selection.start = idx;
+ selection.length = l;
+ selection.format = m_searchResultFormat;
+ selections->append(selection);
+ }
+
+ overlay->addOverlaySelection(block.position() + idx,
+ block.position() + idx + l,
+ m_searchResultFormat.background().color().darker(120),
+ QColor());
+
}
}
}
@@ -2075,6 +2092,8 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
QPen cursor_pen;
d->m_searchResultOverlay->clear();
+ d->m_searchResultUnderlay->clear();
+
while (block.isValid()) {
QRectF r = blockBoundingRect(block).translated(offset);
@@ -2169,7 +2188,9 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
selections.append(o);
}
}
- d->highlightSearchResults(block);
+
+ d->highlightSearchResults(block, d->m_searchResultUnderlay, &selections);
+ d->m_searchResultOverlay->m_selections.append(d->m_searchResultUnderlay->m_selections);
selections += prioritySelections;
bool drawCursor = ((editable || true) // we want the cursor in read-only mode
@@ -2191,6 +2212,12 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
}
}
+ if (d->m_searchResultUnderlay && !d->m_searchExpr.isEmpty()) {
+ d->m_searchResultUnderlay->fill(&painter,
+ d->m_searchResultFormat.background().color(),
+ e->rect());
+ d->m_searchResultUnderlay->clear();
+ }
layout->draw(&painter, offset, selections, er);
@@ -2208,6 +2235,9 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
cursor_pen = painter.pen();
}
+ } else if (r.bottom() >= er.top()-10 && r.top() <= er.bottom()+10) {
+ // search result overlays can cover adjacent blocks
+ d->highlightSearchResults(block, d->m_searchResultOverlay);
}
offset.ry() += r.height();
@@ -2421,11 +2451,13 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
painter.drawLine(QPointF(lineX, 0), QPointF(lineX, viewport()->height()));
}
- if (d->m_searchResultOverlay)
- d->m_searchResultOverlay->paint(&painter, e->rect());
-
if (d->m_overlay && d->m_overlay->isVisible())
d->m_overlay->paint(&painter, e->rect());
+
+ if (d->m_searchResultOverlay && !d->m_searchExpr.isEmpty())
+ d->m_searchResultOverlay->paint(&painter, e->rect());
+// d->m_searchResultOverlay->paintInverted(&painter, e->rect(), d->m_searchResultFormat.background().color());
+
// draw the cursor last, on top of everything
@@ -3934,9 +3966,9 @@ void BaseTextEditor::highlightSearchResults(const QString &txt, Find::IFindSuppo
d->m_searchExpr.setCaseSensitivity((findFlags & Find::IFindSupport::FindCaseSensitively) ?
Qt::CaseSensitive : Qt::CaseInsensitive);
d->m_findFlags = findFlags;
- viewport()->update();
-}
+ d->m_delayedUpdateTimer->start(10);
+}
void BaseTextEditor::setFindScope(const QTextCursor &scope)
{
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index f7c7ed3a6b..39bb0dfedb 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -189,6 +189,7 @@ public:
TextEditorOverlay *m_overlay;
TextEditorOverlay *m_searchResultOverlay;
+ TextEditorOverlay *m_searchResultUnderlay;
QBasicTimer collapsedBlockTimer;
int visibleCollapsedBlockNumber;
@@ -222,7 +223,10 @@ public:
QTextCharFormat m_searchScopeFormat;
QTextCharFormat m_currentLineFormat;
QTextCharFormat m_currentLineNumberFormat;
- void highlightSearchResults(const QTextBlock &block);
+ void highlightSearchResults(const QTextBlock &block,
+ TextEditorOverlay *overlay,
+ QVector<QTextLayout::FormatRange> *selections = 0);
+ QTimer *m_delayedUpdateTimer;
BaseTextEditorEditable *m_editable;
diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp
index 0906a9016f..aca646ccf9 100644
--- a/src/plugins/texteditor/displaysettings.cpp
+++ b/src/plugins/texteditor/displaysettings.cpp
@@ -40,7 +40,7 @@ static const char * const showWrapColumnKey = "ShowWrapColumn";
static const char * const wrapColumnKey = "WrapColumn";
static const char * const visualizeWhitespaceKey = "VisualizeWhitespace";
static const char * const displayFoldingMarkersKey = "DisplayFoldingMarkers";
-static const char * const highlightCurrentLineKey = "HighlightCurrentLineKey";
+static const char * const highlightCurrentLineKey = "HighlightCurrentLine2Key";
static const char * const highlightBlocksKey = "HighlightBlocksKey";
static const char * const animateMatchingParenthesesKey= "AnimateMatchingParenthesesKey";
static const char * const mouseNavigationKey = "MouseNavigation";
@@ -56,7 +56,7 @@ DisplaySettings::DisplaySettings() :
m_wrapColumn(80),
m_visualizeWhitespace(false),
m_displayFoldingMarkers(true),
- m_highlightCurrentLine(true),
+ m_highlightCurrentLine(false),
m_highlightBlocks(false),
m_animateMatchingParentheses(true),
m_mouseNavigation(true),
diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp
index 9b76385efc..1e3065ca3e 100644
--- a/src/plugins/texteditor/texteditoroverlay.cpp
+++ b/src/plugins/texteditor/texteditoroverlay.cpp
@@ -36,7 +36,8 @@ void TextEditorOverlay::clear()
update();
}
-void TextEditorOverlay::addOverlaySelection(int begin, int end, const QColor &color, bool lockSize)
+void TextEditorOverlay::addOverlaySelection(int begin, int end,
+ const QColor &fg, const QColor &bg, bool lockSize)
{
if (end < begin)
return;
@@ -44,7 +45,8 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, const QColor &co
QTextDocument *document = m_editor->document();
OverlaySelection selection;
- selection.m_color = color;
+ selection.m_fg = fg;
+ selection.m_bg = bg;
selection.m_cursor_begin = QTextCursor(document);
selection.m_cursor_begin.setPosition(begin);
@@ -60,9 +62,10 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, const QColor &co
}
-void TextEditorOverlay::addOverlaySelection(const QTextCursor &cursor, const QColor &color, bool lockSize)
+void TextEditorOverlay::addOverlaySelection(const QTextCursor &cursor,
+ const QColor &fg, const QColor &bg, bool lockSize)
{
- addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), color, lockSize);
+ addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), fg, bg, lockSize);
}
QRect TextEditorOverlay::rect() const
@@ -70,20 +73,21 @@ QRect TextEditorOverlay::rect() const
return m_viewport->rect();
}
-void TextEditorOverlay::paintSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end, const QColor &color)
+QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, const QTextCursor &end,
+ const QRect &clip)
{
if (begin.isNull() || end.isNull() || begin.position() > end.position())
- return;
+ return QPainterPath();
QPointF offset = m_editor->contentOffset();
QRect viewportRect = rect();
QTextDocument *document = m_editor->document();
- if (m_editor->blockBoundingGeometry(begin.block()).translated(offset).top() > viewportRect.bottom() + 10
- || m_editor->blockBoundingGeometry(end.block()).translated(offset).bottom() < viewportRect.top() - 10
+ if (m_editor->blockBoundingGeometry(begin.block()).translated(offset).top() > clip.bottom() + 10
+ || m_editor->blockBoundingGeometry(end.block()).translated(offset).bottom() < clip.top() - 10
)
- return; // nothing of the selection is visible
+ return QPainterPath(); // nothing of the selection is visible
QTextBlock block = begin.block();
@@ -154,7 +158,7 @@ void TextEditorOverlay::paintSelection(QPainter *painter, const QTextCursor &beg
if (selection.isEmpty())
- return;
+ return QPainterPath();
QVector<QPointF> points;
@@ -224,34 +228,60 @@ void TextEditorOverlay::paintSelection(QPainter *painter, const QTextCursor &beg
previous = points.at(i);
}
path.closeSubpath();
+ path.translate(offset);
+ return path;
+}
+
+void TextEditorOverlay::paintSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end,
+ const QColor &fg, const QColor &bg)
+{
+ if (begin.isNull() || end.isNull() || begin.position() > end.position())
+ return;
+
+ QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
painter->save();
- QColor penColor = color;
+ QColor penColor = fg;
penColor.setAlpha(220);
QPen pen(penColor, m_borderWidth);
painter->translate(-.5, -.5);
- path.translate(offset);
QRectF pathRect = path.controlPointRect();
- QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft());
- QColor col1 = color.lighter(150);
- col1.setAlpha(20);
- QColor col2 = color;
- col2.setAlpha(80);
- linearGrad.setColorAt(0, col1);
- linearGrad.setColorAt(1, col2);
- QBrush brush(linearGrad);
-
+ 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));
+ } else {
+ painter->setBrush(QBrush());
+ }
painter->setRenderHint(QPainter::Antialiasing);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
- painter->setBrush(brush);
painter->drawPath(path);
painter->restore();
}
+void TextEditorOverlay::fillSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end,
+ const QColor &color)
+{
+ if (begin.isNull() || end.isNull() || begin.position() > end.position())
+ return;
+
+ QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
+
+ painter->save();
+ painter->translate(-.5, -.5);
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->fillPath(path, color);
+ painter->restore();
+}
void TextEditorOverlay::paint(QPainter *painter, const QRect &clip)
{
@@ -266,10 +296,89 @@ void TextEditorOverlay::paint(QPainter *painter, const QRect &clip)
paintSelection(painter,
selection.m_cursor_begin,
selection.m_cursor_end,
- selection.m_color
+ selection.m_fg,
+ selection.m_bg
+ );
+ }
+}
+
+void TextEditorOverlay::fill(QPainter *painter, const QColor &color, const QRect &clip)
+{
+ Q_UNUSED(clip);
+ for (int i = 0; i < m_selections.size(); ++i) {
+ const OverlaySelection &selection = m_selections.at(i);
+ if (selection.m_fixedLength >= 0
+ && selection.m_cursor_end.position() - selection.m_cursor_begin.position()
+ != selection.m_fixedLength)
+ continue;
+
+ fillSelection(painter,
+ selection.m_cursor_begin,
+ selection.m_cursor_end,
+ color
);
}
}
+void TextEditorOverlay::paintInverted(QPainter *painter, const QRect &clip, const QColor &color)
+{
+ QPainterPath path;
+ for (int i = 0; i < m_selections.size(); ++i) {
+ const OverlaySelection &selection = m_selections.at(i);
+ if (selection.m_fixedLength >= 0
+ && selection.m_cursor_end.position() - selection.m_cursor_begin.position()
+ != selection.m_fixedLength)
+ continue;
+ path.addPath(createSelectionPath(selection.m_cursor_begin, selection.m_cursor_end, clip));
+ }
+
+ QRect viewportRect = m_editor->viewport()->rect();
+ QColor background = Qt::black;
+ background.setAlpha(30);
+
+ if (path.isEmpty()) {
+ painter->fillRect(viewportRect, background);
+ return;
+ }
+
+// QPainterPath all;
+// all.addRect(viewportRect);
+// QPainterPath inversion = all.subtracted(path);
+
+ painter->save();
+ QColor penColor = color;
+ penColor.setAlpha(220);
+ QPen pen(penColor, m_borderWidth);
+ QColor brush = color;
+ brush.setAlpha(30);
+ painter->translate(-.5, -.5);
+
+// painter->setRenderHint(QPainter::Antialiasing);
+ //pen.setJoinStyle(Qt::RoundJoin);
+ painter->setPen(pen);
+ painter->setBrush(QBrush());
+ painter->drawPath(path);
+
+ painter->translate(.5, .5);
+
+ QPixmap shadow(clip.size());
+ shadow.fill(background);
+ QPainter pmp(&shadow);
+ pmp.translate(-.5, -.5);
+ pmp.setRenderHint(QPainter::Antialiasing);
+ pmp.setCompositionMode(QPainter::CompositionMode_Source);
+ path.translate(-clip.topLeft());
+ pen.setColor(Qt::transparent);
+ pmp.setPen(pen);
+ pmp.setBrush(Qt::transparent);
+ pmp.drawPath(path);
+ pmp.end();
+
+ painter->drawPixmap(clip.topLeft(), shadow);
+
+// painter->fillPath(inversion, background);
+ painter->restore();
+}
+
diff --git a/src/plugins/texteditor/texteditoroverlay.h b/src/plugins/texteditor/texteditoroverlay.h
index 6516b69bca..7983677643 100644
--- a/src/plugins/texteditor/texteditoroverlay.h
+++ b/src/plugins/texteditor/texteditoroverlay.h
@@ -11,7 +11,8 @@ struct TEXTEDITOR_EXPORT OverlaySelection {
OverlaySelection():m_fixedLength(-1){}
QTextCursor m_cursor_begin;
QTextCursor m_cursor_end;
- QColor m_color;
+ QColor m_fg;
+ QColor m_bg;
int m_fixedLength;
};
@@ -21,7 +22,9 @@ Q_OBJECT
BaseTextEditor *m_editor;
QWidget *m_viewport;
+public:
QList<OverlaySelection> m_selections;
+private:
bool m_visible;
int m_borderWidth;
@@ -31,6 +34,9 @@ public:
QRect rect() const;
void paint(QPainter *painter, const QRect &clip);
+ void fill(QPainter *painter, const QColor &color, const QRect &clip);
+
+ void paintInverted(QPainter *painter, const QRect &clip, const QColor &color);
bool isVisible() const { return m_visible; }
void setVisible(bool b);
@@ -40,13 +46,17 @@ public:
void update();
void clear();
- void addOverlaySelection(const QTextCursor &cursor, const QColor &color, bool lockSize = false);
- void addOverlaySelection(int begin, int end, const QColor &color, bool lockSize = false);
+ 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);
inline bool isEmpty() const { return m_selections.isEmpty(); }
private:
- void paintSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end, const QColor &color);
+ QPainterPath createSelectionPath(const QTextCursor &begin, const QTextCursor &end, const QRect& clip);
+ void paintSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end,
+ const QColor &fg, const QColor &bg);
+ void fillSelection(QPainter *painter, const QTextCursor &begin, const QTextCursor &end,
+ const QColor &color);
};