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 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(); } }
bool XLHighlighter::showSelectionInFragment(QTextFragment fragment) // ---------------------------------------------------------------------------- // Highlight (part of) fragment containing code related to a selected object // ---------------------------------------------------------------------------- { bool matched = false; int spos= fragment.position(); int epos = spos + fragment.length(); int blockstart = currentBlock().begin().fragment().position(); XL::stream_range frag(spos, epos); XL::stream_ranges::iterator r; for (r = selected.begin(); r != selected.end(); r++) { XL::stream_range i = intersect((*r), frag); if (i.first != -1) { int hstart = (int)(i.first) - blockstart; int hcount = (int)(i.second - i.first); setFormat(hstart, hcount, selectedFormat); matched = true; } } return matched; }
void TextDocument::replaceImageUrl(const QUrl &oldName, const QString &newName) { QList <QPair<int, int> > fragments; QTextBlock block = begin(); while(block.isValid()) { QTextBlock::iterator iterator; for(iterator = block.begin(); !(iterator.atEnd()); ++iterator) { QTextFragment fragment = iterator.fragment(); if(fragment.isValid() && fragment.charFormat().isImageFormat()) { QTextImageFormat format = fragment.charFormat().toImageFormat(); if (QUrl::fromEncoded(format.name().toUtf8()) != oldName) {continue;} fragments.append(QPair<int, int>(fragment.position(), fragment.length())); } } block = block.next(); } QTextCursor cursor(this); cursor.beginEditBlock(); QPair<int, int> pair; foreach (pair, fragments) { cursor.setPosition(pair.first); cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, pair.second); QTextImageFormat format = cursor.charFormat().toImageFormat(); format.setName(newName); cursor.mergeCharFormat(format); }
void ChangeFollower::processUpdates(const QList<int> &changedStyles) { KoStyleManager *sm = m_styleManager.data(); if (!sm) { // since the stylemanager would be the one calling this method, I doubt this // will ever happen. But better safe than sorry.. deleteLater(); return; } // optimization strategy; store the formatid of the formats we checked into // a qset for 'hits' and 'ignores' and avoid the copying of the format // (fragment.charFormat() / block.blockFormat()) when the formatId is // already checked previosly QTextCursor cursor(m_document); QTextBlock block = cursor.block(); while (block.isValid()) { QTextBlockFormat bf = block.blockFormat(); int id = bf.intProperty(KoParagraphStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { cursor.setPosition(block.position()); KoParagraphStyle *style = sm->paragraphStyle(id); Q_ASSERT(style); style->applyStyle(bf); cursor.setBlockFormat(bf); } QTextCharFormat cf = block.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(block); } QTextBlock::iterator iter = block.begin(); while (! iter.atEnd()) { QTextFragment fragment = iter.fragment(); cf = fragment.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { // create selection cursor.setPosition(fragment.position()); cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(cf); cursor.mergeCharFormat(cf); } iter++; } block = block.next(); } }
void MoveViewController::selectAndMarkAnchor(const QString& link) { QTextBlock block = this->document->begin(); while(block != this->document->end()) { QTextBlock::iterator it; for(it = block.begin(); !it.atEnd(); ++it) { QTextFragment fragment = it.fragment(); if(!fragment.isValid()) { continue; } QTextCharFormat format = fragment.charFormat(); if(format.isAnchor() && format.anchorHref() == link) { QTextCursor cursor = this->textCursor(); cursor.setPosition(fragment.position()); int len = 0; bool finished = false; // we want to mark (highlight) everything from the // start of the anchor until the end of the move // the end of the move is indicated by an empty space // (there is always an empty space after a move) while(!finished && !it.atEnd()) { if(it.fragment().text().startsWith(" ") || len >= 6) { finished = true; } else { len+= it.fragment().text().length(); it++; } } cursor.setPosition(fragment.position() + len, QTextCursor::KeepAnchor); setTextCursor(cursor); ensureCursorVisible(); return; } } block = block.next(); } }
int main(int argc, char *argv[]) { QApplication app(argc, argv); QTextEdit *editor = new QTextEdit; QTextDocument *document = new QTextDocument(editor); QTextCursor cursor(document); QTextImageFormat imageFormat; imageFormat.setName(":/images/advert.png"); cursor.insertImage(imageFormat); QTextBlock block = cursor.block(); QTextFragment fragment; QTextBlock::iterator it; for (it = block.begin(); !(it.atEnd()); ++it) { fragment = it.fragment(); if (fragment.contains(cursor.position())) break; } //! [0] if (fragment.isValid()) { QTextImageFormat newImageFormat = fragment.charFormat().toImageFormat(); if (newImageFormat.isValid()) { newImageFormat.setName(":/images/newimage.png"); QTextCursor helper = cursor; helper.setPosition(fragment.position()); helper.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); helper.setCharFormat(newImageFormat); //! [0] //! [1] } //! [1] //! [2] } //! [2] cursor.insertBlock(); cursor.insertText("Code less. Create more."); editor->setDocument(document); editor->setWindowTitle(tr("Text Document Image Format")); editor->resize(320, 480); editor->show(); return app.exec(); }
void FlatTextarea::removeSingleEmoji() { QString text; QTextFragment fragment; getSingleEmojiFragment(text, fragment); if (!text.isEmpty()) { QTextCursor t(textCursor()); t.setPosition(fragment.position()); t.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); t.removeSelectedText(); setTextCursor(t); } }
void KoTextWriter::saveParagraph(const QTextBlock &block, int from, int to) { QString changeName = QString(); QTextBlockFormat blockFormat = block.blockFormat(); int outlineLevel = blockFormat.intProperty(KoParagraphStyle::OutlineLevel); if (outlineLevel > 0) { d->writer->startElement("text:h", false); d->writer->addAttribute("text:outline-level", outlineLevel); } else d->writer->startElement("text:p", false); QString styleName = saveParagraphStyle(block); if (!styleName.isEmpty()) d->writer->addAttribute("text:style-name", styleName); // Write the fragments and their formats QTextCursor cursor(block); QTextCharFormat blockCharFormat = cursor.blockCharFormat(); QTextCharFormat previousCharFormat; QTextBlock::iterator it; for (it = block.begin(); !(it.atEnd()); ++it) { QTextFragment currentFragment = it.fragment(); const int fragmentStart = currentFragment.position(); const int fragmentEnd = fragmentStart + currentFragment.length(); if (to != -1 && fragmentStart >= to) break; if (currentFragment.isValid()) { QTextCharFormat charFormat = currentFragment.charFormat(); QTextCharFormat compFormat = charFormat; bool identical; previousCharFormat.clearProperty(KoCharacterStyle::ChangeTrackerId); compFormat.clearProperty(KoCharacterStyle::ChangeTrackerId); if (previousCharFormat == compFormat) identical = true; else identical = false; if ( d->changeTracker && d->changeTracker->containsInlineChanges(charFormat) && d->changeTracker->elementById(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt())->isEnabled()) { KoGenChange change; d->changeTracker->saveInlineChange(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt(), change); changeName = d->sharedData->genChanges().insert(change); d->writer->startElement("text:change-start", false); d->writer->addAttribute("text:change-id", changeName); d->writer->endElement(); } KoInlineObject *inlineObject = d->layout->inlineTextObjectManager()->inlineTextObject(charFormat); if (currentFragment.length() == 1 && inlineObject && currentFragment.text()[0].unicode() == QChar::ObjectReplacementCharacter) { inlineObject->saveOdf(d->context); } else { QString styleName = saveCharacterStyle(charFormat, blockCharFormat); if (charFormat.isAnchor()) { d->writer->startElement("text:a", false); d->writer->addAttribute("xlink:type", "simple"); d->writer->addAttribute("xlink:href", charFormat.anchorHref()); } else if (!styleName.isEmpty() /*&& !identical*/) { d->writer->startElement("text:span", false); d->writer->addAttribute("text:style-name", styleName); } QString text = currentFragment.text(); int spanFrom = fragmentStart >= from ? 0 : from; int spanTo = to == -1 ? fragmentEnd : (fragmentEnd > to ? to : fragmentEnd); if (spanFrom != fragmentStart || spanTo != fragmentEnd) { // avoid mid, if possible d->writer->addTextSpan(text.mid(spanFrom - fragmentStart, spanTo - spanFrom)); } else { d->writer->addTextSpan(text); } if ((!styleName.isEmpty() /*&& !identical*/) || charFormat.isAnchor()) d->writer->endElement(); } // if (inlineObject) if (!changeName.isEmpty()) { d->writer->startElement("text:change-end", false); d->writer->addAttribute("text:change-id",changeName); d->writer->endElement(); changeName=QString(); } previousCharFormat = charFormat; } // if (fragment.valid()) } // foeach(fragment) d->writer->endElement(); }
//绘制stub面板上的显示效果 只显示恶性数据竞争的那一行 void DrcDockWidget::stubDrawText() { QTextDocument *document = ui->resultStubEdit->document(); QTextBlock currentBlock = document->begin(); QTextBlock::iterator it; QTextCursor cursor = ui->resultStubEdit->textCursor(); //此处需要注意的是临时变量的生命周期!!! QString tempStr; int tempPos; while( true) { // 在修改chatformat时会改变当前Block的fragment // 所以++it的处理类似std::map中的erase操作 for (it = currentBlock.begin(); !(it.atEnd()); ) { QTextFragment currentFragment = it.fragment(); if (currentFragment.isValid()) { ++it; int pos = currentFragment.position(); QString strText = currentFragment.text(); QTextCharFormat fmt; QFont font; font.setBold(true); fmt.setFont(font); fmt.setForeground(QBrush(QColor(255, 0, 0))); QTextCursor helper = cursor; char str = strText.at(0).toLatin1(); if(str == 'A') { QString strPart2 = strText.split(':').at(1); if(strPart2.toInt() == 1) { helper.setPosition(tempPos); helper.setPosition(tempPos + tempStr.length(), QTextCursor::KeepAnchor); helper.setCharFormat(fmt); helper.setPosition(pos); helper.setPosition(pos + strText.length(), QTextCursor::KeepAnchor); helper.setCharFormat(fmt); } } else { tempStr = strText; tempPos = pos; } } } currentBlock = currentBlock.next(); if(!currentBlock.isValid()) break; } // 光标移动到最后, 并设置拥有焦点 QTextCursor c = ui->resultStubEdit->textCursor(); c.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); ui->resultStubEdit->setTextCursor(c); ui->resultStubEdit->setFocus(Qt::MouseFocusReason); }
//绘制klee面板上的显示效果 void DrcDockWidget::kleeDrawText() { QTextDocument *document = ui->resultKleeEdit->document(); QTextBlock currentBlock = document->begin(); QTextBlock::iterator it; QTextCursor cursor = ui->resultKleeEdit->textCursor(); while( true) { // 在修改chatformat时会改变当前Block的fragment // 所以++it的处理类似std::map中的erase操作 for (it = currentBlock.begin(); !(it.atEnd()); ) { QTextFragment currentFragment = it.fragment(); if (currentFragment.isValid()) { ++it; int pos = currentFragment.position(); QString strText = currentFragment.text(); qDebug() << "strText: " << strText; if(strText.contains(':')) { char str = strText.at(0).toLatin1(); QTextCharFormat fmt; QColor col; QFont font; font.setBold(true); fmt.setFont(font); fmt.setForeground(QBrush(QColor(255, 0, 0))); QTextCursor helper = cursor; QString strPart1 = strText.split(':').at(0); QString strPart2 = strText.split(':').at(1); switch(str) { case 'V': case 'h': case 'M': pos += strPart1.length() + 1; helper.setPosition(pos); helper.setPosition(pos + strPart2.length(), QTextCursor::KeepAnchor); fmt.setForeground(QBrush(QColor(255, 0, 0))); helper.setCharFormat(fmt); break; case 'i': case '/': pos += strPart1.length() + 1; helper.setPosition(pos); helper.setPosition(pos + strPart2.length(), QTextCursor::KeepAnchor); fmt.setForeground(QBrush(QColor(34, 139, 34))); helper.setCharFormat(fmt); break; case 'T': QString strPart3 = strText.split(':').at(2); //线程ID QString strPart4 = strPart2.split(',').at(0); pos += strPart1.length() + 1; helper.setPosition(pos); helper.setPosition(pos + strPart4.length(), QTextCursor::KeepAnchor); fmt.setForeground(QBrush(QColor(148, 0, 211))); helper.setCharFormat(fmt); pos += strPart2.length() + 1; //读写类型 helper.setPosition(pos); helper.setPosition(pos + strPart3.length(), QTextCursor::KeepAnchor); fmt.setForeground(QBrush(QColor(0, 0, 139))); helper.setCharFormat(fmt); break; } } } } currentBlock = currentBlock.next(); if(!currentBlock.isValid()) break; } // 光标移动到最后, 并设置拥有焦点 QTextCursor c = ui->resultKleeEdit->textCursor(); c.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); ui->resultKleeEdit->setTextCursor(c); ui->resultKleeEdit->setFocus(Qt::MouseFocusReason); }
QString TextEditEx::getPlainText(int _from, int _to) const { if (_from == _to) return ""; if (_to != -1 && _to < _from) { assert(!"invalid data"); return ""; } QString out_string; QTextStream result(&out_string); int pos_start = 0; int length = 0; bool first = true; for (QTextBlock it_block = document()->begin(); it_block != document()->end(); it_block = it_block.next()) { if (!first) result << '\n'; pos_start = it_block.position(); if (_to != -1 && pos_start >= _to) break; for (QTextBlock::iterator it_fragment = it_block.begin(); it_fragment != it_block.end(); ++it_fragment) { QTextFragment currentFragment = it_fragment.fragment(); if (currentFragment.isValid()) { pos_start = currentFragment.position(); length = currentFragment.length(); if (pos_start + length <= _from) continue; if (_to != -1 && pos_start >= _to) break; first = false; if (currentFragment.charFormat().isImageFormat()) { if (pos_start < _from) continue; QTextImageFormat imgFmt = currentFragment.charFormat().toImageFormat(); auto iter = resource_index_.find(imgFmt.name()); if (iter != resource_index_.end()) result << iter->second; } else { QString fragment_text = currentFragment.text(); int c_start = std::max((_from - pos_start), 0); int count = -1; if (_to != -1 && _to <= pos_start + length) count = _to - pos_start - c_start; QString txt = fragment_text.mid(c_start, count); txt.remove(QChar::SoftHyphen); QChar *uc = txt.data(); QChar *e = uc + txt.size(); for (; uc != e; ++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; default: ; } } result << txt; } } } } return out_string; }