BaseTextDocument::~BaseTextDocument() { QTextBlock block = m_document->begin(); while (block.isValid()) { if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) data->documentClosing(); block = block.next(); } delete m_document; m_document = 0; }
qreal Text::baseLine() const { if (styled()) return SimpleText::baseLine(); for (QTextBlock tb = _doc->begin(); tb.isValid(); tb = tb.next()) { const QTextLayout* tl = tb.layout(); if (tl->lineCount()) return (tl->lineAt(0).ascent() + tl->position().y()); } return 0.0; }
/*! * \brief ModelicaEditor::storeLeadingSpaces * Stores the leading spaces information in the text block user data. * \param leadingSpacesMap */ void ModelicaEditor::storeLeadingSpaces(QMap<int, int> leadingSpacesMap) { QTextBlock block = mpPlainTextEdit->document()->firstBlock(); while (block.isValid()) { TextBlockUserData *pTextBlockUserData = BaseEditorDocumentLayout::userData(block); if (pTextBlockUserData) { pTextBlockUserData->setLeadingSpaces(leadingSpacesMap.value(block.blockNumber() + 1, 0)); } block = block.next(); } }
QList<int> Editor::bookmarksList() { QList<int> list; 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 ) list << line; } return list; }
bool VMdEditor::scrollToBlock(int p_blockNumber) { QTextBlock block = document()->findBlockByNumber(p_blockNumber); if (block.isValid()) { VEditUtils::scrollBlockInPage(this, block.blockNumber(), 0); moveCursor(QTextCursor::EndOfBlock); return true; } return false; }
int ExpressionUnderCursor::previousBlockState(const QTextBlock &block) { const QTextBlock prevBlock = block.previous(); if (prevBlock.isValid()) { int state = prevBlock.userState(); if (state != -1) return state; } return 0; }
void TestDocumentLayout::testRestartNumbering() { // create 5 items; restart the 3th. Check numbering. initForNewTest("a\nb\na\nb\nc"); KoParagraphStyle h1; m_styleManager->add(&h1); KoListStyle listStyle; KoListLevelProperties llp; llp.setStyle(KoListStyle::DecimalItem); llp.setStartValue(1); listStyle.setLevelProperties(llp); h1.setListStyle(&listStyle); QTextBlock block = m_doc->begin(); while (block.isValid()) { h1.applyStyle(block); block = block.next(); } QTextCursor cursor(m_doc); cursor.setPosition(5); QCOMPARE(cursor.block().text(), QString("a")); QTextBlockFormat format = cursor.blockFormat(); format.setProperty(KoParagraphStyle::RestartListNumbering, true); cursor.setBlockFormat(format); m_layout->layout(); static const char *const values[] = { "1", "2", "1", "2", "3" }; block = m_doc->begin(); int i = 0; while (block.isValid()) { KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); // qDebug() << data->counterText() << QString(values[i]); QCOMPARE(data->counterText(), QString(values[i++])); block = block.next(); } }
QString LiteEditorWidget::cursorToHtml(QTextCursor cursor) const { QTextDocument *tempDocument = new QTextDocument; QTextCursor tempCursor(tempDocument); tempCursor.insertFragment(cursor.selection()); // Apply the additional formats set by the syntax highlighter QTextBlock start = document()->findBlock(cursor.selectionStart()); QTextBlock end = document()->findBlock(cursor.selectionEnd()); end = end.next(); const int selectionStart = cursor.selectionStart(); const int endOfDocument = tempDocument->characterCount() - 1; for (QTextBlock current = start; current.isValid() && current != end; current = current.next()) { const QTextLayout *layout = current.layout(); foreach (const QTextLayout::FormatRange &range, layout->additionalFormats()) { const int start = current.position() + range.start - selectionStart; const int end = start + range.length; if (end <= 0 || start >= endOfDocument) continue; tempCursor.setPosition(qMax(start, 0)); tempCursor.setPosition(qMin(end, endOfDocument), QTextCursor::KeepAnchor); tempCursor.setCharFormat(range.format); } } // Reset the user states since they are not interesting for (QTextBlock block = tempDocument->begin(); block.isValid(); block = block.next()) block.setUserState(-1); // Make sure the text appears pre-formatted tempCursor.setPosition(0); tempCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); QTextBlockFormat blockFormat = tempCursor.blockFormat(); blockFormat.setNonBreakableLines(true); tempCursor.setBlockFormat(blockFormat); QString html = tempCursor.selection().toHtml();//("utf-8"); html.replace("\t","    "); delete tempDocument; return html; }
int TikzEditor::getCursorPosition(int row, int col) const { int i = 0; QTextBlock p = document()->begin(); while (p.isValid()) { if (row == i) break; i++; p = p.next(); } return p.position() + col; }
int CMakeIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) { QTextBlock previousBlock = block.previous(); // find the next previous block that is non-empty (contains non-whitespace characters) while (previousBlock.isValid() && lineIsEmpty(previousBlock.text())) previousBlock = previousBlock.previous(); if (!previousBlock.isValid()) return 0; const QString previousLine = previousBlock.text(); const QString currentLine = block.text(); int indentation = tabSettings.indentationColumn(previousLine); if (lineStartsBlock(previousLine)) indentation += tabSettings.m_indentSize; if (lineEndsBlock(currentLine)) indentation = qMax(0, indentation - tabSettings.m_indentSize); // increase/decrease/keep the indentation level depending on if we have more opening or closing parantheses return qMax(0, indentation + tabSettings.m_indentSize * paranthesesLevel(previousLine)); }
void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(mLineNumberArea); QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); int bottom = top + (int) blockBoundingRect(block).height(); int startBlock = textCursor().blockNumber(); int endBlock = textCursor().blockNumber(); if(textCursor().hasSelection()) { QString str = textCursor().selection().toPlainText(); int selectedLines = str.count("\n")+1; if(textCursor().position() < textCursor().anchor()) endBlock += selectedLines; else startBlock -= selectedLines; } painter.setBackgroundMode(Qt::OpaqueMode); QFont font = painter.font(); QBrush background = painter.background(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QFont newFont = painter.font(); QString number = QString::number(blockNumber + 1); if(blockNumber >= startBlock && blockNumber <= endBlock) { painter.setBackground(Qt::cyan); painter.setPen(Qt::darkMagenta); newFont.setBold(true); } else { painter.setBackground(background); painter.setPen(Qt::black); } painter.setFont(newFont); painter.drawText(0, top, mLineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); painter.setFont(font); } block = block.next(); top = bottom; bottom = top + (int) blockBoundingRect(block).height(); ++blockNumber; } }
void GenericCodeEditor::paintLineIndicator( QPaintEvent *e ) { QPalette plt( mLineIndicator->palette() ); QRect r( e->rect() ); QPainter p( mLineIndicator ); p.fillRect( r, plt.color( QPalette::Button ) ); p.setPen( plt.color(QPalette::ButtonText) ); p.drawLine( r.topRight(), r.bottomRight() ); QTextDocument *doc = QPlainTextEdit::document(); QTextCursor cursor(textCursor()); int selStartBlock, selEndBlock; if (cursor.hasSelection()) { selStartBlock = doc->findBlock(cursor.selectionStart()).blockNumber(); selEndBlock = doc->findBlock(cursor.selectionEnd()).blockNumber(); } else selStartBlock = selEndBlock = -1; QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); qreal top = blockBoundingGeometry(block).translated(contentOffset()).top(); qreal bottom = top + blockBoundingRect(block).height(); while (block.isValid() && top <= e->rect().bottom()) { if (block.isVisible() && bottom >= e->rect().top()) { p.save(); QRectF numRect( 0, top, mLineIndicator->width() - 1, bottom - top ); int num = blockNumber; if (num >= selStartBlock && num <= selEndBlock) { num -= selStartBlock; p.setPen(Qt::NoPen); p.setBrush(plt.color(QPalette::Highlight)); p.drawRect(numRect); p.setPen(plt.color(QPalette::HighlightedText)); } QString number = QString::number(num + 1); p.drawText(0, top, mLineIndicator->width() - 4, bottom - top, Qt::AlignRight, number); p.restore(); } block = block.next(); top = bottom; bottom = top + blockBoundingRect(block).height(); ++blockNumber; } }
void CodeEditor::keyPressEvent(QKeyEvent *e) { // SHIFT+TAB kommt hier nie an aus nicht nachvollziehbaren Grnden. Auch in event und viewPortEvent nicht. // NOTE: Qt macht daraus automatisch BackTab und versendet das! if( e->key() == Qt::Key_Tab ) { if( e->modifiers() & Qt::ControlModifier ) { // Wir brauchen CTRL+TAB fr Umschalten der Scripts e->ignore(); return; } if( !isReadOnly() && ( hasSelection() || textCursor().position() <= _firstNwsPos( textCursor().block() ) ) ) { if( e->modifiers() == Qt::NoModifier ) { indent(); e->accept(); return; } } }else if( e->key() == Qt::Key_Backtab ) { if( e->modifiers() & Qt::ControlModifier ) { // Wir brauchen CTRL+TAB fr Umschalten der Scripts e->ignore(); return; } if( !isReadOnly() && ( hasSelection() || textCursor().position() <= _firstNwsPos( textCursor().block() ) ) ) { unindent(); e->accept(); return; } }else if( !isReadOnly() && ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return ) ) { e->accept(); if( e->modifiers() != Qt::NoModifier ) return; // Verschlucke Return mit Ctrl etc. textCursor().beginEditBlock(); QPlainTextEdit::keyPressEvent( e ); // Lasse Qt den neuen Block einfgen QTextBlock prev = textCursor().block().previous(); if( prev.isValid() ) { const int ws = _firstNwsPos( prev ); textCursor().insertText( prev.text().left( ws - prev.position() ) ); } textCursor().endEditBlock(); return; } QPlainTextEdit::keyPressEvent( e ); }
void LineNumberArea::paintEvent(QPaintEvent *) { if ( !codeEditor->lineAreaVisble() ) return; QPainter painter(this); painter.fillRect(rect(), Qt::lightGray); //code based partly on: http://john.nachtimwald.com/2009/08/15/qtextedit-with-line-numbers/ QTextBlock block = codeEditor->document()->begin(); int contents_y = codeEditor->verticalScrollBar()->value(); int page_bottom = contents_y + codeEditor->viewport()->height(); QTextBlock current_block = codeEditor->document()->findBlock(codeEditor->textCursor().position()); int line_count = 0; painter.setPen(QColor(Qt::darkGray).darker()); // not exactly black bool bold; QFont font = painter.font(); while (block.isValid()) { line_count += 1; QString number = QString::number(line_count); QPointF position = codeEditor->document()->documentLayout()->blockBoundingRect(block).topLeft(); if (position.y() > page_bottom) break; int y = round(position.y()) - contents_y + codeEditor->fontMetrics().ascent(); if (y>=0) { // the line is visible if (block == current_block) { bold = true; font.setBold(true); painter.setFont(font); } painter.drawText(codeEditor->getAreaWidth() - codeEditor->fontMetrics().width(number) - 3, y, number); // 3 - add some padding if (bold) { font.setBold(false); painter.setFont(font); } if (m_debugLines.indexOf(line_count) >= 0) { painter.setPen(QColor(Qt::red)); painter.setBrush(QColor(Qt::red)); int height = codeEditor->fontMetrics().ascent() ; painter.drawEllipse(position.x(), y - height, height, height); painter.setBrush(QBrush()); painter.setPen(QColor(Qt::darkGray).darker()); // not exactly black } if (m_currentDebugLine >= 0 && line_count == m_currentDebugLine) { QImage image("://themes/boring/gtk-media-play-ltr.png"); painter.drawImage(position.x(), y, image); } } block = block.next(); } }
int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) { QTextBlock block = cursor.block(); const QString text = block.text().trimmed(); if (text == "end" || text == "else" || text.startsWith("elsif") || text.startsWith("rescue") || text == "ensure") { Indenter indenter(const_cast<QTextDocument*>(block.document())); indenter.indentBlock(block, QChar(), tabSettings()); } return 0; // This implementation is buggy #if 0 const QString textFromCursor = text.mid(cursor.positionInBlock()).trimmed(); if (!textFromCursor.isEmpty()) return 0; if (Language::symbolDefinition.indexIn(text) == -1 && Language::startOfBlock.indexIn(text) == -1) { return 0; } int spaces = 0; for (const QChar c : text) { if (!c.isSpace()) break; spaces++; } QString indent = text.left(spaces); QString line; QTextBlock nextBlock = block.next(); while (nextBlock.isValid()) { line = nextBlock.text(); if (Language::endKeyword.indexIn(line) != -1 && line.startsWith(indent)) return 0; if (!line.trimmed().isEmpty()) break; nextBlock = nextBlock.next(); } int pos = cursor.position(); cursor.insertBlock(); cursor.insertText("end"); cursor.setPosition(pos); return 1; #endif }
FontDia::FontDia(QTextCursor* cursor, QWidget* parent) : KDialog(parent), m_cursor(cursor) { //First find out if we have more than one charFormat in our selection. If so, m_initialFormat/m_style will get initialised with the charFormat at the cursor's position. The tabs will get informed of this. if (m_cursor->hasSelection()) { int begin = qMin(m_cursor->anchor(), m_cursor->position()); int end = qMax(m_cursor->anchor(), m_cursor->position()); QTextBlock block = m_cursor->block().document()->findBlock(begin); m_uniqueFormat = true; QTextCursor caret(*m_cursor); caret.setPosition(begin+1); m_initialFormat = caret.charFormat(); while (block.isValid() && block.position() < end) { QTextBlock::iterator iter = block.begin(); while (! iter.atEnd()) { QTextFragment fragment = iter.fragment(); if (fragment.position() >= end) break; if (fragment.position() + fragment.length() <= begin) { iter++; continue; } if (!(m_uniqueFormat = (fragment.charFormat() == m_initialFormat))) break; iter++; } if (!m_uniqueFormat) break; block = block.next(); } } else { m_initialFormat = cursor->charFormat(); m_uniqueFormat = true; } setCaption(i18n("Select Font")); setModal(true); setButtons(Ok | Cancel | Reset | Apply); setDefaultButton(Ok); m_characterGeneral = new CharacterGeneral(this, m_uniqueFormat); m_characterGeneral->hideStyleName(true); setMainWidget(m_characterGeneral); connect(this, SIGNAL(applyClicked()), this, SLOT(slotApply())); connect(this, SIGNAL(okClicked()), this, SLOT(slotOk())); connect(this, SIGNAL(resetClicked()), this, SLOT(slotReset())); initTabs(); }
void CodeEditer::indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(qMin(cursor.selectionStart(), cursor.selectionEnd())); const QTextBlock end = doc->findBlock(qMax(cursor.selectionStart(), cursor.selectionEnd())).next(); do { indentBlock(doc, block, typedChar); block = block.next(); } while (block.isValid() && block != end); } else { indentBlock(doc, cursor.block(), typedChar); } }
/*! Installs the syntax highlighter on the given QTextDocument \a doc. A QSyntaxHighlighter can only be used with one document at a time. */ void QSyntaxHighlighter::setDocument(QTextDocument *doc) { Q_D(QSyntaxHighlighter); if (d->doc) { disconnect(d->doc, SIGNAL(contentsChange(int,int,int)), this, SLOT(_q_reformatBlocks(int,int,int))); QTextCursor cursor(d->doc); cursor.beginEditBlock(); for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next()) blk.layout()->clearAdditionalFormats(); cursor.endEditBlock(); }
QTextLine TabTerminal::_currentTextLine(const QTextCursor & cursor) { const QTextBlock block = cursor.block(); if (!block.isValid()) return QTextLine(); const QTextLayout *layout = block.layout(); if (!layout) return QTextLine(); const int relativePos = cursor.position() - block.position(); return layout->lineForTextPosition(relativePos); }
///Retourne un QTextLine indiquant la position du curseur QTextLine RzxTextEdit::currentTextLine() const { const QTextBlock block = textCursor().block(); if (!block.isValid()) return QTextLine(); const QTextLayout *layout = block.layout(); if (!layout) return QTextLine(); const int relativePos = textCursor().position() - block.position(); return layout->lineForTextPosition(relativePos); }
int BackwardsScanner::previousBlockState(const QTextBlock &block) { const QTextBlock prevBlock = block.previous(); if (prevBlock.isValid()) { int state = prevBlock.userState(); if (state != -1) return state; } return 0; }
void CPPEditorDocument::applyFontSettings() { if (TextEditor::SyntaxHighlighter *highlighter = syntaxHighlighter()) { // Clear all additional formats since they may have changed QTextBlock b = document()->firstBlock(); while (b.isValid()) { QList<QTextLayout::FormatRange> noFormats; highlighter->setExtraAdditionalFormats(b, noFormats); b = b.next(); } } BaseTextDocument::applyFontSettings(); // rehighlights and updates additional formats }
// Reset the header state of a here-doc to 7 // and the state of its body to 6. void Highlighter::resetHereDocStates (QTextBlock block) { if (block.userState() == hereDocTempState) { block.setUserState (hereDocHeaderState); block = block.next(); while (block.isValid() && block.userState() != 0) { block.setUserState (hereDocBodyState); block = block.next(); } } }
bool convertPosition(const QTextDocument *document, int pos, int *line, int *column) { QTextBlock block = document->findBlock(pos); if (!block.isValid()) { (*line) = -1; (*column) = -1; return false; } else { (*line) = block.blockNumber() + 1; (*column) = pos - block.position(); return true; } }
static void indent(QTextDocument *doc, const QTextCursor &cursor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); QTextBlock last = doc->findBlock(cursor.selectionEnd()); do { indent(doc, block); block = block.next(); } while (block.isValid() && block < last); } else { indent(doc, cursor.block()); } }
QString GitEditorWidget::fileNameForLine(int line) const { // 7971b6e7 share/qtcreator/dumper/dumper.py (hjk QTextBlock block = document()->findBlockByLineNumber(line - 1); QTC_ASSERT(block.isValid(), return source()); static QRegExp renameExp(QLatin1String("^" CHANGE_PATTERN "\\s+([^(]+)")); if (renameExp.indexIn(block.text()) != -1) { const QString fileName = renameExp.cap(1).trimmed(); if (!fileName.isEmpty()) return fileName; } return source(); }
int ScCodeEditor::indentationLevel(const QTextCursor & cursor) { QTextDocument *doc = QPlainTextEdit::document(); int startBlockNum = doc->findBlock(cursor.selectionStart()).blockNumber(); QStack<int> stack; int level = 0; int blockNum = 0; QTextBlock block = QPlainTextEdit::document()->begin(); while (block.isValid()) { if (level > 0) { stack.push(level); level = 0; } TextBlockData *data = static_cast<TextBlockData*>(block.userData()); if (data) { int count = data->tokens.size(); for (int idx = 0; idx < count; ++idx) { const Token & token = data->tokens[idx]; switch (token.type) { case Token::OpeningBracket: if (token.character != '(' || stack.size() || token.positionInBlock) level += 1; break; case Token::ClosingBracket: if (level) level -= 1; else if(!stack.isEmpty()) { stack.top() -= 1; if (stack.top() <= 0) stack.pop(); } break; default: ; } } } if (blockNum == startBlockNum) return stack.size(); block = block.next(); ++blockNum; } return -1; }
/* Returns the recommended indent for the bottom line of yyProgram assuming that it starts in a C-style comment, a condition that is tested elsewhere. Essentially, we're trying to align against some text on the previous line. */ int QmlJSIndenter::indentWhenBottomLineStartsInMultiLineComment() { QTextBlock block = yyProgram.lastBlock().previous(); QString blockText; for (; block.isValid(); block = block.previous()) { blockText = block.text(); if (! isOnlyWhiteSpace(blockText)) break; } return indentOfLine(blockText); }
QString GitEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const { // Check for "+++ b/src/plugins/git/giteditor.cpp" (blame and diff) // Go back chunks. const QString newFileIndicator = QLatin1String("+++ b/"); for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) { QString diffFileName = block.text(); if (diffFileName.startsWith(newFileIndicator)) { diffFileName.remove(0, newFileIndicator.size()); return findDiffFile(diffFileName, GitPlugin::instance()->versionControl()); } } return QString(); }
void CodeFormatter::saveCurrentState(const QTextBlock &block) { if (!block.isValid()) return; BlockData blockData; blockData.m_blockRevision = block.revision(); blockData.m_beginState = m_beginState; blockData.m_endState = m_currentState; blockData.m_indentDepth = m_indentDepth; QTextBlock saveableBlock(block); saveBlockData(&saveableBlock, blockData); }