00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _QDOCUMENT_P_H_
00017 #define _QDOCUMENT_P_H_
00018
00019 #include "qce-config.h"
00020
00026 #include "qnfa.h"
00027
00028 #include "qdocument.h"
00029 #include "qdocumentline.h"
00030 #include "qdocumentcursor.h"
00031
00032 #include <QPair>
00033 #include <QHash>
00034 #include <QFont>
00035 #include <QStack>
00036 #include <QQueue>
00037 #if QT_VERSION < 0x040400
00038 #include <QAtomic>
00039 #else
00040 #include <QAtomicInt>
00041 #endif
00042 #include <QUndoStack>
00043 #include <QStringList>
00044 #include <QTextLayout>
00045 #include <QFontMetrics>
00046 #include <QUndoCommand>
00047
00048 #include <QTextLayout>
00049
00050 template <typename T, int x>
00051 class QVarLengthArray;
00052
00053
00054
00055
00056 typedef QVector<int> QSmallArray;
00057 typedef QVector<int> QMediumArray;
00058
00059 class QDocument;
00060 class QDocumentPrivate;
00061 class QDocumentCommand;
00062 class QDocumentCommandBlock;
00063
00064 class QLanguageDefinition;
00065
00066 Q_DECLARE_TYPEINFO(QDocumentSelection, Q_PRIMITIVE_TYPE);
00067
00068 class QCE_EXPORT QDocumentLineHandle
00069 {
00070 friend class QDocument;
00071 friend class QDocumentLine;
00072 friend class QDocumentPrivate;
00073
00074 public:
00075 QDocumentLineHandle(QDocument *d);
00076 QDocumentLineHandle(const QString& s, QDocument *d);
00077
00078 int count() const;
00079 int length() const;
00080
00081 int position() const;
00082
00083 QString text() const;
00084
00085 int line() const;
00086
00087 int xToCursor(int x) const;
00088 int cursorToX(int i) const;
00089
00090 int wrappedLineForCursor(int cpos) const;
00091
00092 int documentOffsetToCursor(int x, int y) const;
00093 void cursorToDocumentOffset(int cpos, int& x, int& y) const;
00094
00095 QPoint cursorToDocumentOffset(int cpos) const;
00096
00097 int nextNonSpaceChar(uint pos) const;
00098 int previousNonSpaceChar(int pos) const;
00099
00100 bool hasFlag(QDocumentLine::State s) const;
00101 void setFlag(QDocumentLine::State s, bool y = true) const;
00102
00103 QDocument* document() const;
00104
00105 QDocumentLineHandle* next() const;
00106 QDocumentLineHandle* previous() const;
00107
00108 void updateWrap() const;
00109
00110 void setFormats(const QVector<int>& formats);
00111
00112 void clearOverlays();
00113 void addOverlay(const QFormatRange& over);
00114 void removeOverlay(const QFormatRange& over);
00115
00116 void shiftOverlays(int position, int offset);
00117
00118 void draw( QPainter *p,
00119 int xOffset,
00120 int vWidth,
00121 const QSmallArray& sel,
00122 const QSmallArray& cursors,
00123 const QPalette& pal,
00124 bool fullSel) const;
00125
00126 inline QString& textBuffer() { setFlag(QDocumentLine::LayoutDirty, true); return m_text; }
00127
00128 inline void ref() { m_ref.ref(); }
00129 inline void deref() { if ( m_ref ) m_ref.deref(); if ( !m_ref ) delete this; }
00130
00131 protected:
00132 ~QDocumentLineHandle();
00133
00134 private:
00135 void layout() const;
00136 void applyOverlays() const;
00137
00138 QMediumArray compose() const;
00139 QList<QTextLayout::FormatRange> decorations() const;
00140
00141 QString m_text;
00142 QDocument *m_doc;
00143 #if QT_VERSION < 0x040400
00144 QBasicAtomic m_ref;
00145 #else
00146 QAtomicInt m_ref;
00147 #endif
00148 mutable int m_indent;
00149 mutable quint16 m_state;
00150 mutable QTextLayout *m_layout;
00151 mutable QVector<int> m_cache;
00152 mutable QVector< QPair<int, int> > m_frontiers;
00153
00154 QNFAMatchContext m_context;
00155
00156 QVector<int> m_formats;
00157 QVector<QParenthesis> m_parens;
00158 QList<QFormatRange> m_overlays;
00159 };
00160
00161 Q_DECLARE_TYPEINFO(QDocumentLineHandle*, Q_PRIMITIVE_TYPE);
00162
00163 class QCE_EXPORT QDocumentCursorHandle
00164 {
00165 friend class QDocumentCursor;
00166 friend class QDocumentPrivate;
00167 friend class QDocumentCommand;
00168
00169 public:
00170 enum Flags
00171 {
00172 Silent = 1,
00173 ColumnMemory = 2,
00174 MoveWithinWrapped = 4
00175 };
00176
00177 QDocument* document() const;
00178
00179 bool atEnd() const;
00180 bool atStart() const;
00181
00182 bool atBlockEnd() const;
00183 bool atBlockStart() const;
00184
00185 bool atLineEnd() const;
00186 bool atLineStart() const;
00187
00188 bool hasSelection() const;
00189
00190 bool isSilent() const;
00191 void setSilent(bool y);
00192
00193 bool isAutoUpdated() const;
00194 void setAutoUpdated(bool y);
00195
00196 QDocumentLine line() const;
00197 QDocumentLine anchorLine() const;
00198
00199 int lineNumber() const;
00200 int columnNumber() const;
00201
00202 int anchorLineNumber() const;
00203 int anchorColumnNumber() const;
00204
00205 int visualColumnNumber() const;
00206
00207 void setColumnNumber(int c, QDocumentCursor::MoveMode m =
00208 QDocumentCursor::MoveAnchor);
00209
00210 QPoint documentPosition() const;
00211 QPoint anchorDocumentPosition() const;
00212
00213 QPolygon documentRegion() const;
00214
00215 int position() const;
00216
00217 void shift(int offset);
00218 void setPosition(int pos, QDocumentCursor::MoveMode m);
00219 bool movePosition(int offset, QDocumentCursor::MoveOperation op, QDocumentCursor::MoveMode m);
00220
00221 void insertText(const QString& s);
00222
00223 void eraseLine();
00224 void deleteChar();
00225 void deletePreviousChar();
00226
00227 QDocumentCursor selectionStart() const;
00228 QDocumentCursor selectionEnd() const;
00229
00230 bool eq(const QDocumentCursorHandle *h);
00231 bool lt(const QDocumentCursorHandle *h);
00232 bool gt(const QDocumentCursorHandle *h);
00233
00234 QString selectedText() const;
00235
00236 void clearSelection();
00237 void removeSelectedText();
00238
00239 void select(QDocumentCursor::SelectionType t);
00240 void setSelectionBoundary(const QDocumentCursor& c);
00241
00242 bool isWithinSelection(const QDocumentCursor& c) const;
00243 QDocumentCursor intersect(const QDocumentCursor& c) const;
00244
00245 void substractBoundaries(int lbeg, int cbeg, int lend, int cend);
00246 void boundaries(int& begline, int& begcol, int& endline, int& endcol) const;
00247 void intersectBoundaries(int& lbeg, int& cbeg, int& lend, int& cend) const;
00248 void intersectBoundaries(QDocumentCursorHandle *h, int& lbeg, int& cbeg, int& lend, int& cend) const;
00249
00250 void beginEditBlock();
00251 void endEditBlock();
00252
00253 void moveTo(int line, int column);
00254 void moveTo(const QDocumentCursor &c);
00255
00256 void copy(const QDocumentCursorHandle *c);
00257
00258 void refreshColumnMemory();
00259 bool hasColumnMemory() const;
00260 void setColumnMemory(bool y);
00261
00262 virtual void execute(QDocumentCommand *c);
00263
00264 inline void ref() { m_ref.ref(); }
00265 inline void deref() { if ( m_ref ) m_ref.deref(); if ( !m_ref ) delete this; }
00266
00267 inline bool hasFlag(int f) const { return m_flags & f; }
00268 inline void setFlag(int f) { m_flags |= f; }
00269 inline void clearFlag(int f) { m_flags &= ~f; }
00270
00271 protected:
00272 QDocumentCursorHandle(QDocument *d, int line = 0);
00273 virtual ~QDocumentCursorHandle();
00274
00275 QDocumentCursorHandle* clone() const;
00276
00277 private:
00278 int m_flags;
00279 QDocument *m_doc;
00280 #if QT_VERSION < 0x040400
00281 QBasicAtomic m_ref;
00282 #else
00283 QAtomicInt m_ref;
00284 #endif
00285 int m_begOffset, m_endOffset, m_max, m_begLine, m_endLine;
00286 QStack<QDocumentCommandBlock*> m_blocks;
00287 };
00288
00289 Q_DECLARE_TYPEINFO(QDocumentCursorHandle*, Q_PRIMITIVE_TYPE);
00290
00291 class QCE_EXPORT QDocumentPrivate
00292 {
00293 friend class QEditConfig;
00294
00295 friend class QDocument;
00296 friend class QDocumentCommand;
00297 friend class QDocumentLineHandle;
00298 friend class QDocumentCursorHandle;
00299
00300 public:
00301 QDocumentPrivate(QDocument *d);
00302 ~QDocumentPrivate();
00303
00304 void execute(QDocumentCommand *cmd);
00305
00306 void draw(QPainter *p, QDocument::PaintContext& cxt);
00307
00308 QDocumentLineHandle* lineForPosition(int& position) const;
00309 int position(const QDocumentLineHandle *l) const;
00310
00311 QDocumentLineHandle* at(int line) const;
00312 int indexOf(const QDocumentLineHandle *l) const;
00313
00314 QDocumentIterator index(const QDocumentLineHandle *l);
00315 QDocumentConstIterator index(const QDocumentLineHandle *l) const;
00316
00317 QDocumentLineHandle* next(const QDocumentLineHandle *l) const;
00318 QDocumentLineHandle* previous(const QDocumentLineHandle *l) const;
00319
00320 void adjustWidth(int l);
00321
00322
00323
00324 void setWidth();
00325 void setHeight();
00326
00327 static void setFont(const QFont& f);
00328
00329 void beginChangeBlock();
00330 void endChangeBlock();
00331
00332 inline int maxMarksPerLine() const
00333 { return m_maxMarksPerLine; }
00334
00335 inline bool hasMarks() const
00336 { return m_marks.count(); }
00337
00338 QList<int> marks(QDocumentLineHandle *h) const;
00339
00340 void addMark(QDocumentLineHandle *h, int mid);
00341 void toggleMark(QDocumentLineHandle *h, int mid);
00342 void removeMark(QDocumentLineHandle *h, int mid);
00343
00344 int findNextMark(int id, int from = 0, int until = -1);
00345 int findPreviousMark(int id, int from = -1, int until = 0);
00346
00347 int getNextGroupId();
00348 void releaseGroupId(int groupId);
00349 void clearMatches(int gid);
00350 void flushMatches(int gid);
00351 void addMatch(int gid, int line, int pos, int len, int format);
00352
00353 void emitFormatsChange (int line, int lines);
00354 void emitContentsChange(int line, int lines);
00355
00356 int visualLine(int textLine) const;
00357 int textLine(int visualLine, int *wrap = 0) const;
00358 void hideEvent(int line, int count);
00359 void showEvent(int line, int count);
00360
00361 void setWidth(int width);
00362
00363 void emitFormatsChanged();
00364 void emitContentsChanged();
00365
00366 void emitLineDeleted(QDocumentLineHandle *h);
00367 void emitMarkChanged(QDocumentLineHandle *l, int m, bool on);
00368
00369 inline QDocumentIterator begin() { return m_lines.begin(); }
00370 inline QDocumentIterator end() { return m_lines.end(); }
00371
00372 inline QDocumentConstIterator constBegin() const { return m_lines.constBegin(); }
00373 inline QDocumentConstIterator constEnd() const { return m_lines.constEnd(); }
00374
00375 protected:
00376 void updateHidden(int line, int count);
00377 void updateWrapped(int line, int count);
00378
00379 void insertLines(int after, const QList<QDocumentLineHandle*>& l);
00380 void removeLines(int after, int n);
00381
00382 void emitWidthChanged();
00383 void emitHeightChanged();
00384
00385 void updateFormatCache();
00386 void setFormatScheme(QFormatScheme *f);
00387 void tunePainter(QPainter *p, int fid);
00388
00389 private:
00390 QDocument *m_doc;
00391 QUndoStack m_commands;
00392 QDocumentCursor *m_editCursor;
00393
00394 bool m_suspend, m_deleting;
00395 QQueue<QPair<int, int> > m_notifications;
00396
00397 QMap<int, int> m_hidden;
00398 QMap<int, int> m_wrapped;
00399 QVector< QPair<QDocumentLineHandle*, int> > m_largest;
00400
00401 struct Match
00402 {
00403 int line;
00404 QFormatRange range;
00405 QDocumentLineHandle *h;
00406 };
00407
00408 struct MatchList : QList<Match>
00409 {
00410 MatchList() : index(0) {}
00411
00412 int index;
00413 };
00414
00415 int m_lastGroupId;
00416 QList<int> m_freeGroupIds;
00417 QHash<int, MatchList> m_matches;
00418
00419 bool m_constrained;
00420 int m_width, m_height;
00421
00422 int m_tabStop;
00423 static int m_defaultTabStop;
00424
00425 static QFont *m_font;
00426 static bool m_fixedPitch;
00427 static QFontMetrics *m_fontMetrics;
00428 static int m_leftMargin;
00429 static QDocument::WhiteSpaceMode m_showSpaces;
00430 static QDocument::LineEnding m_defaultLineEnding;
00431 static int m_lineHeight;
00432 static int m_lineSpacing;
00433 static int m_spaceWidth;
00434 static int m_ascent;
00435 static int m_descent;
00436 static int m_leading;
00437 static int m_wrapMargin;
00438
00439 QFormatScheme *m_formatScheme;
00440 QLanguageDefinition *m_language;
00441 static QFormatScheme *m_defaultFormatScheme;
00442
00443 QVector<QFont> m_fonts;
00444
00445 static QList<QDocumentPrivate*> m_documents;
00446
00447 int m_maxMarksPerLine;
00448 QHash<QDocumentLineHandle*, QList<int> > m_marks;
00449 QHash<QDocumentLineHandle*, QPair<int, int> > m_status;
00450
00451 int _nix, _dos;
00452 QString m_lineEndingString;
00453 QDocument::LineEnding m_lineEnding;
00454
00455 QVector<QDocumentLineHandle*> m_lines;
00456 };
00457
00458 #endif