📄 qtextdocument.cpp
字号:
/*! \fn QTextDocument::modificationChanged(bool changed) This signal is emitted whenever the content of the document changes in a way that affects the modification state. If \a changed is true, the document has been modified; otherwise it is false. For example, calling setModified(false) on a document and then inserting text causes the signal to get emitted. If you undo that operation, causing the document to return to its original unmodified state, the signal will get emitted again.*//*! \property QTextDocument::modified \brief whether the document has been modified by the user \sa modificationChanged()*/bool QTextDocument::isModified() const{ return docHandle()->isModified();}void QTextDocument::setModified(bool m){ docHandle()->setModified(m);}#ifndef QT_NO_PRINTERstatic void printPage(int index, QPainter *painter, const QTextDocument *doc, const QRectF &body, const QPointF &pageNumberPos){ painter->save(); painter->translate(body.left(), body.top() - (index - 1) * body.height()); QRectF view(0, (index - 1) * body.height(), body.width(), body.height()); QAbstractTextDocumentLayout *layout = doc->documentLayout(); QAbstractTextDocumentLayout::PaintContext ctx; painter->setClipRect(view); ctx.clip = view; // don't use the system palette text as default text color, on HP/UX // for example that's white, and white text on white paper doesn't // look that nice ctx.palette.setColor(QPalette::Text, Qt::black); layout->draw(painter, ctx); if (!pageNumberPos.isNull()) { painter->setClipping(false); painter->setFont(QFont(doc->defaultFont())); const QString pageString = QString::number(index); painter->drawText(qRound(pageNumberPos.x() - painter->fontMetrics().width(pageString)), qRound(pageNumberPos.y() + view.top()), pageString); } painter->restore();}/*! Prints the document to the given \a printer. The QPrinter must be set up before being used with this function. This is only a convenience method to print the whole document to the printer. If the document is already paginated through a specified height in the pageSize() property it is printed as-is. If the document is not paginated, like for example a document used in a QTextEdit, then a temporary copy of the document is created and the copy is broken into multiple pages according to the size of the QPrinter's paperRect(). By default a 2 cm margin is set around the document contents. In addition the current page number is printed at the bottom of each page. Note that QPrinter::Selection is not supported as print range with this function since the selection is a property of QTextCursor. If you have a QTextEdit associated with your QTextDocument then you can use QTextEdit's print() function because QTextEdit has access to the user's selection. \sa QTextEdit::print()*/void QTextDocument::print(QPrinter *printer) const{ Q_D(const QTextDocument); if (!d->title.isEmpty()) printer->setDocName(d->title); QPainter p(printer); // Check that there is a valid device to print to. if (!p.isActive()) return; const QTextDocument *doc = this; QTextDocument *clonedDoc = 0; (void)doc->documentLayout(); // make sure that there is a layout QRectF body = QRectF(QPointF(0, 0), d->pageSize); QPointF pageNumberPos; if (d->pageSize.isValid() && !d->pageSize.isNull() && d->pageSize.height() != INT_MAX) { extern int qt_defaultDpi(); qreal sourceDpiX = qt_defaultDpi(); qreal sourceDpiY = sourceDpiX; QPaintDevice *dev = doc->documentLayout()->paintDevice(); if (dev) { sourceDpiX = dev->logicalDpiX(); sourceDpiY = dev->logicalDpiY(); } const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX; const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY; // scale to dpi p.scale(dpiScaleX, dpiScaleY); QSizeF scaledPageSize = d->pageSize; scaledPageSize.rwidth() *= dpiScaleX; scaledPageSize.rheight() *= dpiScaleY; const QSizeF printerPageSize(printer->pageRect().size()); // scale to page p.scale(printerPageSize.width() / scaledPageSize.width(), printerPageSize.height() / scaledPageSize.height()); } else { doc = clone(const_cast<QTextDocument *>(this)); clonedDoc = const_cast<QTextDocument *>(doc); QAbstractTextDocumentLayout *layout = doc->documentLayout(); layout->setPaintDevice(p.device()); const int dpiy = p.device()->logicalDpiY(); const int margin = (int) ((2/2.54)*dpiy); // 2 cm margins QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); fmt.setMargin(margin); doc->rootFrame()->setFrameFormat(fmt); body = QRectF(0, 0, p.device()->width(), p.device()->height()); pageNumberPos = QPointF(body.width() - margin, body.height() - margin + QFontMetrics(doc->defaultFont(), p.device()).ascent() + 5 * p.device()->logicalDpiY() / 72); clonedDoc->setPageSize(body.size()); } int docCopies; int pageCopies; if (printer->collateCopies() == true){ docCopies = 1; pageCopies = printer->numCopies(); } else { docCopies = printer->numCopies(); pageCopies = 1; } int fromPage = printer->fromPage(); int toPage = printer->toPage(); bool ascending = true; if (fromPage == 0 && toPage == 0) { fromPage = 1; toPage = doc->pageCount(); } if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; fromPage = toPage; toPage = tmp; ascending = false; } for (int i = 0; i < docCopies; ++i) { int page = fromPage; while (true) { for (int j = 0; j < pageCopies; ++j) { if (printer->printerState() == QPrinter::Aborted || printer->printerState() == QPrinter::Error) goto UserCanceled; printPage(page, &p, doc, body, pageNumberPos); if (j < pageCopies - 1) printer->newPage(); } if (page == toPage) break; if (ascending) ++page; else --page; printer->newPage(); } if ( i < docCopies - 1) printer->newPage(); }UserCanceled: delete clonedDoc;}#endif/*! \enum QTextDocument::ResourceType This enum describes the types of resources that can be loaded by QTextDocument's loadResource() function. \value HtmlResource The resource contains HTML. \value ImageResource The resource contains image data. Currently supported data types are QVariant::Pixmap and QVariant::Image. If the corresponding variant is of type QVariant::ByteArray then Qt attempts to load the image using QImage::loadFromData. QVariant::Icon is currently not supported. The icon needs to be converted to one of the supported types first, for example using QIcon::pixmap. \value StyleSheetResource The resource contains CSS. \value UserResource The first available value for user defined resource types. \sa loadResource()*//*! Returns data of the specified \a type from the resource with the given \a name. This function is called by the rich text engine to request data that isn't directly stored by QTextDocument, but still associated with it. For example, images are referenced indirectly by the name attribute of a QTextImageFormat object. Resources are cached internally in the document. If a resource can not be found in the cache, loadResource is called to try to load the resource. loadResource should then use addResource to add the resource to the cache.*/QVariant QTextDocument::resource(int type, const QUrl &name) const{ Q_D(const QTextDocument); QVariant r = d->resources.value(name); if (!r.isValid()) { r = d->cachedResources.value(name); if (!r.isValid()) r = const_cast<QTextDocument *>(this)->loadResource(type, name); } return r;}/*! Adds the resource \a resource to the resource cache, using \a type and \a name as identifiers. \a type should be a value from QTextDocument::ResourceType.*/void QTextDocument::addResource(int type, const QUrl &name, const QVariant &resource){ Q_UNUSED(type); Q_D(QTextDocument); d->resources.insert(name, resource);}/*! Loads data of the specified \a type from the resource with the given \a name. This function is called by the rich text engine to request data that isn't directly stored by QTextDocument, but still associated with it. For example, images are referenced indirectly by the name attribute of a QTextImageFormat object. When called by Qt, \a type is one of the values of QTextDocument::ResourceType. If the QTextDocument is a child object of a QTextEdit, QTextBrowser, or a QTextDocument itself then the default implementation tries to retrieve the data from the parent.*/QVariant QTextDocument::loadResource(int type, const QUrl &name){ Q_D(QTextDocument); QVariant r; if (QTextDocument *doc = qobject_cast<QTextDocument *>(parent())) r = doc->loadResource(type, name);#ifndef QT_NO_TEXTEDIT else if (QTextEdit *edit = qobject_cast<QTextEdit *>(parent())) r = edit->loadResource(type, name);#endif#ifndef QT_NO_TEXTCONTROL else if (QTextControl *control = qobject_cast<QTextControl *>(parent())) r = control->loadResource(type, name);#endif if (!r.isNull()) { if (type == ImageResource && r.type() == QVariant::ByteArray) { QPixmap pm; pm.loadFromData(r.toByteArray()); if (!pm.isNull()) r = pm; } d->cachedResources.insert(name, r); } return r;}static QTextFormat formatDifference(const QTextFormat &from, const QTextFormat &to){ QTextFormat diff = to; const QMap<int, QVariant> props = to.properties(); for (QMap<int, QVariant>::ConstIterator it = props.begin(), end = props.end(); it != end; ++it) if (it.value() == from.property(it.key())) diff.clearProperty(it.key()); return diff;}QTextHtmlExporter::QTextHtmlExporter(const QTextDocument *_doc) : doc(_doc), fragmentMarkers(false){ const QFont defaultFont = doc->defaultFont(); defaultCharFormat.setFont(defaultFont); // don't export those for the default font since we cannot turn them off with CSS defaultCharFormat.clearProperty(QTextFormat::FontUnderline); defaultCharFormat.clearProperty(QTextFormat::FontOverline); defaultCharFormat.clearProperty(QTextFormat::FontStrikeOut); defaultCharFormat.clearProperty(QTextFormat::TextUnderlineStyle);}/*! Returns the document in HTML format. The conversion may not be perfect, especially for complex documents, due to the limitations of HTML.*/QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode){ html = QLatin1String("<html><head><meta name=\"qrichtext\" content=\"1\" />"); html.reserve(doc->docHandle()->length()); fragmentMarkers = (mode == ExportFragment); if (!encoding.isEmpty()) html += QString::fromLatin1("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\" />").arg(QString::fromAscii(encoding)); QString title = doc->metaInformation(QTextDocument::DocumentTitle); if (!title.isEmpty()) html += QString::fromLatin1("<title>") + title + QString::fromLatin1("</title>"); html += QLatin1String("<style type=\"text/css\">\n"); html += QLatin1String("p, li { white-space: pre-wrap; }\n"); html += QLatin1String("</style>"); html += QLatin1String("</head><body"); if (mode == ExportEntireDocument) { html += QLatin1String(" style=\""); emitFontFamily(defaultCharFormat.fontFamily()); if (defaultCharFormat.hasProperty(QTextFormat::FontPointSize)) { html += QLatin1String(" font-size:"); html += QString::number(defaultCharFormat.fontPointSize()); html += QLatin1String("pt;"); } html += QLatin1String(" font-weight:"); html += QString::number(defaultCharFormat.fontWeight() * 8); html += QLatin1Char(';'); html += QLatin1String(" font-style:"); html += (defaultCharFormat.fontItalic() ? QLatin1String("italic") : QLatin1String("normal")); html += QLatin1Char(';'); // do not set text-decoration on the default font since those values are /always/ propagated // and cannot be turned off with CSS html += QLatin1Char('\"'); const QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); QBrush bg = fmt.background(); if (bg != Qt::NoBrush) emitAttribute("bgcolor", bg.color().name()); } else { defaultCharFormat = QTextCharFormat(); } html += QLatin1Char('>'); QTextFrameFormat rootFmt = doc->rootFrame()->frameFormat(); rootFmt.clearProperty(QTextFormat::BackgroundBrush); QTextFrameFormat defaultFmt; defaultFmt.setMargin(DefaultRootFrameMargin); if (rootFmt == defaultFmt) emitFrame(doc->rootFrame()->begin()); else emitTextFrame(doc->rootFrame()); html += QLatin1String("</body></html>"); return html;}void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &value){ html += QLatin1Char(' '); html += QLatin1String(attribute); html += QLatin1String("=\""); html += value; html += QLatin1Char('"');}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -