forked from qt-creator/qt-creator
Restrict find & replace to vertical block selection
This commit is contained in:
@@ -215,7 +215,7 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
|
|||||||
QRegExp regexp(before);
|
QRegExp regexp(before);
|
||||||
regexp.setPatternSyntax(usesRegExp ? QRegExp::RegExp : QRegExp::FixedString);
|
regexp.setPatternSyntax(usesRegExp ? QRegExp::RegExp : QRegExp::FixedString);
|
||||||
regexp.setCaseSensitivity((findFlags & IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
regexp.setCaseSensitivity((findFlags & IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
QTextCursor found = document()->find(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
QTextCursor found = findOne(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
||||||
while (!found.isNull() && found.selectionStart() < found.selectionEnd()
|
while (!found.isNull() && found.selectionStart() < found.selectionEnd()
|
||||||
&& inScope(found.selectionStart(), found.selectionEnd())) {
|
&& inScope(found.selectionStart(), found.selectionEnd())) {
|
||||||
++count;
|
++count;
|
||||||
@@ -224,7 +224,7 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
|
|||||||
regexp.exactMatch(found.selectedText());
|
regexp.exactMatch(found.selectedText());
|
||||||
QString realAfter = usesRegExp ? expandRegExpReplacement(after, regexp) : after;
|
QString realAfter = usesRegExp ? expandRegExpReplacement(after, regexp) : after;
|
||||||
editCursor.insertText(realAfter);
|
editCursor.insertText(realAfter);
|
||||||
found = document()->find(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
found = findOne(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
||||||
}
|
}
|
||||||
editCursor.endEditBlock();
|
editCursor.endEditBlock();
|
||||||
return count;
|
return count;
|
||||||
@@ -241,7 +241,7 @@ bool BaseTextFind::find(const QString &txt,
|
|||||||
QRegExp regexp(txt);
|
QRegExp regexp(txt);
|
||||||
regexp.setPatternSyntax((findFlags&IFindSupport::FindRegularExpression) ? QRegExp::RegExp : QRegExp::FixedString);
|
regexp.setPatternSyntax((findFlags&IFindSupport::FindRegularExpression) ? QRegExp::RegExp : QRegExp::FixedString);
|
||||||
regexp.setCaseSensitivity((findFlags&IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
regexp.setCaseSensitivity((findFlags&IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
QTextCursor found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
QTextCursor found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
||||||
|
|
||||||
if (!m_findScope.isNull()) {
|
if (!m_findScope.isNull()) {
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ bool BaseTextFind::find(const QString &txt,
|
|||||||
start.setPosition(m_findScope.selectionStart());
|
start.setPosition(m_findScope.selectionStart());
|
||||||
else
|
else
|
||||||
start.setPosition(m_findScope.selectionEnd());
|
start.setPosition(m_findScope.selectionEnd());
|
||||||
found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
||||||
if (found.isNull() || !inScope(found.selectionStart(), found.selectionEnd()))
|
if (found.isNull() || !inScope(found.selectionStart(), found.selectionEnd()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -263,7 +263,7 @@ bool BaseTextFind::find(const QString &txt,
|
|||||||
start.movePosition(QTextCursor::Start);
|
start.movePosition(QTextCursor::Start);
|
||||||
else
|
else
|
||||||
start.movePosition(QTextCursor::End);
|
start.movePosition(QTextCursor::End);
|
||||||
found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
|
||||||
if (found.isNull()) {
|
if (found.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -275,6 +275,28 @@ bool BaseTextFind::find(const QString &txt,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// helper function. Works just like QTextDocument::find() but supports vertical block selection
|
||||||
|
QTextCursor BaseTextFind::findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const
|
||||||
|
{
|
||||||
|
QTextCursor candidate = document()->find(expr, from, options);
|
||||||
|
if (!m_findScopeVerticalBlockSelection)
|
||||||
|
return candidate;
|
||||||
|
forever {
|
||||||
|
if (!inScope(candidate.selectionStart(), candidate.selectionEnd()))
|
||||||
|
return candidate;
|
||||||
|
QTextCursor b = candidate;
|
||||||
|
b.setPosition(candidate.selectionStart());
|
||||||
|
QTextCursor e = candidate;
|
||||||
|
e.setPosition(candidate.selectionEnd());
|
||||||
|
if (b.positionInBlock() >= m_findScopeFromColumn
|
||||||
|
&& e.positionInBlock() <= m_findScopeToColumn)
|
||||||
|
return candidate;
|
||||||
|
candidate = document()->find(expr, candidate, options);
|
||||||
|
}
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseTextFind::inScope(int startPosition, int endPosition) const
|
bool BaseTextFind::inScope(int startPosition, int endPosition) const
|
||||||
{
|
{
|
||||||
if (m_findScope.isNull())
|
if (m_findScope.isNull())
|
||||||
@@ -288,8 +310,25 @@ void BaseTextFind::defineFindScope()
|
|||||||
QTextCursor cursor = textCursor();
|
QTextCursor cursor = textCursor();
|
||||||
if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
|
if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
|
||||||
m_findScope = cursor;
|
m_findScope = cursor;
|
||||||
emit findScopeChanged(m_findScope);
|
m_findScopeVerticalBlockSelection = false;
|
||||||
cursor.setPosition(cursor.selectionStart());
|
|
||||||
|
int verticalBlockSelection = 0;
|
||||||
|
if (m_plaineditor && m_plaineditor->metaObject()->indexOfProperty("verticalBlockSelection") >= 0)
|
||||||
|
verticalBlockSelection = m_plaineditor->property("verticalBlockSelection").toInt();
|
||||||
|
|
||||||
|
if (verticalBlockSelection) {
|
||||||
|
QTextDocument *doc = document();
|
||||||
|
QTextCursor b(doc->docHandle(), cursor.selectionStart());
|
||||||
|
QTextCursor e(doc->docHandle(), cursor.selectionEnd());
|
||||||
|
m_findScopeFromColumn = qMin(b.positionInBlock(), e.positionInBlock());
|
||||||
|
m_findScopeToColumn = m_findScopeFromColumn + verticalBlockSelection;
|
||||||
|
m_findScope.setPosition(b.block().position() + m_findScopeFromColumn);
|
||||||
|
m_findScope.setPosition(e.block().position() + qMin(e.block().length()-1, m_findScopeToColumn),
|
||||||
|
QTextCursor::KeepAnchor);
|
||||||
|
m_findScopeVerticalBlockSelection = verticalBlockSelection;
|
||||||
|
}
|
||||||
|
emit findScopeChanged(m_findScope, m_findScopeVerticalBlockSelection);
|
||||||
|
cursor.setPosition(m_findScope.selectionStart());
|
||||||
setTextCursor(cursor);
|
setTextCursor(cursor);
|
||||||
} else {
|
} else {
|
||||||
clearFindScope();
|
clearFindScope();
|
||||||
@@ -299,5 +338,6 @@ void BaseTextFind::defineFindScope()
|
|||||||
void BaseTextFind::clearFindScope()
|
void BaseTextFind::clearFindScope()
|
||||||
{
|
{
|
||||||
m_findScope = QTextCursor();
|
m_findScope = QTextCursor();
|
||||||
emit findScopeChanged(m_findScope);
|
m_findScopeVerticalBlockSelection = 0;
|
||||||
|
emit findScopeChanged(m_findScope, m_findScopeVerticalBlockSelection);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void highlightAll(const QString &txt, Find::IFindSupport::FindFlags findFlags);
|
void highlightAll(const QString &txt, Find::IFindSupport::FindFlags findFlags);
|
||||||
void findScopeChanged(const QTextCursor &);
|
void findScopeChanged(const QTextCursor &, int = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool find(const QString &txt,
|
bool find(const QString &txt,
|
||||||
@@ -84,7 +84,11 @@ private:
|
|||||||
QPointer<QTextEdit> m_editor;
|
QPointer<QTextEdit> m_editor;
|
||||||
QPointer<QPlainTextEdit> m_plaineditor;
|
QPointer<QPlainTextEdit> m_plaineditor;
|
||||||
QTextCursor m_findScope;
|
QTextCursor m_findScope;
|
||||||
|
int m_findScopeVerticalBlockSelection;
|
||||||
|
int m_findScopeFromColumn;
|
||||||
|
int m_findScopeToColumn;
|
||||||
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;
|
||||||
int m_incrementalStartPos;
|
int m_incrementalStartPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2195,6 +2195,15 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
|
|||||||
text.replace(QChar::Nbsp, QLatin1Char(' '));
|
text.replace(QChar::Nbsp, QLatin1Char(' '));
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
int l = 1;
|
int l = 1;
|
||||||
|
|
||||||
|
int m_findScopeFirstColumn = 0;
|
||||||
|
if (!m_findScope.isNull() && m_findScopeVerticalBlockSelection) {
|
||||||
|
QTextCursor b = cursor;
|
||||||
|
cursor.setPosition(m_findScope.selectionStart());
|
||||||
|
m_findScopeFirstColumn = cursor.positionInBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
while (idx < text.length()) {
|
while (idx < text.length()) {
|
||||||
idx = m_searchExpr.indexIn(text, idx + l);
|
idx = m_searchExpr.indexIn(text, idx + l);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
@@ -2205,19 +2214,26 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
|
|||||||
|| (idx + l < text.length() && text.at(idx + l).isLetterOrNumber())))
|
|| (idx + l < text.length() && text.at(idx + l).isLetterOrNumber())))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_findScope.isNull()
|
if (!m_findScope.isNull()) {
|
||||||
|| (blockPosition + idx >= m_findScope.selectionStart()
|
if (blockPosition + idx < m_findScope.selectionStart()
|
||||||
&& blockPosition + idx + l <= m_findScope.selectionEnd())) {
|
|| blockPosition + idx + l > m_findScope.selectionEnd())
|
||||||
|
continue;
|
||||||
overlay->addOverlaySelection(blockPosition + idx,
|
if (m_findScopeVerticalBlockSelection) {
|
||||||
blockPosition + idx + l,
|
if (idx < m_findScopeFirstColumn
|
||||||
m_searchResultFormat.background().color().darker(120),
|
|| idx + l > m_findScopeFirstColumn + m_findScopeVerticalBlockSelection)
|
||||||
QColor(),
|
continue;
|
||||||
(idx == cursor.selectionStart() - blockPosition
|
}
|
||||||
&& idx + l == cursor.selectionEnd() - blockPosition)?
|
|
||||||
TextEditorOverlay::DropShadow : 0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
overlay->addOverlaySelection(blockPosition + idx,
|
||||||
|
blockPosition + idx + l,
|
||||||
|
m_searchResultFormat.background().color().darker(120),
|
||||||
|
QColor(),
|
||||||
|
(idx == cursor.selectionStart() - blockPosition
|
||||||
|
&& idx + l == cursor.selectionEnd() - blockPosition)?
|
||||||
|
TextEditorOverlay::DropShadow : 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2475,7 +2491,9 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
|
|||||||
|
|
||||||
TextEditorOverlay *overlay = new TextEditorOverlay(this);
|
TextEditorOverlay *overlay = new TextEditorOverlay(this);
|
||||||
overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120),
|
overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120),
|
||||||
d->m_searchScopeFormat.background().color());
|
d->m_searchScopeFormat.background().color(),
|
||||||
|
0,
|
||||||
|
d->m_findScopeVerticalBlockSelection);
|
||||||
overlay->setAlpha(false);
|
overlay->setAlpha(false);
|
||||||
overlay->paint(&painter, e->rect());
|
overlay->paint(&painter, e->rect());
|
||||||
delete overlay;
|
delete overlay;
|
||||||
@@ -4674,10 +4692,23 @@ void BaseTextEditor::highlightSearchResults(const QString &txt, Find::IFindSuppo
|
|||||||
d->m_delayedUpdateTimer->start(10);
|
d->m_delayedUpdateTimer->start(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTextEditor::setFindScope(const QTextCursor &scope)
|
int BaseTextEditor::verticalBlockSelection() const
|
||||||
|
{
|
||||||
|
if (!d->m_inBlockSelectionMode)
|
||||||
|
return 0;
|
||||||
|
QTextCursor b = textCursor();
|
||||||
|
QTextCursor e = b;
|
||||||
|
b.setPosition(b.selectionStart());
|
||||||
|
e.setPosition(e.selectionEnd());
|
||||||
|
|
||||||
|
return qAbs(b.positionInBlock() - e.positionInBlock()) + d->m_blockSelectionExtraX;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseTextEditor::setFindScope(const QTextCursor &scope, int verticalBlockSelection)
|
||||||
{
|
{
|
||||||
if (scope.isNull() != d->m_findScope.isNull()) {
|
if (scope.isNull() != d->m_findScope.isNull()) {
|
||||||
d->m_findScope = scope;
|
d->m_findScope = scope;
|
||||||
|
d->m_findScopeVerticalBlockSelection = verticalBlockSelection;
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5628,7 +5659,7 @@ BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor)
|
|||||||
BaseTextFind *baseTextFind = new BaseTextFind(editor);
|
BaseTextFind *baseTextFind = new BaseTextFind(editor);
|
||||||
connect(baseTextFind, SIGNAL(highlightAll(QString, Find::IFindSupport::FindFlags)),
|
connect(baseTextFind, SIGNAL(highlightAll(QString, Find::IFindSupport::FindFlags)),
|
||||||
editor, SLOT(highlightSearchResults(QString, Find::IFindSupport::FindFlags)));
|
editor, SLOT(highlightSearchResults(QString, Find::IFindSupport::FindFlags)));
|
||||||
connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor)), editor, SLOT(setFindScope(QTextCursor)));
|
connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor, int)), editor, SLOT(setFindScope(QTextCursor, int)));
|
||||||
aggregate->add(baseTextFind);
|
aggregate->add(baseTextFind);
|
||||||
aggregate->add(editor);
|
aggregate->add(editor);
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ private:
|
|||||||
class TEXTEDITOR_EXPORT BaseTextEditor : public QPlainTextEdit
|
class TEXTEDITOR_EXPORT BaseTextEditor : public QPlainTextEdit
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int verticalBlockSelection READ verticalBlockSelection)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseTextEditor(QWidget *parent);
|
BaseTextEditor(QWidget *parent);
|
||||||
@@ -382,6 +383,9 @@ public:
|
|||||||
|
|
||||||
void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet);
|
void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet);
|
||||||
|
|
||||||
|
|
||||||
|
int verticalBlockSelection() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setDisplayName(const QString &title);
|
void setDisplayName(const QString &title);
|
||||||
|
|
||||||
@@ -457,7 +461,7 @@ private slots:
|
|||||||
void memorizeCursorPosition();
|
void memorizeCursorPosition();
|
||||||
void restoreCursorPosition();
|
void restoreCursorPosition();
|
||||||
void highlightSearchResults(const QString &txt, Find::IFindSupport::FindFlags findFlags);
|
void highlightSearchResults(const QString &txt, Find::IFindSupport::FindFlags findFlags);
|
||||||
void setFindScope(const QTextCursor &);
|
void setFindScope(const QTextCursor &, int);
|
||||||
void currentEditorChanged(Core::IEditor *editor);
|
void currentEditorChanged(Core::IEditor *editor);
|
||||||
void maybeEmitContentsChangedBecauseOfUndo();
|
void maybeEmitContentsChangedBecauseOfUndo();
|
||||||
|
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ public:
|
|||||||
bool m_moveLineUndoHack;
|
bool m_moveLineUndoHack;
|
||||||
|
|
||||||
QTextCursor m_findScope;
|
QTextCursor m_findScope;
|
||||||
|
int m_findScopeVerticalBlockSelection;
|
||||||
QTextCursor m_selectBlockAnchor;
|
QTextCursor m_selectBlockAnchor;
|
||||||
|
|
||||||
void moveCursorVisible(bool ensureVisible = true);
|
void moveCursorVisible(bool ensureVisible = true);
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ 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;
|
||||||
@@ -97,6 +98,8 @@ 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();
|
||||||
}
|
}
|
||||||
@@ -104,9 +107,11 @@ 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
|
||||||
@@ -115,7 +120,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)
|
const QRect &clip, int verticalBlockSelection)
|
||||||
{
|
{
|
||||||
if (begin.isNull() || end.isNull() || begin.position() > end.position())
|
if (begin.isNull() || end.isNull() || begin.position() > end.position())
|
||||||
return QPainterPath();
|
return QPainterPath();
|
||||||
@@ -129,6 +134,7 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
|
|||||||
)
|
)
|
||||||
return QPainterPath(); // nothing of the selection is visible
|
return QPainterPath(); // nothing of the selection is visible
|
||||||
|
|
||||||
|
|
||||||
QTextBlock block = begin.block();
|
QTextBlock block = begin.block();
|
||||||
|
|
||||||
bool inSelection = false;
|
bool inSelection = false;
|
||||||
@@ -159,10 +165,12 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
|
|||||||
|
|
||||||
int beginChar = 0;
|
int beginChar = 0;
|
||||||
if (!inSelection) {
|
if (!inSelection) {
|
||||||
beginChar = begin.position() - begin.block().position();
|
beginChar = begin.positionInBlock();
|
||||||
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;
|
||||||
@@ -173,10 +181,12 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
|
|||||||
int lastLine = blockLayout->lineCount()-1;
|
int lastLine = blockLayout->lineCount()-1;
|
||||||
int endChar = -1;
|
int endChar = -1;
|
||||||
if (block == end.block()) {
|
if (block == end.block()) {
|
||||||
endChar = end.position() - end.block().position();
|
endChar = end.positionInBlock();
|
||||||
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())
|
||||||
@@ -197,7 +207,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 { // empty lines
|
} else if (!verticalBlockSelection){ // 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());
|
||||||
@@ -314,7 +324,8 @@ 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;
|
||||||
@@ -374,7 +385,8 @@ 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,7 +37,8 @@ namespace TextEditor {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
struct TEXTEDITOR_EXPORT OverlaySelection {
|
struct TEXTEDITOR_EXPORT OverlaySelection {
|
||||||
OverlaySelection():m_fixedLength(-1), m_dropShadow(false), m_expandBegin(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;
|
||||||
@@ -45,6 +46,7 @@ struct TEXTEDITOR_EXPORT OverlaySelection {
|
|||||||
int m_fixedLength;
|
int m_fixedLength;
|
||||||
bool m_dropShadow;
|
bool m_dropShadow;
|
||||||
bool m_expandBegin;
|
bool m_expandBegin;
|
||||||
|
int m_verticalBlockSelection;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT TextEditorOverlay : public QObject
|
class TEXTEDITOR_EXPORT TextEditorOverlay : public QObject
|
||||||
@@ -90,9 +92,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);
|
uint overlaySelectionFlags = 0, int verticalBlockSelection = 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);
|
uint overlaySelectionFlags = 0, int verticalBlockSelection = 0);
|
||||||
|
|
||||||
inline bool isEmpty() const { return m_selections.isEmpty(); }
|
inline bool isEmpty() const { return m_selections.isEmpty(); }
|
||||||
|
|
||||||
@@ -101,7 +103,8 @@ 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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user