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); }
// 遍历框架 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(); } }
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)); }
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::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(); }
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); } } } }