📄 qtextdocument.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 "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) != '<' && text.at(open) != '\n') { if (text.at(open) == '&' && text.mid(open+1,3) == "lt;") return true; // support desperate attempt of user to see <...> ++open; } if (open < text.length() && text.at(open) == '<') { const int close = text.indexOf('>', 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] != '!')) 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 += "<p>"; for (int i = 0; i < plain.length(); ++i) { if (plain[i] == '\n'){ int c = 1; while (i+1 < plain.length() && plain[i+1] == '\n') { i++; c++; } if (c == 1) rich += "<br>\n"; else { rich += "</p>\n"; while (--c > 1) rich += "<br>\n"; rich += "<p>"; } col = 0; } else { if (mode == Qt::WhiteSpacePre && plain[i] == '\t'){ rich += 0x00a0U; ++col; while (col % 8) { rich += 0x00a0U; ++col; } } else if (mode == Qt::WhiteSpacePre && plain[i].isSpace()) rich += 0x00a0U; else if (plain[i] == '<') rich +="<"; else if (plain[i] == '>') rich +=">"; else if (plain[i] == '&') rich +="&"; else rich += plain[i]; ++col; } } if (col != 0) rich += "</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*//*! 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);}/*! 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->d_func()->config()->title = d->config()->title; doc->d_func()->pageSize = d->pageSize; doc->d_func()->useDesignMetrics = d->useDesignMetrics; doc->d_func()->setDefaultFont(d->defaultFont()); 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();}/*! Undoes the last editing operation on the document if \link QTextDocument::isUndoAvailable() undo is available\endlink.*/void QTextDocument::undo(){ Q_D(QTextDocument); d->undoRedo(true);}/*! Redoes the last editing operation on the document if \link QTextDocument::isRedoAvailable() redo is available\endlink.*/void QTextDocument::redo(){ Q_D(QTextDocument); d->undoRedo(false);}/*! \internal Appends a custom undo \a item to the undo stack.*/void QTextDocument::appendUndoItem(QAbstractUndoItem *item){ Q_D(QTextDocument); d->appendUndoItem(item);}/*! \property QTextDocument::undoRedoEnabled \brief whether undo/redo are enabled for this document This defaults to true. If disabled, the undo stack is cleared and no items will be added to it.*/void QTextDocument::setUndoRedoEnabled(bool enable){ Q_D(QTextDocument); d->enableUndoRedo(enable);}bool QTextDocument::isUndoRedoEnabled() const{ Q_D(const QTextDocument); return d->isUndoRedoEnabled();}/*! \fn void QTextDocument::markContentsDirty(int position, int length) Marks the contents specified by the given \a position and \a length as "dirty", informing the document that it needs to be layed out again.*/void QTextDocument::markContentsDirty(int from, int length){ Q_D(QTextDocument); if (!d->inContentsChange) d->beginEditBlock(); d->documentChange(from, length); if (!d->inContentsChange) d->endEditBlock();}/*! \property QTextDocument::useDesignMetrics \since 4.1*/void QTextDocument::setUseDesignMetrics(bool b){ Q_D(QTextDocument); d->useDesignMetrics = b; documentLayout()->documentChanged(0, 0, d->length());}bool QTextDocument::useDesignMetrics() const{ Q_D(const QTextDocument); return d->useDesignMetrics;}/*! \fn void QTextDocument::contentsChanged() This signal is emitted whenever the document's content changes; for example, when text is inserted or deleted, or when formatting is applied. \sa contentsChange()*//*! \fn void QTextDocument::contentsChange(int position, int charsRemoved, int charsAdded) This signal is emitted whenever the document's content changes; for example, when text is inserted or deleted, or when formatting is applied. Information is provided about the \a position of the character in the document where the change occurred, the number of characters removed (\a charsRemoved), and the number of characters added (\a charsAdded). The signal is emitted before the document's layout manager is notified about the change. This hook allows you to implement syntax highlighting for the document. \sa QAbstractTextDocumentLayout::documentChanged(), contentsChanged()*//*! \fn QTextDocument::undoAvailable(bool available); This signal is emitted whenever undo operations become available (\a available is true) or unavailable (\a available is false).*//*! \fn QTextDocument::redoAvailable(bool available); This signal is emitted whenever redo operations become available (\a available is true) or unavailable (\a available is false).*//*! \fn QTextDocument::cursorPositionChanged(const QTextCursor &cursor); This signal is emitted whenever the position of a cursor changed due to an editing operation. The cursor that changed is passed in \a cursor.*//*! Returns true is undo is available; otherwise returns false.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -