📄 qtextdocument.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qtextdocument.h"#include <qtextformat.h>#include "qtextdocumentlayout_p.h"#include "qtextdocumentfragment.h"#include "qtextdocumentfragment_p.h"#include "qtexttable.h"#include "qtextlist.h"#include <qdebug.h>#include <qregexp.h>#include <qvarlengtharray.h>#include <qtextcodec.h>#include "qtexthtmlparser_p.h"#include "qpainter.h"#include "qprinter.h"#include "qtextedit.h"#include "qtextcontrol_p.h"#include "qtextdocument_p.h"#include <limits.h>/*! Returns true if the string \a text is likely to be rich text; otherwise returns false. This function uses a fast and therefore simple heuristic. It mainly checks whether there is something that looks like a tag before the first line break. Although the result may be correct for common cases, there is no guarantee. This function is defined in the \c <QTextDocument> header file.*/bool Qt::mightBeRichText(const QString& text){ if (text.isEmpty()) return false; int start = 0; while (start < text.length() && text.at(start).isSpace()) ++start; // skip a leading <?xml ... ?> as for example with xhtml if (text.mid(start, 5) == QLatin1String("<?xml")) { while (start < text.length()) { if (text.at(start) == QLatin1Char('?') && start + 2 < text.length() && text.at(start + 1) == QLatin1Char('>')) { start += 2; break; } ++start; } while (start < text.length() && text.at(start).isSpace()) ++start; } if (text.mid(start, 5).toLower() == QLatin1String("<!doc")) return true; int open = start; while (open < text.length() && text.at(open) != QLatin1Char('<') && text.at(open) != QLatin1Char('\n')) { if (text.at(open) == QLatin1Char('&') && text.mid(open+1,3) == QLatin1String("lt;")) return true; // support desperate attempt of user to see <...> ++open; } if (open < text.length() && text.at(open) == QLatin1Char('<')) { const int close = text.indexOf(QLatin1Char('>'), open); if (close > -1) { QString tag; for (int i = open+1; i < close; ++i) { if (text[i].isDigit() || text[i].isLetter()) tag += text[i]; else if (!tag.isEmpty() && text[i].isSpace()) break; else if (!text[i].isSpace() && (!tag.isEmpty() || text[i] != QLatin1Char('!'))) return false; // that's not a tag } return QTextHtmlParser::lookupElement(tag.toLower()) != -1; } } return false;}/*! Converts the plain text string \a plain to a HTML string with HTML metacharacters \c{<}, \c{>}, and \c{&} replaced by HTML entities. Example: \code QString plain = "#include <QtCore>" QString html = Qt::escape(plain); // html == "#include <QtCore>" \endcode This function is defined in the \c <QTextDocument> header file. \sa convertFromPlainText(), mightBeRichText()*/QString Qt::escape(const QString& plain){ QString rich; rich.reserve(int(plain.length() * 1.1)); for (int i = 0; i < plain.length(); ++i) { if (plain.at(i) == QLatin1Char('<')) rich += QLatin1String("<"); else if (plain.at(i) == QLatin1Char('>')) rich += QLatin1String(">"); else if (plain.at(i) == QLatin1Char('&')) rich += QLatin1String("&"); else rich += plain.at(i); } return rich;}/*! \fn QString Qt::convertFromPlainText(const QString &plain, WhiteSpaceMode mode) Converts the plain text string \a plain to an HTML-formatted paragraph while preserving most of its look. \a mode defines how whitespace is handled. This function is defined in the \c <QTextDocument> header file. \sa escape(), mightBeRichText()*/QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode){ int col = 0; QString rich; rich += QLatin1String("<p>"); for (int i = 0; i < plain.length(); ++i) { if (plain[i] == QLatin1Char('\n')){ int c = 1; while (i+1 < plain.length() && plain[i+1] == QLatin1Char('\n')) { i++; c++; } if (c == 1) rich += QLatin1String("<br>\n"); else { rich += QLatin1String("</p>\n"); while (--c > 1) rich += QLatin1String("<br>\n"); rich += QLatin1String("<p>"); } col = 0; } else { if (mode == Qt::WhiteSpacePre && plain[i] == QLatin1Char('\t')){ rich += QChar(0x00a0U); ++col; while (col % 8) { rich += QChar(0x00a0U); ++col; } } else if (mode == Qt::WhiteSpacePre && plain[i].isSpace()) rich += QChar(0x00a0U); else if (plain[i] == QLatin1Char('<')) rich += QLatin1String("<"); else if (plain[i] == QLatin1Char('>')) rich += QLatin1String(">"); else if (plain[i] == QLatin1Char('&')) rich += QLatin1String("&"); else rich += plain[i]; ++col; } } if (col != 0) rich += QLatin1String("</p>"); return rich;}#ifndef QT_NO_TEXTCODEC/*! \internal This function is defined in the \c <QTextDocument> header file.*/QTextCodec *Qt::codecForHtml(const QByteArray &ba){ return QTextCodec::codecForHtml(ba);}#endif/*! \class QTextDocument qtextdocument.h \brief The QTextDocument class holds formatted text that can be viewed and edited using a QTextEdit. \ingroup text \mainclass QTextDocument is a container for structured rich text documents, providing support for styled text and various types of document elements, such as lists, tables, frames, and images. They can be created for use in a QTextEdit, or used independently. Each document element is described by an associated format object. Each format object is treated as a unique object by QTextDocuments, and can be passed to objectForFormat() to obtain the document element that it is applied to. A QTextDocument can be edited programmatically using a QTextCursor, and its contents can be examined by traversing the document structure. The entire document structure is stored as a hierarchy of document elements beneath the root frame, found with the rootFrame() function. Alternatively, if you just want to iterate over the textual contents of the document you can use begin(), end(), and findBlock() to retrieve text blocks that you can examine and iterate over. The layout of a document is determined by the documentLayout(); you can create your own QAbstractTextDocumentLayout subclass and set it using setDocumentLayout() if you want to use your own layout logic. The document's title can be obtained by calling the documentTitle() function. The toPlainText() and toHtml() convenience functions allow you to retrieve the contents of the document as plain text and HTML. The document's text can be searched using the find() functions. Undo/redo of operations performed on the document can be controlled using the setUndoRedoEnabled() function. The undo/redo system can be controlled by an editor widget through the undo() and redo() slots; the document also provides contentsChanged(), undoAvailable(), and redoAvailable() signals that inform connected editor widgets about the state of the undo/redo system. \sa QTextCursor QTextEdit \link richtext.html Rich Text Processing\endlink*//*! \property QTextDocument::defaultFont \brief the default font used to display the document's text*//*! \property QTextDocument::defaultTextOption \brief the default text option will be set on all \l{QTextLayout}s in the document. When \l{QTextBlock}s are created, the defaultTextOption is set on their QTextLayout. This allows setting global properties for the document such as the default word wrap mode. *//*! Constructs an empty QTextDocument with the given \a parent.*/QTextDocument::QTextDocument(QObject *parent) : QObject(*new QTextDocumentPrivate, parent){ Q_D(QTextDocument); d->init();}/*! Constructs a QTextDocument containing the plain (unformatted) \a text specified, and with the given \a parent.*/QTextDocument::QTextDocument(const QString &text, QObject *parent) : QObject(*new QTextDocumentPrivate, parent){ Q_D(QTextDocument); d->init(); QTextCursor(this).insertText(text);}/*! \internal*/QTextDocument::QTextDocument(QTextDocumentPrivate &dd, QObject *parent) : QObject(dd, parent){ Q_D(QTextDocument); d->init();}/*! Destroys the document.*/QTextDocument::~QTextDocument(){}/*! Creates a new QTextDocument that is a copy of this text document. \a parent is the parent of the returned text document.*/QTextDocument *QTextDocument::clone(QObject *parent) const{ Q_D(const QTextDocument); QTextDocument *doc = new QTextDocument(parent); QTextCursor(doc).insertFragment(QTextDocumentFragment(this)); doc->rootFrame()->setFrameFormat(rootFrame()->frameFormat()); QTextDocumentPrivate *priv = doc->d_func(); priv->title = d->title; priv->pageSize = d->pageSize; priv->defaultTextOption = d->defaultTextOption; priv->setDefaultFont(d->defaultFont()); priv->resources = d->resources; priv->defaultStyleSheet = d->defaultStyleSheet; priv->parsedDefaultStyleSheet = d->parsedDefaultStyleSheet; return doc;}/*! Returns true if the document is empty; otherwise returns false.*/bool QTextDocument::isEmpty() const{ Q_D(const QTextDocument); /* because if we're empty we still have one single paragraph as * one single fragment */ return d->length() <= 1;}/*! Clears the document.*/void QTextDocument::clear(){ Q_D(QTextDocument); d->clear(); d->resources.clear();}/*! \since 4.2 Undoes the last editing operation on the document if undo is available. The provided \a cursor is positioned at the end of the location where the edition operation was undone. See the \l {Overview of Qt's Undo Framework}{Qt Undo Framework} documentation for details. \sa undoAvailable(), isUndoRedoEnabled()*/void QTextDocument::undo(QTextCursor *cursor){ Q_D(QTextDocument); const int pos = d->undoRedo(true); if (cursor && pos >= 0) { *cursor = QTextCursor(this); cursor->setPosition(pos); }}/*! \since 4.2 Redoes the last editing operation on the document if \link QTextDocument::isRedoAvailable() redo is available\endlink. The provided \a cursor is positioned at the end of the location where the edition operation was redone.*/void QTextDocument::redo(QTextCursor *cursor){ Q_D(QTextDocument); const int pos = d->undoRedo(false); if (cursor && pos >= 0) { *cursor = QTextCursor(this); cursor->setPosition(pos); }}/*! \overload*/void QTextDocument::undo(){ Q_D(QTextDocument); d->undoRedo(true);}/*! \overload Redoes the last editing operation on the document if \link QTextDocument::isRedoAvailable() redo is available\endlink.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -