📄 qtexthtmlparser.cpp
字号:
case Html_h5: charFormat.setFontWeight(QFont::Bold); charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(-1)); margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 4; break; case Html_p: margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 12; break; case Html_center: blockFormat.setAlignment(Qt::AlignCenter); break; case Html_ul: listStyle = QTextListFormat::ListDisc; // nested lists don't have margins, except for the toplevel one if (!isNestedList(parser)) { margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 12; } // no left margin as we use indenting instead break; case Html_ol: listStyle = QTextListFormat::ListDecimal; // nested lists don't have margins, except for the toplevel one if (!isNestedList(parser)) { margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 12; } // no left margin as we use indenting instead break; case Html_code: case Html_tt: case Html_kbd: case Html_samp: charFormat.setFontFamily(QString::fromLatin1("Courier New,courier")); // <tt> uses a fixed font, so set the property charFormat.setFontFixedPitch(true); break; case Html_br: text = QChar(QChar::LineSeparator); wsm = QTextHtmlParserNode::WhiteSpacePre; break; // ##### sub / sup case Html_pre: charFormat.setFontFamily(QString::fromLatin1("Courier New,courier")); wsm = WhiteSpacePre; margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 12; // <pre> uses a fixed font charFormat.setFontFixedPitch(true); break; case Html_blockquote: margin[QTextHtmlParser::MarginTop] = 12; margin[QTextHtmlParser::MarginBottom] = 12; margin[QTextHtmlParser::MarginLeft] = 40; margin[QTextHtmlParser::MarginRight] = 40; break; case Html_dl: margin[QTextHtmlParser::MarginTop] = 8; margin[QTextHtmlParser::MarginBottom] = 8; break; case Html_dd: margin[QTextHtmlParser::MarginLeft] = 30; break; case Html_u: charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); break; case Html_s: charFormat.setFontStrikeOut(true); break; case Html_nobr: wsm = WhiteSpaceNoWrap; break; case Html_th: charFormat.setFontWeight(QFont::Bold); blockFormat.setAlignment(Qt::AlignCenter); break; case Html_td: blockFormat.setAlignment(Qt::AlignLeft); break; case Html_sub: charFormat.setVerticalAlignment(QTextCharFormat::AlignSubScript); break; case Html_sup: charFormat.setVerticalAlignment(QTextCharFormat::AlignSuperScript); break; default: break; }}void QTextHtmlParserNode::setListStyle(const QVector<QCss::Value> &cssValues){ for (int i = 0; i < cssValues.count(); ++i) { if (cssValues.at(i).type == QCss::Value::KnownIdentifier) { switch (static_cast<QCss::KnownValue>(cssValues.at(i).variant.toInt())) { case QCss::Value_Disc: hasOwnListStyle = true; listStyle = QTextListFormat::ListDisc; break; case QCss::Value_Square: hasOwnListStyle = true; listStyle = QTextListFormat::ListSquare; break; case QCss::Value_Circle: hasOwnListStyle = true; listStyle = QTextListFormat::ListCircle; break; case QCss::Value_Decimal: hasOwnListStyle = true; listStyle = QTextListFormat::ListDecimal; break; case QCss::Value_LowerAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerAlpha; break; case QCss::Value_UpperAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperAlpha; break; default: break; } } } // allow individual list items to override the style if (id == Html_li && hasOwnListStyle) blockFormat.setProperty(QTextFormat::ListStyle, listStyle);}void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration> &declarations, const QTextDocument *resourceProvider){ QCss::ValueExtractor extractor(declarations); int ignoredBorders[4]; extractor.extractBox(margin, ignoredBorders); for (int i = 0; i < declarations.count(); ++i) { const QCss::Declaration &decl = declarations.at(i); if (decl.values.isEmpty()) continue; QCss::KnownValue identifier = QCss::UnknownValue; if (decl.values.first().type == QCss::Value::KnownIdentifier) identifier = static_cast<QCss::KnownValue>(decl.values.first().variant.toInt()); switch (decl.propertyId) { case QCss::BorderColor: borderBrush = QBrush(decl.colorValue()); break; case QCss::BorderStyles: if (decl.styleValue() != QCss::BorderStyle_Unknown && decl.styleValue() != QCss::BorderStyle_Native) borderStyle = static_cast<QTextFrameFormat::BorderStyle>(decl.styleValue() - 1); break; case QCss::Color: charFormat.setForeground(decl.colorValue()); break; case QCss::Float: cssFloat = QTextFrameFormat::InFlow; switch (identifier) { case QCss::Value_Left: cssFloat = QTextFrameFormat::FloatLeft; break; case QCss::Value_Right: cssFloat = QTextFrameFormat::FloatRight; break; default: break; } break; case QCss::QtBlockIndent: blockFormat.setIndent(decl.values.first().variant.toInt()); break; case QCss::TextIndent: { qreal indent = 0; if (decl.realValue(&indent, "px")) blockFormat.setTextIndent(indent); break; } case QCss::QtListIndent: if (decl.intValue(&cssListIndent)) hasCssListIndent = true; break; case QCss::QtParagraphType: if (decl.values.first().variant.toString().compare(QLatin1String("empty"), Qt::CaseInsensitive) == 0) isEmptyParagraph = true; break; case QCss::QtTableType: if (decl.values.first().variant.toString().compare(QLatin1String("frame"), Qt::CaseInsensitive) == 0) isTextFrame = true; else if (decl.values.first().variant.toString().compare(QLatin1String("root"), Qt::CaseInsensitive) == 0) { isTextFrame = true; isRootFrame = true; } break; case QCss::QtUserState: userState = decl.values.first().variant.toInt(); break; case QCss::Whitespace: switch (identifier) { case QCss::Value_Normal: wsm = QTextHtmlParserNode::WhiteSpaceNormal; break; case QCss::Value_Pre: wsm = QTextHtmlParserNode::WhiteSpacePre; break; case QCss::Value_NoWrap: wsm = QTextHtmlParserNode::WhiteSpaceNoWrap; break; case QCss::Value_PreWrap: wsm = QTextHtmlParserNode::WhiteSpacePreWrap; break; default: break; } break; case QCss::VerticalAlignment: switch (identifier) { case QCss::Value_Sub: charFormat.setVerticalAlignment(QTextCharFormat::AlignSubScript); break; case QCss::Value_Super: charFormat.setVerticalAlignment(QTextCharFormat::AlignSuperScript); break; case QCss::Value_Middle: charFormat.setVerticalAlignment(QTextCharFormat::AlignMiddle); break; case QCss::Value_Top: charFormat.setVerticalAlignment(QTextCharFormat::AlignTop); break; case QCss::Value_Bottom: charFormat.setVerticalAlignment(QTextCharFormat::AlignBottom); break; default: charFormat.setVerticalAlignment(QTextCharFormat::AlignNormal); break; } break; case QCss::PageBreakBefore: switch (identifier) { case QCss::Value_Always: blockFormat.setPageBreakPolicy(blockFormat.pageBreakPolicy() | QTextFormat::PageBreak_AlwaysBefore); break; case QCss::Value_Auto: blockFormat.setPageBreakPolicy(blockFormat.pageBreakPolicy() & ~QTextFormat::PageBreak_AlwaysBefore); break; default: break; } break; case QCss::PageBreakAfter: switch (identifier) { case QCss::Value_Always: blockFormat.setPageBreakPolicy(blockFormat.pageBreakPolicy() | QTextFormat::PageBreak_AlwaysAfter); break; case QCss::Value_Auto: blockFormat.setPageBreakPolicy(blockFormat.pageBreakPolicy() & ~QTextFormat::PageBreak_AlwaysAfter); break; default: break; } break; case QCss::TextUnderlineStyle: switch (identifier) { case QCss::Value_None: charFormat.setUnderlineStyle(QTextCharFormat::NoUnderline); break; case QCss::Value_Solid: charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); break; case QCss::Value_Dashed: charFormat.setUnderlineStyle(QTextCharFormat::DashUnderline); break; case QCss::Value_Dotted: charFormat.setUnderlineStyle(QTextCharFormat::DotLine); break; case QCss::Value_DotDash: charFormat.setUnderlineStyle(QTextCharFormat::DashDotLine); break; case QCss::Value_DotDotDash: charFormat.setUnderlineStyle(QTextCharFormat::DashDotDotLine); break; case QCss::Value_Wave: charFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); break; default: break; } break; case QCss::ListStyleType: case QCss::ListStyle: setListStyle(decl.values); break; default: break; } } QFont f; int adjustment = -255; extractor.extractFont(&f, &adjustment); if (f.resolve() & QFontPrivate::Size) { if (f.pointSize() > 0) { charFormat.setFontPointSize(f.pointSize()); } else if (f.pixelSize() > 0) { charFormat.setProperty(QTextFormat::FontPixelSize, f.pixelSize()); } } if (f.resolve() & QFontPrivate::Style) charFormat.setFontItalic(f.style() != QFont::StyleNormal); if (f.resolve() & QFontPrivate::Weight) charFormat.setFontWeight(f.weight()); if (f.resolve() & QFontPrivate::Family) charFormat.setFontFamily(f.family()); if (f.resolve() & QFontPrivate::Underline) charFormat.setUnderlineStyle(f.underline() ? QTextCharFormat::SingleUnderline : QTextCharFormat::NoUnderline); if (f.resolve() & QFontPrivate::Overline) charFormat.setFontOverline(f.overline()); if (f.resolve() & QFontPrivate::StrikeOut) charFormat.setFontStrikeOut(f.strikeOut()); if (adjustment >= -1) charFormat.setProperty(QTextFormat::FontSizeAdjustment, adjustment); { Qt::Alignment ignoredAlignment; QCss::Repeat ignoredRepeat; QString bgImage; QBrush bgBrush; QCss::Origin ignoredOrigin, ignoredClip; QCss::Attachment ignoredAttachment; extractor.extractBackground(&bgBrush, &bgImage, &ignoredRepeat, &ignoredAlignment, &ignoredOrigin, &ignoredAttachment, &ignoredClip); if (!bgImage.isEmpty() && resourceProvider) { QVariant val = resourceProvider->resource(QTextDocument::ImageResource, bgImage); if (val.type() == QVariant::Image || val.type() == QVariant::Pixmap) { charFormat.setBackground(qvariant_cast<QPixmap>(val)); } else if (val.type() == QVariant::ByteArray) { QPixmap pm; if (pm.loadFromData(val.toByteArray())) charFormat.setBackground(pm); } } else if (bgBrush.style() != Qt::NoBrush) { charFormat.setBackground(bgBrush); } }}bool QTextHtmlParserNode::hasOnlyWhitespace() const{ for (int i = 0; i < text.count(); ++i) if (!text.at(i).isSpace()) return false; return true;}static bool setIntAttribute(int *destination, const QString &value){ bool ok = false; int val = value.toInt(&ok); if (ok) *destination = val; return ok;}static bool setFloatAttribute(qreal *destination, const QString &value){ bool ok = false; qreal val = value.toDouble(&ok); if (ok) *destination = val; return ok;}static void setWidthAttribute(QTextLength *width, QString value){ qreal realVal; bool ok = false; realVal = value.toDouble(&ok); if (ok) { *width = QTextLength(QTextLength::FixedLength, realVal); } else { value = value.trimmed(); if (!value.isEmpty() && value.at(value.length() - 1) == QLatin1Char('%')) { value.chop(1); realVal = value.toDouble(&ok); if (ok) *width = QTextLength(QTextLength::PercentageLength, realVal); } }}void QTextHtmlParserNode::parseStyleAttribute(const QString &value, const QTextDocument *resourceProvider){ QString css = value; css.prepend(QLatin1String("dummy {")); css.append(QLatin1Char('}')); QCss::Parser parser(css); QCss::StyleSheet sheet; parser.parse(&sheet); if (sheet.styleRules.count() != 1) return; applyCssDeclarations(sheet.styleRules.at(0).declarations, resourceProvider);}QStringList QTextHtmlParser::parseAttributes(){ QStringList attrs; while (pos < len) { eatSpace(); if (hasPrefix(QLatin1Char('>')) || hasPrefix(QLatin1Char('/'))) break; QString key = parseWord().toLower(); QString value = QLatin1String("1"); if (key.size() == 0) break; eatSpace(); if (hasPrefix(QLatin1Char('='))){ pos++; eatSpace(); value = parseWord(); } if (value.size() == 0) continue; attrs << key << value; } return attrs;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -