📄 qtextdocumentfragment.cpp
字号:
) block.setIndent(indent); block.merge(node->blockFormat()); charFmt.merge(node->charFormat()); // ####################// block.setFloatPosition(node->cssFloat); if (node->wsm == QTextHtmlParserNode::WhiteSpacePre) block.setNonBreakableLines(true); if (node->bgColor.isValid() && !node->isTableCell) block.setBackground(QBrush(node->bgColor)); if (hasBlock && (!node->isEmptyParagraph || forceBlockMerging)) { if (cursor.position() == 0) { containsCompleteDoc = true; } cursor.setBlockFormat(block); cursor.setBlockCharFormat(charFmt); } else { if (i == 1 && cursor.position() == 0 && node->isEmptyParagraph) { containsCompleteDoc = true; cursor.setBlockFormat(block); cursor.setBlockCharFormat(charFmt); } else { block.clearProperty(QTextFormat::ObjectIndex); charFmt.clearProperty(QTextFormat::ObjectIndex); appendBlock(block, charFmt); } } if (node->isListItem && !lists.isEmpty()) { List &l = lists.last(); if (l.list) { l.list->add(cursor.block()); } else { l.list = cursor.createList(l.format); } } forceBlockMerging = false; if (node->id == Html_body || node->id == Html_html) forceBlockMerging = true; if (node->isEmptyParagraph) { hasBlock = false; continue; } hasBlock = true; } if (node->isAnchor && !node->anchorName.isEmpty()) { setNamedAnchorInNextOutput = true; namedAnchor = node->anchorName; } if (node->text.isEmpty()) continue; hasBlock = false; QTextCharFormat format = node->charFormat(); QString text = node->text; if (setNamedAnchorInNextOutput) { QTextCharFormat fmt = format; fmt.setAnchor(true); fmt.setAnchorName(namedAnchor); cursor.insertText(QString(text.at(0)), fmt); text.remove(0, 1); format.setAnchor(false); format.setAnchorName(QString()); setNamedAnchorInNextOutput = false; } if (!text.isEmpty()) cursor.insertText(text, format); } cursor.endEditBlock();}// returns true if a block tag was closedbool QTextHtmlImporter::closeTag(int i){ const QTextHtmlParserNode *closedNode = &at(i - 1); const int endDepth = depth(i) - 1; int depth = this->depth(i - 1); bool blockTagClosed = false; while (depth > endDepth) { if (closedNode->id == Html_tr && !tables.isEmpty()) { Table &t = tables.last(); if (!t.isTextFrame) { ++t.currentRow; // for broken html with rowspans but missing tr tags while (!t.currentCell.atEnd() && t.currentCell.row < t.currentRow) ++t.currentCell; } blockTagClosed = true; } else if (closedNode->id == Html_table && !tables.isEmpty()) { tables.resize(tables.size() - 1); if (tables.isEmpty()) { cursor = doc->rootFrame()->lastCursorPosition(); } else { Table &t = tables.last(); if (t.isTextFrame) cursor = t.frame->lastCursorPosition(); else cursor = t.currentCell.cell().lastCursorPosition(); } // we don't need an extra block after tables, so we don't // claim to have closed one for the creation of a new one // in import() blockTagClosed = false; } else if (closedNode->isTableCell && !tables.isEmpty()) { Table &t = tables.last(); if (!t.isTextFrame) ++tables.last().currentCell; blockTagClosed = true; } else if (closedNode->isListStart) { Q_ASSERT(!lists.isEmpty()); lists.resize(lists.size() - 1); --indent; blockTagClosed = true; } else if (closedNode->id == Html_hr || closedNode->id == Html_center || closedNode->id == Html_h1 || closedNode->id == Html_h2 || closedNode->id == Html_h3 || closedNode->id == Html_h4 || closedNode->id == Html_h5 || closedNode->id == Html_h6 ) { blockTagClosed = true; } else if (closedNode->id == Html_p) { // blockTagClosed may result in the creation of a // new block if (!closedNode->text.isEmpty()) blockTagClosed = true; } closedNode = &at(closedNode->parent); --depth; } return blockTagClosed;}QTextHtmlImporter::Table QTextHtmlImporter::scanTable(int tableNodeIdx){ Table table; table.columns = 0; QVector<QTextLength> columnWidths; QVector<int> rowSpanCellsPerRow; QVector<int> rowNodes; rowNodes.reserve(at(tableNodeIdx).children.count()); foreach (int row, at(tableNodeIdx).children) switch (at(row).id) { case Html_tr: rowNodes += row; break; case Html_thead: case Html_tbody: case Html_tfoot: foreach (int potentialRow, at(row).children) if (at(potentialRow).id == Html_tr) rowNodes += potentialRow; break; default: break; } int effectiveRow = 0; foreach (int row, rowNodes) { int colsInRow = 0; foreach (int cell, at(row).children) if (at(cell).isTableCell) { const QTextHtmlParserNode &c = at(cell); const int currentColumn = colsInRow; colsInRow += c.tableCellColSpan; if (c.tableCellRowSpan > 1) { rowSpanCellsPerRow.resize(effectiveRow + c.tableCellRowSpan + 1); for (int r = effectiveRow + 1; r < effectiveRow + c.tableCellRowSpan; ++r) rowSpanCellsPerRow[r]++; } columnWidths.resize(qMax(columnWidths.count(), colsInRow)); for (int i = currentColumn; i < currentColumn + c.tableCellColSpan; ++i) if (columnWidths.at(i).type() == QTextLength::VariableLength) columnWidths[i] = c.width; } table.columns = qMax(table.columns, colsInRow + rowSpanCellsPerRow.value(effectiveRow, 0)); ++effectiveRow; rowSpanCellsPerRow.append(0); } table.rows = effectiveRow; if (table.rows == 0 || table.columns == 0) return table; QTextFrameFormat fmt; const QTextHtmlParserNode &node = at(tableNodeIdx); if (node.isTextFrame) { // for plain text frames we set the frame margin // for all of top/bottom/left/right, so in the import // here it doesn't matter which one we pick fmt.setMargin(node.uncollapsedMargin(QTextHtmlParser::MarginTop)); } else { QTextTableFormat tableFmt; tableFmt.setCellSpacing(node.tableCellSpacing); tableFmt.setCellPadding(node.tableCellPadding); if (node.alignment) tableFmt.setAlignment(node.alignment); tableFmt.setColumns(table.columns); tableFmt.setColumnWidthConstraints(columnWidths); fmt = tableFmt; } fmt.setBorder(node.tableBorder); fmt.setWidth(node.width); fmt.setHeight(node.height); if (node.direction < 2) fmt.setLayoutDirection(Qt::LayoutDirection(node.direction)); if (node.bgColor.isValid()) fmt.setBackground(QBrush(node.bgColor)); else fmt.clearBackground(); fmt.setPosition(QTextFrameFormat::Position(node.cssFloat)); if (node.isTextFrame) { table.frame = cursor.insertFrame(fmt); table.isTextFrame = true; } else { QTextTable *textTable = cursor.insertTable(table.rows, table.columns, fmt.toTableFormat()); table.frame = textTable; TableCellIterator it(textTable); foreach (int row, rowNodes) foreach (int cell, at(row).children) if (at(cell).isTableCell) { const QTextHtmlParserNode &c = at(cell); if (c.tableCellColSpan > 1 || c.tableCellRowSpan > 1) textTable->mergeCells(it.row, it.column, c.tableCellRowSpan, c.tableCellColSpan); ++it; } table.currentCell = TableCellIterator(textTable); } return table;}void QTextHtmlImporter::appendBlock(const QTextBlockFormat &format, QTextCharFormat charFmt){ if (setNamedAnchorInNextOutput) { charFmt.setAnchor(true); charFmt.setAnchorName(namedAnchor); setNamedAnchorInNextOutput = false; } cursor.insertBlock(format, charFmt);}/*! \fn QTextDocumentFragment QTextDocumentFragment::fromHtml(const QString &text) Returns a QTextDocumentFragment based on the arbitrary piece of HTML in the given \a text. The formatting is preserved as much as possible; for example, "<b>bold</b>" will become a document fragment with the text "bold" with a bold character format.*/QTextDocumentFragment QTextDocumentFragment::fromHtml(const QString &html){ QTextDocumentFragment res; res.d = new QTextDocumentFragmentPrivate; QTextHtmlImporter importer(res.d->doc, html); importer.import(); res.d->containsCompleteDocument = importer.containsCompleteDocument(); return res;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -