1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtGui module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QTEXTDOCUMENTFRAGMENT_P_H 43 #define QTEXTDOCUMENTFRAGMENT_P_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists purely as an 50 // implementation detail. This header file may change from version to 51 // version without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 56 #include "QtGui/qtextdocument.h" 57 #include "private/qtexthtmlparser_p.h" 58 #include "private/qtextdocument_p.h" 59 #include "QtGui/qtexttable.h" 60 #include "QtCore/qatomic.h" 61 #include "QtCore/qlist.h" 62 #include "QtCore/qmap.h" 63 #include "QtCore/qpointer.h" 64 #include "QtCore/qvarlengtharray.h" 65 #include "QtCore/qdatastream.h" 66 67 QT_BEGIN_NAMESPACE 68 69 class QTextDocumentFragmentPrivate; 70 71 class QTextCopyHelper 72 { 73 public: 74 QTextCopyHelper(const QTextCursor &_source, const QTextCursor &_destination, bool forceCharFormat = false, const QTextCharFormat &fmt = QTextCharFormat()); 75 76 void copy(); 77 78 private: 79 void appendFragments(int pos, int endPos); 80 int appendFragment(int pos, int endPos, int objectIndex = -1); 81 int convertFormatIndex(const QTextFormat &oldFormat, int objectIndexToSet = -1); 82 inline int convertFormatIndex(int oldFormatIndex, int objectIndexToSet = -1) 83 { return convertFormatIndex(src->formatCollection()->format(oldFormatIndex), objectIndexToSet); } convertFormat(const QTextFormat & fmt)84 inline QTextFormat convertFormat(const QTextFormat &fmt) 85 { return dst->formatCollection()->format(convertFormatIndex(fmt)); } 86 87 int insertPos; 88 89 bool forceCharFormat; 90 int primaryCharFormatIndex; 91 92 QTextCursor cursor; 93 QTextDocumentPrivate *dst; 94 QTextDocumentPrivate *src; 95 QTextFormatCollection &formatCollection; 96 const QString originalText; 97 QMap<int, int> objectIndexMap; 98 }; 99 100 class QTextDocumentFragmentPrivate 101 { 102 public: 103 QTextDocumentFragmentPrivate(const QTextCursor &cursor = QTextCursor()); ~QTextDocumentFragmentPrivate()104 inline ~QTextDocumentFragmentPrivate() { delete doc; } 105 106 void insert(QTextCursor &cursor) const; 107 108 QAtomicInt ref; 109 QTextDocument *doc; 110 111 uint importedFromPlainText : 1; 112 private: 113 Q_DISABLE_COPY(QTextDocumentFragmentPrivate) 114 }; 115 116 #ifndef QT_NO_TEXTHTMLPARSER 117 118 class QTextHtmlImporter : public QTextHtmlParser 119 { 120 struct Table; 121 public: 122 enum ImportMode { 123 ImportToFragment, 124 ImportToDocument 125 }; 126 127 QTextHtmlImporter(QTextDocument *_doc, const QString &html, 128 ImportMode mode, 129 const QTextDocument *resourceProvider = 0); 130 131 void import(); 132 133 private: 134 bool closeTag(); 135 136 Table scanTable(int tableNodeIdx); 137 138 enum ProcessNodeResult { ContinueWithNextNode, ContinueWithCurrentNode, ContinueWithNextSibling }; 139 140 void appendBlock(const QTextBlockFormat &format, QTextCharFormat charFmt = QTextCharFormat()); 141 bool appendNodeText(); 142 143 ProcessNodeResult processBlockNode(); 144 ProcessNodeResult processSpecialNodes(); 145 146 struct List 147 { ListList148 inline List() : listNode(0) {} 149 QTextListFormat format; 150 int listNode; 151 QPointer<QTextList> list; 152 }; 153 QVector<List> lists; 154 int indent; 155 156 // insert a named anchor the next time we emit a char format, 157 // either in a block or in regular text 158 QStringList namedAnchors; 159 160 #ifdef Q_CC_SUN 161 friend struct QTextHtmlImporter::Table; 162 #endif 163 struct TableCellIterator 164 { tableTableCellIterator165 inline TableCellIterator(QTextTable *t = 0) : table(t), row(0), column(0) {} 166 167 inline TableCellIterator &operator++() { 168 if (atEnd()) 169 return *this; 170 do { 171 const QTextTableCell cell = table->cellAt(row, column); 172 if (!cell.isValid()) 173 break; 174 column += cell.columnSpan(); 175 if (column >= table->columns()) { 176 column = 0; 177 ++row; 178 } 179 } while (row < table->rows() && table->cellAt(row, column).row() != row); 180 181 return *this; 182 } 183 atEndTableCellIterator184 inline bool atEnd() const { return table == 0 || row >= table->rows(); } 185 cellTableCellIterator186 QTextTableCell cell() const { return table->cellAt(row, column); } 187 188 QTextTable *table; 189 int row; 190 int column; 191 }; 192 193 friend struct Table; 194 struct Table 195 { TableTable196 Table() : isTextFrame(false), rows(0), columns(0), currentRow(0), lastIndent(0) {} 197 QPointer<QTextFrame> frame; 198 bool isTextFrame; 199 int rows; 200 int columns; 201 int currentRow; // ... for buggy html (see html_skipCell testcase) 202 TableCellIterator currentCell; 203 int lastIndent; 204 }; 205 QVector<Table> tables; 206 207 struct RowColSpanInfo 208 { 209 int row, col; 210 int rowSpan, colSpan; 211 }; 212 213 enum WhiteSpace 214 { 215 RemoveWhiteSpace, 216 CollapseWhiteSpace, 217 PreserveWhiteSpace 218 }; 219 220 WhiteSpace compressNextWhitespace; 221 222 QTextDocument *doc; 223 QTextCursor cursor; 224 QTextHtmlParserNode::WhiteSpaceMode wsm; 225 ImportMode importMode; 226 bool hasBlock; 227 bool forceBlockMerging; 228 bool blockTagClosed; 229 int currentNodeIdx; 230 const QTextHtmlParserNode *currentNode; 231 }; 232 233 QT_END_NAMESPACE 234 #endif // QT_NO_TEXTHTMLPARSER 235 236 #endif // QTEXTDOCUMENTFRAGMENT_P_H 237