Fix uses of qRound on non-floating-point types.
[profile/ivi/qtbase.git] / src / gui / text / qtextdocument_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QTEXTDOCUMENT_P_H
43 #define QTEXTDOCUMENT_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 "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"
72
73 // #define QT_QMAP_DEBUG
74
75 #ifdef QT_QMAP_DEBUG
76 #include <iostream>
77 #endif
78
79 QT_BEGIN_NAMESPACE
80
81 class QTextFormatCollection;
82 class QTextFormat;
83 class QTextBlockFormat;
84 class QTextCursorPrivate;
85 class QAbstractTextDocumentLayout;
86 class QTextDocument;
87 class QTextFrame;
88
89 #define QTextBeginningOfFrame QChar(0xfdd0)
90 #define QTextEndOfFrame QChar(0xfdd1)
91
92 class QTextFragmentData : public QFragment<>
93 {
94 public:
95     inline void initialize() {}
96     inline void invalidate() const {}
97     inline void free() {}
98     int stringPosition;
99     int format;
100 };
101
102 class QTextBlockData : public QFragment<3>
103 {
104 public:
105     inline void initialize()
106         { layout = 0; userData = 0; userState = -1; revision = 0; hidden = 0; }
107     void invalidate() const;
108     inline void free()
109     { delete layout; layout = 0; delete userData; userData = 0; }
110
111     mutable int format;
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;
118 };
119
120
121 class QAbstractUndoItem;
122
123 class QTextUndoCommand
124 {
125 public:
126     enum Command {
127         Inserted = 0,
128         Removed = 1,
129         CharFormatChanged = 2,
130         BlockFormatChanged = 3,
131         BlockInserted = 4,
132         BlockRemoved = 5,
133         BlockAdded = 6,
134         BlockDeleted = 7,
135         GroupFormatChange = 8,
136         CursorMoved = 9,
137         Custom = 256
138     };
139     enum Operation {
140         KeepCursor = 0,
141         MoveCursor = 1
142     };
143     quint16 command;
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
147     quint8 operation;
148     int format;
149     quint32 strPos;
150     quint32 pos;
151     union {
152         int blockFormat;
153         quint32 length;
154         QAbstractUndoItem *custom;
155         int objectIndex;
156     };
157     quint32 revision;
158
159     bool tryMerge(const QTextUndoCommand &other);
160 };
161 Q_DECLARE_TYPEINFO(QTextUndoCommand, Q_PRIMITIVE_TYPE);
162
163 class Q_AUTOTEST_EXPORT QTextDocumentPrivate : public QObjectPrivate
164 {
165     Q_DECLARE_PUBLIC(QTextDocument)
166 public:
167     typedef QFragmentMap<QTextFragmentData> FragmentMap;
168     typedef FragmentMap::ConstIterator FragmentIterator;
169     typedef QFragmentMap<QTextBlockData> BlockMap;
170
171     QTextDocumentPrivate();
172     ~QTextDocumentPrivate();
173
174     void init();
175     void clear();
176
177     void setLayout(QAbstractTextDocumentLayout *layout);
178
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);
184
185     void move(int from, int to, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
186     void remove(int pos, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
187
188     void aboutToRemoveCell(int cursorFrom, int cursorEnd);
189
190     QTextFrame *insertFrame(int start, int end, const QTextFrameFormat &format);
191     void removeFrame(QTextFrame *frame);
192
193     enum FormatChangeMode { MergeFormat, SetFormat, SetFormatAndPreserveObjectIndices };
194
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);
198
199     void emitUndoAvailable(bool available);
200     void emitRedoAvailable(bool available);
201
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();
208     void endEditBlock();
209     void finishEdit();
210     inline bool isInEditBlock() const { return editBlock; }
211     void enableUndoRedo(bool enable);
212     inline bool isUndoRedoEnabled() const { return undoEnabled; }
213
214     inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; }
215     inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); }
216
217     inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; }
218     inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; }
219
220     inline QString buffer() const { return text; }
221     QString plainText() const;
222     inline int length() const { return fragments.length(); }
223
224     inline QTextFormatCollection *formatCollection() { return &formats; }
225     inline const QTextFormatCollection *formatCollection() const { return &formats; }
226     inline QAbstractTextDocumentLayout *layout() const { return lout; }
227
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(); }
231
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;
236
237     inline int numBlocks() const { return blocks.numNodes(); }
238
239     const BlockMap &blockMap() const { return blocks; }
240     const FragmentMap &fragmentMap() const { return fragments; }
241     BlockMap &blockMap() { return blocks; }
242     FragmentMap &fragmentMap() { return fragments; }
243
244     static const QTextBlockData *block(const QTextBlock &it) { return it.p->blocks.fragment(it.n); }
245
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;
250
251     void changeObjectFormat(QTextObject *group, int format);
252
253     void setModified(bool m);
254     inline bool isModified() const { return modified; }
255
256     inline QFont defaultFont() const { return formats.defaultFont(); }
257     inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
258
259     void clearUndoRedoStacks(QTextDocument::Stacks stacksToClear, bool emitSignals = false);
260
261 private:
262     bool split(int pos);
263     bool unite(uint f);
264
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);
269
270     void insert_frame(QTextFrame *f);
271     void scan_frames(int pos, int charsRemoved, int charsAdded);
272     static void clearFrame(QTextFrame *f);
273
274     void adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op);
275
276     bool wasUndoAvailable;
277     bool wasRedoAvailable;
278
279 public:
280     void documentChange(int from, int length);
281
282     inline void addCursor(QTextCursorPrivate *c) { cursors.append(c); }
283     inline void removeCursor(QTextCursorPrivate *c) { cursors.removeAll(c); }
284
285     QTextFrame *frameAt(int pos) const;
286     QTextFrame *rootFrame() const;
287
288     QTextObject *objectForIndex(int objectIndex) const;
289     QTextObject *objectForFormat(int formatIndex) const;
290     QTextObject *objectForFormat(const QTextFormat &f) const;
291
292     QTextObject *createObject(const QTextFormat &newFormat, int objectIndex = -1);
293     void deleteObject(QTextObject *object);
294
295     QTextDocument *document() { return q_func(); }
296     const QTextDocument *document() const { return q_func(); }
297
298     bool ensureMaximumBlockCount();
299
300 private:
301     QTextDocumentPrivate(const QTextDocumentPrivate& m);
302     QTextDocumentPrivate& operator= (const QTextDocumentPrivate& m);
303
304     void appendUndoItem(const QTextUndoCommand &c);
305
306     void contentsChanged();
307
308     void compressPieceTable();
309
310     QString text;
311     uint unreachableCharacterCount;
312
313     QVector<QTextUndoCommand> undoStack;
314     bool undoEnabled;
315     int undoState;
316     int revision;
317     // position in undo stack of the last setModified(false) call
318     int modifiedState;
319     bool modified;
320
321     int editBlock;
322     int editBlockCursorPosition;
323     int docChangeFrom;
324     int docChangeOldLength;
325     int docChangeLength;
326     bool framesDirty;
327
328     QTextFormatCollection formats;
329     mutable QTextFrame *rtFrame;
330     QAbstractTextDocumentLayout *lout;
331     FragmentMap fragments;
332     BlockMap blocks;
333     int initialBlockCharFormatIndex;
334
335     QList<QTextCursorPrivate *> cursors;
336     QMap<int, QTextObject *> objects;
337     QMap<QUrl, QVariant> resources;
338     QMap<QUrl, QVariant> cachedResources;
339     QString defaultStyleSheet;
340
341     int lastBlockCount;
342
343 public:
344     QTextOption defaultTextOption;
345     Qt::CursorMoveStyle defaultCursorMoveStyle;
346 #ifndef QT_NO_CSSPARSER
347     QCss::StyleSheet parsedDefaultStyleSheet;
348 #endif
349     int maximumBlockCount;
350     uint needsEnsureMaximumBlockCount : 1;
351     uint inContentsChange : 1;
352     uint blockCursorAdjustment : 1;
353     QSizeF pageSize;
354     QString title;
355     QString url;
356     qreal indentWidth;
357     qreal documentMargin;
358
359     void mergeCachedResources(const QTextDocumentPrivate *priv);
360
361     friend class QTextHtmlExporter;
362     friend class QTextCursor;
363 };
364
365 class QTextTable;
366 class QTextHtmlExporter
367 {
368 public:
369     QTextHtmlExporter(const QTextDocument *_doc);
370
371     enum ExportMode {
372         ExportEntireDocument,
373         ExportFragment
374     };
375
376     QString toHtml(const QByteArray &encoding, ExportMode mode = ExportEntireDocument);
377
378 private:
379     enum StyleMode { EmitStyleTag, OmitStyleTag };
380     enum FrameType { TextFrame, TableFrame, RootFrame };
381
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);
387
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);
398
399     void emitFontFamily(const QString &family);
400
401     void emitBackgroundAttribute(const QTextFormat &format);
402     QString findUrlForImage(const QTextDocument *doc, qint64 cacheKey, bool isPixmap);
403
404     QString html;
405     QTextCharFormat defaultCharFormat;
406     const QTextDocument *doc;
407     bool fragmentMarkers;
408 };
409
410 QT_END_NAMESPACE
411
412 #endif // QTEXTDOCUMENT_P_H