1 /****************************************************************************
2 **
3 ** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
4 **
5 ** This file is part of the Edyuk project <http://edyuk.org>
6 **
7 ** This file may be used under the terms of the GNU General Public License
8 ** version 3 as published by the Free Software Foundation and appearing in the
9 ** file GPL.txt included in the packaging of this file.
10 **
11 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 **
14 ****************************************************************************/
15 
16 #ifndef Header_QDocument_P
17 #define Header_QDocument_P
18 
19 #include "qce-config.h"
20 
21 /*!
22 	\file qdocument_p.h
23 	\brief Definition of the private document API
24 */
25 
26 #include "qdocument.h"
27 #include "qdocumentline.h"
28 #include "qdocumentcursor.h"
29 
30 #include <QHash>
31 #include <QFont>
32 #include <QStack>
33 #include <QQueue>
34 #include <QDateTime>
35 #include <QUndoStack>
36 #include <QStringList>
37 #include <QFontMetricsF>
38 #include <QUndoCommand>
39 #include <QCache>
40 
41 class QDocument;
42 class QDocumentBuffer;
43 class QDocumentPrivate;
44 class QDocumentCommand;
45 class QDocumentCommandBlock;
46 
47 class QLanguageDefinition;
48 
49 Q_DECLARE_TYPEINFO(QDocumentSelection, Q_PRIMITIVE_TYPE);
50 
51 #include "qdocumentline_p.h"
52 
53 #include "qdocumentcursor_p.h"
54 
55 class QCE_EXPORT QDocumentPrivate
56 {
57 	friend class QEditConfig;
58 
59 	friend class QDocument;
60 	friend class QDocumentCommand;
61 	friend class QDocumentLineHandle;
62 	friend class QDocumentCursorHandle;
63 
64 	public:
65 		struct DrawTextLineContext {
66 			/*! additional information passed to drawTextLine()
67 			 * This has been created as part of extract method drawTextLine.
68 			 * Part of the arguments are constants passed to drawTextLine,
69 			 * others may be modified during drawTextLine.
70 			 * The number of required variables can probably be reduced during
71 			 * further refactoring.
72 			 */
73 			int docLineNr;
74 			int editLineNr;
75 			int firstLine; /* constant */
76             qreal pos;  /* vertical position */
77             qreal visiblePos;
78 			bool inSelection;
79 			QBrush base; /* constant */
80 			QBrush alternate; /* constant */
81 		};
82 
83 		QDocumentPrivate(QDocument *d);
84 		~QDocumentPrivate();
85 
86 		void execute(QDocumentCommand *cmd);
87 
88 		void draw(QPainter *p, QDocument::PaintContext& cxt);
89 		void drawTextLine(QPainter *p, QDocument::PaintContext &cxt, DrawTextLineContext &lcxt);
90 		void drawPlaceholders(QPainter *p, QDocument::PaintContext &cxt);
91 		void drawCursors(QPainter *p, const QDocument::PaintContext &cxt);
92 
93 		QString exportAsHtml(const QDocumentCursor& range, bool includeHeader, bool simplifyCSS, int maxLineWidth, int maxWrap) const;
94 
95 		QDocumentLineHandle* lineForPosition(int& position) const;
96 		int position(const QDocumentLineHandle *l) const;
97 
98 		QDocumentLineHandle* at(int line) const;
99 		int indexOf(const QDocumentLineHandle *l, int hint = -1) const;
100 
101 		QDocumentIterator index(const QDocumentLineHandle *l);
102 		QDocumentConstIterator index(const QDocumentLineHandle *l) const;
103 
104 		QDocumentLineHandle* next(const QDocumentLineHandle *l) const;
105 		QDocumentLineHandle* previous(const QDocumentLineHandle *l) const;
106 
107 		void adjustWidth(int l);
108 		//int checkWidth(QDocumentLineHandle *l, int w);
109 		//int checkWidth(QDocumentLineHandle *l, const QString& s);
110 
111 		void setWidth();
112 		void setHeight();
113 
114         static void setBaseFont(const QFont& f, bool forceUpdate = false);
115         static void setFontSizeModifier(int m, bool forceUpdate = false);
116 protected:
117         static void setFont(const QFont& f, bool forceUpdate = false);
118 		static void updateStaticCaches(const QPaintDevice *pd);
119 		void updateInstanceCaches(const QPaintDevice *pd, QDocument::PaintContext &cxt);
120 
121 public:
122 		void beginChangeBlock();
123 		void endChangeBlock();
124 		bool hasChangeBlocks();
125 
126 		void beginDelayedUpdateBlock();
127 		void endDelayedUpdateBlock();
128 
maxMarksPerLine()129 		inline int maxMarksPerLine() const
130 		{ return m_maxMarksPerLine; }
131 
hasMarks()132 		inline bool hasMarks() const
133 		{ return m_marks.count(); }
134 
135 		QList<int> marks(QDocumentLineHandle *h) const;
136 		void hasMark(QDocumentLineHandle *h, int mid);
137 
138 		void addMark(QDocumentLineHandle *h, int mid);
139 		void toggleMark(QDocumentLineHandle *h, int mid);
140 		void removeMark(QDocumentLineHandle *h, int mid);
141 
142 		int findNextMark(int id, int from = 0, int until = -1);
143 		int findPreviousMark(int id, int from = -1, int until = 0);
144 		void removeMarks(int id);
145 
146 
147 		int getNextGroupId();
148 		void releaseGroupId(int groupId);
149 		void clearMatches(int gid);
150 		//void clearMatchesFromToWhenFlushing(int groupId, int firstMatch, int lastMatch);
151 		void flushMatches(int gid);
152 		void addMatch(int gid, int line, int pos, int len, int format);
153 
154 		void emitFormatsChange (int line, int lines);
155 		void emitContentsChange(int line, int lines);
156 
157 		int visualLine(int textLine) const;
158 		int textLine(int visualLine, int *wrap = 0) const;
159 		void hideEvent(int line, int count);
160 		void showEvent(int line, int count);
161 
162         void setWidth(qreal width);
163 		void setHardLineWrap(bool wrap);
164 		void setLineWidthConstraint(bool wrap);
165         void setCenterDocumentInEditor(bool center);
166 		void setCursorBold(bool bold);
167 
168 		void emitFormatsChanged();
169 		void emitContentsChanged();
170 
171 		void emitLineDeleted(QDocumentLineHandle *h);
172 		void emitMarkChanged(QDocumentLineHandle *l, int m, bool on);
173 
begin()174 		inline QDocumentIterator begin() { return m_lines.begin(); }
end()175 		inline QDocumentIterator end() { return m_lines.end(); }
176 
constBegin()177 		inline QDocumentConstIterator constBegin() const { return m_lines.constBegin(); }
constEnd()178 		inline QDocumentConstIterator constEnd() const { return m_lines.constEnd(); }
179 
180 		void markFormatCacheDirty();
181 
182 		void addAutoUpdatedCursor(QDocumentCursorHandle* c);
183 		void removeAutoUpdatedCursor(QDocumentCursorHandle* c);
184 		void discardAutoUpdatedCursors(bool documentDeleted=false);
185 
186 		static void setWorkAround(QDocument::WorkAroundFlag workAround, bool newValue);
187 		static bool hasWorkAround(QDocument::WorkAroundFlag workAround);
188 
189 
190 		static bool getFixedPitch();
191 
192 		void setForceLineWrapCalculation(bool v);
193 
hardLineWrap()194 		bool hardLineWrap() const{
195 			return m_hardLineWrap;
196 		}
lineWidthConstraint()197 		bool lineWidthConstraint() const{
198 			return m_lineWidthConstraint;
199 		}
200 		void removeWrap(int i);
201 
width()202 		int width() const{
203 			return m_width;
204 		}
205 
leftMarginAndPadding()206 		int leftMarginAndPadding() const {
207 			return m_leftMargin + m_leftPadding;
208 		}
209 
getStatus()210 		QHash<QDocumentLineHandle*, QPair<int, int> > getStatus(){
211 		    return m_status;
212 		}
213 
setOverwriteMode(bool overwrite)214 		void setOverwriteMode(bool overwrite){
215 		    m_overwrite=overwrite;
216 		}
217 
218 		QList<int> testGetHiddenLines();
219 	protected:
220 		void updateHidden(int line, int count);
221 		void updateWrapped(int line, int count);
222 
223 		void insertLines(int after, const QList<QDocumentLineHandle*>& l);
224 		void removeLines(int after, int n);
225 
226 		void emitWidthChanged();
227 		void emitHeightChanged();
228 		void emitFontChanged();
229 
230 		static void updateFormatCache(const QPaintDevice *pd);
231 		void setFormatScheme(QFormatScheme *f);
232 		void tunePainter(QPainter *p, int fid);
233 
234         qreal textWidthSingleLetterFallback(int fid, const QString& text);
235         qreal textWidth(int fid, const QString& text);
236         qreal getRenderRangeWidth(int &columnDelta, int curColumn, const RenderRange& r, const int newFont, const QString& text);
237         void drawText(QPainter& p, int fid, const QColor& baseColor, bool selected, qreal &xpos, qreal baseline, const QString& text);
238 
239 	private:
240 		QDocument *m_doc;
241 		QUndoStack m_commands;
242 		QDocumentCursor *m_editCursor;
243 		bool m_drawCursorBold;
244 
245 		bool m_deleting;
246 		QStack<QDocumentCommandBlock*> m_macros;
247 		QList<QPair<int, int> > m_delayedUpdates;
248 		int m_delayedUpdateBlocks;
249 
250 		QMap<int, int> m_hidden;
251 		QMap<int, int> m_wrapped; //map of wrapped lines, (line number => line breaks in logical line)
252 		QVector< QPair<QDocumentLineHandle*, int> > m_largest;
253 
254 		struct Match
255 		{
256 			int line;
257 			QFormatRange range;
258 			QDocumentLineHandle *h;
259 		};
260 
261 		struct MatchList : QList<Match>
262 		{
MatchListMatchList263 			MatchList() : removeLength(0), removeStart(0) {}
264 
265 			int removeLength;
266 			int removeStart;
267 		};
268 
269 		int m_lastGroupId;
270 		QList<int> m_freeGroupIds;
271 		QHash<int, MatchList> m_matches;
272 
273 		bool m_constrained;
274 		bool m_hardLineWrap,m_lineWidthConstraint;
275         qreal m_leftMargin;
276         qreal m_width, m_height;
277 
278 		int m_tabStop;
279 		static int m_defaultTabStop;
280 
281 		static double m_lineSpacingFactor;
282         bool m_centerDocumentInEditor;
283 
284         static QFont *m_baseFont;  // original font associated with the document
285         static QFont *m_font;      // current font, pointSize = m_baseFont.pointSize + m_fontSizeModifier
286         static int m_fontSizeModifier;
287 		static bool m_fixedPitch;
288 		static QDocument::WorkAroundMode m_workArounds;
289         static qreal m_leftPadding;  // width between left edge of the document and start of the text
290 		static QDocument::WhiteSpaceMode m_showSpaces;
291 		static QDocument::LineEnding m_defaultLineEnding;
292 		static QTextCodec* m_defaultCodec;
293 
294 		// caches
295 		static int m_staticCachesLogicalDpiY;
296         static qreal m_lineHeight;
297         static qreal m_lineSpacing;
298         static qreal m_spaceWidth;
299         static qreal m_ascent;
300         static qreal m_descent;
301         static qreal m_leading;
302 
303 		static QVector<QFont> m_fonts;
304         static QList<QFontMetricsF> m_fontMetrics;
305         static CacheCache<qreal> m_fmtWidthCache;
306 		static CacheCache<QPixmap> m_fmtCharacterCache[2];
307 
308 		static QFormatScheme *m_formatScheme;
309 		QLanguageDefinition *m_language;
310 		static QFormatScheme *m_defaultFormatScheme;
311 
312 		static QList<QDocumentPrivate*> m_documents;
313 
314 		int m_maxMarksPerLine;
315 		QHash<QDocumentLineHandle*, QList<int> > m_marks;
316 		QHash<QDocumentLineHandle*, QPair<int, int> > m_status;
317 
318 		int _nix, _dos, _mac;
319 		QString m_lineEndingString;
320 		QDocument::LineEnding m_lineEnding;
321 		QTextCodec *m_codec;
322 
323 		bool m_readOnly;
324 		QDateTime m_lastModified;
325 		QString m_fileName, m_name;
326 		QFileInfo m_fileInfo;
327 
328 		QVector<QDocumentLineHandle*> m_lines;
329 
330         QCache<QDocumentLineHandle*,QImage> m_LineCacheAlternative;
331         QCache<QDocumentLineHandle*,QPixmap> m_LineCache;
332         qreal m_lineCacheXOffset, m_lineCacheWidth;
333 		int m_instanceCachesLogicalDpiY;
334 
335 		QList<QDocumentCursorHandle*> m_autoUpdatedCursorList;
336 		QHash<QDocumentCursorHandle*, int> m_autoUpdatedCursorIndex;
337 
338 		bool m_forceLineWrapCalculation;
339 
340 		bool m_overwrite;
341 };
342 
343 #endif
344