/*! * \brief ModelicaEditor::getPlainText * Reads the leading spaces information from the text block user data and inserts them to the actual string. * \return */ QString ModelicaEditor::getPlainText() { if (mpModelWidget->getLibraryTreeItem()->isInPackageOneFile()) { QString text; QTextBlock block = mpPlainTextEdit->document()->firstBlock(); while (block.isValid()) { TextBlockUserData *pTextBlockUserData = BaseEditorDocumentLayout::userData(block); if (pTextBlockUserData) { if (pTextBlockUserData->getLeadingSpaces() == -1) { TextBlockUserData *pFirstBlockUserData = BaseEditorDocumentLayout::userData(mpPlainTextEdit->document()->firstBlock()); if (pFirstBlockUserData) { pTextBlockUserData->setLeadingSpaces(pFirstBlockUserData->getLeadingSpaces()); } else { pTextBlockUserData->setLeadingSpaces(0); } } text += QString(pTextBlockUserData->getLeadingSpaces(), ' '); } text += block.text(); block = block.next(); if (block.isValid()) { // not last block text += "\n"; } } return text; } else { return mpPlainTextEdit->toPlainText(); } }
void TikzEditor::showMatchingBrackets() { for (QTextBlock block = firstVisibleBlock(); block.isValid(); block = block.next()) { if (blockBoundingGeometry(block).top() > viewport()->height()) break; const QString text = block.text(); const int textLength = text.length(); for (int i = 0; i < textLength; ++i) { if (block.position() + i == m_matchingBegin || block.position() + i == m_matchingEnd) { QList<QTextEdit::ExtraSelection> extraSelectionList = extraSelections(); if (!isReadOnly()) { QTextEdit::ExtraSelection selection; selection.format.setBackground(m_matchingColor); selection.cursor = textCursor(); selection.cursor.setPosition(block.position() + i, QTextCursor::MoveAnchor); selection.cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); extraSelectionList.append(selection); } setExtraSelections(extraSelectionList); } } } }
/************************************************* // Function: PaintLineNumberArea // Description: 绘制左侧行号区域 // Calls: // Called By: CLineNumberArea::paintEvent // Parameter: QPaintEvent *event // Return: void // Others: 通过CLineNumberArea类的paintEvent函数来调用本函数, 以保证能够实时更新该行数 *************************************************/ void CCodeEditor::PaintLineNumberArea(QPaintEvent *event) { QPainter painter(m_lineNumberArea); painter.fillRect(event->rect(), Qt::lightGray); /*行数背景颜色*/ QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); /*当前行(从0开始)*/ int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top() + fontMetrics().descent();/*绘制区域的顶部*/ int bottom = top + (int)blockBoundingRect(block).height(); /*绘制区域的底部*/ /*绘制可见区域*/ while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QString number = QString::number(blockNumber + 1); painter.setPen(Qt::black); /*行号颜色*/ painter.drawText(0, top, m_lineNumberArea->width(), fontMetrics().height(), Qt::AlignCenter, number); } block = block.next(); top = bottom; bottom = top + (int)blockBoundingRect(block).height(); ++blockNumber; } }
void CppCodeStylePreferencesWidget::updatePreview() { CppCodeStylePreferences *cppCodeStylePreferences = m_preferences ? m_preferences : CppToolsSettings::instance()->cppCodeStyle(); const CppCodeStyleSettings ccss = cppCodeStylePreferences->currentCodeStyleSettings(); const TextEditor::TabSettings ts = cppCodeStylePreferences->currentTabSettings(); QtStyleCodeFormatter formatter(ts, ccss); foreach (TextEditor::SnippetEditorWidget *preview, m_previews) { preview->setTabSettings(ts); preview->setCodeStyle(cppCodeStylePreferences); QTextDocument *doc = preview->document(); formatter.invalidateCache(doc); QTextBlock block = doc->firstBlock(); QTextCursor tc = preview->textCursor(); tc.beginEditBlock(); while (block.isValid()) { preview->indenter()->indentBlock(doc, block, QChar::Null, ts); block = block.next(); } tc.endEditBlock(); }
bool TextBlockUserData::findNextBlockClosingParenthesis(QTextCursor *cursor) { QTextBlock block = cursor->block(); int position = cursor->position(); int ignore = 0; while (block.isValid()) { Parentheses parenList = BaseTextDocumentLayout::parentheses(block); if (!parenList.isEmpty() && !BaseTextDocumentLayout::ifdefedOut(block)) { for (int i = 0; i < parenList.count(); ++i) { Parenthesis paren = parenList.at(i); if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-') && paren.chr != QLatin1Char('[') && paren.chr != QLatin1Char(']')) continue; if (block == cursor->block() && (position - block.position() > paren.pos - (paren.type == Parenthesis::Opened ? 1 : 0))) continue; if (paren.type == Parenthesis::Opened) { ++ignore; } else if (ignore > 0) { --ignore; } else { cursor->setPosition(block.position() + paren.pos+1); return true; } } } block = block.next(); } return false; }
void TikzEditor::printWhiteSpaces(QPainter &painter) { const QFontMetrics fontMetrics = QFontMetrics(document()->defaultFont()); for (QTextBlock block = firstVisibleBlock(); block.isValid(); block = block.next()) { if (blockBoundingGeometry(block).top() > viewport()->height()) break; const QString text = block.text(); const int textLength = text.length(); for (int i = 0; i < textLength; ++i) { QTextCursor cursor = textCursor(); cursor.setPosition(block.position() + i, QTextCursor::MoveAnchor); const QRect rect = cursorRect(cursor); // const QFontMetrics fontMetrics = QFontMetrics(cursor.charFormat().font()); if (m_showWhiteSpaces && text.at(i) == ' ') paintSpace(painter, rect.x() + spaceWidth() / 2.0, rect.y() + fontMetrics.height() / 2.0); else if (m_showTabulators && text.at(i) == '\t') paintTabstop(painter, rect.x() + spaceWidth() / 2.0, rect.y() + fontMetrics.height() / 2.0); } } }
//! Activated whenever LineNumberArea Widget paint event is raised. //! Writes the line numbers for the visible blocks. void ModelicaEditor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(mpLineNumberArea); painter.fillRect(event->rect(), QColor(240, 240, 240)); QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); int bottom = top + (int) blockBoundingRect(block).height(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QString number = QString::number(blockNumber + 1); // make the current highlighted line number darker if (blockNumber == textCursor().blockNumber()) { painter.setPen(QColor(64, 64, 64)); } else { painter.setPen(Qt::gray); } painter.setFont(document()->defaultFont()); QFontMetrics fontMetrics (document()->defaultFont()); painter.drawText(0, top, mpLineNumberArea->width() - 5, fontMetrics.height(), Qt::AlignRight, number); } block = block.next(); top = bottom; bottom = top + (int) blockBoundingRect(block).height(); ++blockNumber; } }
void GenericCodeEditor::updateCurrentLineHighlighting() { int currentCursorBlock = textCursor().blockNumber(); int first_block_num = qMin(mLastCursorBlock, currentCursorBlock); int second_block_num = qMax(mLastCursorBlock, currentCursorBlock); QRegion region(0,0,0,0); QTextBlock block = firstVisibleBlock(); int block_num = block.blockNumber(); qreal top = blockBoundingGeometry(block).translated(contentOffset()).top(); qreal max_top = viewport()->rect().bottom(); while (block.isValid() && block_num <= second_block_num && top <= max_top) { QRectF block_rect = blockBoundingRect(block); if (block_num == first_block_num || block_num == second_block_num) { region += block_rect.translated(0, top).toRect(); } top += block_rect.height(); block = block.next(); ++block_num; } viewport()->update( region ); }
void CppQtStyleIndenter::indent(QTextDocument *doc, const QTextCursor &cursor, const QChar &typedChar, const TextEditor::TabSettings &tabSettings) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next(); CppTools::QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings()); codeFormatter.updateStateUntil(block); QTextCursor tc = cursor; tc.beginEditBlock(); do { int indent; int padding; codeFormatter.indentFor(block, &indent, &padding); tabSettings.indentLine(block, indent + padding, padding); codeFormatter.updateLineStateChange(block); block = block.next(); } while (block.isValid() && block != end); tc.endEditBlock(); } else { indentBlock(doc, cursor.block(), typedChar, tabSettings); } }
void DevHighlighter::reformatBlocks(int from, int charsRemoved, int charsAdded) { QTextBlock block = doc->findBlock(from); if (!block.isValid()) return; QTextBlock endBlock; if (charsAdded > charsRemoved || charsAdded == charsRemoved) endBlock = doc->findBlock(from + charsAdded); else endBlock = block; bool forceHighlightOfNextBlock = false; while (block.isValid() && (!(endBlock < block) || forceHighlightOfNextBlock) ) { const int stateBeforeHighlight = block.userState(); reformatBlock(block); forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight); block = block.next(); } formatChanges.clear(); }
int GenericCodeEditor::findAll( const QRegExp &expr, QTextDocument::FindFlags options ) { mSearchSelections.clear(); if(expr.isEmpty()) { this->updateExtraSelections(); return 0; } QTextEdit::ExtraSelection selection; selection.format = mSearchResultTextFormat; QTextDocument *doc = QPlainTextEdit::document(); QTextBlock block = doc->begin(); QTextCursor cursor; while (block.isValid()) { int blockPos = block.position(); int offset = 0; while(findInBlock(doc, block, expr, offset, options, cursor)) { offset = cursor.selectionEnd() - blockPos; if (cursor.hasSelection()) { selection.cursor = cursor; mSearchSelections.append(selection); } else offset += 1; } block = block.next(); } this->updateExtraSelections(); return mSearchSelections.count(); }
void CodeHighlighter::updateFormatting(QTextDocument* _document, CodeHighlighterSettings const& _settings) { QTextBlock block = _document->firstBlock(); QList<QTextLayout::FormatRange> ranges; Formats::const_iterator format = m_formats.begin(); while (true) { while ((format == m_formats.end() || (block.position() + block.length() <= format->start)) && block.isValid()) { auto layout = block.layout(); layout->clearAdditionalFormats(); layout->setAdditionalFormats(ranges); _document->markContentsDirty(block.position(), block.length()); block = block.next(); ranges.clear(); } if (!block.isValid()) break; int intersectionStart = std::max(format->start, block.position()); int intersectionLength = std::min(format->start + format->length, block.position() + block.length()) - intersectionStart; if (intersectionLength > 0) { QTextLayout::FormatRange range; range.format = _settings.formats[format->token]; range.start = format->start - block.position(); range.length = format->length; ranges.append(range); } ++format; } }
void TextEditor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); // painter.fillRect(event->rect(), Qt::black); QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); int bottom = top + (int) blockBoundingRect(block).height(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QString number = QString::number(blockNumber + 1); painter.setPen(Qt::darkGray); painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); } block = block.next(); top = bottom; bottom = top + (int) blockBoundingRect(block).height(); ++blockNumber; } }
static int findClosingMatch(const QTextDocument *doc, int cursorPosition) { QTextBlock block = doc->findBlock(cursorPosition); JSBlockData *blockData = reinterpret_cast<JSBlockData*>(block.userData()); if (!blockData->bracketPositions.isEmpty()) { int depth = 1; while (block.isValid()) { blockData = reinterpret_cast<JSBlockData*>(block.userData()); if (blockData && !blockData->bracketPositions.isEmpty()) { for (int c = 0; c < blockData->bracketPositions.count(); ++c) { int absPos = block.position() + blockData->bracketPositions.at(c); if (absPos <= cursorPosition) continue; if (doc->characterAt(absPos) == '{') depth++; else depth--; if (depth == 0) return absPos; } } block = block.next(); } } return -1; }
void Text::spatiumChanged(qreal oldVal, qreal newVal) { Element::spatiumChanged(oldVal, newVal); if (!sizeIsSpatiumDependent() || styled()) return; qreal v = newVal / oldVal; QTextCursor c(_doc); QTextBlock cb = _doc->begin(); while (cb.isValid()) { QTextBlock::iterator i(cb.begin()); for (; !i.atEnd(); ++i) { QTextFragment f = i.fragment(); if (f.isValid()) { int pos = f.position(); int len = f.length(); c.setPosition(pos, QTextCursor::MoveAnchor); c.setPosition(pos + len, QTextCursor::KeepAnchor); QTextCharFormat cf = c.charFormat(); QFont font = cf.font(); font.setPointSizeF(font.pointSizeF() * v); cf.setFont(font); c.setCharFormat(cf); } } cb = cb.next(); } }
void MarginWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.fillRect(event->rect(), Qt::transparent); QTextBlock block = m_sourceViewer->firstVisibleBlock(); int top = m_sourceViewer->blockBoundingGeometry(block).translated(m_sourceViewer->contentOffset()).top(); int bottom = (top + m_sourceViewer->blockBoundingRect(block).height()); const int right = (width() - 5); const int selectionStart = m_sourceViewer->document()->findBlock(m_sourceViewer->textCursor().selectionStart()).blockNumber(); const int selectionEnd = m_sourceViewer->document()->findBlock(m_sourceViewer->textCursor().selectionEnd()).blockNumber(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QColor textColor(palette().color(QPalette::Text)); textColor.setAlpha((block.blockNumber() >= selectionStart && block.blockNumber() <= selectionEnd) ? 250 : 150); painter.setPen(textColor); painter.drawText(0, top, right, fontMetrics().height(), Qt::AlignRight, QString::number(block.blockNumber() + 1)); } block = block.next(); top = bottom; bottom = (top + m_sourceViewer->blockBoundingRect(block).height()); } }
bool CodeEditor::matchLeftParenthesis(QTextBlock currentBlock, int i, int numLeftParentheses) { TextBlockData *data = static_cast<TextBlockData *>(currentBlock.userData()); QVector<ParenthesisInfo *> infos = data->parentheses(); int docPos = currentBlock.position(); for (; i < infos.size(); ++i) { ParenthesisInfo *info = infos.at(i); if (info->character == '(') { ++numLeftParentheses; continue; } if (info->character == ')' && numLeftParentheses == 0) { createParenthesisSelection(docPos + info->position); return true; } else --numLeftParentheses; } currentBlock = currentBlock.next(); if (currentBlock.isValid()) return matchLeftParenthesis(currentBlock, 0, numLeftParentheses); return false; }
void GenericCodeEditor::paintEvent( QPaintEvent *event ) { if (mHighlightCurrentLine) { int cursor_block_num = textCursor().blockNumber(); QTextBlock block = firstVisibleBlock(); int block_num = block.blockNumber(); qreal top = blockBoundingGeometry(block).translated(contentOffset()).top(); qreal max_top = event->rect().bottom(); while (block.isValid() && block_num <= cursor_block_num && top <= max_top) { QRectF block_rect = blockBoundingRect(block); if (block_num == cursor_block_num) { QPainter painter(viewport()); painter.fillRect( block_rect.translated(0, top), mCurrentLineTextFormat.background().color() ); painter.end(); break; } top += block_rect.height(); block = block.next(); ++block_num; } } QPlainTextEdit::paintEvent(event); }
bool AutoCompleter::isNextBlockIndented(const QTextBlock ¤tBlock) const { QTextBlock block = currentBlock; int indentation = m_tabSettings.indentationColumn(block.text()); if (block.next().isValid()) { // not the last block block = block.next(); //skip all empty blocks while (block.isValid() && m_tabSettings.onlySpace(block.text())) block = block.next(); if (block.isValid() && m_tabSettings.indentationColumn(block.text()) > indentation) return true; } return false; }
int TikzEditor::numOfLines() const { int num = 0; QTextBlock p; for (p = document()->begin(); p.isValid(); p = p.next()) ++num; return num; }
void HGMarkdownHighlighter::clearFormatting() { QTextBlock block = document->firstBlock(); while (block.isValid()) { block.layout()->clearAdditionalFormats(); block = block.next(); } }
/** utility: fetch text in range from a text document */ QString ParenMatching::range::plainText(QTextDocument *doc) const { QString x; QTextBlock b = doc->findBlock(beg), e = doc->findBlock(end); QTextStream s(&x); if (b != e) { s << b.text().mid(b.position() - beg) << endl; for (b = b.next(); b != e; b = b.next()) s << b.text() << endl; s << b.text().left(end - b.position()); } else s << b.text().mid(b.position() - beg, end - beg); return x; }
///Indique si on est à la dernière ligne bool RzxTextEdit::atEnd() const { QTextBlock block = textCursor().block(); if(block.next().isValid()) return false; QTextLine line = currentTextLine(); return line.isValid() && line.lineNumber() == block.layout()->lineCount() - 1; }
void TestDocumentLayout::testBasicList() { initForNewTest("Base\nListItem\nListItem2: The quick brown fox jums over the lazy dog.\nNormal\nNormal"); KoParagraphStyle style; QTextBlock block = m_doc->begin(); style.applyStyle(block); block = block.next(); QVERIFY(block.isValid()); KoListStyle listStyle; KoListLevelProperties level1; level1.setStyle(KoListStyle::Bullet); listStyle.setLevelProperties(level1); style.setListStyle(&listStyle); style.applyStyle(block); // make this a listStyle QVERIFY(block.textList()); QCOMPARE(block.textList()->format().intProperty(QTextListFormat::ListStyle), (int) KoListStyle::Bullet); block = block.next(); QVERIFY(block.isValid()); style.applyStyle(block); // make this a listStyle m_layout->layout(); QTextLayout *blockLayout = m_block.layout(); QCOMPARE(blockLayout->lineAt(0).x(), 0.0); block = m_doc->begin().next(); QVERIFY(block.isValid()); blockLayout = block.layout(); // parag 2 KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); qreal counterSpacing = data->counterSpacing(); QVERIFY(counterSpacing > 0.); // 12 is hardcoded to be the width of a discitem (taken from the default font): QCOMPARE(blockLayout->lineAt(0).x(), 12.0 + counterSpacing); block = block.next(); QVERIFY(block.isValid()); blockLayout = block.layout(); // parag 3 QCOMPARE(blockLayout->lineAt(0).x(), 12.0 + counterSpacing); QVERIFY(blockLayout->lineCount() > 1); QCOMPARE(blockLayout->lineAt(1).x(), 12.0 + counterSpacing); // make sure not only the first line is indented block = block.next(); QVERIFY(block.isValid()); blockLayout = block.layout(); // parag 4 QCOMPARE(blockLayout->lineAt(0).x(), 0.0); }
void DevLineNumber::paintEvent(QPaintEvent *e) { const QPixmap pm[] ={ QPixmap(":/break.png"), QPixmap(":/error.png") }; int n = 1, contentsY = editor->verticalScrollBar()->value(); qreal pageBottom = contentsY + editor->viewport()->height(); const QFontMetrics fm( editor->document()->defaultFont() ); QPainter p(this); for (QTextBlock block = editor->document()->begin(); block.isValid(); block = block.next(), ++n ) { QTextLayout *layout = block.layout(); const QRectF boundingRect = layout->boundingRect(); QPointF position = layout->position(); if (position.y() + boundingRect.height() < contentsY) continue; if (position.y() > pageBottom) break; int posY = qRound(position.y()); BlockData *dat = BlockData::data(block); const QString txt = QString::number(n); p.drawText( 0, posY - contentsY, width(), fm.lineSpacing(), Qt::AlignRight | Qt::AlignVCenter, txt); if ( !dat ) continue; int x = 0; if ( dat->s & BlockData::BreakPoint ) p.drawPixmap( 15*(x++), posY - contentsY +(fm.lineSpacing() - (*pm).height())/2, (*pm).width(), (*pm).height(), *pm); if ( dat->s & BlockData::Error ) p.drawPixmap( 15*(x++), posY - contentsY +(fm.lineSpacing() - pm[1].height())/2, pm[1].width(), pm[1].height(), pm[1]); } }
/** Automatically indents the QTextDocument doc by using indent/outdent regular expressions. @todo The expressions are currently hardcoded and used to indent XQuery, XML and XSLT documents. */ void AutoIndent::indentDocument(QTextDocument *doc) { int level = 0; QList<QRegExp> indentRules; indentRules.append( QRegExp( "<\\w+[^>]*[^/]>" ) ); indentRules.append( QRegExp( "\\{" ) ); //indentRules.append( QRegExp( "(for|return)" ) ); QRegExp outdentRule( "(\\}|</[^>])" ); QString tNew; for ( QTextBlock block = doc->firstBlock(); block.isValid(); block = block.next() ) { QString t = block.text().trimmed(); const int indentCount = matchCount( indentRules, t ); level += indentCount; const int outdentCount = matchCount( outdentRule, t ); level -= outdentCount; if (level < 0) level = 0; if ( !t.isEmpty() ) // don't indent empty lines { const bool foundIndent = (indentCount > 0); // const bool foundOutdent = (outdentCount > 0); if ( foundIndent ) indent(t, level - indentCount + outdentCount); // don't indent start tag (stays on current level) else indent(t, level); // we are in an indent block } // line break when not the last line if ( block.next().isValid() ) t += "\n"; // add to result tNew += t; //tNew.prepend( QString("[%1 , %2] : ").arg(indentCount, 2).arg(outdentCount, 2); } doc->setPlainText(tNew); }
void TextDocumentPrivate::resetRevisions() { TextDocumentLayout *documentLayout = qobject_cast<TextDocumentLayout*>(m_document.documentLayout()); QTC_ASSERT(documentLayout, return); documentLayout->lastSaveRevision = m_document.revision(); for (QTextBlock block = m_document.begin(); block.isValid(); block = block.next()) block.setRevision(documentLayout->lastSaveRevision); }
// Set the alignment of all blocks to the given alignment void setAlignment(Qt::Alignment align) { QTextDocument* textDocument = document(); for (QTextBlock it = textDocument->begin(); it != textDocument->end(); it = it.next()) { QTextCursor cur(it); QTextBlockFormat format = cur.blockFormat(); format.setAlignment(align); cur.setBlockFormat(format); } }
void Editor::clearAllBookmarks() { int line = 1; for ( QTextBlock block = m_textEdit->document()->begin(); block.isValid(); block = block.next(), line++ ) { BlockUserData *blockUserData = ( BlockUserData* ) block.userData(); if ( blockUserData && blockUserData->bookmark ) toggleBookmark ( line ); } }
bool NCEdit::isFolded(int line) const { QTextBlock block = document()->findBlockByNumber(line - 1); if (!block.isValid()) return false; block = block.next(); if (!block.isValid()) return false; return !block.isVisible(); }