Commit 29b073e9 authored by mae's avatar mae
Browse files

Refactor block selection

Block selection was "broken" when using tabs, or rather
incomplete: It treated tabs as normal characters, which
has shown to be unexpected by people using tabs in code.

The new implementation has a vastly improved find scope
as well. In addition, creating a blog selection with
mouse or keyboard feels a lot more solid now, as the
actual selection is detached from possible valid cursor
positions.

Task-number: QTCREATORBUG-1541
parent 9b338fbb
...@@ -39,14 +39,16 @@ using namespace Find; ...@@ -39,14 +39,16 @@ using namespace Find;
BaseTextFind::BaseTextFind(QTextEdit *editor) BaseTextFind::BaseTextFind(QTextEdit *editor)
: m_editor(editor) : m_editor(editor)
, m_findScopeVerticalBlockSelection(0) , m_findScopeVerticalBlockSelectionFirstColumn(-1)
, m_findScopeVerticalBlockSelectionLastColumn(-1)
, m_incrementalStartPos(-1) , m_incrementalStartPos(-1)
{ {
} }
BaseTextFind::BaseTextFind(QPlainTextEdit *editor) BaseTextFind::BaseTextFind(QPlainTextEdit *editor)
: m_plaineditor(editor) : m_plaineditor(editor)
, m_findScopeVerticalBlockSelection(0) , m_findScopeVerticalBlockSelectionFirstColumn(-1)
, m_findScopeVerticalBlockSelectionLastColumn(-1)
, m_incrementalStartPos(-1) , m_incrementalStartPos(-1)
{ {
} }
...@@ -268,17 +270,16 @@ QTextCursor BaseTextFind::findOne(const QRegExp &expr, const QTextCursor &from, ...@@ -268,17 +270,16 @@ QTextCursor BaseTextFind::findOne(const QRegExp &expr, const QTextCursor &from,
if (candidate.isNull()) if (candidate.isNull())
return candidate; return candidate;
if (!m_findScopeVerticalBlockSelection) if (m_findScopeVerticalBlockSelectionFirstColumn < 0)
return candidate; return candidate;
forever { forever {
if (!inScope(candidate.selectionStart(), candidate.selectionEnd())) if (!inScope(candidate.selectionStart(), candidate.selectionEnd()))
return candidate; return candidate;
QTextCursor b = candidate; bool inVerticalFindScope = false;
b.setPosition(candidate.selectionStart()); QMetaObject::invokeMethod(m_plaineditor, "inFindScope", Qt::DirectConnection,
QTextCursor e = candidate; Q_RETURN_ARG(bool, inVerticalFindScope),
e.setPosition(candidate.selectionEnd()); Q_ARG(QTextCursor, candidate));
if (b.positionInBlock() >= m_findScopeStart.positionInBlock() + 1 if (inVerticalFindScope)
&& e.positionInBlock() <= m_findScopeStart.positionInBlock() + 1 + m_findScopeVerticalBlockSelection)
return candidate; return candidate;
candidate = document()->find(expr, candidate, options); candidate = document()->find(expr, candidate, options);
} }
...@@ -299,23 +300,19 @@ void BaseTextFind::defineFindScope() ...@@ -299,23 +300,19 @@ void BaseTextFind::defineFindScope()
if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) { if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
m_findScopeStart = QTextCursor(document()->docHandle(), qMax(0, cursor.selectionStart()-1)); m_findScopeStart = QTextCursor(document()->docHandle(), qMax(0, cursor.selectionStart()-1));
m_findScopeEnd = QTextCursor(document()->docHandle(), cursor.selectionEnd()); m_findScopeEnd = QTextCursor(document()->docHandle(), cursor.selectionEnd());
m_findScopeVerticalBlockSelection = 0; m_findScopeVerticalBlockSelectionFirstColumn = -1;
m_findScopeVerticalBlockSelectionLastColumn = -1;
int verticalBlockSelection = 0;
if (m_plaineditor && m_plaineditor->metaObject()->indexOfProperty("verticalBlockSelection") >= 0) if (m_plaineditor && m_plaineditor->metaObject()->indexOfProperty("verticalBlockSelectionFirstColumn") >= 0) {
verticalBlockSelection = m_plaineditor->property("verticalBlockSelection").toInt(); m_findScopeVerticalBlockSelectionFirstColumn
= m_plaineditor->property("verticalBlockSelectionFirstColumn").toInt();
if (verticalBlockSelection) { m_findScopeVerticalBlockSelectionLastColumn
QTextCursor findScopeVisualStart(document()->docHandle(), cursor.selectionStart()); = m_plaineditor->property("verticalBlockSelectionLastColumn").toInt();
int findScopeFromColumn = qMin(findScopeVisualStart.positionInBlock(),
m_findScopeEnd.positionInBlock());
int findScopeToColumn = findScopeFromColumn + verticalBlockSelection;
m_findScopeStart.setPosition(findScopeVisualStart.block().position() + findScopeFromColumn - 1);
m_findScopeEnd.setPosition(m_findScopeEnd.block().position()
+ qMin(m_findScopeEnd.block().length()-1, findScopeToColumn));
m_findScopeVerticalBlockSelection = verticalBlockSelection;
} }
emit findScopeChanged(m_findScopeStart, m_findScopeEnd, m_findScopeVerticalBlockSelection);
emit findScopeChanged(m_findScopeStart, m_findScopeEnd,
m_findScopeVerticalBlockSelectionFirstColumn,
m_findScopeVerticalBlockSelectionLastColumn);
cursor.setPosition(m_findScopeStart.position()+1); cursor.setPosition(m_findScopeStart.position()+1);
setTextCursor(cursor); setTextCursor(cursor);
} else { } else {
...@@ -327,6 +324,9 @@ void BaseTextFind::clearFindScope() ...@@ -327,6 +324,9 @@ void BaseTextFind::clearFindScope()
{ {
m_findScopeStart = QTextCursor(); m_findScopeStart = QTextCursor();
m_findScopeEnd = QTextCursor(); m_findScopeEnd = QTextCursor();
m_findScopeVerticalBlockSelection = 0; m_findScopeVerticalBlockSelectionFirstColumn = -1;
emit findScopeChanged(m_findScopeStart, m_findScopeEnd, m_findScopeVerticalBlockSelection); m_findScopeVerticalBlockSelectionLastColumn = -1;
emit findScopeChanged(m_findScopeStart, m_findScopeEnd,
m_findScopeVerticalBlockSelectionFirstColumn,
m_findScopeVerticalBlockSelectionLastColumn);
} }
...@@ -72,7 +72,9 @@ public: ...@@ -72,7 +72,9 @@ public:
signals: signals:
void highlightAll(const QString &txt, Find::FindFlags findFlags); void highlightAll(const QString &txt, Find::FindFlags findFlags);
void findScopeChanged(const QTextCursor &start, const QTextCursor &end, int verticalBlockSelection); void findScopeChanged(const QTextCursor &start, const QTextCursor &end,
int verticalBlockSelectionFirstColumn,
int verticalBlockSelectionLastColumn);
private: private:
bool find(const QString &txt, bool find(const QString &txt,
...@@ -89,7 +91,8 @@ private: ...@@ -89,7 +91,8 @@ private:
QPointer<QPlainTextEdit> m_plaineditor; QPointer<QPlainTextEdit> m_plaineditor;
QTextCursor m_findScopeStart; QTextCursor m_findScopeStart;
QTextCursor m_findScopeEnd; QTextCursor m_findScopeEnd;
int m_findScopeVerticalBlockSelection; int m_findScopeVerticalBlockSelectionFirstColumn;
int m_findScopeVerticalBlockSelectionLastColumn;
bool inScope(int startPosition, int endPosition) const; bool inScope(int startPosition, int endPosition) const;
QTextCursor findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const; QTextCursor findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const;
int m_incrementalStartPos; int m_incrementalStartPos;
......
...@@ -591,7 +591,11 @@ void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &form ...@@ -591,7 +591,11 @@ void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &form
bool OutputWindow::isScrollbarAtBottom() const bool OutputWindow::isScrollbarAtBottom() const
{ {
return verticalScrollBar()->value() == verticalScrollBar()->maximum(); return isVisible()
&& (blockBoundingRect(document()->lastBlock()).bottom()
+ contentOffset().y() <= viewport()->rect().bottom());
// return verticalScrollBar()->value() == verticalScrollBar()->maximum();
} }
void OutputWindow::scrollToBottom() void OutputWindow::scrollToBottom()
......
This diff is collapsed.
...@@ -47,6 +47,7 @@ namespace Utils { ...@@ -47,6 +47,7 @@ namespace Utils {
} }
namespace TextEditor { namespace TextEditor {
struct TabSettings;
namespace Internal { namespace Internal {
class BaseTextEditorPrivate; class BaseTextEditorPrivate;
...@@ -55,6 +56,28 @@ namespace Internal { ...@@ -55,6 +56,28 @@ namespace Internal {
struct RefactorMarker; struct RefactorMarker;
typedef QList<RefactorMarker> RefactorMarkers; typedef QList<RefactorMarker> RefactorMarkers;
class TEXTEDITOR_EXPORT BaseTextBlockSelection
{
public:
bool isValid() const{ return !firstBlock.isNull() && !lastBlock.isNull(); }
void clear() { firstBlock = lastBlock = QTextCursor(); }
QTextCursor firstBlock; // defines the first block
QTextCursor lastBlock; // defines the last block
int firstVisualColumn; // defines the first visual column of the selection
int lastVisualColumn; // defines the last visual column of the selection
enum Anchor {TopLeft = 0, TopRight, BottomLeft, BottomRight} anchor;
BaseTextBlockSelection():firstVisualColumn(0), lastVisualColumn(0), anchor(BottomRight){}
void moveAnchor(int blockNumber, int visualColumn);
inline int anchorColumnNumber() const { return (anchor % 2) ? lastVisualColumn : firstVisualColumn; }
inline int anchorBlockNumber() const {
return (anchor <= TopRight ? firstBlock.blockNumber() : lastBlock.blockNumber()); }
QTextCursor selection(const TabSettings &ts) const;
void fromSelection(const TabSettings &ts, const QTextCursor &selection);
};
} }
class ITextMarkable; class ITextMarkable;
...@@ -66,8 +89,6 @@ struct BehaviorSettings; ...@@ -66,8 +89,6 @@ struct BehaviorSettings;
struct CompletionSettings; struct CompletionSettings;
struct DisplaySettings; struct DisplaySettings;
struct StorageSettings; struct StorageSettings;
struct TabSettings;
class TEXTEDITOR_EXPORT BaseTextEditorAnimator : public QObject class TEXTEDITOR_EXPORT BaseTextEditorAnimator : public QObject
{ {
...@@ -113,8 +134,8 @@ private: ...@@ -113,8 +134,8 @@ private:
class TEXTEDITOR_EXPORT BaseTextEditor : public QPlainTextEdit class TEXTEDITOR_EXPORT BaseTextEditor : public QPlainTextEdit
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int verticalBlockSelection READ verticalBlockSelection) Q_PROPERTY(int verticalBlockSelectionFirstColumn READ verticalBlockSelectionFirstColumn)
Q_PROPERTY(int verticalBlockSelectionLastColumn READ verticalBlockSelectionLastColumn)
public: public:
BaseTextEditor(QWidget *parent); BaseTextEditor(QWidget *parent);
~BaseTextEditor(); ~BaseTextEditor();
...@@ -214,7 +235,8 @@ public: ...@@ -214,7 +235,8 @@ public:
void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet); void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet);
int verticalBlockSelection() const; int verticalBlockSelectionFirstColumn() const;
int verticalBlockSelectionLastColumn() const;
QRegion translatedLineRegion(int lineStart, int lineEnd) const; QRegion translatedLineRegion(int lineStart, int lineEnd) const;
...@@ -315,7 +337,9 @@ private slots: ...@@ -315,7 +337,9 @@ private slots:
void documentAboutToBeReloaded(); void documentAboutToBeReloaded();
void documentReloaded(); void documentReloaded();
void highlightSearchResults(const QString &txt, Find::FindFlags findFlags); void highlightSearchResults(const QString &txt, Find::FindFlags findFlags);
void setFindScope(const QTextCursor &start, const QTextCursor &end, int); void setFindScope(const QTextCursor &start, const QTextCursor &end, int, int);
bool inFindScope(const QTextCursor &cursor);
bool inFindScope(int selectionStart, int selectionEnd);
void currentEditorChanged(Core::IEditor *editor); void currentEditorChanged(Core::IEditor *editor);
void maybeEmitContentsChangedBecauseOfUndo(); void maybeEmitContentsChangedBecauseOfUndo();
...@@ -532,6 +556,8 @@ private slots: ...@@ -532,6 +556,8 @@ private slots:
// auto completion // auto completion
void _q_requestAutoCompletion(); void _q_requestAutoCompletion();
void handleBlockSelection(int diff_row, int diff_col);
// parentheses matcher // parentheses matcher
void _q_matchParentheses(); void _q_matchParentheses();
void _q_highlightBlocks(); void _q_highlightBlocks();
......
...@@ -245,8 +245,6 @@ public: ...@@ -245,8 +245,6 @@ public:
// block selection mode // block selection mode
bool m_inBlockSelectionMode; bool m_inBlockSelectionMode;
bool m_lastEventWasBlockSelectionEvent;
int m_blockSelectionExtraX;
void clearBlockSelection(); void clearBlockSelection();
QString copyBlockSelection(); QString copyBlockSelection();
void removeBlockSelection(const QString &text = QString()); void removeBlockSelection(const QString &text = QString());
...@@ -254,9 +252,13 @@ public: ...@@ -254,9 +252,13 @@ public:
QTextCursor m_findScopeStart; QTextCursor m_findScopeStart;
QTextCursor m_findScopeEnd; QTextCursor m_findScopeEnd;
int m_findScopeVerticalBlockSelection; int m_findScopeVerticalBlockSelectionFirstColumn;
int m_findScopeVerticalBlockSelectionLastColumn;
QTextCursor m_selectBlockAnchor; QTextCursor m_selectBlockAnchor;
Internal::BaseTextBlockSelection m_blockSelection;
void moveCursorVisible(bool ensureVisible = true); void moveCursorVisible(bool ensureVisible = true);
int visualIndent(const QTextBlock &block) const; int visualIndent(const QTextBlock &block) const;
......
...@@ -226,6 +226,22 @@ int TabSettings::columnAt(const QString &text, int position) const ...@@ -226,6 +226,22 @@ int TabSettings::columnAt(const QString &text, int position) const
return column; return column;
} }
int TabSettings::positionAtColumn(const QString &text, int column, int *offset) const
{
int col = 0;
int i = 0;
while (i < text.size() && col < column) {
if (text.at(i) == QLatin1Char('\t'))
col = col - (col % m_tabSize) + m_tabSize;
else
++col;
++i;
}
if (offset)
*offset = column - col;
return i;
}
int TabSettings::spacesLeftFromPosition(const QString &text, int position) const int TabSettings::spacesLeftFromPosition(const QString &text, int position) const
{ {
int i = position; int i = position;
......
...@@ -61,6 +61,7 @@ struct TEXTEDITOR_EXPORT TabSettings ...@@ -61,6 +61,7 @@ struct TEXTEDITOR_EXPORT TabSettings
int firstNonSpace(const QString &text) const; int firstNonSpace(const QString &text) const;
inline bool onlySpace(const QString &text) const { return firstNonSpace(text) == text.length(); } inline bool onlySpace(const QString &text) const { return firstNonSpace(text) == text.length(); }
int columnAt(const QString &text, int position) const; int columnAt(const QString &text, int position) const;
int positionAtColumn(const QString &text, int column, int *offset = 0) const;
int spacesLeftFromPosition(const QString &text, int position) const; int spacesLeftFromPosition(const QString &text, int position) const;
int indentedColumn(int column, bool doIndent = true) const; int indentedColumn(int column, bool doIndent = true) const;
QString indentationString(int startColumn, int targetColumn, const QTextBlock &currentBlock = QTextBlock()) const; QString indentationString(int startColumn, int targetColumn, const QTextBlock &currentBlock = QTextBlock()) const;
......
...@@ -72,8 +72,7 @@ void TextEditorOverlay::clear() ...@@ -72,8 +72,7 @@ void TextEditorOverlay::clear()
void TextEditorOverlay::addOverlaySelection(int begin, int end, void TextEditorOverlay::addOverlaySelection(int begin, int end,
const QColor &fg, const QColor &bg, const QColor &fg, const QColor &bg,
uint overlaySelectionFlags, uint overlaySelectionFlags)
int verticalBlockSelection)
{ {
if (end < begin) if (end < begin)
return; return;
...@@ -84,14 +83,15 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, ...@@ -84,14 +83,15 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
selection.m_fg = fg; selection.m_fg = fg;
selection.m_bg = bg; selection.m_bg = bg;
selection.m_cursor_begin = QTextCursor(document->docHandle(), begin);
selection.m_cursor_end = QTextCursor(document->docHandle(), end);
if (overlaySelectionFlags & ExpandBegin) { if (overlaySelectionFlags & ExpandBegin) {
if (begin > 0 && begin < end) { // not empty if (begin > 0 && begin < end) { // not empty
selection.m_expandBegin = true; selection.m_cursor_begin.setKeepPositionOnInsert(true);
} }
} }
selection.m_cursor_begin = QTextCursor(document->docHandle(), begin);
selection.m_cursor_end = QTextCursor(document->docHandle(), end);
if (overlaySelectionFlags & LockSize) if (overlaySelectionFlags & LockSize)
selection.m_fixedLength = (end - begin); selection.m_fixedLength = (end - begin);
...@@ -99,8 +99,6 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, ...@@ -99,8 +99,6 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
selection.m_dropShadow = (overlaySelectionFlags & DropShadow); selection.m_dropShadow = (overlaySelectionFlags & DropShadow);
selection.m_verticalBlockSelection = verticalBlockSelection;
m_selections.append(selection); m_selections.append(selection);
update(); update();
} }
...@@ -108,11 +106,9 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, ...@@ -108,11 +106,9 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
void TextEditorOverlay::addOverlaySelection(const QTextCursor &cursor, void TextEditorOverlay::addOverlaySelection(const QTextCursor &cursor,
const QColor &fg, const QColor &bg, const QColor &fg, const QColor &bg,
uint overlaySelectionFlags, uint overlaySelectionFlags)
int verticalBlockSelection)
{ {
addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), fg, bg, overlaySelectionFlags, addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), fg, bg, overlaySelectionFlags);
verticalBlockSelection);
} }
QRect TextEditorOverlay::rect() const QRect TextEditorOverlay::rect() const
...@@ -121,7 +117,7 @@ QRect TextEditorOverlay::rect() const ...@@ -121,7 +117,7 @@ QRect TextEditorOverlay::rect() const
} }
QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, const QTextCursor &end, QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, const QTextCursor &end,
const QRect &clip, int verticalBlockSelection) const QRect &clip)
{ {
if (begin.isNull() || end.isNull() || begin.position() > end.position()) if (begin.isNull() || end.isNull() || begin.position() > end.position())
return QPainterPath(); return QPainterPath();
...@@ -173,8 +169,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co ...@@ -173,8 +169,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
line = blockLayout->lineForTextPosition(beginChar); line = blockLayout->lineForTextPosition(beginChar);
inSelection = true; inSelection = true;
firstOrLastBlock = true; firstOrLastBlock = true;
} else if (verticalBlockSelection) {
beginChar = qMin(block.length()-1, begin.positionInBlock());
} else { } else {
while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace()) while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace())
++beginChar; ++beginChar;
...@@ -189,8 +183,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co ...@@ -189,8 +183,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
lastLine = blockLayout->lineForTextPosition(endChar).lineNumber(); lastLine = blockLayout->lineForTextPosition(endChar).lineNumber();
inSelection = false; inSelection = false;
firstOrLastBlock = true; firstOrLastBlock = true;
} else if (verticalBlockSelection) {
endChar = qMin(block.length()-1, begin.positionInBlock() + verticalBlockSelection);
} else { } else {
endChar = block.length(); endChar = block.length();
while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace()) while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace())
...@@ -211,7 +203,7 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co ...@@ -211,7 +203,7 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
lineRect.setRight(line.cursorToX(endChar)); lineRect.setRight(line.cursorToX(endChar));
selection += lineRect.translated(blockGeometry.topLeft()); selection += lineRect.translated(blockGeometry.topLeft());
} }
} else if (!verticalBlockSelection){ // empty lines } else { // empty lines
const int emptyLineSelectionSize = 16; const int emptyLineSelectionSize = 16;
if (!firstOrLastBlock && !selection.isEmpty()) { // middle if (!firstOrLastBlock && !selection.isEmpty()) { // middle
lineRect.setLeft(selection.last().left()); lineRect.setLeft(selection.last().left());
...@@ -315,8 +307,6 @@ void TextEditorOverlay::paintSelection(QPainter *painter, ...@@ -315,8 +307,6 @@ void TextEditorOverlay::paintSelection(QPainter *painter,
{ {
QTextCursor begin = selection.m_cursor_begin; QTextCursor begin = selection.m_cursor_begin;
if (selection.m_expandBegin)
begin.setPosition(begin.position() + 1);
const QTextCursor &end= selection.m_cursor_end; const QTextCursor &end= selection.m_cursor_end;
const QColor &fg = selection.m_fg; const QColor &fg = selection.m_fg;
...@@ -328,8 +318,7 @@ void TextEditorOverlay::paintSelection(QPainter *painter, ...@@ -328,8 +318,7 @@ void TextEditorOverlay::paintSelection(QPainter *painter,
|| begin.position() > end.position()) || begin.position() > end.position())
return; return;
QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect(), QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
selection.m_verticalBlockSelection);
painter->save(); painter->save();
QColor penColor = fg; QColor penColor = fg;
...@@ -389,8 +378,7 @@ void TextEditorOverlay::fillSelection(QPainter *painter, ...@@ -389,8 +378,7 @@ void TextEditorOverlay::fillSelection(QPainter *painter,
if (begin.isNull() || end.isNull() || begin.position() > end.position()) if (begin.isNull() || end.isNull() || begin.position() > end.position())
return; return;
QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect(), QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
selection.m_verticalBlockSelection);
painter->save(); painter->save();
painter->translate(-.5, -.5); painter->translate(-.5, -.5);
......
...@@ -37,17 +37,14 @@ namespace TextEditor { ...@@ -37,17 +37,14 @@ namespace TextEditor {
namespace Internal { namespace Internal {
struct TEXTEDITOR_EXPORT OverlaySelection { struct TEXTEDITOR_EXPORT OverlaySelection {
OverlaySelection():m_fixedLength(-1), m_dropShadow(false), OverlaySelection():m_fixedLength(-1), m_dropShadow(false){}
m_expandBegin(false), m_verticalBlockSelection(0){}
QTextCursor m_cursor_begin; QTextCursor m_cursor_begin;
QTextCursor m_cursor_end; QTextCursor m_cursor_end;
QColor m_fg; QColor m_fg;
QColor m_bg; QColor m_bg;
int m_fixedLength; int m_fixedLength;
bool m_dropShadow; bool m_dropShadow;
bool m_expandBegin; };
int m_verticalBlockSelection;
};
class TEXTEDITOR_EXPORT TextEditorOverlay : public QObject class TEXTEDITOR_EXPORT TextEditorOverlay : public QObject
{ {
...@@ -92,9 +89,9 @@ public: ...@@ -92,9 +89,9 @@ public:
}; };
void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg, void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg,
uint overlaySelectionFlags = 0, int verticalBlockSelection = 0); uint overlaySelectionFlags = 0);
void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg, void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg,
uint overlaySelectionFlags = 0, int verticalBlockSelection = 0); uint overlaySelectionFlags = 0);
inline bool isEmpty() const { return m_selections.isEmpty(); } inline bool isEmpty() const { return m_selections.isEmpty(); }
...@@ -103,8 +100,7 @@ public: ...@@ -103,8 +100,7 @@ public:
bool hasCursorInSelection(const QTextCursor &cursor) const; bool hasCursorInSelection(const QTextCursor &cursor) const;
private: private:
QPainterPath createSelectionPath(const QTextCursor &begin, const QTextCursor &end, const QRect& clip, QPainterPath createSelectionPath(const QTextCursor &begin, const QTextCursor &end, const QRect& clip);
int verticalBlockSelection);
void paintSelection(QPainter *painter, const OverlaySelection &selection); void paintSelection(QPainter *painter, const OverlaySelection &selection);
void fillSelection(QPainter *painter, const OverlaySelection &selection, const QColor &color); void fillSelection(QPainter *painter, const OverlaySelection &selection, const QColor &color);
......