src/gui/text/qtextdocument_p.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    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 "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 
       
    78 QT_BEGIN_NAMESPACE
       
    79 
       
    80 class QTextFormatCollection;
       
    81 class QTextFormat;
       
    82 class QTextBlockFormat;
       
    83 class QTextCursorPrivate;
       
    84 class QAbstractTextDocumentLayout;
       
    85 class QTextDocument;
       
    86 class QTextFrame;
       
    87 
       
    88 #define QTextBeginningOfFrame QChar(0xfdd0)
       
    89 #define QTextEndOfFrame QChar(0xfdd1)
       
    90 
       
    91 class QTextFragmentData : public QFragment<>
       
    92 {
       
    93 public:
       
    94     inline void initialize() {}
       
    95     inline void invalidate() const {}
       
    96     inline void free() {}
       
    97     int stringPosition;
       
    98     int format;
       
    99 };
       
   100 
       
   101 class QTextBlockData : public QFragment<3>
       
   102 {
       
   103 public:
       
   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 
       
   120 class QAbstractUndoItem;
       
   121 
       
   122 class QTextUndoCommand
       
   123 {
       
   124 public:
       
   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 };
       
   159 Q_DECLARE_TYPEINFO(QTextUndoCommand, Q_PRIMITIVE_TYPE);
       
   160 
       
   161 class Q_AUTOTEST_EXPORT QTextDocumentPrivate : public QObjectPrivate
       
   162 {
       
   163     Q_DECLARE_PUBLIC(QTextDocument)
       
   164 public:
       
   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 QString buffer() const { return text; }
       
   216     QString plainText() const;
       
   217     inline int length() const { return fragments.length(); }
       
   218 
       
   219     inline QTextFormatCollection *formatCollection() { return &formats; }
       
   220     inline const QTextFormatCollection *formatCollection() const { return &formats; }
       
   221     inline QAbstractTextDocumentLayout *layout() const { return lout; }
       
   222 
       
   223     inline FragmentIterator find(int pos) const { return fragments.find(pos); }
       
   224     inline FragmentIterator begin() const { return fragments.begin(); }
       
   225     inline FragmentIterator end() const { return fragments.end(); }
       
   226 
       
   227     inline QTextBlock blocksBegin() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.firstNode()); }
       
   228     inline QTextBlock blocksEnd() const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), 0); }
       
   229     inline QTextBlock blocksFind(int pos) const { return QTextBlock(const_cast<QTextDocumentPrivate *>(this), blocks.findNode(pos)); }
       
   230     int blockCharFormatIndex(int node) const;
       
   231 
       
   232     inline int numBlocks() const { return blocks.numNodes(); }
       
   233 
       
   234     const BlockMap &blockMap() const { return blocks; }
       
   235     const FragmentMap &fragmentMap() const { return fragments; }
       
   236     BlockMap &blockMap() { return blocks; }
       
   237     FragmentMap &fragmentMap() { return fragments; }
       
   238 
       
   239     static const QTextBlockData *block(const QTextBlock &it) { return it.p->blocks.fragment(it.n); }
       
   240 
       
   241     int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
       
   242     int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
       
   243 
       
   244     void changeObjectFormat(QTextObject *group, int format);
       
   245 
       
   246     void setModified(bool m);
       
   247     inline bool isModified() const { return modified; }
       
   248 
       
   249     inline QFont defaultFont() const { return formats.defaultFont(); }
       
   250     inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
       
   251 
       
   252 private:
       
   253     bool split(int pos);
       
   254     bool unite(uint f);
       
   255     void truncateUndoStack();
       
   256 
       
   257     void insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op);
       
   258     int insert_block(int pos, uint strPos, int format, int blockformat, QTextUndoCommand::Operation op, int command);
       
   259     int remove_string(int pos, uint length, QTextUndoCommand::Operation op);
       
   260     int remove_block(int pos, int *blockformat, int command, QTextUndoCommand::Operation op);
       
   261 
       
   262     void insert_frame(QTextFrame *f);
       
   263     void scan_frames(int pos, int charsRemoved, int charsAdded);
       
   264     static void clearFrame(QTextFrame *f);
       
   265 
       
   266     void adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op);
       
   267 
       
   268     bool wasUndoAvailable;
       
   269     bool wasRedoAvailable;
       
   270 
       
   271 public:
       
   272     void documentChange(int from, int length);
       
   273 
       
   274     inline void addCursor(QTextCursorPrivate *c) { cursors.append(c); }
       
   275     inline void removeCursor(QTextCursorPrivate *c) { cursors.removeAll(c); changedCursors.removeAll(c); }
       
   276 
       
   277     QTextFrame *frameAt(int pos) const;
       
   278     QTextFrame *rootFrame() const;
       
   279 
       
   280     QTextObject *objectForIndex(int objectIndex) const;
       
   281     QTextObject *objectForFormat(int formatIndex) const;
       
   282     QTextObject *objectForFormat(const QTextFormat &f) const;
       
   283 
       
   284     QTextObject *createObject(const QTextFormat &newFormat, int objectIndex = -1);
       
   285     void deleteObject(QTextObject *object);
       
   286 
       
   287     QTextDocument *document() { return q_func(); }
       
   288     const QTextDocument *document() const { return q_func(); }
       
   289 
       
   290     bool ensureMaximumBlockCount();
       
   291 
       
   292 private:
       
   293     QTextDocumentPrivate(const QTextDocumentPrivate& m);
       
   294     QTextDocumentPrivate& operator= (const QTextDocumentPrivate& m);
       
   295 
       
   296     void appendUndoItem(const QTextUndoCommand &c);
       
   297 
       
   298     void contentsChanged();
       
   299 
       
   300     void compressPieceTable();
       
   301 
       
   302     QString text;
       
   303     uint unreachableCharacterCount;
       
   304 
       
   305     QVector<QTextUndoCommand> undoStack;
       
   306     bool undoEnabled;
       
   307     int undoState;
       
   308     int revision;
       
   309     // position in undo stack of the last setModified(false) call
       
   310     int modifiedState;
       
   311     bool modified;
       
   312 
       
   313     int editBlock;
       
   314     int docChangeFrom;
       
   315     int docChangeOldLength;
       
   316     int docChangeLength;
       
   317     bool framesDirty;
       
   318 
       
   319     QTextFormatCollection formats;
       
   320     mutable QTextFrame *rtFrame;
       
   321     QAbstractTextDocumentLayout *lout;
       
   322     FragmentMap fragments;
       
   323     BlockMap blocks;
       
   324     int initialBlockCharFormatIndex;
       
   325 
       
   326     QList<QTextCursorPrivate*> cursors;
       
   327     QList<QTextCursorPrivate*> changedCursors;
       
   328     QMap<int, QTextObject *> objects;
       
   329     QMap<QUrl, QVariant> resources;
       
   330     QMap<QUrl, QVariant> cachedResources;
       
   331     QString defaultStyleSheet;
       
   332 
       
   333     int lastBlockCount;
       
   334 
       
   335 public:
       
   336     QTextOption defaultTextOption;
       
   337 #ifndef QT_NO_CSSPARSER
       
   338     QCss::StyleSheet parsedDefaultStyleSheet;
       
   339 #endif
       
   340     int maximumBlockCount;
       
   341     uint needsEnsureMaximumBlockCount : 1;
       
   342     uint inContentsChange : 1;
       
   343     QSizeF pageSize;
       
   344     QString title;
       
   345     QString url;
       
   346     qreal indentWidth;
       
   347     qreal documentMargin;
       
   348 
       
   349     void mergeCachedResources(const QTextDocumentPrivate *priv);
       
   350 
       
   351     friend class QTextHtmlExporter;
       
   352     friend class QTextCursor;
       
   353 };
       
   354 
       
   355 class QTextTable;
       
   356 class QTextHtmlExporter
       
   357 {
       
   358 public:
       
   359     QTextHtmlExporter(const QTextDocument *_doc);
       
   360 
       
   361     enum ExportMode {
       
   362         ExportEntireDocument,
       
   363         ExportFragment
       
   364     };
       
   365 
       
   366     QString toHtml(const QByteArray &encoding, ExportMode mode = ExportEntireDocument);
       
   367 
       
   368 private:
       
   369     enum StyleMode { EmitStyleTag, OmitStyleTag };
       
   370     enum FrameType { TextFrame, TableFrame, RootFrame };
       
   371 
       
   372     void emitFrame(QTextFrame::Iterator frameIt);
       
   373     void emitTextFrame(const QTextFrame *frame);
       
   374     void emitBlock(const QTextBlock &block);
       
   375     void emitTable(const QTextTable *table);
       
   376     void emitFragment(const QTextFragment &fragment);
       
   377 
       
   378     void emitBlockAttributes(const QTextBlock &block);
       
   379     bool emitCharFormatStyle(const QTextCharFormat &format);
       
   380     void emitTextLength(const char *attribute, const QTextLength &length);
       
   381     void emitAlignment(Qt::Alignment alignment);
       
   382     void emitFloatStyle(QTextFrameFormat::Position pos, StyleMode mode = EmitStyleTag);
       
   383     void emitMargins(const QString &top, const QString &bottom, const QString &left, const QString &right);
       
   384     void emitAttribute(const char *attribute, const QString &value);
       
   385     void emitFrameStyle(const QTextFrameFormat &format, FrameType frameType);
       
   386     void emitBorderStyle(QTextFrameFormat::BorderStyle style);
       
   387     void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy);
       
   388 
       
   389     void emitFontFamily(const QString &family);
       
   390 
       
   391     void emitBackgroundAttribute(const QTextFormat &format);
       
   392     QString findUrlForImage(const QTextDocument *doc, qint64 cacheKey, bool isPixmap);
       
   393 
       
   394     QString html;
       
   395     QTextCharFormat defaultCharFormat;
       
   396     const QTextDocument *doc;
       
   397     bool fragmentMarkers;
       
   398 };
       
   399 
       
   400 QT_END_NAMESPACE
       
   401 
       
   402 #endif // QTEXTDOCUMENT_P_H