void XmlWriter::processFrame(QDomElement &parent, QTextFrame *frame) { QDomElement frameElement = document->createElement("frame"); frameElement.setAttribute("begin", frame->firstPosition()); frameElement.setAttribute("end", frame->lastPosition()); parent.appendChild(frameElement); //! [0] QTextFrame::iterator it; for (it = frame->begin(); !(it.atEnd()); ++it) { QTextFrame *childFrame = it.currentFrame(); QTextBlock childBlock = it.currentBlock(); if (childFrame) { QTextTable *childTable = qobject_cast<QTextTable*>(childFrame); if (childTable) processTable(frameElement, childTable); else processFrame(frameElement, childFrame); } else if (childBlock.isValid()) //! [0] //! [1] processBlock(frameElement, childBlock); } //! [1] }
void TextDocumentModel::fillFrameIterator(const QTextFrame::iterator &it, QStandardItem *parent) { if (QTextFrame *frame = it.currentFrame()) { const QRectF b = m_document->documentLayout()->frameBoundingRect(frame); QTextTable *table = qobject_cast<QTextTable *>(frame); auto item = new QStandardItem; if (table) { item->setText(tr("Table")); appendRow(parent, item, table->format(), b); fillTable(table, item); } else { item->setText(tr("Frame")); appendRow(parent, item, frame->frameFormat(), b); fillFrame(frame, item); } } const QTextBlock block = it.currentBlock(); if (block.isValid()) { auto item = new QStandardItem; item->setText(tr("Block: %1").arg(block.text())); const QRectF b = m_document->documentLayout()->blockBoundingRect(block); appendRow(parent, item, block.blockFormat(), b); fillBlock(block, item); } }
int TextDocumentStructureModel::rowCount(const QModelIndex &index) const { kDebug(32500) << "-------------------------- index:"<<index<<m_textDocument; if (! m_textDocument) { return 0; } if (! index.isValid()) { // one root frame return 1; } Q_ASSERT(index.internalId() < uint(m_nodeDataTable.count())); const NodeData &nodeData = m_nodeDataTable.at(index.internalId()); if (nodeData.type == NodeData::Frame) { QTextFrame* frame = nodeData.frame; // count frames and blocks int count = 0; for (QTextFrame::iterator iterator = frame->begin(); !iterator.atEnd(); ++iterator) { ++count; } return count; } // should be a block then, no childs for now return 0; }
int KTextDocumentLayout::hitTestIterated(QTextFrame::iterator begin, QTextFrame::iterator end, const QPointF &point, Qt::HitTestAccuracy accuracy) const { int position = -1; QTextFrame::iterator it = begin; for (it = begin; it != end; ++it) { QTextBlock block = it.currentBlock(); QTextTable *table = qobject_cast<QTextTable*>(it.currentFrame()); QTextFrame *subFrame = it.currentFrame(); if (table) { QTextTableCell cell = m_state->hitTestTable(table, point); if (cell.isValid()) { position = hitTestIterated(cell.begin(), cell.end(), point, accuracy); if (position == -1) position = cell.lastPosition(); return position; } continue; } else if (subFrame) { position = hitTestIterated(subFrame->begin(), subFrame->end(), point, accuracy); if (position != -1) return position; continue; } else { if (!block.isValid()) continue; } // kDebug(32500) <<"hitTest[" << point.x() <<"," << point.y() <<"]"; QTextLayout *layout = block.layout(); if (point.y() > layout->boundingRect().bottom()) { // just skip this block. position = block.position() + block.length() - 1; continue; } for (int i = 0; i < layout->lineCount(); i++) { QTextLine line = layout->lineAt(i); // kDebug(32500) <<" + line[" << line.textStart() <<"]:" << line.y() <<"-" << line.height(); if (point.y() > line.y() + line.height()) { position = line.textStart() + line.textLength(); continue; } if (accuracy == Qt::ExactHit && point.y() < line.y()) // between lines return -1; if (accuracy == Qt::ExactHit && // left or right of line (point.x() < line.x() || point.x() > line.x() + line.width())) return -1; if (point.x() > line.width() && layout->textOption().textDirection() == Qt::RightToLeft) { // totally right of RTL text means the position is the start of the text. return block.position() + line.textStart(); } return block.position() + line.xToCursor(point.x()); } } return -1; }
void QSGTextNode::addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color, QSGText::TextStyle style, const QColor &styleColor) { Q_UNUSED(position) QTextFrame *textFrame = textDocument->rootFrame(); QPointF p = textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft(); QTextFrame::iterator it = textFrame->begin(); while (!it.atEnd()) { addTextBlock(p, textDocument, it.currentBlock(), color, style, styleColor); ++it; } }
void QQuickTextNode::addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &textColor, QQuickText::TextStyle style, const QColor &styleColor, const QColor &anchorColor, const QColor &selectionColor, const QColor &selectedTextColor, int selectionStart, int selectionEnd) { QQuickTextNodeEngine engine; engine.setTextColor(textColor); engine.setSelectedTextColor(selectedTextColor); engine.setSelectionColor(selectionColor); engine.setAnchorColor(anchorColor); engine.setPosition(position); QList<QTextFrame *> frames; frames.append(textDocument->rootFrame()); while (!frames.isEmpty()) { QTextFrame *textFrame = frames.takeFirst(); frames.append(textFrame->childFrames()); engine.addFrameDecorations(textDocument, textFrame); if (textFrame->firstPosition() > textFrame->lastPosition() && textFrame->frameFormat().position() != QTextFrameFormat::InFlow) { const int pos = textFrame->firstPosition() - 1; ProtectedLayoutAccessor *a = static_cast<ProtectedLayoutAccessor *>(textDocument->documentLayout()); QTextCharFormat format = a->formatAccessor(pos); QRectF rect = a->frameBoundingRect(textFrame); QTextBlock block = textFrame->firstCursorPosition().block(); engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position())); engine.addTextObject(rect.topLeft(), format, QQuickTextNodeEngine::Unselected, textDocument, pos, textFrame->frameFormat().position()); } else { QTextFrame::iterator it = textFrame->begin(); while (!it.atEnd()) { Q_ASSERT(!engine.currentLine().isValid()); QTextBlock block = it.currentBlock(); engine.addTextBlock(textDocument, block, position, textColor, anchorColor, selectionStart, selectionEnd); ++it; } } } engine.addToSceneGraph(this, style, styleColor); }
QModelIndex TextDocumentStructureModel::parent(const QModelIndex &index) const { kDebug(32500) << "-------------------------- index:"<<index<<m_textDocument; if (! m_textDocument || ! index.isValid()) { return QModelIndex(); } Q_ASSERT(index.internalId() < uint(m_nodeDataTable.count())); const NodeData &nodeData = m_nodeDataTable.at(index.internalId()); QTextFrame* parentFrame; if (nodeData.type == NodeData::Frame) { parentFrame = nodeData.frame->parentFrame(); } else { QTextBlock block = m_textDocument->findBlockByNumber(nodeData.blockNumber); Q_ASSERT(block.isValid()); // QTextBlock's API has no option to query the parentframe, so get it via a cursor QTextCursor cursor(block); parentFrame = cursor.currentFrame(); } if (! parentFrame) { return QModelIndex(); } QTextFrame* grandParentFrame = parentFrame->parentFrame(); // parent is root frame? if (! grandParentFrame) { Q_ASSERT(parentFrame == m_textDocument->rootFrame()); return createIndex(0, 0, static_cast<quintptr>(0)); } // find position of parentFrame bool posFound = false; int row = 0; for (QTextFrame::iterator iterator = grandParentFrame->begin(); !iterator.atEnd(); ++iterator) { if (iterator.currentFrame() == parentFrame) { posFound = true; break; } ++row; } Q_ASSERT(posFound);Q_UNUSED(posFound); return createIndex(row, 0, frameIndex(parentFrame)); }
// 遍历框架 void MainWindow::showTextFrame() { QTextDocument *document = ui->textEdit->document(); QTextFrame *frame = document->rootFrame(); // 建立QTextFrame类的迭代器 QTextFrame::iterator it; for (it = frame->begin(); !(it.atEnd()); ++it) { // 获取当前框架的指针 QTextFrame *childFrame = it.currentFrame(); // 获取当前文本块 QTextBlock childBlock = it.currentBlock(); if (childFrame) qDebug() << "frame"; else if (childBlock.isValid()) qDebug() << "block:" << childBlock.text(); } }
QString TextDocumentSerializer::processList(QTextFrame::iterator &it) { QString text; QTextBlock block = it.currentBlock(); while(block.textList()){ text += processBlockContent(block); ++it; block = it.currentBlock(); } --it; return QString("<ul>%1</ul>").arg(text); }
void XmlWriter::processTableCell(QDomElement &parent, const QTextTableCell &cell) { QDomElement element = document->createElement("cell"); element.setAttribute("row", cell.row()); element.setAttribute("column", cell.column()); QTextFrame::iterator it; for (it = cell.begin(); !(it.atEnd()); ++it) { QTextFrame *childFrame = it.currentFrame(); QTextBlock childBlock = it.currentBlock(); if (childFrame) processFrame(element, childFrame); else if (childBlock.isValid()) processBlock(element, childBlock); } parent.appendChild(element); }
QModelIndex TextDocumentStructureModel::index(int row, int column, const QModelIndex &parentIndex) const { kDebug(32500) << "-------------------------- row:" << row << "column:"<<column << "index:"<<parentIndex<<m_textDocument; if (! m_textDocument) { return QModelIndex(); } if (! parentIndex.isValid()) { return createIndex(row, column, static_cast<quintptr>(0)); } Q_ASSERT(parentIndex.internalId() < uint(m_nodeDataTable.count())); const NodeData &nodeData = m_nodeDataTable.at(parentIndex.internalId()); // can be only frame for now Q_ASSERT(nodeData.type == NodeData::Frame); QTextFrame* parentFrame = nodeData.frame; int index = -1; int count = 0; for (QTextFrame::iterator iterator = parentFrame->begin(); !iterator.atEnd(); ++iterator) { if (count == row) { QTextFrame *frame = iterator.currentFrame(); if (frame) { index = frameIndex(frame); break; } else { QTextBlock block = iterator.currentBlock(); if (block.isValid()) { index = blockIndex(block); break; } } } ++count; } Q_ASSERT(index != -1); return createIndex(row, column, index); }
void MainWindow::showTable() { QTextCursor cursor = editor->textCursor(); QTextTable *table = cursor.currentTable(); if (!table) return; QTableWidget *tableWidget = new QTableWidget(table->rows(), table->columns()); //! [9] for (int row = 0; row < table->rows(); ++row) { for (int column = 0; column < table->columns(); ++column) { QTextTableCell tableCell = table->cellAt(row, column); //! [9] QTextFrame::iterator it; QString text; for (it = tableCell.begin(); !(it.atEnd()); ++it) { QTextBlock childBlock = it.currentBlock(); if (childBlock.isValid()) text += childBlock.text(); } QTableWidgetItem *newItem = new QTableWidgetItem(text); tableWidget->setItem(row, column, newItem); /* //! [10] processTableCell(tableCell); //! [10] */ //! [11] } //! [11] //! [12] } //! [12] tableWidget->setWindowTitle(tr("Table Contents")); tableWidget->show(); }
void QTextOdfWriter::writeFrame(QXmlStreamWriter &writer, const QTextFrame *frame) { Q_ASSERT(frame); const QTextTable *table = qobject_cast<const QTextTable*> (frame); if (table) { // Start a table. writer.writeStartElement(tableNS, QString::fromLatin1("table")); writer.writeEmptyElement(tableNS, QString::fromLatin1("table-column")); writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-repeated"), QString::number(table->columns())); } else if (frame->document() && frame->document()->rootFrame() != frame) { // start a section writer.writeStartElement(textNS, QString::fromLatin1("section")); } QTextFrame::iterator iterator = frame->begin(); QTextFrame *child = 0; int tableRow = -1; while (! iterator.atEnd()) { if (iterator.currentFrame() && child != iterator.currentFrame()) writeFrame(writer, iterator.currentFrame()); else { // no frame, its a block QTextBlock block = iterator.currentBlock(); if (table) { QTextTableCell cell = table->cellAt(block.position()); if (tableRow < cell.row()) { if (tableRow >= 0) writer.writeEndElement(); // close table row tableRow = cell.row(); writer.writeStartElement(tableNS, QString::fromLatin1("table-row")); } writer.writeStartElement(tableNS, QString::fromLatin1("table-cell")); if (cell.columnSpan() > 1) writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-spanned"), QString::number(cell.columnSpan())); if (cell.rowSpan() > 1) writer.writeAttribute(tableNS, QString::fromLatin1("number-rows-spanned"), QString::number(cell.rowSpan())); if (cell.format().isTableCellFormat()) { writer.writeAttribute(tableNS, QString::fromLatin1("style-name"), QString::fromLatin1("T%1").arg(cell.tableCellFormatIndex())); } } writeBlock(writer, block); if (table) writer.writeEndElement(); // table-cell } child = iterator.currentFrame(); ++iterator; } if (tableRow >= 0) writer.writeEndElement(); // close table-row if (table || (frame->document() && frame->document()->rootFrame() != frame)) writer.writeEndElement(); // close table or section element }
QString TextDocumentSerializer::processFrame(QTextFrame *frame) { QString text; QTextFrame::iterator it = frame->begin(); while(!it.atEnd()){ QTextFrame *childFrame = it.currentFrame(); QTextBlock childBlock = it.currentBlock(); if(childFrame) text += processFrame(childFrame); else if(childBlock.isValid()){ if(childBlock.textList()) text = removeTrailingLineBreaks(text); text += processBlock(childBlock, it); } ++it; } text = removeTrailingLineBreaks(text); return text; }
void MainWindow::showList() { QTextCursor cursor = editor->textCursor(); QTextFrame *frame = cursor.currentFrame(); if (!frame) return; QTreeWidget *treeWidget = new QTreeWidget; treeWidget->setColumnCount(1); QStringList headerLabels; headerLabels << tr("Lists"); treeWidget->setHeaderLabels(headerLabels); QTreeWidgetItem *parentItem = 0; QTreeWidgetItem *item; QTreeWidgetItem *lastItem = 0; parentItems.clear(); previousItems.clear(); //! [3] QTextFrame::iterator it; for (it = frame->begin(); !(it.atEnd()); ++it) { QTextBlock block = it.currentBlock(); if (block.isValid()) { QTextList *list = block.textList(); if (list) { int index = list->itemNumber(block); //! [3] if (index == 0) { parentItems.append(parentItem); previousItems.append(lastItem); listStructures.append(list); parentItem = lastItem; lastItem = 0; if (parentItem != 0) item = new QTreeWidgetItem(parentItem, lastItem); else item = new QTreeWidgetItem(treeWidget, lastItem); } else { while (parentItem != 0 && listStructures.last() != list) { listStructures.pop_back(); parentItem = parentItems.takeLast(); lastItem = previousItems.takeLast(); } if (parentItem != 0) item = new QTreeWidgetItem(parentItem, lastItem); else item = new QTreeWidgetItem(treeWidget, lastItem); } item->setText(0, block.text()); lastItem = item; /* //! [4] processListItem(list, index); //! [4] */ //! [5] } //! [5] //! [6] } //! [6] //! [7] } //! [7] treeWidget->setWindowTitle(tr("List Contents")); treeWidget->show(); }
QString Format::frameToString( QTextFrame *frame ) { QString out; QTextFrame::iterator it; for( it = frame->begin(); it != frame->end(); ++it ) { QTextBlock block = it.currentBlock(); if ( block.isValid() ) { out += "<block"; QTextCursor c( block ); QDateTime dt = TextFormats::lastModified( c ); if ( dt.isValid() ) { out += " lastmodified=\"" + dt.toString( Qt::ISODate ) + "\""; } if ( TextFormats::isTitle( c ) ) { out += " titlestyle=\"title\""; } else if ( TextFormats::isSubTitle( c ) ) { out += " titlestyle=\"subtitle\""; } QTextBlockFormat blockFormat = block.blockFormat(); if ( blockFormat.isValid() ) { QTextList *list = block.textList(); if ( list ) { QTextListFormat f = list->format(); out += " liststyle=\""; switch( f.style() ) { default: case QTextListFormat::ListDisc: out += "disc"; break; case QTextListFormat::ListDecimal: out += "decimal"; break; } out += "\""; out += " listindent=\"" + QString::number( f.indent() ) + "\""; } else { if ( blockFormat.indent() != 0 ) { out += " blockindent=\"" + QString::number( blockFormat.indent() ) + "\""; } } } out += ">\n"; QTextBlock::iterator it2; for( it2 = block.begin(); it2 != block.end(); ++it2 ) { QTextFragment fragment = it2.fragment(); if ( !fragment.isValid() ) continue; QString text = fragment.text(); QString outText; for( int i = 0; i < text.size(); ++i ) { if ( text.at( i ) == 0xfffc ) { outText += "<todo status=\""; QTextImageFormat imageFormat = fragment.charFormat().toImageFormat(); if ( imageFormat.isValid() ) { if ( imageFormat.name().contains( "done" ) ) outText += "done"; else outText += "todo"; } else { dbg() << "NO IMAGE FORMAT" << endl; } outText += "\"/>"; } else { outText += escape( QString( text.at( i ) ) ); } } out += " <fragment"; QTextCharFormat format = fragment.charFormat(); if ( !format.anchorHref().isEmpty() ) { out += " link=\"" + escape( format.anchorHref() ) + "\""; } if ( format.fontWeight() == QFont::Bold ) { out += " bold=\"true\""; } if ( format.fontItalic() ) { out += " italic=\"true\""; } if ( format.hasProperty( QTextFormat::FontPointSize ) && format.fontPointSize() != 10 ) { out += " fontsize=\"" + QString::number( format.fontPointSize() ) + "\""; } if ( outText.trimmed().isEmpty() ) outText.replace( " ", "[FIXME:space]" ); out += ">" + outText + "</fragment>\n"; } out += "</block>"; out += "\n"; } QTextFrame *f = it.currentFrame(); if ( f ) { QTextFrameFormat format = f->frameFormat(); out += "<frame"; if ( format.hasProperty( TextFormats::FrameType ) ) { out += " type="; if ( format.property( TextFormats::FrameType ) == TextFormats::CodeFrame ) { out += "\"code\""; } else { out += "\"undefined\""; } } out += ">\n"; out += frameToString( f ); out += "</frame>\n"; } } return out; }
void QQuickTextNode::updateNodes() { return; deleteContent(); if (m_text.isEmpty()) return; if (m_usePixmapCache) { // ### gunnar: port properly // QPixmap pixmap = generatedPixmap(); // if (pixmap.isNull()) // return; // QSGImageNode *pixmapNode = m_context->createImageNode(); // pixmapNode->setRect(pixmap.rect()); // pixmapNode->setSourceRect(pixmap.rect()); // pixmapNode->setOpacity(m_opacity); // pixmapNode->setClampToEdge(true); // pixmapNode->setLinearFiltering(m_linearFiltering); // appendChildNode(pixmapNode); } else { if (m_text.isEmpty()) return; // Implement styling by drawing text several times at slight shifts. shiftForStyle // contains the sequence of shifted positions at which to draw the text. All except // the last will be drawn with styleColor. QList<QPointF> shiftForStyle; switch (m_textStyle) { case OutlineTextStyle: // ### Should be made faster by implementing outline material shiftForStyle << QPointF(-1, 0); shiftForStyle << QPointF(0, -1); shiftForStyle << QPointF(1, 0); shiftForStyle << QPointF(0, 1); break; case SunkenTextStyle: shiftForStyle << QPointF(0, -1); break; case RaisedTextStyle: shiftForStyle << QPointF(0, 1); break; default: break; } shiftForStyle << QPointF(0, 0); // Regular position while (!shiftForStyle.isEmpty()) { QPointF shift = shiftForStyle.takeFirst(); // Use styleColor for all but last shift if (m_richText) { QColor overrideColor = shiftForStyle.isEmpty() ? QColor() : m_styleColor; QTextFrame *textFrame = m_textDocument->rootFrame(); QPointF p = m_textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft(); QTextFrame::iterator it = textFrame->begin(); while (!it.atEnd()) { addTextBlock(shift + p, it.currentBlock(), overrideColor); ++it; } } else { addTextLayout(shift, m_textLayout, shiftForStyle.isEmpty() ? m_color : m_styleColor); } } } }