source: trunk/src/gui/text/qtextdocument_p.h@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 13.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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 "QtCore/qmap.h"
68#include "QtCore/qvariant.h"
69#include "QtCore/qurl.h"
70#include "private/qcssparser_p.h"
71
72// #define QT_QMAP_DEBUG
73
74#ifdef QT_QMAP_DEBUG
75#include <iostream>
76#endif
77
78QT_BEGIN_NAMESPACE
79
80class QTextFormatCollection;
81class QTextFormat;
82class QTextBlockFormat;
83class QTextCursorPrivate;
84class QAbstractTextDocumentLayout;
85class QTextDocument;
86class QTextFrame;
87
88#define QTextBeginningOfFrame QChar(0xfdd0)
89#define QTextEndOfFrame QChar(0xfdd1)
90
91class QTextFragmentData : public QFragment<>
92{
93public:
94 inline void initialize() {}
95 inline void invalidate() const {}
96 inline void free() {}
97 int stringPosition;
98 int format;
99};
100
101class QTextBlockData : public QFragment<3>
102{
103public:
104 inline void initialize()
105 { layout = 0; userData = 0; userState = -1; revision = 0; hidden = 0; }
106 void invalidate() const;
107 inline void free()
108 { delete layout; layout = 0; delete userData; userData = 0; }
109
110 mutable int format;
111 // ##### probably store a QTextEngine * here!
112 mutable QTextLayout *layout;
113 mutable QTextBlockUserData *userData;
114 mutable int userState;
115 mutable int revision : 31;
116 mutable uint hidden : 1;
117};
118
119
120class QAbstractUndoItem;
121
122class QTextUndoCommand
123{
124public:
125 enum Command {
126 Inserted = 0,
127 Removed = 1,
128 CharFormatChanged = 2,
129 BlockFormatChanged = 3,
130 BlockInserted = 4,
131 BlockRemoved = 5,
132 BlockAdded = 6,
133 BlockDeleted = 7,
134 GroupFormatChange = 8,
135 Custom = 256
136 };
137 enum Operation {
138 KeepCursor = 0,
139 MoveCursor = 1
140 };
141 quint16 command;
142 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
143 uint block_end : 1; // the last command in an undo block has this set to 1.
144 uint block_padding : 6; // padding since block used to be a quint8
145 quint8 operation;
146 int format;
147 quint32 strPos;
148 quint32 pos;
149 union {
150 int blockFormat;
151 quint32 length;
152 QAbstractUndoItem *custom;
153 int objectIndex;
154 };
155 quint32 revision;
156
157 bool tryMerge(const QTextUndoCommand &other);
158};
159Q_DECLARE_TYPEINFO(QTextUndoCommand, Q_PRIMITIVE_TYPE);
160
161class Q_AUTOTEST_EXPORT QTextDocumentPrivate : public QObjectPrivate
162{
163 Q_DECLARE_PUBLIC(QTextDocument)
164public:
165 typedef QFragmentMap<QTextFragmentData> FragmentMap;
166 typedef FragmentMap::ConstIterator FragmentIterator;
167 typedef QFragmentMap<QTextBlockData> BlockMap;
168
169 QTextDocumentPrivate();
170 ~QTextDocumentPrivate();
171
172 void init();
173 void clear();
174
175 void setLayout(QAbstractTextDocumentLayout *layout);
176
177 void insert(int pos, const QString &text, int format);
178 void insert(int pos, int strPos, int strLength, int format);
179 int insertBlock(int pos, int blockFormat, int charFormat, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
180 int insertBlock(const QChar &blockSeparator, int pos, int blockFormat, int charFormat,
181 QTextUndoCommand::Operation op = QTextUndoCommand::MoveCursor);
182
183 void move(int from, int to, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
184 void remove(int pos, int length, QTextUndoCommand::Operation = QTextUndoCommand::MoveCursor);
185
186 void aboutToRemoveCell(int cursorFrom, int cursorEnd);
187
188 QTextFrame *insertFrame(int start, int end, const QTextFrameFormat &format);
189 void removeFrame(QTextFrame *frame);
190
191 enum FormatChangeMode { MergeFormat, SetFormat, SetFormatAndPreserveObjectIndices };
192
193 void setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode = SetFormat);
194 void setBlockFormat(const QTextBlock &from, const QTextBlock &to,
195 const QTextBlockFormat &newFormat, FormatChangeMode mode = SetFormat);
196
197 void emitUndoAvailable(bool available);
198 void emitRedoAvailable(bool available);
199
200 int undoRedo(bool undo);
201 inline void undo() { undoRedo(true); }
202 inline void redo() { undoRedo(false); }
203 void appendUndoItem(QAbstractUndoItem *);
204 inline void beginEditBlock() { if (0 == editBlock++) ++revision; }
205 void joinPreviousEditBlock();
206 void endEditBlock();
207 void finishEdit();
208 inline bool isInEditBlock() const { return editBlock; }
209 void enableUndoRedo(bool enable);
210 inline bool isUndoRedoEnabled() const { return undoEnabled; }
211
212 inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; }
213 inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); }
214
215 inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; }
216 inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; }
217
218 inline QString buffer() const { return text; }
219 QString plainText() const;
220 inline int length() const { return fragments.length(); }
221
222 inline QTextFormatCollection *formatCollection() { return &formats; }
223 inline const QTextFormatCollection *formatCollection() const { return &formats; }
224 inline QAbstractTextDocumentLayout *layout() const { return lout; }
225
226 inline FragmentIterator find(int pos) const { return fragments.find(pos); }
227 inline FragmentIterator begin() const { return fragments.begin(); }
228 inline FragmentIterator end() const { return fragments.end(); }
229
230 inline QTextBlock blocksBegin() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.firstNode()); }
231 inline QTextBlock blocksEnd() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), 0); }
232 inline QTextBlock blocksFind(int pos) const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.findNode(pos)); }
233 int blockCharFormatIndex(int node) const;
234
235 inline int numBlocks() const { return blocks.numNodes(); }
236
237 const BlockMap &blockMap() const { return blocks; }
238 const FragmentMap &fragmentMap() const { return fragments; }
239 BlockMap &blockMap() { return blocks; }
240 FragmentMap &fragmentMap() { return fragments; }
241
242 static const QTextBlockData *block(const QTextBlock &it) { return it.p->blocks.fragment(it.n); }
243
244 int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
245 int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
246
247 void changeObjectFormat(QTextObject *group, int format);
248
249 void setModified(bool m);
250 inline bool isModified() const { return modified; }
251
252 inline QFont defaultFont() const { return formats.defaultFont(); }
253 inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
254
255private:
256 bool split(int pos);
257 bool unite(uint f);
258 void truncateUndoStack();
259
260 void insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op);
261 int insert_block(int pos, uint strPos, int format, int blockformat, QTextUndoCommand::Operation op, int command);
262 int remove_string(int pos, uint length, QTextUndoCommand::Operation op);
263 int remove_block(int pos, int *blockformat, int command, QTextUndoCommand::Operation op);
264
265 void insert_frame(QTextFrame *f);
266 void scan_frames(int pos, int charsRemoved, int charsAdded);
267 static void clearFrame(QTextFrame *f);
268
269 void adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op);
270
271 bool wasUndoAvailable;
272 bool wasRedoAvailable;
273
274public:
275 void documentChange(int from, int length);
276
277 inline void addCursor(QTextCursorPrivate *c) { cursors.append(c); }
278 inline void removeCursor(QTextCursorPrivate *c) { cursors.removeAll(c); changedCursors.removeAll(c); }
279
280 QTextFrame *frameAt(int pos) const;
281 QTextFrame *rootFrame() const;
282
283 QTextObject *objectForIndex(int objectIndex) const;
284 QTextObject *objectForFormat(int formatIndex) const;
285 QTextObject *objectForFormat(const QTextFormat &f) const;
286
287 QTextObject *createObject(const QTextFormat &newFormat, int objectIndex = -1);
288 void deleteObject(QTextObject *object);
289
290 QTextDocument *document() { return q_func(); }
291 const QTextDocument *document() const { return q_func(); }
292
293 bool ensureMaximumBlockCount();
294
295private:
296 QTextDocumentPrivate(const QTextDocumentPrivate& m);
297 QTextDocumentPrivate& operator= (const QTextDocumentPrivate& m);
298
299 void appendUndoItem(const QTextUndoCommand &c);
300
301 void contentsChanged();
302
303 void compressPieceTable();
304
305 QString text;
306 uint unreachableCharacterCount;
307
308 QVector<QTextUndoCommand> undoStack;
309 bool undoEnabled;
310 int undoState;
311 int revision;
312 // position in undo stack of the last setModified(false) call
313 int modifiedState;
314 bool modified;
315
316 int editBlock;
317 int docChangeFrom;
318 int docChangeOldLength;
319 int docChangeLength;
320 bool framesDirty;
321
322 QTextFormatCollection formats;
323 mutable QTextFrame *rtFrame;
324 QAbstractTextDocumentLayout *lout;
325 FragmentMap fragments;
326 BlockMap blocks;
327 int initialBlockCharFormatIndex;
328
329 QList<QTextCursorPrivate*> cursors;
330 QList<QTextCursorPrivate*> changedCursors;
331 QMap<int, QTextObject *> objects;
332 QMap<QUrl, QVariant> resources;
333 QMap<QUrl, QVariant> cachedResources;
334 QString defaultStyleSheet;
335
336 int lastBlockCount;
337
338public:
339 QTextOption defaultTextOption;
340#ifndef QT_NO_CSSPARSER
341 QCss::StyleSheet parsedDefaultStyleSheet;
342#endif
343 int maximumBlockCount;
344 uint needsEnsureMaximumBlockCount : 1;
345 uint inContentsChange : 1;
346 QSizeF pageSize;
347 QString title;
348 QString url;
349 qreal indentWidth;
350 qreal documentMargin;
351
352 void mergeCachedResources(const QTextDocumentPrivate *priv);
353
354 friend class QTextHtmlExporter;
355 friend class QTextCursor;
356};
357
358class QTextTable;
359class QTextHtmlExporter
360{
361public:
362 QTextHtmlExporter(const QTextDocument *_doc);
363
364 enum ExportMode {
365 ExportEntireDocument,
366 ExportFragment
367 };
368
369 QString toHtml(const QByteArray &encoding, ExportMode mode = ExportEntireDocument);
370
371private:
372 enum StyleMode { EmitStyleTag, OmitStyleTag };
373 enum FrameType { TextFrame, TableFrame, RootFrame };
374
375 void emitFrame(QTextFrame::Iterator frameIt);
376 void emitTextFrame(const QTextFrame *frame);
377 void emitBlock(const QTextBlock &block);
378 void emitTable(const QTextTable *table);
379 void emitFragment(const QTextFragment &fragment);
380
381 void emitBlockAttributes(const QTextBlock &block);
382 bool emitCharFormatStyle(const QTextCharFormat &format);
383 void emitTextLength(const char *attribute, const QTextLength &length);
384 void emitAlignment(Qt::Alignment alignment);
385 void emitFloatStyle(QTextFrameFormat::Position pos, StyleMode mode = EmitStyleTag);
386 void emitMargins(const QString &top, const QString &bottom, const QString &left, const QString &right);
387 void emitAttribute(const char *attribute, const QString &value);
388 void emitFrameStyle(const QTextFrameFormat &format, FrameType frameType);
389 void emitBorderStyle(QTextFrameFormat::BorderStyle style);
390 void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy);
391
392 void emitFontFamily(const QString &family);
393
394 void emitBackgroundAttribute(const QTextFormat &format);
395 QString findUrlForImage(const QTextDocument *doc, qint64 cacheKey, bool isPixmap);
396
397 QString html;
398 QTextCharFormat defaultCharFormat;
399 const QTextDocument *doc;
400 bool fragmentMarkers;
401};
402
403QT_END_NAMESPACE
404
405#endif // QTEXTDOCUMENT_P_H
Note: See TracBrowser for help on using the repository browser.