1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QTEXTDOCUMENT_P_H
43 #define QTEXTDOCUMENT_P_H
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.
56 #include "QtCore/qglobal.h"
57 #include "QtCore/qstring.h"
58 #include "QtCore/qvector.h"
59 #include "QtCore/qlist.h"
60 #include "private/qobject_p.h"
61 #include "private/qfragmentmap_p.h"
62 #include "QtGui/qtextlayout.h"
63 #include "QtGui/qtextoption.h"
64 #include "private/qtextformat_p.h"
65 #include "QtGui/qtextdocument.h"
66 #include "QtGui/qtextobject.h"
67 #include "QtGui/qtextcursor.h"
68 #include "QtCore/qmap.h"
69 #include "QtCore/qvariant.h"
70 #include "QtCore/qurl.h"
71 #include "private/qcssparser_p.h"
73 // #define QT_QMAP_DEBUG
81 class QTextFormatCollection;
83 class QTextBlockFormat;
84 class QTextCursorPrivate;
85 class QAbstractTextDocumentLayout;
89 #define QTextBeginningOfFrame QChar(0xfdd0)
90 #define QTextEndOfFrame QChar(0xfdd1)
92 class QTextFragmentData : public QFragment<>
95 inline void initialize() {}
96 inline void invalidate() const {}
102 class QTextBlockData : public QFragment<3>
105 inline void initialize()
106 { layout = 0; userData = 0; userState = -1; revision = 0; hidden = 0; }
107 void invalidate() const;
109 { delete layout; layout = 0; delete userData; userData = 0; }
112 // ##### probably store a QTextEngine * here!
113 mutable QTextLayout *layout;
114 mutable QTextBlockUserData *userData;
115 mutable int userState;
116 mutable int revision : 31;
117 mutable uint hidden : 1;
121 class QAbstractUndoItem;
123 class QTextUndoCommand
129 CharFormatChanged = 2,
130 BlockFormatChanged = 3,
135 GroupFormatChange = 8,
144 uint block_part : 1; // all commands that are part of an undo block (including the first and the last one) have this set to 1
145 uint block_end : 1; // the last command in an undo block has this set to 1.
146 uint block_padding : 6; // padding since block used to be a quint8
154 QAbstractUndoItem *custom;
159 bool tryMerge(const QTextUndoCommand &other);
161 Q_DECLARE_TYPEINFO(QTextUndoCommand, Q_PRIMITIVE_TYPE);
163 class Q_AUTOTEST_EXPORT QTextDocumentPrivate : public QObjectPrivate
165 Q_DECLARE_PUBLIC(QTextDocument)
167 typedef QFragmentMap<QTextFragmentData> FragmentMap;
168 typedef FragmentMap::ConstIterator FragmentIterator;
169 typedef QFragmentMap<QTextBlockData> BlockMap;
171 QTextDocumentPrivate();
172 ~QTextDocumentPrivate();
177 void setLayout(QAbstractTextDocumentLayout *layout);
179 void insert(int pos, const QString &text, int format);
180 void insert(int pos, int strPos, int strLength, int format);
181 int insertBlock(int pos, int blockFormat, int charFormat, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
182 int insertBlock(const QChar &blockSeparator, int pos, int blockFormat, int charFormat,
183 QTextUndoCommand::Operation op = QTextUndoCommand::MoveCursor);
185 void move(int from, int to, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
186 void remove(int pos, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
188 void aboutToRemoveCell(int cursorFrom, int cursorEnd);
190 QTextFrame *insertFrame(int start, int end, const QTextFrameFormat &format);
191 void removeFrame(QTextFrame *frame);
193 enum FormatChangeMode { MergeFormat, SetFormat, SetFormatAndPreserveObjectIndices };
195 void setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode = SetFormat);
196 void setBlockFormat(const QTextBlock &from, const QTextBlock &to,
197 const QTextBlockFormat &newFormat, FormatChangeMode mode = SetFormat);
199 void emitUndoAvailable(bool available);
200 void emitRedoAvailable(bool available);
202 int undoRedo(bool undo);
203 inline void undo() { undoRedo(true); }
204 inline void redo() { undoRedo(false); }
205 void appendUndoItem(QAbstractUndoItem *);
206 inline void beginEditBlock() { if (0 == editBlock++) ++revision; }
207 void joinPreviousEditBlock();
210 inline bool isInEditBlock() const { return editBlock; }
211 void enableUndoRedo(bool enable);
212 inline bool isUndoRedoEnabled() const { return undoEnabled; }
214 inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; }
215 inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); }
217 inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; }
218 inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; }
220 inline QString buffer() const { return text; }
221 QString plainText() const;
222 inline int length() const { return fragments.length(); }
224 inline QTextFormatCollection *formatCollection() { return &formats; }
225 inline const QTextFormatCollection *formatCollection() const { return &formats; }
226 inline QAbstractTextDocumentLayout *layout() const { return lout; }
228 inline FragmentIterator find(int pos) const { return fragments.find(pos); }
229 inline FragmentIterator begin() const { return fragments.begin(); }
230 inline FragmentIterator end() const { return fragments.end(); }
232 inline QTextBlock blocksBegin() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.firstNode()); }
233 inline QTextBlock blocksEnd() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), 0); }
234 inline QTextBlock blocksFind(int pos) const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.findNode(pos)); }
235 int blockCharFormatIndex(int node) const;
237 inline int numBlocks() const { return blocks.numNodes(); }
239 const BlockMap &blockMap() const { return blocks; }
240 const FragmentMap &fragmentMap() const { return fragments; }
241 BlockMap &blockMap() { return blocks; }
242 FragmentMap &fragmentMap() { return fragments; }
244 static const QTextBlockData *block(const QTextBlock &it) { return it.p->blocks.fragment(it.n); }
246 int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
247 int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
248 int leftCursorPosition(int position) const;
249 int rightCursorPosition(int position) const;
251 void changeObjectFormat(QTextObject *group, int format);
253 void setModified(bool m);
254 inline bool isModified() const { return modified; }
256 inline QFont defaultFont() const { return formats.defaultFont(); }
257 inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
259 void clearUndoRedoStacks(QTextDocument::Stacks stacksToClear, bool emitSignals = false);
265 void insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op);
266 int insert_block(int pos, uint strPos, int format, int blockformat, QTextUndoCommand::Operation op, int command);
267 int remove_string(int pos, uint length, QTextUndoCommand::Operation op);
268 int remove_block(int pos, int *blockformat, int command, QTextUndoCommand::Operation op);
270 void insert_frame(QTextFrame *f);
271 void scan_frames(int pos, int charsRemoved, int charsAdded);
272 static void clearFrame(QTextFrame *f);
274 void adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op);
276 bool wasUndoAvailable;
277 bool wasRedoAvailable;
280 void documentChange(int from, int length);
282 inline void addCursor(QTextCursorPrivate *c) { cursors.append(c); }
283 inline void removeCursor(QTextCursorPrivate *c) { cursors.removeAll(c); }
285 QTextFrame *frameAt(int pos) const;
286 QTextFrame *rootFrame() const;
288 QTextObject *objectForIndex(int objectIndex) const;
289 QTextObject *objectForFormat(int formatIndex) const;
290 QTextObject *objectForFormat(const QTextFormat &f) const;
292 QTextObject *createObject(const QTextFormat &newFormat, int objectIndex = -1);
293 void deleteObject(QTextObject *object);
295 QTextDocument *document() { return q_func(); }
296 const QTextDocument *document() const { return q_func(); }
298 bool ensureMaximumBlockCount();
301 QTextDocumentPrivate(const QTextDocumentPrivate& m);
302 QTextDocumentPrivate& operator= (const QTextDocumentPrivate& m);
304 void appendUndoItem(const QTextUndoCommand &c);
306 void contentsChanged();
308 void compressPieceTable();
311 uint unreachableCharacterCount;
313 QVector<QTextUndoCommand> undoStack;
317 // position in undo stack of the last setModified(false) call
322 int editBlockCursorPosition;
324 int docChangeOldLength;
328 QTextFormatCollection formats;
329 mutable QTextFrame *rtFrame;
330 QAbstractTextDocumentLayout *lout;
331 FragmentMap fragments;
333 int initialBlockCharFormatIndex;
335 QList<QTextCursorPrivate *> cursors;
336 QMap<int, QTextObject *> objects;
337 QMap<QUrl, QVariant> resources;
338 QMap<QUrl, QVariant> cachedResources;
339 QString defaultStyleSheet;
344 QTextOption defaultTextOption;
345 Qt::CursorMoveStyle defaultCursorMoveStyle;
346 #ifndef QT_NO_CSSPARSER
347 QCss::StyleSheet parsedDefaultStyleSheet;
349 int maximumBlockCount;
350 uint needsEnsureMaximumBlockCount : 1;
351 uint inContentsChange : 1;
352 uint blockCursorAdjustment : 1;
357 qreal documentMargin;
359 void mergeCachedResources(const QTextDocumentPrivate *priv);
361 friend class QTextHtmlExporter;
362 friend class QTextCursor;
366 class QTextHtmlExporter
369 QTextHtmlExporter(const QTextDocument *_doc);
372 ExportEntireDocument,
376 QString toHtml(const QByteArray &encoding, ExportMode mode = ExportEntireDocument);
379 enum StyleMode { EmitStyleTag, OmitStyleTag };
380 enum FrameType { TextFrame, TableFrame, RootFrame };
382 void emitFrame(QTextFrame::Iterator frameIt);
383 void emitTextFrame(const QTextFrame *frame);
384 void emitBlock(const QTextBlock &block);
385 void emitTable(const QTextTable *table);
386 void emitFragment(const QTextFragment &fragment);
388 void emitBlockAttributes(const QTextBlock &block);
389 bool emitCharFormatStyle(const QTextCharFormat &format);
390 void emitTextLength(const char *attribute, const QTextLength &length);
391 void emitAlignment(Qt::Alignment alignment);
392 void emitFloatStyle(QTextFrameFormat::Position pos, StyleMode mode = EmitStyleTag);
393 void emitMargins(const QString &top, const QString &bottom, const QString &left, const QString &right);
394 void emitAttribute(const char *attribute, const QString &value);
395 void emitFrameStyle(const QTextFrameFormat &format, FrameType frameType);
396 void emitBorderStyle(QTextFrameFormat::BorderStyle style);
397 void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy);
399 void emitFontFamily(const QString &family);
401 void emitBackgroundAttribute(const QTextFormat &format);
402 QString findUrlForImage(const QTextDocument *doc, qint64 cacheKey, bool isPixmap);
405 QTextCharFormat defaultCharFormat;
406 const QTextDocument *doc;
407 bool fragmentMarkers;
412 #endif // QTEXTDOCUMENT_P_H