aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/texteditor/tabsettings.cpp9
-rw-r--r--src/plugins/texteditor/tabsettings.h2
-rw-r--r--src/plugins/texteditor/textdocument.cpp121
-rw-r--r--src/plugins/texteditor/textdocument.h6
-rw-r--r--src/plugins/texteditor/texteditor.cpp31
5 files changed, 112 insertions, 57 deletions
diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp
index 9a075f25af6..edc04739a35 100644
--- a/src/plugins/texteditor/tabsettings.cpp
+++ b/src/plugins/texteditor/tabsettings.cpp
@@ -198,12 +198,13 @@ int TabSettings::columnAt(const QString &text, int position) const
return column;
}
-int TabSettings::positionAtColumn(const QString &text, int column, int *offset) const
+int TabSettings::positionAtColumn(const QString &text, int column, int *offset, bool allowOverstep) const
{
int col = 0;
int i = 0;
- while (i < text.size() && col < column) {
- if (text.at(i) == QLatin1Char('\t'))
+ int textSize = text.size();
+ while ((i < textSize || allowOverstep) && col < column) {
+ if (i < textSize && text.at(i) == QLatin1Char('\t'))
col = col - (col % m_tabSize) + m_tabSize;
else
++col;
@@ -228,6 +229,8 @@ int TabSettings::columnCountForText(const QString &text, int startColumn) const
int TabSettings::spacesLeftFromPosition(const QString &text, int position)
{
+ if (position >= text.size())
+ return 0;
int i = position;
while (i > 0) {
if (!text.at(i-1).isSpace())
diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h
index 0522b026838..37d41f925e3 100644
--- a/src/plugins/texteditor/tabsettings.h
+++ b/src/plugins/texteditor/tabsettings.h
@@ -70,7 +70,7 @@ public:
int lineIndentPosition(const QString &text) const;
int columnAt(const QString &text, int position) const;
- int positionAtColumn(const QString &text, int column, int *offset = 0) const;
+ int positionAtColumn(const QString &text, int column, int *offset = 0, bool allowOverstep = false) const;
int columnCountForText(const QString &text, int startColumn = 0) const;
int indentedColumn(int column, bool doIndent = true) const;
QString indentationString(int startColumn, int targetColumn, const QTextBlock &currentBlock = QTextBlock()) const;
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index 3d5b0680314..dc3d7b4d522 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -87,7 +87,8 @@ public:
{
}
- QTextCursor indentOrUnindent(const QTextCursor &textCursor, bool doIndent);
+ QTextCursor indentOrUnindent(const QTextCursor &textCursor, bool doIndent,
+ bool blockSelection = false, int column = 0, int *offset = 0);
void resetRevisions();
void updateRevisions();
@@ -111,56 +112,84 @@ public:
TextMarks m_marksCache; // Marks not owned
};
-QTextCursor TextDocumentPrivate::indentOrUnindent(const QTextCursor &textCursor, bool doIndent)
+QTextCursor TextDocumentPrivate::indentOrUnindent(const QTextCursor &textCursor, bool doIndent,
+ bool blockSelection, int columnIn, int *offset)
{
QTextCursor cursor = textCursor;
cursor.beginEditBlock();
- if (cursor.hasSelection()) {
- // Indent or unindent the selected lines
- int pos = cursor.position();
- int anchor = cursor.anchor();
- int start = qMin(anchor, pos);
- int end = qMax(anchor, pos);
-
- QTextBlock startBlock = m_document.findBlock(start);
- QTextBlock endBlock = m_document.findBlock(end-1).next();
-
- if (startBlock.next() == endBlock
- && (start > startBlock.position() || end < endBlock.position() - 1)) {
- // Only one line partially selected.
+ TabSettings &ts = m_tabSettings;
+
+ // Indent or unindent the selected lines
+ int pos = cursor.position();
+ int column = blockSelection ? columnIn
+ : ts.columnAt(cursor.block().text(), cursor.positionInBlock());
+ int anchor = cursor.anchor();
+ int start = qMin(anchor, pos);
+ int end = qMax(anchor, pos);
+ bool modified = true;
+
+ QTextBlock startBlock = m_document.findBlock(start);
+ QTextBlock endBlock = m_document.findBlock(end).next();
+
+ const bool oneLinePartial = (startBlock.next() == endBlock)
+ && (start > startBlock.position() || end < endBlock.position() - 1);
+
+ // Make sure one line selection will get processed in "for" loop
+ if (startBlock == endBlock)
+ endBlock = endBlock.next();
+
+ if (cursor.hasSelection() && !blockSelection && !oneLinePartial) {
+ for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
+ const QString text = block.text();
+ int indentPosition = ts.lineIndentPosition(text);
+ if (!doIndent && !indentPosition)
+ indentPosition = ts.firstNonSpace(text);
+ int targetColumn = ts.indentedColumn(ts.columnAt(text, indentPosition), doIndent);
+ cursor.setPosition(block.position() + indentPosition);
+ cursor.insertText(ts.indentationString(0, targetColumn, block));
+ cursor.setPosition(block.position());
+ cursor.setPosition(block.position() + indentPosition, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
- } else {
- for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
- QString text = block.text();
- int indentPosition = m_tabSettings.lineIndentPosition(text);
- if (!doIndent && !indentPosition)
- indentPosition = m_tabSettings.firstNonSpace(text);
- int targetColumn = m_tabSettings.indentedColumn(m_tabSettings.columnAt(text, indentPosition), doIndent);
- cursor.setPosition(block.position() + indentPosition);
- cursor.insertText(m_tabSettings.indentationString(0, targetColumn, block));
- cursor.setPosition(block.position());
- cursor.setPosition(block.position() + indentPosition, QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
+ modified = false;
+ }
+ } else if (cursor.hasSelection() && !blockSelection && oneLinePartial) {
+ // Only one line partially selected.
+ cursor.removeSelectedText();
+ } else {
+ // Indent or unindent at cursor position
+ for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
+ QString text = block.text();
+
+ int blockColumn = ts.columnAt(text, text.size());
+ if (blockColumn < column) {
+ cursor.setPosition(block.position() + text.size());
+ cursor.insertText(ts.indentationString(blockColumn, column, block));
+ text = block.text();
}
- cursor.endEditBlock();
- return textCursor;
+
+ int indentPosition = ts.positionAtColumn(text, column, 0, true);
+ int spaces = ts.spacesLeftFromPosition(text, indentPosition);
+ int startColumn = ts.columnAt(text, indentPosition - spaces);
+ int targetColumn = ts.indentedColumn(ts.columnAt(text, indentPosition), doIndent);
+ cursor.setPosition(block.position() + indentPosition);
+ cursor.setPosition(block.position() + indentPosition - spaces, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ cursor.insertText(ts.indentationString(startColumn, targetColumn, block));
+ }
+ // Preserve initial anchor of block selection
+ if (blockSelection) {
+ end = cursor.position();
+ if (offset)
+ *offset = ts.columnAt(cursor.block().text(), cursor.positionInBlock()) - column;
+ cursor.setPosition(start);
+ cursor.setPosition(end, QTextCursor::KeepAnchor);
}
}
- // Indent or unindent at cursor position
- QTextBlock block = cursor.block();
- QString text = block.text();
- int indentPosition = cursor.positionInBlock();
- int spaces = m_tabSettings.spacesLeftFromPosition(text, indentPosition);
- int startColumn = m_tabSettings.columnAt(text, indentPosition - spaces);
- int targetColumn = m_tabSettings.indentedColumn(m_tabSettings.columnAt(text, indentPosition), doIndent);
- cursor.setPosition(block.position() + indentPosition);
- cursor.setPosition(block.position() + indentPosition - spaces, QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
- cursor.insertText(m_tabSettings.indentationString(startColumn, targetColumn, block));
cursor.endEditBlock();
- return cursor;
+
+ return modified ? cursor : textCursor;
}
void TextDocumentPrivate::resetRevisions()
@@ -359,14 +388,16 @@ void TextDocument::autoReindent(const QTextCursor &cursor)
d->m_indenter->reindent(&d->m_document, cursor, d->m_tabSettings);
}
-QTextCursor TextDocument::indent(const QTextCursor &cursor)
+QTextCursor TextDocument::indent(const QTextCursor &cursor, bool blockSelection, int column,
+ int *offset)
{
- return d->indentOrUnindent(cursor, true);
+ return d->indentOrUnindent(cursor, true, blockSelection, column, offset);
}
-QTextCursor TextDocument::unindent(const QTextCursor &cursor)
+QTextCursor TextDocument::unindent(const QTextCursor &cursor, bool blockSelection, int column,
+ int *offset)
{
- return d->indentOrUnindent(cursor, false);
+ return d->indentOrUnindent(cursor, false, blockSelection, column, offset);
}
const ExtraEncodingSettings &TextDocument::extraEncodingSettings() const
diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h
index 56715d2c9fd..987e1bcdffe 100644
--- a/src/plugins/texteditor/textdocument.h
+++ b/src/plugins/texteditor/textdocument.h
@@ -89,8 +89,10 @@ public:
Indenter *indenter() const;
void autoIndent(const QTextCursor &cursor, QChar typedChar = QChar::Null);
void autoReindent(const QTextCursor &cursor);
- QTextCursor indent(const QTextCursor &cursor);
- QTextCursor unindent(const QTextCursor &cursor);
+ QTextCursor indent(const QTextCursor &cursor, bool blockSelection = false, int column = 0,
+ int *offset = 0);
+ QTextCursor unindent(const QTextCursor &cursor, bool blockSelection = false, int column = 0,
+ int *offset = 0);
TextMarks marks() const;
bool addMark(TextMark *mark);
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index b7f5302fef9..514130aabcc 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -1495,12 +1495,26 @@ void TextEditorWidget::lowercaseSelection()
void TextEditorWidget::indent()
{
- setTextCursor(textDocument()->indent(textCursor()));
+ int offset = 0;
+ doSetTextCursor(textDocument()->indent(textCursor(), d->m_inBlockSelectionMode,
+ d->m_blockSelection.positionColumn, &offset),
+ d->m_inBlockSelectionMode);
+ if (d->m_inBlockSelectionMode) {
+ d->m_blockSelection.anchorColumn += offset;
+ d->m_blockSelection.positionColumn += offset;
+ }
}
void TextEditorWidget::unindent()
{
- setTextCursor(textDocument()->unindent(textCursor()));
+ int offset = 0;
+ doSetTextCursor(textDocument()->unindent(textCursor(), d->m_inBlockSelectionMode,
+ d->m_blockSelection.positionColumn, &offset),
+ d->m_inBlockSelectionMode);
+ if (d->m_inBlockSelectionMode) {
+ d->m_blockSelection.anchorColumn += offset;
+ d->m_blockSelection.positionColumn += offset;
+ }
}
void TextEditorWidget::undo()
@@ -2254,10 +2268,15 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
}
d->m_document->autoIndent(cursor);
} else {
- if (e->key() == Qt::Key_Tab)
- indent();
- else
- unindent();
+ if (d->m_inBlockSelectionMode
+ && d->m_blockSelection.firstVisualColumn() != d->m_blockSelection.lastVisualColumn()) {
+ d->removeBlockSelection();
+ } else {
+ if (e->key() == Qt::Key_Tab)
+ indent();
+ else
+ unindent();
+ }
}
e->accept();
return;