本文整理汇总了C++中QTextBlock::length方法的典型用法代码示例。如果您正苦于以下问题:C++ QTextBlock::length方法的具体用法?C++ QTextBlock::length怎么用?C++ QTextBlock::length使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QTextBlock
的用法示例。
在下文中一共展示了QTextBlock::length方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: formatAtCursor
void ClangFormat::formatAtCursor()
{
const TextEditor::TextEditorWidget *widget
= TextEditor::TextEditorWidget::currentTextEditorWidget();
if (!widget)
return;
const QTextCursor tc = widget->textCursor();
if (tc.hasSelection()) {
const int offset = tc.selectionStart();
const int length = tc.selectionEnd() - offset;
BeautifierPlugin::formatCurrentFile(command(offset, length));
} else {
// Pretend that the current line was selected.
// Note that clang-format will extend the range to the next bigger
// syntactic construct if needed.
const QTextBlock block = tc.block();
const int offset = block.position();
const int length = block.length();
BeautifierPlugin::formatCurrentFile(command(offset, length));
}
}
示例2: processBlock
void XmlWriter::processBlock(QDomElement &parent, const QTextBlock &block)
{
QDomElement blockElement = document->createElement("block");
blockElement.setAttribute("position", block.position());
blockElement.setAttribute("length", block.length());
parent.appendChild(blockElement);
QTextBlock::iterator it;
for (it = block.begin(); !(it.atEnd()); ++it) {
QTextFragment fragment = it.fragment();
if (fragment.isValid()) {
QDomElement fragmentElement = document->createElement("fragment");
blockElement.appendChild(fragmentElement);
fragmentElement.setAttribute("length", fragment.length());
QDomText fragmentText = document->createTextNode(fragment.text());
fragmentElement.appendChild(fragmentText);
}
}
}
示例3: upperCase
void Changecase::upperCase()
{
QTextBlock block = m_document->findBlock(m_startPosition);
int pos = block.position();
bool finished = false;
bool foundToBeChanged = false;
while (true) {
QString text = block.text();
QString result;
QString::ConstIterator constIter = text.constBegin();
while (pos < m_endPosition && constIter != text.constEnd()) {
if (pos >= m_startPosition) {
if (!foundToBeChanged && constIter->isLower())
foundToBeChanged = true;
result.append(constIter->toUpper());
}
pos++;
constIter++;
}
if (!(block.isValid() && block.position() + block.length() < m_endPosition))
finished = true;
if (foundToBeChanged) {
m_cursor.setPosition(qMax(m_startPosition, block.position()));
m_cursor.setPosition(qMin(pos, m_endPosition), QTextCursor::KeepAnchor);
m_cursor.insertText(result);
}
if (finished)
break;
block = block.next();
pos = block.position();
}
}
示例4: isInComment
bool QssCompletionAssistProcessor::isInComment() const
{
QTextBlock block = m_interface->textDocument()->findBlock(m_interface->position());
QTextBlock prevBlock = block.previous();
QList<Token> tokenList;
Lexer lexer;
lexer.setScanComments(true);
if (prevBlock.isValid())
lexer.setState(qssLexerState(prevBlock.userState()));
tokenList = lexer.scanMore(block.text());
int index = m_interface->position() - block.position();
Q_FOREACH (const Token &t, tokenList) {
if (t.is(Token::Comment) && index >= t.begin() && index < t.end()) {
qDebug() << "InComment";
return true;
}
}
if (index == block.length() && (lexer.state() & Lexer::MultiLineComment)) {
qDebug() << "InComment";
return true;
}
return false;
}
示例5: updateTextCursor
void QmlJSOutlineWidget::updateTextCursor(const QModelIndex &index)
{
QModelIndex sourceIndex = m_filterModel->mapToSource(index);
AST::SourceLocation location
= m_editor->qmlJsEditorDocument()->outlineModel()->sourceLocation(sourceIndex);
if (!location.isValid())
return;
const QTextBlock lastBlock = m_editor->document()->lastBlock();
const uint textLength = lastBlock.position() + lastBlock.length();
if (location.offset >= textLength)
return;
Core::EditorManager::cutForwardNavigationHistory();
Core::EditorManager::addCurrentPositionToNavigationHistory();
QTextCursor textCursor = m_editor->textCursor();
m_blockCursorSync = true;
textCursor.setPosition(location.offset);
m_editor->setTextCursor(textCursor);
m_editor->centerCursor();
m_blockCursorSync = false;
}
示例6: getFirstAndLastVisiblePosition
QPair<int, int> getFirstAndLastVisiblePosition(Editor *editor)
{
QTextCursor cursor = editor->textCursor();
QTextDocument *doc = editor->document();
int currentLine = doc->findBlock(cursor.position()).blockNumber();
int cursorHeight = editor->cursorRect().height();
int lineCountToFirstVisibleLine = editor->cursorRect().top() / cursorHeight;
int firstVisibleLineNum = currentLine - lineCountToFirstVisibleLine;
if (firstVisibleLineNum < 0) {
firstVisibleLineNum = 0;
}
int maxLineNumOnScreen = (editor->viewport()->height() / cursorHeight);
if (maxLineNumOnScreen < 1) {
maxLineNumOnScreen = 1;
}
int firstPos = doc->findBlockByNumber(firstVisibleLineNum).position();
int lastVisibleLineNum = firstVisibleLineNum + maxLineNumOnScreen - 1;
QTextBlock lastVisibleTextBlock = doc->findBlockByNumber(lastVisibleLineNum);
if (!lastVisibleTextBlock.isValid()) {
lastVisibleTextBlock = doc->lastBlock();
}
int lastPos = lastVisibleTextBlock.position() + lastVisibleTextBlock.length() - 1;
return QPair<int, int>(firstPos, lastPos);
}
示例7: highlight
void HGMarkdownHighlighter::highlight()
{
if (cached_elements == NULL) {
qDebug() << "cached_elements is NULL";
return;
}
if (highlightingStyles == NULL)
this->setDefaultStyles();
this->clearFormatting();
for (int i = 0; i < highlightingStyles->size(); i++)
{
HighlightingStyle style = highlightingStyles->at(i);
pmh_element *elem_cursor = cached_elements[style.type];
while (elem_cursor != NULL)
{
if (elem_cursor->end <= elem_cursor->pos) {
elem_cursor = elem_cursor->next;
continue;
}
// "The QTextLayout object can only be modified from the
// documentChanged implementation of a QAbstractTextDocumentLayout
// subclass. Any changes applied from the outside cause undefined
// behavior." -- we are breaking this rule here. There might be
// a better (more correct) way to do this.
int startBlockNum = document->findBlock(elem_cursor->pos).blockNumber();
int endBlockNum = document->findBlock(elem_cursor->end).blockNumber();
for (int j = startBlockNum; j <= endBlockNum; j++)
{
QTextBlock block = document->findBlockByNumber(j);
QTextLayout *layout = block.layout();
QList<QTextLayout::FormatRange> list = layout->additionalFormats();
int blockpos = block.position();
QTextLayout::FormatRange r;
r.format = style.format;
if (j == startBlockNum) {
r.start = elem_cursor->pos - blockpos;
r.length = (startBlockNum == endBlockNum)
? elem_cursor->end - elem_cursor->pos
: block.length() - r.start;
} else if (j == endBlockNum) {
r.start = 0;
r.length = elem_cursor->end - blockpos;
} else {
r.start = 0;
r.length = block.length();
}
list.append(r);
layout->setAdditionalFormats(list);
}
elem_cursor = elem_cursor->next;
}
}
document->markContentsDirty(0, document->characterCount());
}
示例8: getText
QString FlatTextarea::getText(int32 start, int32 end) const {
if (end >= 0 && end <= start) return QString();
if (start < 0) start = 0;
bool full = (start == 0) && (end < 0);
QTextDocument *doc(document());
QTextBlock from = full ? doc->begin() : doc->findBlock(start), till = (end < 0) ? doc->end() : doc->findBlock(end);
if (till.isValid()) till = till.next();
int32 possibleLen = 0;
for (QTextBlock b = from; b != till; b = b.next()) {
possibleLen += b.length();
}
QString result;
result.reserve(possibleLen + 1);
if (!full && end < 0) {
end = possibleLen;
}
for (QTextBlock b = from; b != till; b = b.next()) {
for (QTextBlock::Iterator iter = b.begin(); !iter.atEnd(); ++iter) {
QTextFragment fragment(iter.fragment());
if (!fragment.isValid()) continue;
int32 p = full ? 0 : fragment.position(), e = full ? 0 : (p + fragment.length());
if (!full) {
if (p >= end || e <= start) {
continue;
}
}
QTextCharFormat f = fragment.charFormat();
QString emojiText;
QString t(fragment.text());
if (!full) {
if (p < start) {
t = t.mid(start - p, end - start);
} else if (e > end) {
t = t.mid(0, end - p);
}
}
QChar *ub = t.data(), *uc = ub, *ue = uc + t.size();
for (; uc != ue; ++uc) {
switch (uc->unicode()) {
case 0xfdd0: // QTextBeginningOfFrame
case 0xfdd1: // QTextEndOfFrame
case QChar::ParagraphSeparator:
case QChar::LineSeparator:
*uc = QLatin1Char('\n');
break;
case QChar::Nbsp:
*uc = QLatin1Char(' ');
break;
case QChar::ObjectReplacementCharacter:
if (emojiText.isEmpty() && f.isImageFormat()) {
QString imageName = static_cast<QTextImageFormat*>(&f)->name();
if (imageName.startsWith(QLatin1String("emoji://e."))) {
if (EmojiPtr emoji = emojiFromUrl(imageName)) {
emojiText = textEmojiString(emoji);
}
}
}
if (uc > ub) result.append(ub, uc - ub);
if (!emojiText.isEmpty()) result.append(emojiText);
ub = uc + 1;
break;
}
}
if (uc > ub) result.append(ub, uc - ub);
}
result.append('\n');
}
result.chop(1);
return result;
}
示例9: sentenceCase
void Changecase::sentenceCase()
{
QTextBlock block = m_document->findBlock(m_startPosition);
QTextCursor backCursor(m_cursor);
int pos = block.position() + block.length() - 1;
// TODO
// * Exception?
while (true) {
QString text = block.text();
int prevLetterIndex = -1;
QChar currentWord;
pos = block.position() + block.length() - 1;
QString::Iterator iter = text.end();
if (text.isEmpty()) { // empty block, go to next block
if (!(block.isValid() && block.position() + block.length() < m_endPosition))
break;
block = block.next();
continue;
}
iter--;
while (iter != text.begin()) {
while (iter != text.begin() && !iter->isSpace()) {
iter--;
pos--;
}
prevLetterIndex = pos;
currentWord = QChar(*(iter + 1));
while (iter != text.begin() && iter->isSpace()) {
iter--;
pos--;
}
// found end of sentence, go back to last found letter (indicating start of a word)
if (iter != text.begin() && (*iter == QChar('.') || *iter == QChar('!') || *iter == QChar('?'))) {
if (prevLetterIndex >= m_startPosition && prevLetterIndex <= m_endPosition && currentWord.isLower()) {
// kDebug() <<"Found end of sentence" << *iter <<" :" << currentWord;
m_cursor.setPosition(prevLetterIndex);
m_cursor.deleteChar();
m_cursor.insertText(currentWord.toUpper());
iter--;
pos--;
}
else if (prevLetterIndex < m_startPosition)
break;
}
}
if (iter == text.begin() && --pos >= m_startPosition) { // start of paragraph, must be start of a sentence also
if (pos + 1 == prevLetterIndex && (*iter).isLower()) {
m_cursor.setPosition(pos);
m_cursor.deleteChar();
m_cursor.insertText((*iter).toUpper());
}
else if (!(*iter).isLetter() && currentWord.isLower()) {
m_cursor.setPosition(prevLetterIndex);
m_cursor.deleteChar();
m_cursor.insertText(currentWord.toUpper());
}
}
if (!(block.isValid() && block.position() + block.length() < m_endPosition))
break;
block = block.next();
}
}
示例10: undoRedo
int QTextDocumentPrivate::undoRedo(bool undo)
{
PMDEBUG("%s, undoState=%d, undoStack size=%d", undo ? "undo:" : "redo:", undoState, undoStack.size());
if (!undoEnabled || (undo && undoState == 0) || (!undo && undoState == undoStack.size()))
return -1;
undoEnabled = false;
beginEditBlock();
while (1) {
if (undo)
--undoState;
QTextUndoCommand &c = undoStack[undoState];
int resetBlockRevision = c.pos;
switch(c.command) {
case QTextUndoCommand::Inserted:
remove(c.pos, c.length, (QTextUndoCommand::Operation)c.operation);
PMDEBUG(" erase: from %d, length %d", c.pos, c.length);
c.command = QTextUndoCommand::Removed;
break;
case QTextUndoCommand::Removed:
PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos);
insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation);
c.command = QTextUndoCommand::Inserted;
break;
case QTextUndoCommand::BlockInserted:
case QTextUndoCommand::BlockAdded:
remove_block(c.pos, &c.blockFormat, c.command, (QTextUndoCommand::Operation)c.operation);
PMDEBUG(" blockremove: from %d", c.pos);
if (c.command == QTextUndoCommand::BlockInserted)
c.command = QTextUndoCommand::BlockRemoved;
else
c.command = QTextUndoCommand::BlockDeleted;
break;
case QTextUndoCommand::BlockRemoved:
case QTextUndoCommand::BlockDeleted:
PMDEBUG(" blockinsert: charformat %d blockformat %d (pos %d, strpos=%d)", c.format, c.blockFormat, c.pos, c.strPos);
insert_block(c.pos, c.strPos, c.format, c.blockFormat, (QTextUndoCommand::Operation)c.operation, c.command);
resetBlockRevision += 1;
if (c.command == QTextUndoCommand::BlockRemoved)
c.command = QTextUndoCommand::BlockInserted;
else
c.command = QTextUndoCommand::BlockAdded;
break;
case QTextUndoCommand::CharFormatChanged: {
resetBlockRevision = -1; // ## TODO
PMDEBUG(" charFormat: format %d (from %d, length %d)", c.format, c.pos, c.length);
FragmentIterator it = find(c.pos);
Q_ASSERT(!it.atEnd());
int oldFormat = it.value()->format;
setCharFormat(c.pos, c.length, formats.charFormat(c.format));
c.format = oldFormat;
break;
}
case QTextUndoCommand::BlockFormatChanged: {
resetBlockRevision = -1; // ## TODO
PMDEBUG(" blockformat: format %d pos %d", c.format, c.pos);
QTextBlock it = blocksFind(c.pos);
Q_ASSERT(it.isValid());
int oldFormat = block(it)->format;
block(it)->format = c.format;
QTextBlockGroup *oldGroup = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(oldFormat)));
QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(c.format)));
c.format = oldFormat;
if (group != oldGroup) {
if (oldGroup)
oldGroup->blockRemoved(it);
if (group)
group->blockInserted(it);
} else if (group) {
group->blockFormatChanged(it);
}
documentChange(it.position(), it.length());
break;
}
case QTextUndoCommand::GroupFormatChange: {
resetBlockRevision = -1; // ## TODO
PMDEBUG(" group format change");
QTextObject *object = objectForIndex(c.objectIndex);
int oldFormat = formats.objectFormatIndex(c.objectIndex);
changeObjectFormat(object, c.format);
c.format = oldFormat;
break;
}
case QTextUndoCommand::Custom:
resetBlockRevision = -1; // ## TODO
if (undo)
c.custom->undo();
else
c.custom->redo();
break;
default:
Q_ASSERT(false);
}
if (resetBlockRevision >= 0) {
int b = blocks.findNode(resetBlockRevision);
QTextBlockData *B = blocks.fragment(b);
//.........这里部分代码省略.........
示例11: highlight
void MarkdownHighlighter::highlight()
{
if (cached_elements == nullptr) {
// Shouldn't happen
return;
}
QHash<int, QList<QTextLayout::FormatRange> > lists;
QHash<int, QList<QTextLayout::FormatRange> >::iterator hashIter;
QList<QTextBlock> blocks;
this->clearFormatting();
for (int i = 0; i < highlightingStyles.size(); i++) {
HighlightingStyle style = highlightingStyles.at(i);
pmh_element *elem_cursor = cached_elements[style.type];
while (elem_cursor != NULL) {
if (elem_cursor->end <= elem_cursor->pos) {
elem_cursor = elem_cursor->next;
continue;
}
// "The QTextLayout object can only be modified from the
// documentChanged implementation of a QAbstractTextDocumentLayout
// subclass. Any changes applied from the outside cause undefined
// behavior." -- we are breaking this rule here. There might be
// a better (more correct) way to do this.
int startBlockNum = document->findBlock(elem_cursor->pos).blockNumber();
int endBlockNum = document->findBlock(elem_cursor->end).blockNumber();
for (int j = startBlockNum; j <= endBlockNum; j++) {
QTextBlock block = document->findBlockByNumber(j);
hashIter = lists.find(block.blockNumber());
if (hashIter == lists.end()) {
QList<QTextLayout::FormatRange> emptyList;
hashIter = lists.insert(block.blockNumber(), emptyList);
blocks.append(block);
}
int blockpos = block.position();
QTextLayout::FormatRange r;
r.format = style.format;
if (j == startBlockNum) {
r.start = elem_cursor->pos - blockpos;
r.length = (startBlockNum == endBlockNum)
? elem_cursor->end - elem_cursor->pos
: block.length() - r.start;
} else if (j == endBlockNum) {
r.start = 0;
r.length = elem_cursor->end - blockpos;
} else {
r.start = 0;
r.length = block.length();
}
hashIter.value().append(r);
}
elem_cursor = elem_cursor->next;
}
}
std::sort(blocks.begin(), blocks.end());
for (auto &block : blocks) {
hashIter = lists.find(block.blockNumber());
std::sort(hashIter.value().begin(), hashIter.value().end(), &MarkdownHighlighter::formatLessThan);
block.layout()->setAdditionalFormats(hashIter.value());
}
document->markContentsDirty(0, document->characterCount());
}
示例12: paintEvent
void BaseEditor::paintEvent(QPaintEvent *e)
{
//copy from QPlainTextEditor
QPainter painter(viewport());
Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout()));
QPointF offset(contentOffset());
QRect er = e->rect();
QRect viewportRect = viewport()->rect();
bool editable = !isReadOnly();
QTextBlock block = firstVisibleBlock();
qreal maximumWidth = document()->documentLayout()->documentSize().width();
//margin
qreal lineX = 0;
if (conf->isDisplayRightColumnMargin()) {
// Don't use QFontMetricsF::averageCharWidth here, due to it returning
// a fractional size even when this is not supported by the platform.
lineX = QFontMetricsF(document()->defaultFont()).width(QLatin1Char('X')) * conf->getRightMarginColumn() + offset.x() + 4;
if (lineX < viewportRect.width()) {
const QBrush background = QBrush(QColor(239, 239, 239));
painter.fillRect(QRectF(lineX, er.top(), viewportRect.width() - lineX, er.height()),
background);
const QColor col = (palette().base().color().value() > 128) ? Qt::black : Qt::white;
const QPen pen = painter.pen();
painter.setPen(blendColors(background.isOpaque() ? background.color() : palette().base().color(),
col, 32));
painter.drawLine(QPointF(lineX, er.top()), QPointF(lineX, er.bottom()));
painter.setPen(pen);
}
}
// Set a brush origin so that the WaveUnderline knows where the wave started
painter.setBrushOrigin(offset);
// keep right margin clean from full-width selection
int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
- document()->documentMargin();
er.setRight(qMin(er.right(), maxX));
painter.setClipRect(er);
QAbstractTextDocumentLayout::PaintContext context = getPaintContext();
while (block.isValid()) {
QRectF r = blockBoundingRect(block).translated(offset);
QTextLayout *layout = block.layout();
if (!block.isVisible()) {
offset.ry() += r.height();
block = block.next();
continue;
}
if (r.bottom() >= er.top() && r.top() <= er.bottom()) {
QTextBlockFormat blockFormat = block.blockFormat();
QBrush bg = blockFormat.background();
if (bg != Qt::NoBrush) {
QRectF contentsRect = r;
contentsRect.setWidth(qMax(r.width(), maximumWidth));
fillBackground(&painter, contentsRect, bg);
}
QVector<QTextLayout::FormatRange> selections;
int blpos = block.position();
int bllen = block.length();
for (int i = 0; i < context.selections.size(); ++i) {
const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i);
const int selStart = range.cursor.selectionStart() - blpos;
const int selEnd = range.cursor.selectionEnd() - blpos;
if (selStart < bllen && selEnd > 0
&& selEnd > selStart) {
QTextLayout::FormatRange o;
o.start = selStart;
o.length = selEnd - selStart;
o.format = range.format;
selections.append(o);
} else if (!range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection)
&& block.contains(range.cursor.position())) {
// for full width selections we don't require an actual selection, just
// a position to specify the line. that's more convenience in usage.
QTextLayout::FormatRange o;
QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos);
o.start = l.textStart();
o.length = l.textLength();
if (o.start + o.length == bllen - 1)
++o.length; // include newline
o.format = range.format;
selections.append(o);
}
}
//.........这里部分代码省略.........
示例13: blinkCode
void ScCodeEditor::blinkCode( const QTextCursor & c )
{
if( !c.document() || !c.hasSelection() ) return;
Settings::Manager *settings = Main::settings();
QTextCharFormat evalCodeTextFormat = settings->getThemeVal("evaluatedCode");
QTextDocument *doc = c.document();
int startPos = c.selectionStart();
int endPos = c.selectionEnd();
QTextBlock startBlock = doc->findBlock(startPos);
QTextBlock endBlock = doc->findBlock(endPos);
startPos -= startBlock.position();
endPos -= endBlock.position();
// Get the bounds of visible blocks within the cursor's selection:
QTextBlock block = firstVisibleBlock();
int idx = block.blockNumber();
int sidx = startBlock.blockNumber();
QTextBlock firstBlock, lastBlock;
firstBlock = lastBlock = block;
QRectF geom = blockBoundingGeometry(block).translated(contentOffset());
qreal top = geom.top();
qreal bottom = top;
qreal width=0;
while(block.isValid() && bottom < viewport()->rect().height())
{
if(block.isVisible())
{
QTextLayout *l = block.layout();
QRectF r = l->boundingRect();
bottom += r.height();
if(idx < sidx) {
// Block not within the selection. Will skip it.
top = bottom;
}
else {
// Block within the selection.
width = qMax(width, l->maximumWidth() + r.left());
}
}
if(block == endBlock) break;
block = block.next();
++idx;
if(top == bottom)
firstBlock = block;
}
lastBlock = block;
if(bottom == top) {
//qDebug("no visible block.");
return;
}
// Construct a pixmap to render the code on:
QPixmap pix( QSize(qCeil(width), qCeil(bottom - top)) );
pix.fill(QColor(0,0,0,0));
// Render the visible blocks:
QPainter painter(&pix);
QVector<QTextLayout::FormatRange> selections;
block = firstBlock;
int y=0;
while( block.isValid() )
{
if (block.isVisible())
{
QRectF blockRect = block.layout()->boundingRect();
// Use extra char formatting to hide code outside of selection
// and modify the appearance of selected code:
QTextLayout::FormatRange range;
selections.clear();
int start = 0;
if(block == startBlock) {
range.start = 0;
range.length = startPos;
range.format.setForeground(QColor(0,0,0,0));
range.format.setBackground(Qt::NoBrush);
selections.append(range);
start = startPos;
}
range.start = start;
range.length = (block == endBlock ? endPos : block.length() - 1) - range.start;
range.format = evalCodeTextFormat;
selections.append(range);
//.........这里部分代码省略.........
示例14: resultReady
void MarkdownHighlighter::resultReady(pmh_element **elements)
{
QTextBlock block = document()->firstBlock();
while (block.isValid()) {
block.layout()->clearAdditionalFormats();
block = block.next();
}
if (!elements) {
qDebug() << "elements is null";
return;
}
// QTextDocument::characterCount returns a value one higher than the
// actual character count.
// See: https://bugreports.qt.nokia.com//browse/QTBUG-4841
// document->toPlainText().length() would give us the correct value
// but it's probably too slow.
unsigned long max_offset = document()->characterCount() - 1;
for (int i = 0; i < highlightingStyles.size(); i++)
{
HighlightingStyle style = highlightingStyles.at(i);
pmh_element *elem_cursor = elements[style.type];
while (elem_cursor != NULL)
{
unsigned long pos = elem_cursor->pos;
unsigned long end = elem_cursor->end;
if (end <= pos || max_offset < pos)
{
elem_cursor = elem_cursor->next;
continue;
}
if (max_offset < end)
end = max_offset;
// "The QTextLayout object can only be modified from the
// documentChanged implementation of a QAbstractTextDocumentLayout
// subclass. Any changes applied from the outside cause undefined
// behavior." -- we are breaking this rule here. There might be
// a better (more correct) way to do this.
int startBlockNum = document()->findBlock(pos).blockNumber();
int endBlockNum = document()->findBlock(end).blockNumber();
for (int j = startBlockNum; j <= endBlockNum; j++)
{
QTextBlock block = document()->findBlockByNumber(j);
QTextLayout *layout = block.layout();
QList<QTextLayout::FormatRange> list = layout->additionalFormats();
int blockpos = block.position();
QTextLayout::FormatRange r;
r.format = style.format;
if (/*_makeLinksClickable
&&*/ (elem_cursor->type == pmh_LINK
|| elem_cursor->type == pmh_AUTO_LINK_URL
|| elem_cursor->type == pmh_AUTO_LINK_EMAIL
|| elem_cursor->type == pmh_REFERENCE)
&& elem_cursor->address != NULL)
{
QString address(elem_cursor->address);
if (elem_cursor->type == pmh_AUTO_LINK_EMAIL && !address.startsWith("mailto:"))
address = "mailto:" + address;
QTextCharFormat linkFormat(r.format);
linkFormat.setAnchor(true);
linkFormat.setAnchorHref(address);
linkFormat.setToolTip(address);
r.format = linkFormat;
}
if (j == startBlockNum) {
r.start = pos - blockpos;
r.length = (startBlockNum == endBlockNum)
? end - pos
: block.length() - r.start;
} else if (j == endBlockNum) {
r.start = 0;
r.length = end - blockpos;
} else {
r.start = 0;
r.length = block.length();
}
list.append(r);
layout->setAdditionalFormats(list);
}
elem_cursor = elem_cursor->next;
}
}
document()->markContentsDirty(0, document()->characterCount());
pmh_free_elements(elements);
}
示例15: unCommentSelection
void Utils::unCommentSelection(QPlainTextEdit *edit, CommentFlag flag, const CommentDefinition &definition)
{
if (!definition.hasSingleLineStyle() && !definition.hasMultiLineStyle())
return;
QTextCursor cursor = edit->textCursor();
QTextDocument *doc = cursor.document();
if (!cursor.hasSelection() && (flag == BlockComment) ) {
if (definition.hasMultiLineStyle()) {
cursor.beginEditBlock();
cursor.insertText(definition.multiLineStart());
cursor.insertText(definition.multiLineEnd());
cursor.movePosition(QTextCursor::Left,QTextCursor::MoveAnchor,definition.multiLineEnd().length());
cursor.endEditBlock();
edit->setTextCursor(cursor);
return;
}
}
cursor.beginEditBlock();
int pos = cursor.position();
int anchor = cursor.anchor();
int start = qMin(anchor, pos);
int end = qMax(anchor, pos);
bool anchorIsStart = (anchor == start);
QTextBlock startBlock = doc->findBlock(start);
QTextBlock endBlock = doc->findBlock(end);
if (end > start && endBlock.position() == end) {
--end;
endBlock = endBlock.previous();
}
bool doMultiLineStyleUncomment = false;
bool doMultiLineStyleComment = false;
bool doSingleLineStyleUncomment = false;
bool hasSelection = cursor.hasSelection();
int firstSpacesOffset = -1;
if (hasSelection && definition.hasMultiLineStyle()) {
QString startText = startBlock.text();
int startPos = start - startBlock.position();
const int multiLineStartLength = definition.multiLineStart().length();
bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty();
if (startPos >= multiLineStartLength
&& isComment(startText,
startPos - multiLineStartLength,
definition,
&CommentDefinition::multiLineStart)) {
startPos -= multiLineStartLength;
start -= multiLineStartLength;
}
bool hasSelStart = (startPos <= startText.length() - multiLineStartLength
&& isComment(startText,
startPos,
definition,
&CommentDefinition::multiLineStart));
QString endText = endBlock.text();
int endPos = end - endBlock.position();
const int multiLineEndLength = definition.multiLineEnd().length();
bool hasTrailingCharacters =
!endText.left(endPos).remove(definition.singleLine()).trimmed().isEmpty()
&& !endText.mid(endPos).trimmed().isEmpty();
if (endPos <= endText.length() - multiLineEndLength
&& isComment(endText, endPos, definition, &CommentDefinition::multiLineEnd)) {
endPos += multiLineEndLength;
end += multiLineEndLength;
}
bool hasSelEnd = (endPos >= multiLineEndLength
&& isComment(endText,
endPos - multiLineEndLength,
definition,
&CommentDefinition::multiLineEnd));
doMultiLineStyleUncomment = hasSelStart && hasSelEnd;
doMultiLineStyleComment = !doMultiLineStyleUncomment
&& (hasLeadingCharacters
|| hasTrailingCharacters
|| !definition.hasSingleLineStyle()
|| (flag == BlockComment));
} else if (!hasSelection && !definition.hasSingleLineStyle()) {
QString text = startBlock.text().trimmed();
doMultiLineStyleUncomment = text.startsWith(definition.multiLineStart())
&& text.endsWith(definition.multiLineEnd());
doMultiLineStyleComment = !doMultiLineStyleUncomment && !text.isEmpty();
start = startBlock.position();
end = endBlock.position() + endBlock.length() - 1;
//.........这里部分代码省略.........