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

Last change on this file since 135 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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