📄 qtextcursor.cpp
字号:
\a text, for example: \code cursor.clearSelection(); cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); cursor.insertText("Hello World"); \endcode This clears any existing selection, selects the word at the cursor (i.e. from position() forward), and replaces the selection with the phrase "Hello World". Any ASCII linefeed characters (\\n) in the inserted text are transformed into unicode block separators, corresponding to insertBlock() calls. \sa charFormat() hasSelection()*/void QTextCursor::insertText(const QString &text){ QTextCharFormat fmt = charFormat(); fmt.clearProperty(QTextFormat::ObjectType); insertText(text, fmt);}/*! \overload Inserts \a text at the current position with the given \a format.*/void QTextCursor::insertText(const QString &text, const QTextCharFormat &format){ if (!d || !d->priv) return; Q_ASSERT(format.isValid()); d->priv->beginEditBlock(); d->remove(); if (!text.isEmpty()) { QTextFormatCollection *formats = d->priv->formatCollection(); int formatIdx = formats->indexForFormat(format); Q_ASSERT(formats->format(formatIdx).isCharFormat()); QTextBlockFormat blockFmt = blockFormat(); int textStart = 0; for (int i = 0; i < text.length(); ++i) { QChar ch = text.at(i); const int textEnd = i; if (ch == QLatin1Char('\r') && (i + 1) < text.length() && text.at(i + 1) == QLatin1Char('\n')) { ++i; ch = text.at(i); } if (ch == QLatin1Char('\n') || ch == QChar::ParagraphSeparator || ch == QLatin1Char('\r')) { if (textEnd > textStart) d->priv->insert(d->position, QString(text.unicode() + textStart, textEnd - textStart), formatIdx); textStart = i + 1; d->insertBlock(blockFmt, format); } } if (textStart < text.length()) d->priv->insert(d->position, QString(text.unicode() + textStart, text.length() - textStart), formatIdx); } d->priv->endEditBlock();}/*! If there is no selected text, deletes the character \e at the current cursor position; otherwise deletes the selected text. \sa deletePreviousChar() hasSelection() clearSelection()*/void QTextCursor::deleteChar(){ if (!d || !d->priv) return; if (d->position == d->anchor) { if (!d->canDelete(d->position)) return; d->adjusted_anchor = d->anchor = d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters); } d->remove(); d->setX();}/*! If there is no selected text, deletes the character \e before the current cursor position; otherwise deletes the selected text. \sa deleteChar() hasSelection() clearSelection()*/void QTextCursor::deletePreviousChar(){ if (!d || !d->priv) return; if (d->position == d->anchor) { if (d->anchor < 1 || !d->canDelete(d->anchor-1)) return; d->anchor--; QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); const QTextFragmentData * const frag = fragIt.value(); int fpos = fragIt.position(); QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { // second half of a surrogate, check if we have the first half as well, // if yes delete both at once uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) --d->anchor; } d->adjusted_anchor = d->anchor; } d->remove(); d->setX();}/*! Selects text in the document according to the given \a selection.*/void QTextCursor::select(SelectionType selection){ if (!d || !d->priv) return; clearSelection(); const QTextBlock block = d->block(); const int relativePos = d->position - block.position(); switch (selection) { case LineUnderCursor: movePosition(StartOfLine); movePosition(EndOfLine, KeepAnchor); break; case WordUnderCursor: if (relativePos == block.length() - 1) break; movePosition(StartOfWord); movePosition(EndOfWord, KeepAnchor); break; case BlockUnderCursor: movePosition(StartOfBlock); // also select the paragraph separator if (movePosition(PreviousBlock)) { movePosition(EndOfBlock); movePosition(NextBlock, KeepAnchor); } movePosition(EndOfBlock, KeepAnchor); break; }}/*! Returns true if the cursor contains a selection; otherwise returns false.*/bool QTextCursor::hasSelection() const{ return !!d && d->position != d->anchor;}/*! Returns true if the cursor contains a selection that is not simply a range from selectionStart() to selectionEnd(); otherwise returns false. Complex selections are ones that span at least two cells in a table; their extent is specified by selectedTableCells().*/bool QTextCursor::hasComplexSelection() const{ if (!d) return false; return d->complexSelectionTable() != 0;}/*! If the selection spans over table cells, \a firstRow is populated with the number of the first row in the selection, \a firstColumn with the number of the first column in the selection, and \a numRows and \a numColumns with the number of rows and columns in the selection. If the selection does not span any table cells the results are harmless but undefined.*/void QTextCursor::selectedTableCells(int *firstRow, int *numRows, int *firstColumn, int *numColumns) const{ *firstRow = -1; *firstColumn = -1; *numRows = -1; *numColumns = -1; if (!d || d->position == d->anchor) return; d->selectedTableCells(firstRow, numRows, firstColumn, numColumns);}/*! Clears the current selection. Note that it does \bold{not} delete the text of the selection. \sa removeSelectedText() hasSelection()*/void QTextCursor::clearSelection(){ if (!d) return; d->adjusted_anchor = d->anchor = d->position; d->currentCharFormat = -1;}/*! If there is a selection, its content is deleted; otherwise does nothing. \sa hasSelection()*/void QTextCursor::removeSelectedText(){ if (!d || !d->priv || d->position == d->anchor) return; d->remove(); d->setX();}/*! Returns the start of the selection or position() if the cursor doesn't have a selection. \sa selectionEnd() position() anchor()*/int QTextCursor::selectionStart() const{ if (!d || !d->priv) return -1; return qMin(d->position, d->adjusted_anchor);}/*! Returns the end of the selection or position() if the cursor doesn't have a selection. \sa selectionStart() position() anchor()*/int QTextCursor::selectionEnd() const{ if (!d || !d->priv) return -1; return qMax(d->position, d->adjusted_anchor);}static void getText(QString &text, QTextDocumentPrivate *priv, const QString &docText, int pos, int end){ while (pos < end) { QTextDocumentPrivate::FragmentIterator fragIt = priv->find(pos); const QTextFragmentData * const frag = fragIt.value(); const int offsetInFragment = qMax(0, pos - fragIt.position()); const int len = qMin(int(frag->size - offsetInFragment), end - pos); text += QString(docText.constData() + frag->stringPosition + offsetInFragment, len); pos += len; }}/*! Returns the current selection's text (which may be empty). This only returns the text, with no rich text formatting information. If you want a document fragment (i.e. formatted rich text) use selection() instead.*/QString QTextCursor::selectedText() const{ if (!d || !d->priv || d->position == d->anchor) return QString(); const QString docText = d->priv->buffer(); QString text; QTextTable *table = d->complexSelectionTable(); if (table) { int row_start, col_start, num_rows, num_cols; selectedTableCells(&row_start, &num_rows, &col_start, &num_cols); Q_ASSERT(row_start != -1); for (int r = row_start; r < row_start + num_rows; ++r) { for (int c = col_start; c < col_start + num_cols; ++c) { QTextTableCell cell = table->cellAt(r, c); int rspan = cell.rowSpan(); int cspan = cell.columnSpan(); if (rspan != 1) { int cr = cell.row(); if (cr != r) continue; } if (cspan != 1) { int cc = cell.column(); if (cc != c) continue; } getText(text, d->priv, docText, cell.firstPosition(), cell.lastPosition()); } } } else { getText(text, d->priv, docText, selectionStart(), selectionEnd()); } return text;}/*! Returns the current selection (which may be empty) with all its formatting information. If you just want the selected text (i.e. plain text) use selectedText() instead.*/QTextDocumentFragment QTextCursor::selection() const{ return QTextDocumentFragment(*this);}/*! Returns the block that contains the cursor.*/QTextBlock QTextCursor::block() const{ if (!d || !d->priv) return QTextBlock(); return d->block();}/*! Returns the block format of the block the cursor is in. \sa setBlockFormat() charFormat() */QTextBlockFormat QTextCursor::blockFormat() const{ if (!d || !d->priv) return QTextBlockFormat(); return d->block().blockFormat();}/*! Sets the block format of the current block (or all blocks that are contained in the selection) to \a format. \sa blockFormat()*/void QTextCursor::setBlockFormat(const QTextBlockFormat &format){ if (!d || !d->priv) return; d->setBlockFormat(format, QTextDocumentPrivate::SetFormat);}/*! Modifies the block format of the current block (or all blocks that are contained in the selection) with the block format specified by \a modifier. \sa setBlockFormat()*/void QTextCursor::mergeBlockFormat(const QTextBlockFormat &modifier){ if (!d || !d->priv) return; d->setBlockFormat(modifier, QTextDocumentPrivate::MergeFormat);}/*! Returns the block character format of the block the cursor is in. The block char format is the format used when inserting text at the beginning of a block. \sa setBlockCharFormat() */QTextCharFormat QTextCursor::blockCharFormat() const{ if (!d || !d->priv) return QTextCharFormat(); return d->block().charFormat();}/*! Sets the block char format of the current block (or all blocks that are contained in the selection) to \a format. \sa blockCharFormat()*/void QTextCursor::setBlockCharFormat(const QTextCharFormat &format){ if (!d || !d->priv) return; d->setBlockCharFormat(format, QTextDocumentPrivate::SetFormat);}/*! Modifies the block char format of the current block (or all blocks that are contained in the selection) with the block format specified by \a modifier. \sa setBlockCharFormat()*/void QTextCursor::mergeBlockCharFormat(const QTextCharFormat &modifier){ if (!d || !d->priv) return; d->setBlockCharFormat(modifier, QTextDocumentPrivate::MergeFormat);}/*! Returns the format of the character immediately before the cursor position(). \sa insertText(), blockFormat() */QTextCharFormat QTextCursor::charFormat() const{ if (!d || !d->priv) return QTextCharFormat(); int idx = d->currentCharFormat; if (idx == -1) { int pos = d->position - 1; if (pos == -1) { idx = d->priv->blockCharFormatIndex(d->priv->blockMap().firstNode()); } else { Q_ASSERT(pos >= 0 && pos < d->priv->length()); QTextDocumentPrivate::FragmentIterator it = d->priv->find(pos); Q_ASSERT(!it.atEnd()); idx = it.value()->format; } } QTextCharFormat cfmt = d->priv->formatCollection()->charFormat(idx); cfmt.clearProperty(QTextFormat::ObjectIndex); Q_ASSERT(cfmt.isValid()); return cfmt;}/*! Set the character format to the given \a format for the current selection. Does nothing if the cursor does not have a selection. \sa hasSelection()*/void QTextCursor::setCharFormat(const QTextCharFormat &format){ if (!d || !d->priv) return; if (d->position == d->anchor) { d->currentCharFormat = d->priv->formatCollection()->indexForFormat(format); return; } d->setCharFormat(format, QTextDocumentPrivate::SetFormat);}/*! Applies all the properties set in \a modifier to all the character formats that are part of the selection. Does nothing if the cursor does not have a selection. \sa hasSelection()*/void QTextCursor::mergeCharFormat(const QTextCharFormat &modifier){ if (!d || !d->priv) return; if (d->position == d->anchor) { QTextCharFormat format = charFormat(); format.merge(modifier); d->currentCharFormat = d->priv->formatCollection()->indexForFormat(format); return; } d->setCharFormat(modifier, QTextDocumentPrivate::MergeFormat);}/*! Returns true if the cursor is at the start of a block; otherwise returns false.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -