void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const TabSettings &tabSettings) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next(); // skip empty blocks while (block.isValid() && block != end) { QString bt = block.text(); if (tabSettings.firstNonSpace(bt) < bt.size()) break; indentBlock(doc, block, QChar::Null, tabSettings); block = block.next(); } int previousIndentation = tabSettings.indentationColumn(block.text()); indentBlock(doc, block, QChar::Null, tabSettings); int currentIndentation = tabSettings.indentationColumn(block.text()); int delta = currentIndentation - previousIndentation; block = block.next(); while (block.isValid() && block != end) { tabSettings.reindentLine(block, delta); block = block.next(); } } else { indentBlock(doc, cursor.block(), QChar::Null, tabSettings); } }
int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor, const TabSettings &tabSettings) { if (!m_autoParenthesesEnabled) return 0; QTextDocument *doc = cursor.document(); if (doc->characterAt(cursor.position() - 1) != QLatin1Char('{')) return 0; if (!contextAllowsAutoParentheses(cursor)) return 0; // verify that we indeed do have an extra opening brace in the document QTextBlock block = cursor.block(); const QString textFromCusror = block.text().mid(cursor.positionInBlock()).trimmed(); int braceDepth = TextDocumentLayout::braceDepth(doc->lastBlock()); if (braceDepth <= 0 && (textFromCusror.isEmpty() || textFromCusror.at(0) != QLatin1Char('}'))) return 0; // braces are all balanced or worse, no need to do anything and separator inserted not between '{' and '}' // we have an extra brace , let's see if we should close it /* verify that the next block is not further intended compared to the current block. This covers the following case: if (condition) {| statement; */ int indentation = tabSettings.indentationColumn(block.text()); if (block.next().isValid()) { // not the last block block = block.next(); //skip all empty blocks while (block.isValid() && tabSettings.onlySpace(block.text())) block = block.next(); if (block.isValid() && tabSettings.indentationColumn(block.text()) > indentation) return 0; } const QString &textToInsert = insertParagraphSeparator(cursor); int pos = cursor.position(); cursor.insertBlock(); cursor.insertText(textToInsert); cursor.setPosition(pos); // if we actually insert a separator, allow it to be overwritten if // user types it if (!textToInsert.isEmpty()) m_allowSkippingOfBlockEnd = true; return 1; }
QTextCursor BaseTextBlockSelection::selection(const TabSettings &ts) const { QTextCursor cursor = firstBlock; if (anchor <= TopRight) { cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn)); cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn), QTextCursor::KeepAnchor); } else { cursor.setPosition(firstBlock.block().position() + ts.positionAtColumn(firstBlock.block().text(), firstVisualColumn)); cursor.setPosition(lastBlock.block().position() + ts.positionAtColumn(lastBlock.block().text(), lastVisualColumn), QTextCursor::KeepAnchor); } return cursor; }
void BaseTextBlockSelection::fromSelection(const TabSettings &ts, const QTextCursor &selection) { firstBlock = selection; firstBlock.setPosition(selection.selectionStart()); firstVisualColumn = ts.columnAt(firstBlock.block().text(), firstBlock.positionInBlock()); lastBlock = selection; lastBlock.setPosition(selection.selectionEnd()); lastVisualColumn = ts.columnAt(lastBlock.block().text(), lastBlock.positionInBlock()); if (selection.anchor() > selection.position()) anchor = TopLeft; else anchor = BottomRight; firstBlock.movePosition(QTextCursor::StartOfBlock); lastBlock.movePosition(QTextCursor::EndOfBlock); }
void Indenter::indentBlock(QTextDocument *doc, const QTextBlock &block, const QChar &typedChar, const TabSettings &tabSettings) { Q_UNUSED(doc); Q_UNUSED(typedChar); const int indent = indentFor(block, tabSettings); if (indent < 0) return; tabSettings.indentLine(block, indent); }
int NormalIndenter::indentFor(const QTextBlock &block, const TabSettings &tabSettings) { Q_UNUSED(tabSettings); QTextBlock previous = block.previous(); if (!previous.isValid()) return 0; const QString previousText = previous.text(); // Empty line indicates a start of a new paragraph. Leave as is. if (previousText.isEmpty() || previousText.trimmed().isEmpty()) return 0; return tabSettings.indentationColumn(previousText); }
int BaseTextBlockSelection::position(const TabSettings &ts) const { const QTextBlock &block = anchor <= TopRight ? lastBlock.block() : firstBlock.block(); const int column = anchor % 2 ? firstVisualColumn : lastVisualColumn; return block.position() + ts.positionAtColumn(block.text(), column); }