-rw-r--r-- | noncore/apps/opie-write/qrichtext.cpp | 72 |
1 files changed, 23 insertions, 49 deletions
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp index 768da44..b457cd6 100644 --- a/noncore/apps/opie-write/qrichtext.cpp +++ b/noncore/apps/opie-write/qrichtext.cpp | |||
@@ -1,6903 +1,6877 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | ** $Id$ | 2 | ** $Id$ |
3 | ** | 3 | ** |
4 | ** Implementation of the internal Qt classes dealing with rich text | 4 | ** Implementation of the internal Qt classes dealing with rich text |
5 | ** | 5 | ** |
6 | ** Created : 990101 | 6 | ** Created : 990101 |
7 | ** | 7 | ** |
8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. | 8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. |
9 | ** | 9 | ** |
10 | ** This file is part of the kernel module of the Qt GUI Toolkit. | 10 | ** This file is part of the kernel module of the Qt GUI Toolkit. |
11 | ** | 11 | ** |
12 | ** This file may be distributed under the terms of the Q Public License | 12 | ** This file may be distributed under the terms of the Q Public License |
13 | ** as defined by Trolltech AS of Norway and appearing in the file | 13 | ** as defined by Trolltech AS of Norway and appearing in the file |
14 | ** LICENSE.QPL included in the packaging of this file. | 14 | ** LICENSE.QPL included in the packaging of this file. |
15 | ** | 15 | ** |
16 | ** This file may be distributed and/or modified under the terms of the | 16 | ** This file may be distributed and/or modified under the terms of the |
17 | ** GNU General Public License version 2 as published by the Free Software | 17 | ** GNU General Public License version 2 as published by the Free Software |
18 | ** Foundation and appearing in the file LICENSE.GPL included in the | 18 | ** Foundation and appearing in the file LICENSE.GPL included in the |
19 | ** packaging of this file. | 19 | ** packaging of this file. |
20 | ** | 20 | ** |
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition |
22 | ** licenses may use this file in accordance with the Qt Commercial License | 22 | ** licenses may use this file in accordance with the Qt Commercial License |
23 | ** Agreement provided with the Software. | 23 | ** Agreement provided with the Software. |
24 | ** | 24 | ** |
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
27 | ** | 27 | ** |
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for |
29 | ** information about Qt Commercial License Agreements. | 29 | ** information about Qt Commercial License Agreements. |
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. |
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
32 | ** | 32 | ** |
33 | ** Contact info@trolltech.com if any conditions of this licensing are | 33 | ** Contact info@trolltech.com if any conditions of this licensing are |
34 | ** not clear to you. | 34 | ** not clear to you. |
35 | ** | 35 | ** |
36 | **********************************************************************/ | 36 | **********************************************************************/ |
37 | 37 | ||
38 | #include "qrichtext_p.h" | 38 | #include "qrichtext_p.h" |
39 | 39 | ||
40 | /* OPIE */ | 40 | /* OPIE */ |
41 | #include <opie2/odebug.h> | 41 | #include <opie2/odebug.h> |
42 | using namespace Opie::Core; | 42 | using namespace Opie::Core; |
43 | 43 | ||
44 | /* QT */ | 44 | /* QT */ |
45 | #include "qdragobject.h" | 45 | #include "qdragobject.h" |
46 | #include "qpaintdevicemetrics.h" | 46 | #include "qpaintdevicemetrics.h" |
47 | #include "qdrawutil.h" | 47 | #include "qdrawutil.h" |
48 | #include "qcleanuphandler.h" | 48 | #include "qcleanuphandler.h" |
49 | 49 | ||
50 | /* STD */ | 50 | /* STD */ |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> |
52 | 52 | ||
53 | using namespace Qt3; | 53 | using namespace Qt3; |
54 | 54 | ||
55 | static QTextCursor* richTextExportStart = 0; | 55 | static QTextCursor* richTextExportStart = 0; |
56 | static QTextCursor* richTextExportEnd = 0; | 56 | static QTextCursor* richTextExportEnd = 0; |
57 | 57 | ||
58 | static QTextFormatCollection *qFormatCollection = 0; | 58 | static QTextFormatCollection *qFormatCollection = 0; |
59 | 59 | ||
60 | const int border_tolerance = 2; | 60 | const int border_tolerance = 2; |
61 | 61 | ||
62 | #ifdef Q_WS_WIN | 62 | #ifdef Q_WS_WIN |
63 | #include "qt_windows.h" | 63 | #include "qt_windows.h" |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | #define QChar_linesep QChar(0x2028U) | 66 | #define QChar_linesep QChar(0x2028U) |
67 | 67 | ||
68 | static inline bool is_printer( QPainter *p ) | 68 | static inline bool is_printer( QPainter *p ) |
69 | { | 69 | { |
70 | if ( !p || !p->device() ) | 70 | if ( !p || !p->device() ) |
71 | return FALSE; | 71 | return FALSE; |
72 | return p->device()->devType() == QInternal::Printer; | 72 | return p->device()->devType() == QInternal::Printer; |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline int scale( int value, QPainter *painter ) | 75 | static inline int scale( int value, QPainter *painter ) |
76 | { | 76 | { |
77 | if ( is_printer( painter ) ) { | 77 | if ( is_printer( painter ) ) { |
78 | QPaintDeviceMetrics metrics( painter->device() ); | 78 | QPaintDeviceMetrics metrics( painter->device() ); |
79 | #if defined(Q_WS_X11) | 79 | #if defined(Q_WS_X11) |
80 | value = value * metrics.logicalDpiY() / QPaintDevice::x11AppDpiY(); | 80 | value = value * metrics.logicalDpiY() / QPaintDevice::x11AppDpiY(); |
81 | #elif defined (Q_WS_WIN) | 81 | #elif defined (Q_WS_WIN) |
82 | HDC hdc = GetDC( 0 ); | 82 | HDC hdc = GetDC( 0 ); |
83 | int gdc = GetDeviceCaps( hdc, LOGPIXELSY ); | 83 | int gdc = GetDeviceCaps( hdc, LOGPIXELSY ); |
84 | if ( gdc ) | 84 | if ( gdc ) |
85 | value = value * metrics.logicalDpiY() / gdc; | 85 | value = value * metrics.logicalDpiY() / gdc; |
86 | ReleaseDC( 0, hdc ); | 86 | ReleaseDC( 0, hdc ); |
87 | #elif defined (Q_WS_MAC) | 87 | #elif defined (Q_WS_MAC) |
88 | value = value * metrics.logicalDpiY() / 75; // ##### FIXME | 88 | value = value * metrics.logicalDpiY() / 75; // ##### FIXME |
89 | #elif defined (Q_WS_QWS) | 89 | #elif defined (Q_WS_QWS) |
90 | value = value * metrics.logicalDpiY() / 75; | 90 | value = value * metrics.logicalDpiY() / 75; |
91 | #endif | 91 | #endif |
92 | } | 92 | } |
93 | return value; | 93 | return value; |
94 | } | 94 | } |
95 | 95 | ||
96 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 96 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
97 | 97 | ||
98 | void QTextCommandHistory::addCommand( QTextCommand *cmd ) | 98 | void QTextCommandHistory::addCommand( QTextCommand *cmd ) |
99 | { | 99 | { |
100 | if ( current < (int)history.count() - 1 ) { | 100 | if ( current < (int)history.count() - 1 ) { |
101 | QPtrList<QTextCommand> commands; | 101 | QPtrList<QTextCommand> commands; |
102 | commands.setAutoDelete( FALSE ); | 102 | commands.setAutoDelete( FALSE ); |
103 | 103 | ||
104 | for( int i = 0; i <= current; ++i ) { | 104 | for( int i = 0; i <= current; ++i ) { |
105 | commands.insert( i, history.at( 0 ) ); | 105 | commands.insert( i, history.at( 0 ) ); |
106 | history.take( 0 ); | 106 | history.take( 0 ); |
107 | } | 107 | } |
108 | 108 | ||
109 | commands.append( cmd ); | 109 | commands.append( cmd ); |
110 | history.clear(); | 110 | history.clear(); |
111 | history = commands; | 111 | history = commands; |
112 | history.setAutoDelete( TRUE ); | 112 | history.setAutoDelete( TRUE ); |
113 | } else { | 113 | } else { |
114 | history.append( cmd ); | 114 | history.append( cmd ); |
115 | } | 115 | } |
116 | 116 | ||
117 | if ( (int)history.count() > steps ) | 117 | if ( (int)history.count() > steps ) |
118 | history.removeFirst(); | 118 | history.removeFirst(); |
119 | else | 119 | else |
120 | ++current; | 120 | ++current; |
121 | } | 121 | } |
122 | 122 | ||
123 | QTextCursor *QTextCommandHistory::undo( QTextCursor *c ) | 123 | QTextCursor *QTextCommandHistory::undo( QTextCursor *c ) |
124 | { | 124 | { |
125 | if ( current > -1 ) { | 125 | if ( current > -1 ) { |
126 | QTextCursor *c2 = history.at( current )->unexecute( c ); | 126 | QTextCursor *c2 = history.at( current )->unexecute( c ); |
127 | --current; | 127 | --current; |
128 | return c2; | 128 | return c2; |
129 | } | 129 | } |
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | QTextCursor *QTextCommandHistory::redo( QTextCursor *c ) | 133 | QTextCursor *QTextCommandHistory::redo( QTextCursor *c ) |
134 | { | 134 | { |
135 | if ( current > -1 ) { | 135 | if ( current > -1 ) { |
136 | if ( current < (int)history.count() - 1 ) { | 136 | if ( current < (int)history.count() - 1 ) { |
137 | ++current; | 137 | ++current; |
138 | return history.at( current )->execute( c ); | 138 | return history.at( current )->execute( c ); |
139 | } | 139 | } |
140 | } else { | 140 | } else { |
141 | if ( history.count() > 0 ) { | 141 | if ( history.count() > 0 ) { |
142 | ++current; | 142 | ++current; |
143 | return history.at( current )->execute( c ); | 143 | return history.at( current )->execute( c ); |
144 | } | 144 | } |
145 | } | 145 | } |
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | bool QTextCommandHistory::isUndoAvailable() | 149 | bool QTextCommandHistory::isUndoAvailable() |
150 | { | 150 | { |
151 | return current > -1; | 151 | return current > -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | bool QTextCommandHistory::isRedoAvailable() | 154 | bool QTextCommandHistory::isRedoAvailable() |
155 | { | 155 | { |
156 | return current > -1 && current < (int)history.count() - 1 || current == -1 && history.count() > 0; | 156 | return current > -1 && current < (int)history.count() - 1 || current == -1 && history.count() > 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 159 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
160 | 160 | ||
161 | QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, | 161 | QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, |
162 | const QByteArray& oldStyleInfo ) | 162 | const QByteArray& oldStyleInfo ) |
163 | : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo ) | 163 | : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo ) |
164 | { | 164 | { |
165 | for ( int j = 0; j < (int)text.size(); ++j ) { | 165 | for ( int j = 0; j < (int)text.size(); ++j ) { |
166 | if ( text[ j ].format() ) | 166 | if ( text[ j ].format() ) |
167 | text[ j ].format()->addRef(); | 167 | text[ j ].format()->addRef(); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str ) | 171 | QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str ) |
172 | : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str ) | 172 | : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str ) |
173 | { | 173 | { |
174 | for ( int i = 0; i < (int)text.size(); ++i ) { | 174 | for ( int i = 0; i < (int)text.size(); ++i ) { |
175 | if ( text[ i ].format() ) | 175 | if ( text[ i ].format() ) |
176 | text[ i ].format()->addRef(); | 176 | text[ i ].format()->addRef(); |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | QTextDeleteCommand::~QTextDeleteCommand() | 180 | QTextDeleteCommand::~QTextDeleteCommand() |
181 | { | 181 | { |
182 | for ( int i = 0; i < (int)text.size(); ++i ) { | 182 | for ( int i = 0; i < (int)text.size(); ++i ) { |
183 | if ( text[ i ].format() ) | 183 | if ( text[ i ].format() ) |
184 | text[ i ].format()->removeRef(); | 184 | text[ i ].format()->removeRef(); |
185 | } | 185 | } |
186 | text.resize( 0 ); | 186 | text.resize( 0 ); |
187 | } | 187 | } |
188 | 188 | ||
189 | QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) | 189 | QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) |
190 | { | 190 | { |
191 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; | 191 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; |
192 | if ( !s && doc ) { | 192 | if ( !s ) { |
193 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; | 193 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; |
194 | return 0; | 194 | return 0; |
195 | } else if ( !doc ) { | ||
196 | owarn << "No valid doc" << oendl; | ||
197 | return 0; | ||
198 | } | 195 | } |
199 | 196 | ||
200 | cursor.setParagraph( s ); | 197 | cursor.setParagraph( s ); |
201 | cursor.setIndex( index ); | 198 | cursor.setIndex( index ); |
202 | int len = text.size(); | 199 | int len = text.size(); |
203 | if ( c ) | 200 | if ( c ) |
204 | *c = cursor; | 201 | *c = cursor; |
205 | if ( doc ) { | 202 | if ( doc ) { |
206 | doc->setSelectionStart( QTextDocument::Temp, cursor ); | 203 | doc->setSelectionStart( QTextDocument::Temp, cursor ); |
207 | for ( int i = 0; i < len; ++i ) | 204 | for ( int i = 0; i < len; ++i ) |
208 | cursor.gotoNextLetter(); | 205 | cursor.gotoNextLetter(); |
209 | doc->setSelectionEnd( QTextDocument::Temp, cursor ); | 206 | doc->setSelectionEnd( QTextDocument::Temp, cursor ); |
210 | doc->removeSelectedText( QTextDocument::Temp, &cursor ); | 207 | doc->removeSelectedText( QTextDocument::Temp, &cursor ); |
211 | if ( c ) | 208 | if ( c ) |
212 | *c = cursor; | 209 | *c = cursor; |
213 | } else { | 210 | } else { |
214 | s->remove( index, len ); | 211 | s->remove( index, len ); |
215 | } | 212 | } |
216 | 213 | ||
217 | return c; | 214 | return c; |
218 | } | 215 | } |
219 | 216 | ||
220 | QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) | 217 | QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) |
221 | { | 218 | { |
222 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; | 219 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; |
223 | if ( !s && doc ) { | 220 | if ( !s ) { |
224 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; | 221 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; |
225 | return 0; | 222 | return 0; |
226 | } else if ( !doc ) { | ||
227 | owarn << "No valid doc" << oendl; | ||
228 | return 0; | ||
229 | } | 223 | } |
230 | 224 | ||
231 | cursor.setParagraph( s ); | 225 | cursor.setParagraph( s ); |
232 | cursor.setIndex( index ); | 226 | cursor.setIndex( index ); |
233 | QString str = QTextString::toString( text ); | 227 | QString str = QTextString::toString( text ); |
234 | cursor.insert( str, TRUE, &text ); | 228 | cursor.insert( str, TRUE, &text ); |
235 | cursor.setParagraph( s ); | 229 | cursor.setParagraph( s ); |
236 | cursor.setIndex( index ); | 230 | cursor.setIndex( index ); |
237 | if ( c ) { | 231 | if ( c ) { |
238 | c->setParagraph( s ); | 232 | c->setParagraph( s ); |
239 | c->setIndex( index ); | 233 | c->setIndex( index ); |
240 | for ( int i = 0; i < (int)text.size(); ++i ) | 234 | for ( int i = 0; i < (int)text.size(); ++i ) |
241 | c->gotoNextLetter(); | 235 | c->gotoNextLetter(); |
242 | } else { | ||
243 | owarn << "No valid cursor" << oendl; | ||
244 | return 0; | ||
245 | } | 236 | } |
246 | 237 | ||
247 | if ( !styleInformation.isEmpty() ) { | 238 | if ( !styleInformation.isEmpty() ) { |
248 | QDataStream styleStream( styleInformation, IO_ReadOnly ); | 239 | QDataStream styleStream( styleInformation, IO_ReadOnly ); |
249 | int num; | 240 | int num; |
250 | styleStream >> num; | 241 | styleStream >> num; |
251 | QTextParagraph *p = s; | 242 | QTextParagraph *p = s; |
252 | while ( num-- && p ) { | 243 | while ( num-- && p ) { |
253 | p->readStyleInformation( styleStream ); | 244 | p->readStyleInformation( styleStream ); |
254 | p = p->next(); | 245 | p = p->next(); |
255 | } | 246 | } |
256 | } | 247 | } |
257 | s = cursor.paragraph(); | 248 | s = cursor.paragraph(); |
258 | while ( s ) { | 249 | while ( s ) { |
259 | s->format(); | 250 | s->format(); |
260 | s->setChanged( TRUE ); | 251 | s->setChanged( TRUE ); |
261 | if ( s == c->paragraph() ) | 252 | if ( s == c->paragraph() ) |
262 | break; | 253 | break; |
263 | s = s->next(); | 254 | s = s->next(); |
264 | } | 255 | } |
265 | 256 | ||
266 | return &cursor; | 257 | return &cursor; |
267 | } | 258 | } |
268 | 259 | ||
269 | QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, | 260 | QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, |
270 | const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl ) | 261 | const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl ) |
271 | : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl ) | 262 | : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl ) |
272 | { | 263 | { |
273 | format = d->formatCollection()->format( f ); | 264 | format = d->formatCollection()->format( f ); |
274 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { | 265 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { |
275 | if ( oldFormats[ j ].format() ) | 266 | if ( oldFormats[ j ].format() ) |
276 | oldFormats[ j ].format()->addRef(); | 267 | oldFormats[ j ].format()->addRef(); |
277 | } | 268 | } |
278 | } | 269 | } |
279 | 270 | ||
280 | QTextFormatCommand::~QTextFormatCommand() | 271 | QTextFormatCommand::~QTextFormatCommand() |
281 | { | 272 | { |
282 | format->removeRef(); | 273 | format->removeRef(); |
283 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { | 274 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { |
284 | if ( oldFormats[ j ].format() ) | 275 | if ( oldFormats[ j ].format() ) |
285 | oldFormats[ j ].format()->removeRef(); | 276 | oldFormats[ j ].format()->removeRef(); |
286 | } | 277 | } |
287 | } | 278 | } |
288 | 279 | ||
289 | QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) | 280 | QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) |
290 | { | 281 | { |
291 | QTextParagraph *sp = doc->paragAt( startId ); | 282 | QTextParagraph *sp = doc->paragAt( startId ); |
292 | QTextParagraph *ep = doc->paragAt( endId ); | 283 | QTextParagraph *ep = doc->paragAt( endId ); |
293 | if ( !sp || !ep ) | 284 | if ( !sp || !ep ) |
294 | return c; | 285 | return c; |
295 | 286 | ||
296 | QTextCursor start( doc ); | 287 | QTextCursor start( doc ); |
297 | start.setParagraph( sp ); | 288 | start.setParagraph( sp ); |
298 | start.setIndex( startIndex ); | 289 | start.setIndex( startIndex ); |
299 | QTextCursor end( doc ); | 290 | QTextCursor end( doc ); |
300 | end.setParagraph( ep ); | 291 | end.setParagraph( ep ); |
301 | end.setIndex( endIndex ); | 292 | end.setIndex( endIndex ); |
302 | 293 | ||
303 | doc->setSelectionStart( QTextDocument::Temp, start ); | 294 | doc->setSelectionStart( QTextDocument::Temp, start ); |
304 | doc->setSelectionEnd( QTextDocument::Temp, end ); | 295 | doc->setSelectionEnd( QTextDocument::Temp, end ); |
305 | doc->setFormat( QTextDocument::Temp, format, flags ); | 296 | doc->setFormat( QTextDocument::Temp, format, flags ); |
306 | doc->removeSelection( QTextDocument::Temp ); | 297 | doc->removeSelection( QTextDocument::Temp ); |
307 | if ( endIndex == ep->length() ) | 298 | if ( endIndex == ep->length() ) |
308 | end.gotoLeft(); | 299 | end.gotoLeft(); |
309 | *c = end; | 300 | *c = end; |
310 | return c; | 301 | return c; |
311 | } | 302 | } |
312 | 303 | ||
313 | QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) | 304 | QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) |
314 | { | 305 | { |
315 | QTextParagraph *sp = doc->paragAt( startId ); | 306 | QTextParagraph *sp = doc->paragAt( startId ); |
316 | QTextParagraph *ep = doc->paragAt( endId ); | 307 | QTextParagraph *ep = doc->paragAt( endId ); |
317 | if ( !sp || !ep ) | 308 | if ( !sp || !ep ) |
318 | return 0; | 309 | return 0; |
319 | 310 | ||
320 | int idx = startIndex; | 311 | int idx = startIndex; |
321 | int fIndex = 0; | 312 | int fIndex = 0; |
322 | for ( ;; ) { | 313 | for ( ;; ) { |
323 | if ( oldFormats.at( fIndex ).c == '\n' ) { | 314 | if ( oldFormats.at( fIndex ).c == '\n' ) { |
324 | if ( idx > 0 ) { | 315 | if ( idx > 0 ) { |
325 | if ( idx < sp->length() && fIndex > 0 ) | 316 | if ( idx < sp->length() && fIndex > 0 ) |
326 | sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() ); | 317 | sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() ); |
327 | if ( sp == ep ) | 318 | if ( sp == ep ) |
328 | break; | 319 | break; |
329 | sp = sp->next(); | 320 | sp = sp->next(); |
330 | idx = 0; | 321 | idx = 0; |
331 | } | 322 | } |
332 | fIndex++; | 323 | fIndex++; |
333 | } | 324 | } |
334 | if ( oldFormats.at( fIndex ).format() ) | 325 | if ( oldFormats.at( fIndex ).format() ) |
335 | sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() ); | 326 | sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() ); |
336 | idx++; | 327 | idx++; |
337 | fIndex++; | 328 | fIndex++; |
338 | if ( fIndex >= (int)oldFormats.size() ) | 329 | if ( fIndex >= (int)oldFormats.size() ) |
339 | break; | 330 | break; |
340 | if ( idx >= sp->length() ) { | 331 | if ( idx >= sp->length() ) { |
341 | if ( sp == ep ) | 332 | if ( sp == ep ) |
342 | break; | 333 | break; |
343 | sp = sp->next(); | 334 | sp = sp->next(); |
344 | idx = 0; | 335 | idx = 0; |
345 | } | 336 | } |
346 | } | 337 | } |
347 | 338 | ||
348 | QTextCursor end( doc ); | 339 | QTextCursor end( doc ); |
349 | end.setParagraph( ep ); | 340 | end.setParagraph( ep ); |
350 | end.setIndex( endIndex ); | 341 | end.setIndex( endIndex ); |
351 | if ( endIndex == ep->length() ) | 342 | if ( endIndex == ep->length() ) |
352 | end.gotoLeft(); | 343 | end.gotoLeft(); |
353 | *c = end; | 344 | *c = end; |
354 | return c; | 345 | return c; |
355 | } | 346 | } |
356 | 347 | ||
357 | QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange ) | 348 | QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange ) |
358 | : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange ) | 349 | : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange ) |
359 | { | 350 | { |
360 | after = readStyleInformation( d, fParag, lParag ); | 351 | after = readStyleInformation( d, fParag, lParag ); |
361 | } | 352 | } |
362 | 353 | ||
363 | 354 | ||
364 | QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag ) | 355 | QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag ) |
365 | { | 356 | { |
366 | QByteArray style; | 357 | QByteArray style; |
367 | QTextParagraph *p = doc->paragAt( fParag ); | 358 | QTextParagraph *p = doc->paragAt( fParag ); |
368 | if ( !p ) | 359 | if ( !p ) |
369 | return style; | 360 | return style; |
370 | QDataStream styleStream( style, IO_WriteOnly ); | 361 | QDataStream styleStream( style, IO_WriteOnly ); |
371 | int num = lParag - fParag + 1; | 362 | int num = lParag - fParag + 1; |
372 | styleStream << num; | 363 | styleStream << num; |
373 | while ( num -- && p ) { | 364 | while ( num -- && p ) { |
374 | p->writeStyleInformation( styleStream ); | 365 | p->writeStyleInformation( styleStream ); |
375 | p = p->next(); | 366 | p = p->next(); |
376 | } | 367 | } |
377 | return style; | 368 | return style; |
378 | } | 369 | } |
379 | 370 | ||
380 | void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style ) | 371 | void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style ) |
381 | { | 372 | { |
382 | QTextParagraph *p = doc->paragAt( fParag ); | 373 | QTextParagraph *p = doc->paragAt( fParag ); |
383 | if ( !p ) | 374 | if ( !p ) |
384 | return; | 375 | return; |
385 | QDataStream styleStream( style, IO_ReadOnly ); | 376 | QDataStream styleStream( style, IO_ReadOnly ); |
386 | int num; | 377 | int num; |
387 | styleStream >> num; | 378 | styleStream >> num; |
388 | while ( num-- && p ) { | 379 | while ( num-- && p ) { |
389 | p->readStyleInformation( styleStream ); | 380 | p->readStyleInformation( styleStream ); |
390 | p = p->next(); | 381 | p = p->next(); |
391 | } | 382 | } |
392 | } | 383 | } |
393 | 384 | ||
394 | QTextCursor *QTextStyleCommand::execute( QTextCursor *c ) | 385 | QTextCursor *QTextStyleCommand::execute( QTextCursor *c ) |
395 | { | 386 | { |
396 | writeStyleInformation( doc, firstParag, after ); | 387 | writeStyleInformation( doc, firstParag, after ); |
397 | return c; | 388 | return c; |
398 | } | 389 | } |
399 | 390 | ||
400 | QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c ) | 391 | QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c ) |
401 | { | 392 | { |
402 | writeStyleInformation( doc, firstParag, before ); | 393 | writeStyleInformation( doc, firstParag, before ); |
403 | return c; | 394 | return c; |
404 | } | 395 | } |
405 | 396 | ||
406 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 397 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
407 | 398 | ||
408 | QTextCursor::QTextCursor( QTextDocument *d ) | 399 | QTextCursor::QTextCursor( QTextDocument *d ) |
409 | : idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ), | 400 | : idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ), |
410 | valid( TRUE ) | 401 | valid( TRUE ) |
411 | { | 402 | { |
412 | para = d ? d->firstParagraph() : 0; | 403 | para = d ? d->firstParagraph() : 0; |
413 | } | 404 | } |
414 | 405 | ||
415 | QTextCursor::QTextCursor( const QTextCursor &c ) | 406 | QTextCursor::QTextCursor( const QTextCursor &c ) |
416 | { | 407 | { |
417 | ox = c.ox; | 408 | ox = c.ox; |
418 | oy = c.oy; | 409 | oy = c.oy; |
419 | idx = c.idx; | 410 | idx = c.idx; |
420 | para = c.para; | 411 | para = c.para; |
421 | tmpIndex = c.tmpIndex; | 412 | tmpIndex = c.tmpIndex; |
422 | indices = c.indices; | 413 | indices = c.indices; |
423 | paras = c.paras; | 414 | paras = c.paras; |
424 | xOffsets = c.xOffsets; | 415 | xOffsets = c.xOffsets; |
425 | yOffsets = c.yOffsets; | 416 | yOffsets = c.yOffsets; |
426 | valid = c.valid; | 417 | valid = c.valid; |
427 | } | 418 | } |
428 | 419 | ||
429 | QTextCursor &QTextCursor::operator=( const QTextCursor &c ) | 420 | QTextCursor &QTextCursor::operator=( const QTextCursor &c ) |
430 | { | 421 | { |
431 | ox = c.ox; | 422 | ox = c.ox; |
432 | oy = c.oy; | 423 | oy = c.oy; |
433 | idx = c.idx; | 424 | idx = c.idx; |
434 | para = c.para; | 425 | para = c.para; |
435 | tmpIndex = c.tmpIndex; | 426 | tmpIndex = c.tmpIndex; |
436 | indices = c.indices; | 427 | indices = c.indices; |
437 | paras = c.paras; | 428 | paras = c.paras; |
438 | xOffsets = c.xOffsets; | 429 | xOffsets = c.xOffsets; |
439 | yOffsets = c.yOffsets; | 430 | yOffsets = c.yOffsets; |
440 | valid = c.valid; | 431 | valid = c.valid; |
441 | 432 | ||
442 | return *this; | 433 | return *this; |
443 | } | 434 | } |
444 | 435 | ||
445 | bool QTextCursor::operator==( const QTextCursor &c ) const | 436 | bool QTextCursor::operator==( const QTextCursor &c ) const |
446 | { | 437 | { |
447 | return para == c.para && idx == c.idx; | 438 | return para == c.para && idx == c.idx; |
448 | } | 439 | } |
449 | 440 | ||
450 | int QTextCursor::totalOffsetX() const | 441 | int QTextCursor::totalOffsetX() const |
451 | { | 442 | { |
452 | int xoff = ox; | 443 | int xoff = ox; |
453 | for ( QValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit ) | 444 | for ( QValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit ) |
454 | xoff += *xit; | 445 | xoff += *xit; |
455 | return xoff; | 446 | return xoff; |
456 | } | 447 | } |
457 | 448 | ||
458 | int QTextCursor::totalOffsetY() const | 449 | int QTextCursor::totalOffsetY() const |
459 | { | 450 | { |
460 | int yoff = oy; | 451 | int yoff = oy; |
461 | for ( QValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit ) | 452 | for ( QValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit ) |
462 | yoff += *yit; | 453 | yoff += *yit; |
463 | return yoff; | 454 | return yoff; |
464 | } | 455 | } |
465 | 456 | ||
466 | void QTextCursor::gotoIntoNested( const QPoint &globalPos ) | 457 | void QTextCursor::gotoIntoNested( const QPoint &globalPos ) |
467 | { | 458 | { |
468 | if ( !para ) | 459 | if ( !para ) |
469 | return; | 460 | return; |
470 | push(); | 461 | push(); |
471 | ox = 0; | 462 | ox = 0; |
472 | int bl, y; | 463 | int bl, y; |
473 | para->lineHeightOfChar( idx, &bl, &y ); | 464 | para->lineHeightOfChar( idx, &bl, &y ); |
474 | oy = y + para->rect().y(); | 465 | oy = y + para->rect().y(); |
475 | QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() ); | 466 | QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() ); |
476 | Q_ASSERT( para->at( idx )->isCustom() ); | 467 | Q_ASSERT( para->at( idx )->isCustom() ); |
477 | ox = para->at( idx )->x; | 468 | ox = para->at( idx )->x; |
478 | 469 | ||
479 | QTextDocument* doc = document(); | 470 | QTextDocument* doc = document(); |
480 | para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, p ); | 471 | para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, p ); |
481 | } | 472 | } |
482 | 473 | ||
483 | void QTextCursor::invalidateNested() | 474 | void QTextCursor::invalidateNested() |
484 | { | 475 | { |
485 | QValueStack<QTextParagraph*>::Iterator it = paras.begin(); | 476 | QValueStack<QTextParagraph*>::Iterator it = paras.begin(); |
486 | QValueStack<int>::Iterator it2 = indices.begin(); | 477 | QValueStack<int>::Iterator it2 = indices.begin(); |
487 | for ( ; it != paras.end(); ++it, ++it2 ) { | 478 | for ( ; it != paras.end(); ++it, ++it2 ) { |
488 | if ( *it == para ) | 479 | if ( *it == para ) |
489 | continue; | 480 | continue; |
490 | (*it)->invalidate( 0 ); | 481 | (*it)->invalidate( 0 ); |
491 | if ( (*it)->at( *it2 )->isCustom() ) | 482 | if ( (*it)->at( *it2 )->isCustom() ) |
492 | (*it)->at( *it2 )->customItem()->invalidate(); | 483 | (*it)->at( *it2 )->customItem()->invalidate(); |
493 | } | 484 | } |
494 | } | 485 | } |
495 | 486 | ||
496 | void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QTextStringChar> *formatting ) | 487 | void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QTextStringChar> *formatting ) |
497 | { | 488 | { |
498 | tmpIndex = -1; | 489 | tmpIndex = -1; |
499 | bool justInsert = TRUE; | 490 | bool justInsert = TRUE; |
500 | QString s( str ); | 491 | QString s( str ); |
501 | #if defined(Q_WS_WIN) | 492 | #if defined(Q_WS_WIN) |
502 | if ( checkNewLine ) { | 493 | if ( checkNewLine ) { |
503 | int i = 0; | 494 | int i = 0; |
504 | while ( ( i = s.find( '\r', i ) ) != -1 ) | 495 | while ( ( i = s.find( '\r', i ) ) != -1 ) |
505 | s.remove( i ,1 ); | 496 | s.remove( i ,1 ); |
506 | } | 497 | } |
507 | #endif | 498 | #endif |
508 | if ( checkNewLine ) | 499 | if ( checkNewLine ) |
509 | justInsert = s.find( '\n' ) == -1; | 500 | justInsert = s.find( '\n' ) == -1; |
510 | if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index | 501 | if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index |
511 | para->insert( idx, s.unicode(), s.length() ); | 502 | para->insert( idx, s.unicode(), s.length() ); |
512 | if ( formatting ) { | 503 | if ( formatting ) { |
513 | for ( int i = 0; i < (int)s.length(); ++i ) { | 504 | for ( int i = 0; i < (int)s.length(); ++i ) { |
514 | if ( formatting->at( i ).format() ) { | 505 | if ( formatting->at( i ).format() ) { |
515 | formatting->at( i ).format()->addRef(); | 506 | formatting->at( i ).format()->addRef(); |
516 | para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE ); | 507 | para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE ); |
517 | } | 508 | } |
518 | } | 509 | } |
519 | } | 510 | } |
520 | idx += s.length(); | 511 | idx += s.length(); |
521 | } else { // we split at new lines | 512 | } else { // we split at new lines |
522 | int start = -1; | 513 | int start = -1; |
523 | int end; | 514 | int end; |
524 | int y = para->rect().y() + para->rect().height(); | 515 | int y = para->rect().y() + para->rect().height(); |
525 | int lastIndex = 0; | 516 | int lastIndex = 0; |
526 | do { | 517 | do { |
527 | end = s.find( '\n', start + 1 ); // find line break | 518 | end = s.find( '\n', start + 1 ); // find line break |
528 | if ( end == -1 ) // didn't find one, so end of line is end of string | 519 | if ( end == -1 ) // didn't find one, so end of line is end of string |
529 | end = s.length(); | 520 | end = s.length(); |
530 | int len = (start == -1 ? end : end - start - 1); | 521 | int len = (start == -1 ? end : end - start - 1); |
531 | if ( len > 0 ) // insert the line | 522 | if ( len > 0 ) // insert the line |
532 | para->insert( idx, s.unicode() + start + 1, len ); | 523 | para->insert( idx, s.unicode() + start + 1, len ); |
533 | else | 524 | else |
534 | para->invalidate( 0 ); | 525 | para->invalidate( 0 ); |
535 | if ( formatting ) { // set formats to the chars of the line | 526 | if ( formatting ) { // set formats to the chars of the line |
536 | for ( int i = 0; i < len; ++i ) { | 527 | for ( int i = 0; i < len; ++i ) { |
537 | if ( formatting->at( i + lastIndex ).format() ) { | 528 | if ( formatting->at( i + lastIndex ).format() ) { |
538 | formatting->at( i + lastIndex ).format()->addRef(); | 529 | formatting->at( i + lastIndex ).format()->addRef(); |
539 | para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE ); | 530 | para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE ); |
540 | } | 531 | } |
541 | } | 532 | } |
542 | lastIndex += len; | 533 | lastIndex += len; |
543 | } | 534 | } |
544 | start = end; // next start is at the end of this line | 535 | start = end; // next start is at the end of this line |
545 | idx += len; // increase the index of the cursor to the end of the inserted text | 536 | idx += len; // increase the index of the cursor to the end of the inserted text |
546 | if ( s[end] == '\n' ) { // if at the end was a line break, break the line | 537 | if ( s[end] == '\n' ) { // if at the end was a line break, break the line |
547 | splitAndInsertEmptyParagraph( FALSE, TRUE ); | 538 | splitAndInsertEmptyParagraph( FALSE, TRUE ); |
548 | para->setEndState( -1 ); | 539 | para->setEndState( -1 ); |
549 | para->prev()->format( -1, FALSE ); | 540 | para->prev()->format( -1, FALSE ); |
550 | lastIndex++; | 541 | lastIndex++; |
551 | } | 542 | } |
552 | 543 | ||
553 | } while ( end < (int)s.length() ); | 544 | } while ( end < (int)s.length() ); |
554 | 545 | ||
555 | para->format( -1, FALSE ); | 546 | para->format( -1, FALSE ); |
556 | int dy = para->rect().y() + para->rect().height() - y; | 547 | int dy = para->rect().y() + para->rect().height() - y; |
557 | QTextParagraph *p = para; | 548 | QTextParagraph *p = para; |
558 | p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 ); | 549 | p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 ); |
559 | p = p->next(); | 550 | p = p->next(); |
560 | while ( p ) { | 551 | while ( p ) { |
561 | p->setParagId( p->prev()->paragId() + 1 ); | 552 | p->setParagId( p->prev()->paragId() + 1 ); |
562 | p->move( dy ); | 553 | p->move( dy ); |
563 | p->invalidate( 0 ); | 554 | p->invalidate( 0 ); |
564 | p->setEndState( -1 ); | 555 | p->setEndState( -1 ); |
565 | p = p->next(); | 556 | p = p->next(); |
566 | } | 557 | } |
567 | } | 558 | } |
568 | 559 | ||
569 | int h = para->rect().height(); | 560 | int h = para->rect().height(); |
570 | para->format( -1, TRUE ); | 561 | para->format( -1, TRUE ); |
571 | if ( h != para->rect().height() ) | 562 | if ( h != para->rect().height() ) |
572 | invalidateNested(); | 563 | invalidateNested(); |
573 | else if ( para->document() && para->document()->parent() ) | 564 | else if ( para->document() && para->document()->parent() ) |
574 | para->document()->nextDoubleBuffered = TRUE; | 565 | para->document()->nextDoubleBuffered = TRUE; |
575 | } | 566 | } |
576 | 567 | ||
577 | void QTextCursor::gotoLeft() | 568 | void QTextCursor::gotoLeft() |
578 | { | 569 | { |
579 | if ( para->string()->isRightToLeft() ) | 570 | if ( para->string()->isRightToLeft() ) |
580 | gotoNextLetter(); | 571 | gotoNextLetter(); |
581 | else | 572 | else |
582 | gotoPreviousLetter(); | 573 | gotoPreviousLetter(); |
583 | } | 574 | } |
584 | 575 | ||
585 | void QTextCursor::gotoPreviousLetter() | 576 | void QTextCursor::gotoPreviousLetter() |
586 | { | 577 | { |
587 | tmpIndex = -1; | 578 | tmpIndex = -1; |
588 | 579 | ||
589 | if ( idx > 0 ) { | 580 | if ( idx > 0 ) { |
590 | idx--; | 581 | idx--; |
591 | const QTextStringChar *tsc = para->at( idx ); | 582 | const QTextStringChar *tsc = para->at( idx ); |
592 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) | 583 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) |
593 | processNesting( EnterEnd ); | 584 | processNesting( EnterEnd ); |
594 | } else if ( para->prev() ) { | 585 | } else if ( para->prev() ) { |
595 | para = para->prev(); | 586 | para = para->prev(); |
596 | while ( !para->isVisible() && para->prev() ) | 587 | while ( !para->isVisible() && para->prev() ) |
597 | para = para->prev(); | 588 | para = para->prev(); |
598 | idx = para->length() - 1; | 589 | idx = para->length() - 1; |
599 | } else if ( nestedDepth() ) { | 590 | } else if ( nestedDepth() ) { |
600 | pop(); | 591 | pop(); |
601 | processNesting( Prev ); | 592 | processNesting( Prev ); |
602 | if ( idx == -1 ) { | 593 | if ( idx == -1 ) { |
603 | pop(); | 594 | pop(); |
604 | if ( idx > 0 ) { | 595 | if ( idx > 0 ) { |
605 | idx--; | 596 | idx--; |
606 | } else if ( para->prev() ) { | 597 | } else if ( para->prev() ) { |
607 | para = para->prev(); | 598 | para = para->prev(); |
608 | idx = para->length() - 1; | 599 | idx = para->length() - 1; |
609 | } | 600 | } |
610 | } | 601 | } |
611 | } | 602 | } |
612 | } | 603 | } |
613 | 604 | ||
614 | void QTextCursor::push() | 605 | void QTextCursor::push() |
615 | { | 606 | { |
616 | indices.push( idx ); | 607 | indices.push( idx ); |
617 | paras.push( para ); | 608 | paras.push( para ); |
618 | xOffsets.push( ox ); | 609 | xOffsets.push( ox ); |
619 | yOffsets.push( oy ); | 610 | yOffsets.push( oy ); |
620 | } | 611 | } |
621 | 612 | ||
622 | void QTextCursor::pop() | 613 | void QTextCursor::pop() |
623 | { | 614 | { |
624 | if ( indices.isEmpty() ) | 615 | if ( indices.isEmpty() ) |
625 | return; | 616 | return; |
626 | idx = indices.pop(); | 617 | idx = indices.pop(); |
627 | para = paras.pop(); | 618 | para = paras.pop(); |
628 | ox = xOffsets.pop(); | 619 | ox = xOffsets.pop(); |
629 | oy = yOffsets.pop(); | 620 | oy = yOffsets.pop(); |
630 | } | 621 | } |
631 | 622 | ||
632 | void QTextCursor::restoreState() | 623 | void QTextCursor::restoreState() |
633 | { | 624 | { |
634 | while ( !indices.isEmpty() ) | 625 | while ( !indices.isEmpty() ) |
635 | pop(); | 626 | pop(); |
636 | } | 627 | } |
637 | 628 | ||
638 | bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link ) | 629 | bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link ) |
639 | { | 630 | { |
640 | QPoint pos( p ); | 631 | QPoint pos( p ); |
641 | QRect r; | 632 | QRect r; |
642 | QTextParagraph *str = s; | 633 | QTextParagraph *str = s; |
643 | if ( pos.y() < s->rect().y() ) | 634 | if ( pos.y() < s->rect().y() ) |
644 | pos.setY( s->rect().y() ); | 635 | pos.setY( s->rect().y() ); |
645 | while ( s ) { | 636 | while ( s ) { |
646 | r = s->rect(); | 637 | r = s->rect(); |
647 | r.setWidth( document() ? document()->width() : QWIDGETSIZE_MAX ); | 638 | r.setWidth( document() ? document()->width() : QWIDGETSIZE_MAX ); |
648 | if ( s->isVisible() ) | 639 | if ( s->isVisible() ) |
649 | str = s; | 640 | str = s; |
650 | if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() ) | 641 | if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() ) |
651 | break; | 642 | break; |
652 | s = s->next(); | 643 | s = s->next(); |
653 | } | 644 | } |
654 | 645 | ||
655 | if ( !s || !str ) | 646 | if ( !s || !str ) |
656 | return FALSE; | 647 | return FALSE; |
657 | 648 | ||
658 | s = str; | 649 | s = str; |
659 | 650 | ||
660 | setParagraph( s ); | 651 | setParagraph( s ); |
661 | int y = s->rect().y(); | 652 | int y = s->rect().y(); |
662 | int lines = s->lines(); | 653 | int lines = s->lines(); |
663 | QTextStringChar *chr = 0; | 654 | QTextStringChar *chr = 0; |
664 | int index = 0; | 655 | int index = 0; |
665 | int i = 0; | 656 | int i = 0; |
666 | int cy = 0; | 657 | int cy = 0; |
667 | int ch = 0; | 658 | int ch = 0; |
668 | for ( ; i < lines; ++i ) { | 659 | for ( ; i < lines; ++i ) { |
669 | chr = s->lineStartOfLine( i, &index ); | 660 | chr = s->lineStartOfLine( i, &index ); |
670 | cy = s->lineY( i ); | 661 | cy = s->lineY( i ); |
671 | ch = s->lineHeight( i ); | 662 | ch = s->lineHeight( i ); |
672 | if ( !chr ) | 663 | if ( !chr ) |
673 | return FALSE; | 664 | return FALSE; |
674 | if ( pos.y() <= y + cy + ch ) | 665 | if ( pos.y() <= y + cy + ch ) |
675 | break; | 666 | break; |
676 | } | 667 | } |
677 | int nextLine; | 668 | int nextLine; |
678 | if ( i < lines - 1 ) | 669 | if ( i < lines - 1 ) |
679 | s->lineStartOfLine( i+1, &nextLine ); | 670 | s->lineStartOfLine( i+1, &nextLine ); |
680 | else | 671 | else |
681 | nextLine = s->length(); | 672 | nextLine = s->length(); |
682 | i = index; | 673 | i = index; |
683 | int x = s->rect().x(); | 674 | int x = s->rect().x(); |
684 | if ( pos.x() < x ) | 675 | if ( pos.x() < x ) |
685 | pos.setX( x + 1 ); | 676 | pos.setX( x + 1 ); |
686 | int cw; | 677 | int cw; |
687 | int curpos = s->length()-1; | 678 | int curpos = s->length()-1; |
688 | int dist = 10000000; | 679 | int dist = 10000000; |
689 | bool inCustom = FALSE; | 680 | bool inCustom = FALSE; |
690 | while ( i < nextLine ) { | 681 | while ( i < nextLine ) { |
691 | chr = s->at(i); | 682 | chr = s->at(i); |
692 | int cpos = x + chr->x; | 683 | int cpos = x + chr->x; |
693 | cw = s->string()->width( i ); | 684 | cw = s->string()->width( i ); |
694 | if ( chr->isCustom() && chr->customItem()->isNested() ) { | 685 | if ( chr->isCustom() && chr->customItem()->isNested() ) { |
695 | if ( pos.x() >= cpos && pos.x() <= cpos + cw && | 686 | if ( pos.x() >= cpos && pos.x() <= cpos + cw && |
696 | pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) { | 687 | pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) { |
697 | inCustom = TRUE; | 688 | inCustom = TRUE; |
698 | curpos = i; | 689 | curpos = i; |
699 | break; | 690 | break; |
700 | } | 691 | } |
701 | } else { | 692 | } else { |
702 | if( chr->rightToLeft ) | 693 | if( chr->rightToLeft ) |
703 | cpos += cw; | 694 | cpos += cw; |
704 | int d = cpos - pos.x(); | 695 | int d = cpos - pos.x(); |
705 | bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft; | 696 | bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft; |
706 | if ( QABS( d ) < dist || (dist == d && dm == TRUE ) ) { | 697 | if ( QABS( d ) < dist || (dist == d && dm == TRUE ) ) { |
707 | dist = QABS( d ); | 698 | dist = QABS( d ); |
708 | if ( !link || pos.x() >= x + chr->x ) | 699 | if ( !link || pos.x() >= x + chr->x ) |
709 | curpos = i; | 700 | curpos = i; |
710 | } | 701 | } |
711 | } | 702 | } |
712 | i++; | 703 | i++; |
713 | } | 704 | } |
714 | setIndex( curpos ); | 705 | setIndex( curpos ); |
715 | 706 | ||
716 | if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) { | 707 | if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) { |
717 | QTextDocument *oldDoc = para->document(); | 708 | QTextDocument *oldDoc = para->document(); |
718 | gotoIntoNested( pos ); | 709 | gotoIntoNested( pos ); |
719 | if ( oldDoc == para->document() ) | 710 | if ( oldDoc == para->document() ) |
720 | return TRUE; | 711 | return TRUE; |
721 | QPoint p( pos.x() - offsetX(), pos.y() - offsetY() ); | 712 | QPoint p( pos.x() - offsetX(), pos.y() - offsetY() ); |
722 | if ( !place( p, document()->firstParagraph(), link ) ) | 713 | if ( !place( p, document()->firstParagraph(), link ) ) |
723 | pop(); | 714 | pop(); |
724 | } | 715 | } |
725 | return TRUE; | 716 | return TRUE; |
726 | } | 717 | } |
727 | 718 | ||
728 | void QTextCursor::processNesting( Operation op ) | 719 | void QTextCursor::processNesting( Operation op ) |
729 | { | 720 | { |
730 | if ( !para->document() ) | 721 | if ( !para->document() ) |
731 | return; | 722 | return; |
732 | QTextDocument* doc = para->document(); | 723 | QTextDocument* doc = para->document(); |
733 | push(); | 724 | push(); |
734 | ox = para->at( idx )->x; | 725 | ox = para->at( idx )->x; |
735 | int bl, y; | 726 | int bl, y; |
736 | para->lineHeightOfChar( idx, &bl, &y ); | 727 | para->lineHeightOfChar( idx, &bl, &y ); |
737 | oy = y + para->rect().y(); | 728 | oy = y + para->rect().y(); |
738 | bool ok = FALSE; | 729 | bool ok = FALSE; |
739 | 730 | ||
740 | switch ( op ) { | 731 | switch ( op ) { |
741 | case EnterBegin: | 732 | case EnterBegin: |
742 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy ); | 733 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy ); |
743 | break; | 734 | break; |
744 | case EnterEnd: | 735 | case EnterEnd: |
745 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE ); | 736 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE ); |
746 | break; | 737 | break; |
747 | case Next: | 738 | case Next: |
748 | ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy ); | 739 | ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy ); |
749 | break; | 740 | break; |
750 | case Prev: | 741 | case Prev: |
751 | ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy ); | 742 | ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy ); |
752 | break; | 743 | break; |
753 | case Down: | 744 | case Down: |
754 | ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy ); | 745 | ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy ); |
755 | break; | 746 | break; |
756 | case Up: | 747 | case Up: |
757 | ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy ); | 748 | ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy ); |
758 | break; | 749 | break; |
759 | } | 750 | } |
760 | if ( !ok ) | 751 | if ( !ok ) |
761 | pop(); | 752 | pop(); |
762 | } | 753 | } |
763 | 754 | ||
764 | void QTextCursor::gotoRight() | 755 | void QTextCursor::gotoRight() |
765 | { | 756 | { |
766 | if ( para->string()->isRightToLeft() ) | 757 | if ( para->string()->isRightToLeft() ) |
767 | gotoPreviousLetter(); | 758 | gotoPreviousLetter(); |
768 | else | 759 | else |
769 | gotoNextLetter(); | 760 | gotoNextLetter(); |
770 | } | 761 | } |
771 | 762 | ||
772 | void QTextCursor::gotoNextLetter() | 763 | void QTextCursor::gotoNextLetter() |
773 | { | 764 | { |
774 | tmpIndex = -1; | 765 | tmpIndex = -1; |
775 | 766 | ||
776 | const QTextStringChar *tsc = para->at( idx ); | 767 | const QTextStringChar *tsc = para->at( idx ); |
777 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) { | 768 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) { |
778 | processNesting( EnterBegin ); | 769 | processNesting( EnterBegin ); |
779 | return; | 770 | return; |
780 | } | 771 | } |
781 | 772 | ||
782 | if ( idx < para->length() - 1 ) { | 773 | if ( idx < para->length() - 1 ) { |
783 | idx++; | 774 | idx++; |
784 | } else if ( para->next() ) { | 775 | } else if ( para->next() ) { |
785 | para = para->next(); | 776 | para = para->next(); |
786 | while ( !para->isVisible() && para->next() ) | 777 | while ( !para->isVisible() && para->next() ) |
787 | para = para->next(); | 778 | para = para->next(); |
788 | idx = 0; | 779 | idx = 0; |
789 | } else if ( nestedDepth() ) { | 780 | } else if ( nestedDepth() ) { |
790 | pop(); | 781 | pop(); |
791 | processNesting( Next ); | 782 | processNesting( Next ); |
792 | if ( idx == -1 ) { | 783 | if ( idx == -1 ) { |
793 | pop(); | 784 | pop(); |
794 | if ( idx < para->length() - 1 ) { | 785 | if ( idx < para->length() - 1 ) { |
795 | idx++; | 786 | idx++; |
796 | } else if ( para->next() ) { | 787 | } else if ( para->next() ) { |
797 | para = para->next(); | 788 | para = para->next(); |
798 | idx = 0; | 789 | idx = 0; |
799 | } | 790 | } |
800 | } | 791 | } |
801 | } | 792 | } |
802 | } | 793 | } |
803 | 794 | ||
804 | void QTextCursor::gotoUp() | 795 | void QTextCursor::gotoUp() |
805 | { | 796 | { |
806 | int indexOfLineStart; | 797 | int indexOfLineStart; |
807 | int line; | 798 | int line; |
808 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 799 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
809 | if ( !c ) | 800 | if ( !c ) |
810 | return; | 801 | return; |
811 | 802 | ||
812 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); | 803 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); |
813 | if ( indexOfLineStart == 0 ) { | 804 | if ( indexOfLineStart == 0 ) { |
814 | if ( !para->prev() ) { | 805 | if ( !para->prev() ) { |
815 | if ( !nestedDepth() ) | 806 | if ( !nestedDepth() ) |
816 | return; | 807 | return; |
817 | pop(); | 808 | pop(); |
818 | processNesting( Up ); | 809 | processNesting( Up ); |
819 | if ( idx == -1 ) { | 810 | if ( idx == -1 ) { |
820 | pop(); | 811 | pop(); |
821 | if ( !para->prev() ) | 812 | if ( !para->prev() ) |
822 | return; | 813 | return; |
823 | idx = tmpIndex = 0; | 814 | idx = tmpIndex = 0; |
824 | } else { | 815 | } else { |
825 | tmpIndex = -1; | 816 | tmpIndex = -1; |
826 | return; | 817 | return; |
827 | } | 818 | } |
828 | } | 819 | } |
829 | QTextParagraph *p = para->prev(); | 820 | QTextParagraph *p = para->prev(); |
830 | while ( p && !p->isVisible() ) | 821 | while ( p && !p->isVisible() ) |
831 | p = p->prev(); | 822 | p = p->prev(); |
832 | if ( p ) | 823 | if ( p ) |
833 | para = p; | 824 | para = p; |
834 | int lastLine = para->lines() - 1; | 825 | int lastLine = para->lines() - 1; |
835 | if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) ) | 826 | if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) ) |
836 | return; | 827 | return; |
837 | if ( indexOfLineStart + tmpIndex < para->length() ) | 828 | if ( indexOfLineStart + tmpIndex < para->length() ) |
838 | idx = indexOfLineStart + tmpIndex; | 829 | idx = indexOfLineStart + tmpIndex; |
839 | else | 830 | else |
840 | idx = para->length() - 1; | 831 | idx = para->length() - 1; |
841 | } else { | 832 | } else { |
842 | --line; | 833 | --line; |
843 | int oldIndexOfLineStart = indexOfLineStart; | 834 | int oldIndexOfLineStart = indexOfLineStart; |
844 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) | 835 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) |
845 | return; | 836 | return; |
846 | if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart ) | 837 | if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart ) |
847 | idx = indexOfLineStart + tmpIndex; | 838 | idx = indexOfLineStart + tmpIndex; |
848 | else | 839 | else |
849 | idx = oldIndexOfLineStart - 1; | 840 | idx = oldIndexOfLineStart - 1; |
850 | } | 841 | } |
851 | } | 842 | } |
852 | 843 | ||
853 | void QTextCursor::gotoDown() | 844 | void QTextCursor::gotoDown() |
854 | { | 845 | { |
855 | int indexOfLineStart; | 846 | int indexOfLineStart; |
856 | int line; | 847 | int line; |
857 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 848 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
858 | if ( !c ) | 849 | if ( !c ) |
859 | return; | 850 | return; |
860 | 851 | ||
861 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); | 852 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); |
862 | if ( line == para->lines() - 1 ) { | 853 | if ( line == para->lines() - 1 ) { |
863 | if ( !para->next() ) { | 854 | if ( !para->next() ) { |
864 | if ( !nestedDepth() ) | 855 | if ( !nestedDepth() ) |
865 | return; | 856 | return; |
866 | pop(); | 857 | pop(); |
867 | processNesting( Down ); | 858 | processNesting( Down ); |
868 | if ( idx == -1 ) { | 859 | if ( idx == -1 ) { |
869 | pop(); | 860 | pop(); |
870 | if ( !para->next() ) | 861 | if ( !para->next() ) |
871 | return; | 862 | return; |
872 | idx = tmpIndex = 0; | 863 | idx = tmpIndex = 0; |
873 | } else { | 864 | } else { |
874 | tmpIndex = -1; | 865 | tmpIndex = -1; |
875 | return; | 866 | return; |
876 | } | 867 | } |
877 | } | 868 | } |
878 | QTextParagraph *s = para->next(); | 869 | QTextParagraph *s = para->next(); |
879 | while ( s && !s->isVisible() ) | 870 | while ( s && !s->isVisible() ) |
880 | s = s->next(); | 871 | s = s->next(); |
881 | if ( s ) | 872 | if ( s ) |
882 | para = s; | 873 | para = s; |
883 | if ( !para->lineStartOfLine( 0, &indexOfLineStart ) ) | 874 | if ( !para->lineStartOfLine( 0, &indexOfLineStart ) ) |
884 | return; | 875 | return; |
885 | int end; | 876 | int end; |
886 | if ( para->lines() == 1 ) | 877 | if ( para->lines() == 1 ) |
887 | end = para->length(); | 878 | end = para->length(); |
888 | else | 879 | else |
889 | para->lineStartOfLine( 1, &end ); | 880 | para->lineStartOfLine( 1, &end ); |
890 | if ( indexOfLineStart + tmpIndex < end ) | 881 | if ( indexOfLineStart + tmpIndex < end ) |
891 | idx = indexOfLineStart + tmpIndex; | 882 | idx = indexOfLineStart + tmpIndex; |
892 | else | 883 | else |
893 | idx = end - 1; | 884 | idx = end - 1; |
894 | } else { | 885 | } else { |
895 | ++line; | 886 | ++line; |
896 | int end; | 887 | int end; |
897 | if ( line == para->lines() - 1 ) | 888 | if ( line == para->lines() - 1 ) |
898 | end = para->length(); | 889 | end = para->length(); |
899 | else | 890 | else |
900 | para->lineStartOfLine( line + 1, &end ); | 891 | para->lineStartOfLine( line + 1, &end ); |
901 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) | 892 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) |
902 | return; | 893 | return; |
903 | if ( indexOfLineStart + tmpIndex < end ) | 894 | if ( indexOfLineStart + tmpIndex < end ) |
904 | idx = indexOfLineStart + tmpIndex; | 895 | idx = indexOfLineStart + tmpIndex; |
905 | else | 896 | else |
906 | idx = end - 1; | 897 | idx = end - 1; |
907 | } | 898 | } |
908 | } | 899 | } |
909 | 900 | ||
910 | void QTextCursor::gotoLineEnd() | 901 | void QTextCursor::gotoLineEnd() |
911 | { | 902 | { |
912 | tmpIndex = -1; | 903 | tmpIndex = -1; |
913 | int indexOfLineStart; | 904 | int indexOfLineStart; |
914 | int line; | 905 | int line; |
915 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 906 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
916 | if ( !c ) | 907 | if ( !c ) |
917 | return; | 908 | return; |
918 | 909 | ||
919 | if ( line == para->lines() - 1 ) { | 910 | if ( line == para->lines() - 1 ) { |
920 | idx = para->length() - 1; | 911 | idx = para->length() - 1; |
921 | } else { | 912 | } else { |
922 | c = para->lineStartOfLine( ++line, &indexOfLineStart ); | 913 | c = para->lineStartOfLine( ++line, &indexOfLineStart ); |
923 | indexOfLineStart--; | 914 | indexOfLineStart--; |
924 | idx = indexOfLineStart; | 915 | idx = indexOfLineStart; |
925 | } | 916 | } |
926 | } | 917 | } |
927 | 918 | ||
928 | void QTextCursor::gotoLineStart() | 919 | void QTextCursor::gotoLineStart() |
929 | { | 920 | { |
930 | tmpIndex = -1; | 921 | tmpIndex = -1; |
931 | int indexOfLineStart; | 922 | int indexOfLineStart; |
932 | int line; | 923 | int line; |
933 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 924 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
934 | if ( !c ) | 925 | if ( !c ) |
935 | return; | 926 | return; |
936 | 927 | ||
937 | idx = indexOfLineStart; | 928 | idx = indexOfLineStart; |
938 | } | 929 | } |
939 | 930 | ||
940 | void QTextCursor::gotoHome() | 931 | void QTextCursor::gotoHome() |
941 | { | 932 | { |
942 | if ( topParagraph()->document() ) | 933 | if ( topParagraph()->document() ) |
943 | gotoPosition( topParagraph()->document()->firstParagraph() ); | 934 | gotoPosition( topParagraph()->document()->firstParagraph() ); |
944 | else | 935 | else |
945 | gotoLineStart(); | 936 | gotoLineStart(); |
946 | } | 937 | } |
947 | 938 | ||
948 | void QTextCursor::gotoEnd() | 939 | void QTextCursor::gotoEnd() |
949 | { | 940 | { |
950 | if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() ) | 941 | if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() ) |
951 | gotoPosition( topParagraph()->document()->lastParagraph(), | 942 | gotoPosition( topParagraph()->document()->lastParagraph(), |
952 | topParagraph()->document()->lastParagraph()->length() - 1); | 943 | topParagraph()->document()->lastParagraph()->length() - 1); |
953 | else | 944 | else |
954 | gotoLineEnd(); | 945 | gotoLineEnd(); |
955 | } | 946 | } |
956 | 947 | ||
957 | void QTextCursor::gotoPageUp( int visibleHeight ) | 948 | void QTextCursor::gotoPageUp( int visibleHeight ) |
958 | { | 949 | { |
959 | int targetY = globalY() - visibleHeight; | 950 | int targetY = globalY() - visibleHeight; |
960 | QTextParagraph* old; int index; | 951 | QTextParagraph* old; int index; |
961 | do { | 952 | do { |
962 | old = para; index = idx; | 953 | old = para; index = idx; |
963 | gotoUp(); | 954 | gotoUp(); |
964 | } while ( (old != para || index != idx) && globalY() > targetY ); | 955 | } while ( (old != para || index != idx) && globalY() > targetY ); |
965 | } | 956 | } |
966 | 957 | ||
967 | void QTextCursor::gotoPageDown( int visibleHeight ) | 958 | void QTextCursor::gotoPageDown( int visibleHeight ) |
968 | { | 959 | { |
969 | int targetY = globalY() + visibleHeight; | 960 | int targetY = globalY() + visibleHeight; |
970 | QTextParagraph* old; int index; | 961 | QTextParagraph* old; int index; |
971 | do { | 962 | do { |
972 | old = para; index = idx; | 963 | old = para; index = idx; |
973 | gotoDown(); | 964 | gotoDown(); |
974 | } while ( (old != para || index != idx) && globalY() < targetY ); | 965 | } while ( (old != para || index != idx) && globalY() < targetY ); |
975 | } | 966 | } |
976 | 967 | ||
977 | void QTextCursor::gotoWordRight() | 968 | void QTextCursor::gotoWordRight() |
978 | { | 969 | { |
979 | if ( para->string()->isRightToLeft() ) | 970 | if ( para->string()->isRightToLeft() ) |
980 | gotoPreviousWord(); | 971 | gotoPreviousWord(); |
981 | else | 972 | else |
982 | gotoNextWord(); | 973 | gotoNextWord(); |
983 | } | 974 | } |
984 | 975 | ||
985 | void QTextCursor::gotoWordLeft() | 976 | void QTextCursor::gotoWordLeft() |
986 | { | 977 | { |
987 | if ( para->string()->isRightToLeft() ) | 978 | if ( para->string()->isRightToLeft() ) |
988 | gotoNextWord(); | 979 | gotoNextWord(); |
989 | else | 980 | else |
990 | gotoPreviousWord(); | 981 | gotoPreviousWord(); |
991 | } | 982 | } |
992 | 983 | ||
993 | void QTextCursor::gotoPreviousWord() | 984 | void QTextCursor::gotoPreviousWord() |
994 | { | 985 | { |
995 | gotoPreviousLetter(); | 986 | gotoPreviousLetter(); |
996 | tmpIndex = -1; | 987 | tmpIndex = -1; |
997 | QTextString *s = para->string(); | 988 | QTextString *s = para->string(); |
998 | bool allowSame = FALSE; | 989 | bool allowSame = FALSE; |
999 | if ( idx == ((int)s->length()-1) ) | 990 | if ( idx == ((int)s->length()-1) ) |
1000 | return; | 991 | return; |
1001 | for ( int i = idx; i >= 0; --i ) { | 992 | for ( int i = idx; i >= 0; --i ) { |
1002 | if ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 993 | if ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1003 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) { | 994 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) { |
1004 | if ( !allowSame ) | 995 | if ( !allowSame ) |
1005 | continue; | 996 | continue; |
1006 | idx = i + 1; | 997 | idx = i + 1; |
1007 | return; | 998 | return; |
1008 | } | 999 | } |
1009 | if ( !allowSame && !( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1000 | if ( !allowSame && !( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1010 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) | 1001 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) |
1011 | allowSame = TRUE; | 1002 | allowSame = TRUE; |
1012 | } | 1003 | } |
1013 | idx = 0; | 1004 | idx = 0; |
1014 | } | 1005 | } |
1015 | 1006 | ||
1016 | void QTextCursor::gotoNextWord() | 1007 | void QTextCursor::gotoNextWord() |
1017 | { | 1008 | { |
1018 | tmpIndex = -1; | 1009 | tmpIndex = -1; |
1019 | QTextString *s = para->string(); | 1010 | QTextString *s = para->string(); |
1020 | bool allowSame = FALSE; | 1011 | bool allowSame = FALSE; |
1021 | for ( int i = idx; i < (int)s->length(); ++i ) { | 1012 | for ( int i = idx; i < (int)s->length(); ++i ) { |
1022 | if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1013 | if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1023 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';') ) { | 1014 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';') ) { |
1024 | if ( !allowSame ) | 1015 | if ( !allowSame ) |
1025 | continue; | 1016 | continue; |
1026 | idx = i; | 1017 | idx = i; |
1027 | return; | 1018 | return; |
1028 | } | 1019 | } |
1029 | if ( !allowSame && ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1020 | if ( !allowSame && ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1030 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) | 1021 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) |
1031 | allowSame = TRUE; | 1022 | allowSame = TRUE; |
1032 | 1023 | ||
1033 | } | 1024 | } |
1034 | 1025 | ||
1035 | if ( idx < ((int)s->length()-1) ) { | 1026 | if ( idx < ((int)s->length()-1) ) { |
1036 | gotoLineEnd(); | 1027 | gotoLineEnd(); |
1037 | } else if ( para->next() ) { | 1028 | } else if ( para->next() ) { |
1038 | QTextParagraph *p = para->next(); | 1029 | QTextParagraph *p = para->next(); |
1039 | while ( p && !p->isVisible() ) | 1030 | while ( p && !p->isVisible() ) |
1040 | p = p->next(); | 1031 | p = p->next(); |
1041 | if ( s ) { | 1032 | if ( s ) { |
1042 | para = p; | 1033 | para = p; |
1043 | idx = 0; | 1034 | idx = 0; |
1044 | } | 1035 | } |
1045 | } else { | 1036 | } else { |
1046 | gotoLineEnd(); | 1037 | gotoLineEnd(); |
1047 | } | 1038 | } |
1048 | } | 1039 | } |
1049 | 1040 | ||
1050 | bool QTextCursor::atParagStart() | 1041 | bool QTextCursor::atParagStart() |
1051 | { | 1042 | { |
1052 | return idx == 0; | 1043 | return idx == 0; |
1053 | } | 1044 | } |
1054 | 1045 | ||
1055 | bool QTextCursor::atParagEnd() | 1046 | bool QTextCursor::atParagEnd() |
1056 | { | 1047 | { |
1057 | return idx == para->length() - 1; | 1048 | return idx == para->length() - 1; |
1058 | } | 1049 | } |
1059 | 1050 | ||
1060 | void QTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds ) | 1051 | void QTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds ) |
1061 | { | 1052 | { |
1062 | if ( !para->document() ) | 1053 | if ( !para->document() ) |
1063 | return; | 1054 | return; |
1064 | tmpIndex = -1; | 1055 | tmpIndex = -1; |
1065 | QTextFormat *f = 0; | 1056 | QTextFormat *f = 0; |
1066 | if ( para->document()->useFormatCollection() ) { | 1057 | if ( para->document()->useFormatCollection() ) { |
1067 | f = para->at( idx )->format(); | 1058 | f = para->at( idx )->format(); |
1068 | if ( idx == para->length() - 1 && idx > 0 ) | 1059 | if ( idx == para->length() - 1 && idx > 0 ) |
1069 | f = para->at( idx - 1 )->format(); | 1060 | f = para->at( idx - 1 )->format(); |
1070 | if ( f->isMisspelled() ) { | 1061 | if ( f->isMisspelled() ) { |
1071 | f->removeRef(); | 1062 | f->removeRef(); |
1072 | f = para->document()->formatCollection()->format( f->font(), f->color() ); | 1063 | f = para->document()->formatCollection()->format( f->font(), f->color() ); |
1073 | } | 1064 | } |
1074 | } | 1065 | } |
1075 | 1066 | ||
1076 | if ( atParagEnd() ) { | 1067 | if ( atParagEnd() ) { |
1077 | QTextParagraph *n = para->next(); | 1068 | QTextParagraph *n = para->next(); |
1078 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); | 1069 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); |
1079 | if ( f ) | 1070 | if ( f ) |
1080 | s->setFormat( 0, 1, f, TRUE ); | 1071 | s->setFormat( 0, 1, f, TRUE ); |
1081 | s->copyParagData( para ); | 1072 | s->copyParagData( para ); |
1082 | if ( ind ) { | 1073 | if ( ind ) { |
1083 | int oi, ni; | 1074 | int oi, ni; |
1084 | s->indent( &oi, &ni ); | 1075 | s->indent( &oi, &ni ); |
1085 | para = s; | 1076 | para = s; |
1086 | idx = ni; | 1077 | idx = ni; |
1087 | } else { | 1078 | } else { |
1088 | para = s; | 1079 | para = s; |
1089 | idx = 0; | 1080 | idx = 0; |
1090 | } | 1081 | } |
1091 | } else if ( atParagStart() ) { | 1082 | } else if ( atParagStart() ) { |
1092 | QTextParagraph *p = para->prev(); | 1083 | QTextParagraph *p = para->prev(); |
1093 | QTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds ); | 1084 | QTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds ); |
1094 | if ( f ) | 1085 | if ( f ) |
1095 | s->setFormat( 0, 1, f, TRUE ); | 1086 | s->setFormat( 0, 1, f, TRUE ); |
1096 | s->copyParagData( para ); | 1087 | s->copyParagData( para ); |
1097 | if ( ind ) { | 1088 | if ( ind ) { |
1098 | s->indent(); | 1089 | s->indent(); |
1099 | s->format(); | 1090 | s->format(); |
1100 | indent(); | 1091 | indent(); |
1101 | para->format(); | 1092 | para->format(); |
1102 | } | 1093 | } |
1103 | } else { | 1094 | } else { |
1104 | QString str = para->string()->toString().mid( idx, 0xFFFFFF ); | 1095 | QString str = para->string()->toString().mid( idx, 0xFFFFFF ); |
1105 | QTextParagraph *n = para->next(); | 1096 | QTextParagraph *n = para->next(); |
1106 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); | 1097 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); |
1107 | s->copyParagData( para ); | 1098 | s->copyParagData( para ); |
1108 | s->remove( 0, 1 ); | 1099 | s->remove( 0, 1 ); |
1109 | s->append( str, TRUE ); | 1100 | s->append( str, TRUE ); |
1110 | for ( uint i = 0; i < str.length(); ++i ) { | 1101 | for ( uint i = 0; i < str.length(); ++i ) { |
1111 | QTextStringChar* tsc = para->at( idx + i ); | 1102 | QTextStringChar* tsc = para->at( idx + i ); |
1112 | s->setFormat( i, 1, tsc->format(), TRUE ); | 1103 | s->setFormat( i, 1, tsc->format(), TRUE ); |
1113 | if ( tsc->isCustom() ) { | 1104 | if ( tsc->isCustom() ) { |
1114 | QTextCustomItem * item = tsc->customItem(); | 1105 | QTextCustomItem * item = tsc->customItem(); |
1115 | s->at( i )->setCustomItem( item ); | 1106 | s->at( i )->setCustomItem( item ); |
1116 | tsc->loseCustomItem(); | 1107 | tsc->loseCustomItem(); |
1117 | } | 1108 | } |
1118 | if ( tsc->isAnchor() ) | 1109 | if ( tsc->isAnchor() ) |
1119 | s->at( i )->setAnchor( tsc->anchorName(), | 1110 | s->at( i )->setAnchor( tsc->anchorName(), |
1120 | tsc->anchorHref() ); | 1111 | tsc->anchorHref() ); |
1121 | } | 1112 | } |
1122 | para->truncate( idx ); | 1113 | para->truncate( idx ); |
1123 | if ( ind ) { | 1114 | if ( ind ) { |
1124 | int oi, ni; | 1115 | int oi, ni; |
1125 | s->indent( &oi, &ni ); | 1116 | s->indent( &oi, &ni ); |
1126 | para = s; | 1117 | para = s; |
1127 | idx = ni; | 1118 | idx = ni; |
1128 | } else { | 1119 | } else { |
1129 | para = s; | 1120 | para = s; |
1130 | idx = 0; | 1121 | idx = 0; |
1131 | } | 1122 | } |
1132 | } | 1123 | } |
1133 | 1124 | ||
1134 | invalidateNested(); | 1125 | invalidateNested(); |
1135 | } | 1126 | } |
1136 | 1127 | ||
1137 | bool QTextCursor::remove() | 1128 | bool QTextCursor::remove() |
1138 | { | 1129 | { |
1139 | tmpIndex = -1; | 1130 | tmpIndex = -1; |
1140 | if ( !atParagEnd() ) { | 1131 | if ( !atParagEnd() ) { |
1141 | para->remove( idx, 1 ); | 1132 | para->remove( idx, 1 ); |
1142 | int h = para->rect().height(); | 1133 | int h = para->rect().height(); |
1143 | para->format( -1, TRUE ); | 1134 | para->format( -1, TRUE ); |
1144 | if ( h != para->rect().height() ) | 1135 | if ( h != para->rect().height() ) |
1145 | invalidateNested(); | 1136 | invalidateNested(); |
1146 | else if ( para->document() && para->document()->parent() ) | 1137 | else if ( para->document() && para->document()->parent() ) |
1147 | para->document()->nextDoubleBuffered = TRUE; | 1138 | para->document()->nextDoubleBuffered = TRUE; |
1148 | return FALSE; | 1139 | return FALSE; |
1149 | } else if ( para->next() ) { | 1140 | } else if ( para->next() ) { |
1150 | para->join( para->next() ); | 1141 | para->join( para->next() ); |
1151 | invalidateNested(); | 1142 | invalidateNested(); |
1152 | return TRUE; | 1143 | return TRUE; |
1153 | } | 1144 | } |
1154 | return FALSE; | 1145 | return FALSE; |
1155 | } | 1146 | } |
1156 | 1147 | ||
1157 | void QTextCursor::indent() | 1148 | void QTextCursor::indent() |
1158 | { | 1149 | { |
1159 | int oi = 0, ni = 0; | 1150 | int oi = 0, ni = 0; |
1160 | para->indent( &oi, &ni ); | 1151 | para->indent( &oi, &ni ); |
1161 | if ( oi == ni ) | 1152 | if ( oi == ni ) |
1162 | return; | 1153 | return; |
1163 | 1154 | ||
1164 | if ( idx >= oi ) | 1155 | if ( idx >= oi ) |
1165 | idx += ni - oi; | 1156 | idx += ni - oi; |
1166 | else | 1157 | else |
1167 | idx = ni; | 1158 | idx = ni; |
1168 | } | 1159 | } |
1169 | 1160 | ||
1170 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 1161 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1171 | 1162 | ||
1172 | QTextDocument::QTextDocument( QTextDocument *p ) | 1163 | QTextDocument::QTextDocument( QTextDocument *p ) |
1173 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) | 1164 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) |
1174 | { | 1165 | { |
1175 | fCollection = new QTextFormatCollection; | 1166 | fCollection = new QTextFormatCollection; |
1176 | init(); | 1167 | init(); |
1177 | } | 1168 | } |
1178 | 1169 | ||
1179 | QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f ) | 1170 | QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f ) |
1180 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) | 1171 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) |
1181 | { | 1172 | { |
1182 | fCollection = f; | 1173 | fCollection = f; |
1183 | init(); | 1174 | init(); |
1184 | } | 1175 | } |
1185 | 1176 | ||
1186 | void QTextDocument::init() | 1177 | void QTextDocument::init() |
1187 | { | 1178 | { |
1188 | oTextValid = TRUE; | 1179 | oTextValid = TRUE; |
1189 | mightHaveCustomItems = FALSE; | 1180 | mightHaveCustomItems = FALSE; |
1190 | if ( par ) | 1181 | if ( par ) |
1191 | par->insertChild( this ); | 1182 | par->insertChild( this ); |
1192 | pProcessor = 0; | 1183 | pProcessor = 0; |
1193 | useFC = TRUE; | 1184 | useFC = TRUE; |
1194 | pFormatter = 0; | 1185 | pFormatter = 0; |
1195 | indenter = 0; | 1186 | indenter = 0; |
1196 | fParag = 0; | 1187 | fParag = 0; |
1197 | txtFormat = Qt::AutoText; | 1188 | txtFormat = Qt::AutoText; |
1198 | preferRichText = FALSE; | 1189 | preferRichText = FALSE; |
1199 | pages = FALSE; | 1190 | pages = FALSE; |
1200 | focusIndicator.parag = 0; | 1191 | focusIndicator.parag = 0; |
1201 | minw = 0; | 1192 | minw = 0; |
1202 | wused = 0; | 1193 | wused = 0; |
1203 | minwParag = curParag = 0; | 1194 | minwParag = curParag = 0; |
1204 | align = AlignAuto; | 1195 | align = AlignAuto; |
1205 | nSelections = 1; | 1196 | nSelections = 1; |
1206 | 1197 | ||
1207 | setStyleSheet( QStyleSheet::defaultSheet() ); | 1198 | setStyleSheet( QStyleSheet::defaultSheet() ); |
1208 | factory_ = QMimeSourceFactory::defaultFactory(); | 1199 | factory_ = QMimeSourceFactory::defaultFactory(); |
1209 | contxt = QString::null; | 1200 | contxt = QString::null; |
1210 | 1201 | ||
1211 | underlLinks = par ? par->underlLinks : TRUE; | 1202 | underlLinks = par ? par->underlLinks : TRUE; |
1212 | backBrush = 0; | 1203 | backBrush = 0; |
1213 | buf_pixmap = 0; | 1204 | buf_pixmap = 0; |
1214 | nextDoubleBuffered = FALSE; | 1205 | nextDoubleBuffered = FALSE; |
1215 | 1206 | ||
1216 | if ( par ) | 1207 | if ( par ) |
1217 | withoutDoubleBuffer = par->withoutDoubleBuffer; | 1208 | withoutDoubleBuffer = par->withoutDoubleBuffer; |
1218 | else | 1209 | else |
1219 | withoutDoubleBuffer = FALSE; | 1210 | withoutDoubleBuffer = FALSE; |
1220 | 1211 | ||
1221 | lParag = fParag = createParagraph( this, 0, 0 ); | 1212 | lParag = fParag = createParagraph( this, 0, 0 ); |
1222 | 1213 | ||
1223 | cx = 0; | 1214 | cx = 0; |
1224 | cy = 2; | 1215 | cy = 2; |
1225 | if ( par ) | 1216 | if ( par ) |
1226 | cx = cy = 0; | 1217 | cx = cy = 0; |
1227 | cw = 600; | 1218 | cw = 600; |
1228 | vw = 0; | 1219 | vw = 0; |
1229 | flow_ = new QTextFlow; | 1220 | flow_ = new QTextFlow; |
1230 | flow_->setWidth( cw ); | 1221 | flow_->setWidth( cw ); |
1231 | 1222 | ||
1232 | leftmargin = rightmargin = 4; | 1223 | leftmargin = rightmargin = 4; |
1233 | scaleFontsFactor = 1; | 1224 | scaleFontsFactor = 1; |
1234 | 1225 | ||
1235 | 1226 | ||
1236 | selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight ); | 1227 | selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight ); |
1237 | selectionText[ Standard ] = TRUE; | 1228 | selectionText[ Standard ] = TRUE; |
1238 | commandHistory = new QTextCommandHistory( 100 ); | 1229 | commandHistory = new QTextCommandHistory( 100 ); |
1239 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; | 1230 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; |
1240 | } | 1231 | } |
1241 | 1232 | ||
1242 | QTextDocument::~QTextDocument() | 1233 | QTextDocument::~QTextDocument() |
1243 | { | 1234 | { |
1244 | if ( par ) | 1235 | if ( par ) |
1245 | par->removeChild( this ); | 1236 | par->removeChild( this ); |
1246 | clear(); | 1237 | clear(); |
1247 | delete commandHistory; | 1238 | delete commandHistory; |
1248 | delete flow_; | 1239 | delete flow_; |
1249 | if ( !par ) | 1240 | if ( !par ) |
1250 | delete pFormatter; | 1241 | delete pFormatter; |
1251 | delete fCollection; | 1242 | delete fCollection; |
1252 | delete pProcessor; | 1243 | delete pProcessor; |
1253 | delete buf_pixmap; | 1244 | delete buf_pixmap; |
1254 | delete indenter; | 1245 | delete indenter; |
1255 | delete backBrush; | 1246 | delete backBrush; |
1256 | if ( tArray ) | 1247 | if ( tArray ) |
1257 | delete [] tArray; | 1248 | delete [] tArray; |
1258 | } | 1249 | } |
1259 | 1250 | ||
1260 | void QTextDocument::clear( bool createEmptyParag ) | 1251 | void QTextDocument::clear( bool createEmptyParag ) |
1261 | { | 1252 | { |
1262 | if ( flow_ ) | 1253 | if ( flow_ ) |
1263 | flow_->clear(); | 1254 | flow_->clear(); |
1264 | while ( fParag ) { | 1255 | while ( fParag ) { |
1265 | QTextParagraph *p = fParag->next(); | 1256 | QTextParagraph *p = fParag->next(); |
1266 | delete fParag; | 1257 | delete fParag; |
1267 | fParag = p; | 1258 | fParag = p; |
1268 | } | 1259 | } |
1269 | fParag = lParag = 0; | 1260 | fParag = lParag = 0; |
1270 | if ( createEmptyParag ) | 1261 | if ( createEmptyParag ) |
1271 | fParag = lParag = createParagraph( this ); | 1262 | fParag = lParag = createParagraph( this ); |
1272 | selections.clear(); | 1263 | selections.clear(); |
1273 | oText = QString::null; | 1264 | oText = QString::null; |
1274 | oTextValid = TRUE; | 1265 | oTextValid = TRUE; |
1275 | } | 1266 | } |
1276 | 1267 | ||
1277 | int QTextDocument::widthUsed() const | 1268 | int QTextDocument::widthUsed() const |
1278 | { | 1269 | { |
1279 | return wused + border_tolerance; | 1270 | return wused + border_tolerance; |
1280 | } | 1271 | } |
1281 | 1272 | ||
1282 | int QTextDocument::height() const | 1273 | int QTextDocument::height() const |
1283 | { | 1274 | { |
1284 | int h = 0; | 1275 | int h = 0; |
1285 | if ( lParag ) | 1276 | if ( lParag ) |
1286 | h = lParag->rect().top() + lParag->rect().height() + 1; | 1277 | h = lParag->rect().top() + lParag->rect().height() + 1; |
1287 | int fh = flow_->boundingRect().bottom(); | 1278 | int fh = flow_->boundingRect().bottom(); |
1288 | return QMAX( h, fh ); | 1279 | return QMAX( h, fh ); |
1289 | } | 1280 | } |
1290 | 1281 | ||
1291 | 1282 | ||
1292 | 1283 | ||
1293 | QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) | 1284 | QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) |
1294 | { | 1285 | { |
1295 | return new QTextParagraph( d, pr, nx, updateIds ); | 1286 | return new QTextParagraph( d, pr, nx, updateIds ); |
1296 | } | 1287 | } |
1297 | 1288 | ||
1298 | bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p ) | 1289 | bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p ) |
1299 | { | 1290 | { |
1300 | if ( needed == -1 ) { | 1291 | if ( needed == -1 ) { |
1301 | minw = 0; | 1292 | minw = 0; |
1302 | wused = 0; | 1293 | wused = 0; |
1303 | p = 0; | 1294 | p = 0; |
1304 | } | 1295 | } |
1305 | if ( p == minwParag ) { | 1296 | if ( p == minwParag ) { |
1306 | minw = needed; | 1297 | minw = needed; |
1307 | emit minimumWidthChanged( minw ); | 1298 | emit minimumWidthChanged( minw ); |
1308 | } else if ( needed > minw ) { | 1299 | } else if ( needed > minw ) { |
1309 | minw = needed; | 1300 | minw = needed; |
1310 | minwParag = p; | 1301 | minwParag = p; |
1311 | emit minimumWidthChanged( minw ); | 1302 | emit minimumWidthChanged( minw ); |
1312 | } | 1303 | } |
1313 | wused = QMAX( wused, used ); | 1304 | wused = QMAX( wused, used ); |
1314 | wused = QMAX( wused, minw ); | 1305 | wused = QMAX( wused, minw ); |
1315 | cw = QMAX( minw, cw ); | 1306 | cw = QMAX( minw, cw ); |
1316 | return TRUE; | 1307 | return TRUE; |
1317 | } | 1308 | } |
1318 | 1309 | ||
1319 | void QTextDocument::setPlainText( const QString &text ) | 1310 | void QTextDocument::setPlainText( const QString &text ) |
1320 | { | 1311 | { |
1321 | clear(); | 1312 | clear(); |
1322 | preferRichText = FALSE; | 1313 | preferRichText = FALSE; |
1323 | oTextValid = TRUE; | 1314 | oTextValid = TRUE; |
1324 | oText = text; | 1315 | oText = text; |
1325 | 1316 | ||
1326 | int lastNl = 0; | 1317 | int lastNl = 0; |
1327 | int nl = text.find( '\n' ); | 1318 | int nl = text.find( '\n' ); |
1328 | if ( nl == -1 ) { | 1319 | if ( nl == -1 ) { |
1329 | lParag = createParagraph( this, lParag, 0 ); | 1320 | lParag = createParagraph( this, lParag, 0 ); |
1330 | if ( !fParag ) | 1321 | if ( !fParag ) |
1331 | fParag = lParag; | 1322 | fParag = lParag; |
1332 | QString s = text; | 1323 | QString s = text; |
1333 | if ( !s.isEmpty() ) { | 1324 | if ( !s.isEmpty() ) { |
1334 | if ( s[ (int)s.length() - 1 ] == '\r' ) | 1325 | if ( s[ (int)s.length() - 1 ] == '\r' ) |
1335 | s.remove( s.length() - 1, 1 ); | 1326 | s.remove( s.length() - 1, 1 ); |
1336 | lParag->append( s ); | 1327 | lParag->append( s ); |
1337 | } | 1328 | } |
1338 | } else { | 1329 | } else { |
1339 | for (;;) { | 1330 | for (;;) { |
1340 | lParag = createParagraph( this, lParag, 0 ); | 1331 | lParag = createParagraph( this, lParag, 0 ); |
1341 | if ( !fParag ) | 1332 | if ( !fParag ) |
1342 | fParag = lParag; | 1333 | fParag = lParag; |
1343 | QString s = text.mid( lastNl, nl - lastNl ); | 1334 | QString s = text.mid( lastNl, nl - lastNl ); |
1344 | if ( !s.isEmpty() ) { | 1335 | if ( !s.isEmpty() ) { |
1345 | if ( s[ (int)s.length() - 1 ] == '\r' ) | 1336 | if ( s[ (int)s.length() - 1 ] == '\r' ) |
1346 | s.remove( s.length() - 1, 1 ); | 1337 | s.remove( s.length() - 1, 1 ); |
1347 | lParag->append( s ); | 1338 | lParag->append( s ); |
1348 | } | 1339 | } |
1349 | if ( nl == 0xffffff ) | 1340 | if ( nl == 0xffffff ) |
1350 | break; | 1341 | break; |
1351 | lastNl = nl + 1; | 1342 | lastNl = nl + 1; |
1352 | nl = text.find( '\n', nl + 1 ); | 1343 | nl = text.find( '\n', nl + 1 ); |
1353 | if ( nl == -1 ) | 1344 | if ( nl == -1 ) |
1354 | nl = 0xffffff; | 1345 | nl = 0xffffff; |
1355 | } | 1346 | } |
1356 | } | 1347 | } |
1357 | if ( !lParag ) | 1348 | if ( !lParag ) |
1358 | lParag = fParag = createParagraph( this, 0, 0 ); | 1349 | lParag = fParag = createParagraph( this, 0, 0 ); |
1359 | } | 1350 | } |
1360 | 1351 | ||
1361 | struct Q_EXPORT QTextDocumentTag { | 1352 | struct Q_EXPORT QTextDocumentTag { |
1362 | QTextDocumentTag(){} | 1353 | QTextDocumentTag(){} |
1363 | QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f ) | 1354 | QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f ) |
1364 | :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) { | 1355 | :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) { |
1365 | wsm = QStyleSheetItem::WhiteSpaceNormal; | 1356 | wsm = QStyleSheetItem::WhiteSpaceNormal; |
1366 | } | 1357 | } |
1367 | QString name; | 1358 | QString name; |
1368 | const QStyleSheetItem* style; | 1359 | const QStyleSheetItem* style; |
1369 | QString anchorHref; | 1360 | QString anchorHref; |
1370 | QStyleSheetItem::WhiteSpaceMode wsm; | 1361 | QStyleSheetItem::WhiteSpaceMode wsm; |
1371 | QTextFormat format; | 1362 | QTextFormat format; |
1372 | int alignment : 16; | 1363 | int alignment : 16; |
1373 | int direction : 5; | 1364 | int direction : 5; |
1374 | QStyleSheetItem::ListStyle liststyle; | 1365 | QStyleSheetItem::ListStyle liststyle; |
1375 | 1366 | ||
1376 | QTextDocumentTag( const QTextDocumentTag& t ) { | 1367 | QTextDocumentTag( const QTextDocumentTag& t ) { |
1377 | name = t.name; | 1368 | name = t.name; |
1378 | style = t.style; | 1369 | style = t.style; |
1379 | anchorHref = t.anchorHref; | 1370 | anchorHref = t.anchorHref; |
1380 | wsm = t.wsm; | 1371 | wsm = t.wsm; |
1381 | format = t.format; | 1372 | format = t.format; |
1382 | alignment = t.alignment; | 1373 | alignment = t.alignment; |
1383 | direction = t.direction; | 1374 | direction = t.direction; |
1384 | liststyle = t.liststyle; | 1375 | liststyle = t.liststyle; |
1385 | } | 1376 | } |
1386 | QTextDocumentTag& operator=(const QTextDocumentTag& t) { | 1377 | QTextDocumentTag& operator=(const QTextDocumentTag& t) { |
1387 | name = t.name; | 1378 | name = t.name; |
1388 | style = t.style; | 1379 | style = t.style; |
1389 | anchorHref = t.anchorHref; | 1380 | anchorHref = t.anchorHref; |
1390 | wsm = t.wsm; | 1381 | wsm = t.wsm; |
1391 | format = t.format; | 1382 | format = t.format; |
1392 | alignment = t.alignment; | 1383 | alignment = t.alignment; |
1393 | direction = t.direction; | 1384 | direction = t.direction; |
1394 | liststyle = t.liststyle; | 1385 | liststyle = t.liststyle; |
1395 | return *this; | 1386 | return *this; |
1396 | } | 1387 | } |
1397 | 1388 | ||
1398 | #if defined(Q_FULL_TEMPLATE_INSTANTIATION) | 1389 | #if defined(Q_FULL_TEMPLATE_INSTANTIATION) |
1399 | bool operator==( const QTextDocumentTag& ) const { return FALSE; } | 1390 | bool operator==( const QTextDocumentTag& ) const { return FALSE; } |
1400 | #endif | 1391 | #endif |
1401 | }; | 1392 | }; |
1402 | 1393 | ||
1403 | 1394 | ||
1404 | #define NEWPAR do { \ | 1395 | #define NEWPAR do{ if ( !hasNewPar) { \ |
1405 | if ( !hasNewPar) { \ | 1396 | if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ |
1406 | if ( !curpar ) { \ | 1397 | curpar->remove( curpar->length()-2, 1 ); \ |
1407 | owarn << "no current paragraph" << oendl; \ | 1398 | curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \ |
1408 | return; \ | 1399 | hasNewPar = TRUE; \ |
1409 | } \ | 1400 | curpar->rtext = TRUE; \ |
1410 | if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ | 1401 | curpar->align = curtag.alignment; \ |
1411 | curpar->remove( curpar->length()-2, 1 ); \ | 1402 | curpar->lstyle = curtag.liststyle; \ |
1412 | curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); \ | 1403 | curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ |
1413 | if ( !curpar ) { \ | 1404 | curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ |
1414 | owarn << "failed in creating a new paragraph" << oendl; \ | 1405 | space = TRUE; \ |
1415 | return; \ | 1406 | delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \ |
1416 | } \ | 1407 | int i = 0; \ |
1417 | vec = 0; \ | 1408 | for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ |
1418 | } \ | 1409 | vec->insert( i++, (*it).style ); \ |
1419 | hasNewPar = TRUE; \ | 1410 | vec->insert( i, curtag.style ); \ |
1420 | curpar->rtext = TRUE; \ | 1411 | }while(FALSE) |
1421 | curpar->align = curtag.alignment; \ | 1412 | |
1422 | curpar->lstyle = curtag.liststyle; \ | ||
1423 | curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ | ||
1424 | curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ | ||
1425 | space = TRUE; \ | ||
1426 | delete vec; \ | ||
1427 | vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \ | ||
1428 | int i = 0; \ | ||
1429 | for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ | ||
1430 | vec->insert( i++, (*it).style ); \ | ||
1431 | vec->insert( i, curtag.style ); \ | ||
1432 | } while ( FALSE ) | ||
1433 | 1413 | ||
1434 | void QTextDocument::setRichText( const QString &text, const QString &context ) | 1414 | void QTextDocument::setRichText( const QString &text, const QString &context ) |
1435 | { | 1415 | { |
1436 | if ( !context.isEmpty() ) | 1416 | if ( !context.isEmpty() ) |
1437 | setContext( context ); | 1417 | setContext( context ); |
1438 | clear(); | 1418 | clear(); |
1439 | fParag = lParag = createParagraph( this ); | 1419 | fParag = lParag = createParagraph( this ); |
1440 | oTextValid = TRUE; | 1420 | oTextValid = TRUE; |
1441 | oText = text; | 1421 | oText = text; |
1442 | setRichTextInternal( text ); | 1422 | setRichTextInternal( text ); |
1443 | fParag->rtext = TRUE; | 1423 | fParag->rtext = TRUE; |
1444 | } | 1424 | } |
1445 | 1425 | ||
1446 | void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) | 1426 | void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) |
1447 | { | 1427 | { |
1448 | QTextParagraph* curpar = lParag; | 1428 | QTextParagraph* curpar = lParag; |
1449 | int pos = 0; | 1429 | int pos = 0; |
1450 | QValueStack<QTextDocumentTag> tags; | 1430 | QValueStack<QTextDocumentTag> tags; |
1451 | QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); | 1431 | QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); |
1452 | QTextDocumentTag curtag = initag; | 1432 | QTextDocumentTag curtag = initag; |
1453 | bool space = TRUE; | 1433 | bool space = TRUE; |
1454 | bool canMergeLi = FALSE; | 1434 | bool canMergeLi = FALSE; |
1455 | 1435 | ||
1456 | bool textEditMode = FALSE; | 1436 | bool textEditMode = FALSE; |
1457 | 1437 | ||
1458 | const QChar* doc = text.unicode(); | 1438 | const QChar* doc = text.unicode(); |
1459 | int length = text.length(); | 1439 | int length = text.length(); |
1460 | bool hasNewPar = curpar->length() <= 1; | 1440 | bool hasNewPar = curpar->length() <= 1; |
1461 | QString anchorName; | 1441 | QString anchorName; |
1462 | 1442 | ||
1463 | // style sheet handling for margin and line spacing calculation below | 1443 | // style sheet handling for margin and line spacing calculation below |
1464 | QTextParagraph* stylesPar = curpar; | 1444 | QTextParagraph* stylesPar = curpar; |
1465 | QPtrVector<QStyleSheetItem>* vec = 0; | 1445 | QPtrVector<QStyleSheetItem>* vec = 0; |
1466 | QPtrList< QPtrVector<QStyleSheetItem> > styles; | 1446 | QPtrList< QPtrVector<QStyleSheetItem> > styles; |
1467 | styles.setAutoDelete( TRUE ); | 1447 | styles.setAutoDelete( TRUE ); |
1468 | 1448 | ||
1469 | if ( cursor ) { | 1449 | if ( cursor ) { |
1470 | cursor->splitAndInsertEmptyParagraph(); | 1450 | cursor->splitAndInsertEmptyParagraph(); |
1471 | QTextCursor tmp = *cursor; | 1451 | QTextCursor tmp = *cursor; |
1472 | tmp.gotoPreviousLetter(); | 1452 | tmp.gotoPreviousLetter(); |
1473 | stylesPar = curpar = tmp.paragraph(); | 1453 | stylesPar = curpar = tmp.paragraph(); |
1474 | hasNewPar = TRUE; | 1454 | hasNewPar = TRUE; |
1475 | textEditMode = TRUE; | 1455 | textEditMode = TRUE; |
1476 | } else { | 1456 | } else { |
1477 | NEWPAR; | 1457 | NEWPAR; |
1478 | } | 1458 | } |
1479 | 1459 | ||
1480 | // set rtext spacing to FALSE for the initial paragraph. | 1460 | // set rtext spacing to FALSE for the initial paragraph. |
1481 | curpar->rtext = FALSE; | 1461 | curpar->rtext = FALSE; |
1482 | 1462 | ||
1483 | QString wellKnownTags = "br hr wsp table qt body meta title"; | 1463 | QString wellKnownTags = "br hr wsp table qt body meta title"; |
1484 | 1464 | ||
1485 | while ( pos < length ) { | 1465 | while ( pos < length ) { |
1486 | if ( hasPrefix(doc, length, pos, '<' ) ){ | 1466 | if ( hasPrefix(doc, length, pos, '<' ) ){ |
1487 | if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { | 1467 | if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { |
1488 | // open tag | 1468 | // open tag |
1489 | QMap<QString, QString> attr; | 1469 | QMap<QString, QString> attr; |
1490 | bool emptyTag = FALSE; | 1470 | bool emptyTag = FALSE; |
1491 | QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag); | 1471 | QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag); |
1492 | if ( tagname.isEmpty() ) | 1472 | if ( tagname.isEmpty() ) |
1493 | continue; // nothing we could do with this, probably parse error | 1473 | continue; // nothing we could do with this, probably parse error |
1494 | 1474 | ||
1495 | const QStyleSheetItem* nstyle = sheet_->item(tagname); | 1475 | const QStyleSheetItem* nstyle = sheet_->item(tagname); |
1496 | 1476 | ||
1497 | if ( nstyle ) { | 1477 | if ( nstyle ) { |
1498 | // we might have to close some 'forgotten' tags | 1478 | // we might have to close some 'forgotten' tags |
1499 | while ( !nstyle->allowedInContext( curtag.style ) ) { | 1479 | while ( !nstyle->allowedInContext( curtag.style ) ) { |
1500 | QString msg; | 1480 | QString msg; |
1501 | msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)", | 1481 | msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)", |
1502 | tagname.ascii(), curtag.style->name().ascii(), pos); | 1482 | tagname.ascii(), curtag.style->name().ascii(), pos); |
1503 | sheet_->error( msg ); | 1483 | sheet_->error( msg ); |
1504 | if ( tags.isEmpty() ) | 1484 | if ( tags.isEmpty() ) |
1505 | break; | 1485 | break; |
1506 | curtag = tags.pop(); | 1486 | curtag = tags.pop(); |
1507 | } | 1487 | } |
1508 | 1488 | ||
1509 | /* special handling for p and li for HTML | 1489 | /* special handling for p and li for HTML |
1510 | compatibility. We do not want to embed blocks in | 1490 | compatibility. We do not want to embed blocks in |
1511 | p, and we do not want new blocks inside non-empty | 1491 | p, and we do not want new blocks inside non-empty |
1512 | lis. Plus we want to merge empty lis sometimes. */ | 1492 | lis. Plus we want to merge empty lis sometimes. */ |
1513 | if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1493 | if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1514 | canMergeLi = TRUE; | 1494 | canMergeLi = TRUE; |
1515 | } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { | 1495 | } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { |
1516 | while ( curtag.style->name() == "p" ) { | 1496 | while ( curtag.style->name() == "p" ) { |
1517 | if ( tags.isEmpty() ) | 1497 | if ( tags.isEmpty() ) |
1518 | break; | 1498 | break; |
1519 | curtag = tags.pop(); | 1499 | curtag = tags.pop(); |
1520 | } | 1500 | } |
1521 | 1501 | ||
1522 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1502 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1523 | // we are in a li and a new block comes along | 1503 | // we are in a li and a new block comes along |
1524 | if ( nstyle->name() == "ul" || nstyle->name() == "ol" ) | 1504 | if ( nstyle->name() == "ul" || nstyle->name() == "ol" ) |
1525 | hasNewPar = FALSE; // we want an empty li (like most browsers) | 1505 | hasNewPar = FALSE; // we want an empty li (like most browsers) |
1526 | if ( !hasNewPar ) { | 1506 | if ( !hasNewPar ) { |
1527 | /* do not add new blocks inside | 1507 | /* do not add new blocks inside |
1528 | non-empty lis */ | 1508 | non-empty lis */ |
1529 | while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1509 | while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1530 | if ( tags.isEmpty() ) | 1510 | if ( tags.isEmpty() ) |
1531 | break; | 1511 | break; |
1532 | curtag = tags.pop(); | 1512 | curtag = tags.pop(); |
1533 | } | 1513 | } |
1534 | } else if ( canMergeLi ) { | 1514 | } else if ( canMergeLi ) { |
1535 | /* we have an empty li and a block | 1515 | /* we have an empty li and a block |
1536 | comes along, merge them */ | 1516 | comes along, merge them */ |
1537 | nstyle = curtag.style; | 1517 | nstyle = curtag.style; |
1538 | } | 1518 | } |
1539 | canMergeLi = FALSE; | 1519 | canMergeLi = FALSE; |
1540 | } | 1520 | } |
1541 | } | 1521 | } |
1542 | } | 1522 | } |
1543 | 1523 | ||
1544 | QTextCustomItem* custom = 0; | 1524 | QTextCustomItem* custom = 0; |
1545 | 1525 | ||
1546 | // some well-known tags, some have a nstyle, some not | 1526 | // some well-known tags, some have a nstyle, some not |
1547 | if ( wellKnownTags.find( tagname ) != -1 ) { | 1527 | if ( wellKnownTags.find( tagname ) != -1 ) { |
1548 | if ( tagname == "br" ) { | 1528 | if ( tagname == "br" ) { |
1549 | emptyTag = space = TRUE; | 1529 | emptyTag = space = TRUE; |
1550 | int index = QMAX( curpar->length(),1) - 1; | 1530 | int index = QMAX( curpar->length(),1) - 1; |
1551 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1531 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1552 | curpar->append( QChar_linesep ); | 1532 | curpar->append( QChar_linesep ); |
1553 | curpar->setFormat( index, 1, &format ); | 1533 | curpar->setFormat( index, 1, &format ); |
1554 | } else if ( tagname == "hr" ) { | 1534 | } else if ( tagname == "hr" ) { |
1555 | emptyTag = space = TRUE; | 1535 | emptyTag = space = TRUE; |
1556 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); | 1536 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); |
1557 | NEWPAR; | 1537 | NEWPAR; |
1558 | } else if ( tagname == "table" ) { | 1538 | } else if ( tagname == "table" ) { |
1559 | emptyTag = space = TRUE; | 1539 | emptyTag = space = TRUE; |
1560 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1540 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1561 | curpar->setAlignment( curtag.alignment ); | 1541 | curpar->setAlignment( curtag.alignment ); |
1562 | custom = parseTable( attr, format, doc, length, pos, curpar ); | 1542 | custom = parseTable( attr, format, doc, length, pos, curpar ); |
1563 | } else if ( tagname == "qt" || tagname == "body" ) { | 1543 | } else if ( tagname == "qt" || tagname == "body" ) { |
1564 | if ( attr.contains( "bgcolor" ) ) { | 1544 | if ( attr.contains( "bgcolor" ) ) { |
1565 | QBrush *b = new QBrush( QColor( attr["bgcolor"] ) ); | 1545 | QBrush *b = new QBrush( QColor( attr["bgcolor"] ) ); |
1566 | setPaper( b ); | 1546 | setPaper( b ); |
1567 | } | 1547 | } |
1568 | if ( attr.contains( "background" ) ) { | 1548 | if ( attr.contains( "background" ) ) { |
1569 | QImage img; | 1549 | QImage img; |
1570 | QString bg = attr["background"]; | 1550 | QString bg = attr["background"]; |
1571 | const QMimeSource* m = factory_->data( bg, contxt ); | 1551 | const QMimeSource* m = factory_->data( bg, contxt ); |
1572 | if ( !m ) { | 1552 | if ( !m ) { |
1573 | owarn << "QRichText: no mimesource for " << bg.latin1() << "" << oendl; | 1553 | owarn << "QRichText: no mimesource for " << bg.latin1() << "" << oendl; |
1574 | } else { | 1554 | } else { |
1575 | if ( !QImageDrag::decode( m, img ) ) { | 1555 | if ( !QImageDrag::decode( m, img ) ) { |
1576 | owarn << "QTextImage: cannot decode " << bg.latin1() << "" << oendl; | 1556 | owarn << "QTextImage: cannot decode " << bg.latin1() << "" << oendl; |
1577 | } | 1557 | } |
1578 | } | 1558 | } |
1579 | if ( !img.isNull() ) { | 1559 | if ( !img.isNull() ) { |
1580 | QPixmap pm; | 1560 | QPixmap pm; |
1581 | pm.convertFromImage( img ); | 1561 | pm.convertFromImage( img ); |
1582 | QBrush *b = new QBrush( QColor(), pm ); | 1562 | QBrush *b = new QBrush( QColor(), pm ); |
1583 | setPaper( b ); | 1563 | setPaper( b ); |
1584 | } | 1564 | } |
1585 | } | 1565 | } |
1586 | if ( attr.contains( "text" ) ) { | 1566 | if ( attr.contains( "text" ) ) { |
1587 | QColor c( attr["text"] ); | 1567 | QColor c( attr["text"] ); |
1588 | if ( formatCollection()->defaultFormat()->color() != c ) { | 1568 | if ( formatCollection()->defaultFormat()->color() != c ) { |
1589 | QDict<QTextFormat> formats = formatCollection()->dict(); | 1569 | QDict<QTextFormat> formats = formatCollection()->dict(); |
1590 | QDictIterator<QTextFormat> it( formats ); | 1570 | QDictIterator<QTextFormat> it( formats ); |
1591 | while ( it.current() ) { | 1571 | while ( it.current() ) { |
1592 | if ( it.current() == formatCollection()->defaultFormat() ) { | 1572 | if ( it.current() == formatCollection()->defaultFormat() ) { |
1593 | ++it; | 1573 | ++it; |
1594 | continue; | 1574 | continue; |
1595 | } | 1575 | } |
1596 | it.current()->setColor( c ); | 1576 | it.current()->setColor( c ); |
1597 | ++it; | 1577 | ++it; |
1598 | } | 1578 | } |
1599 | formatCollection()->defaultFormat()->setColor( c ); | 1579 | formatCollection()->defaultFormat()->setColor( c ); |
1600 | curtag.format.setColor( c ); | 1580 | curtag.format.setColor( c ); |
1601 | } | 1581 | } |
1602 | } | 1582 | } |
1603 | if ( attr.contains( "link" ) ) | 1583 | if ( attr.contains( "link" ) ) |
1604 | linkColor = QColor( attr["link"] ); | 1584 | linkColor = QColor( attr["link"] ); |
1605 | if ( attr.contains( "title" ) ) | 1585 | if ( attr.contains( "title" ) ) |
1606 | attribs.replace( "title", attr["title"] ); | 1586 | attribs.replace( "title", attr["title"] ); |
1607 | 1587 | ||
1608 | if ( textEditMode ) { | 1588 | if ( textEditMode ) { |
1609 | if ( attr.contains("style" ) ) { | 1589 | if ( attr.contains("style" ) ) { |
1610 | QString a = attr["style"]; | 1590 | QString a = attr["style"]; |
1611 | for ( int s = 0; s < a.contains(';')+1; s++ ) { | 1591 | for ( int s = 0; s < a.contains(';')+1; s++ ) { |
1612 | QString style = QTextDocument::section( a, ";", s, s ); | 1592 | QString style = QTextDocument::section( a, ";", s, s ); |
1613 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { | 1593 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { |
1614 | scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) / | 1594 | scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) / |
1615 | style.mid( 10, style.length() - 12 ).toInt(); | 1595 | style.mid( 10, style.length() - 12 ).toInt(); |
1616 | } | 1596 | } |
1617 | } | 1597 | } |
1618 | } | 1598 | } |
1619 | nstyle = 0; // ignore body in textEditMode | 1599 | nstyle = 0; // ignore body in textEditMode |
1620 | } | 1600 | } |
1621 | // end qt- and body-tag handling | 1601 | // end qt- and body-tag handling |
1622 | } else if ( tagname == "meta" ) { | 1602 | } else if ( tagname == "meta" ) { |
1623 | if ( attr["name"] == "qrichtext" && attr["content"] == "1" ) | 1603 | if ( attr["name"] == "qrichtext" && attr["content"] == "1" ) |
1624 | textEditMode = TRUE; | 1604 | textEditMode = TRUE; |
1625 | } else if ( tagname == "title" ) { | 1605 | } else if ( tagname == "title" ) { |
1626 | QString title; | 1606 | QString title; |
1627 | while ( pos < length ) { | 1607 | while ( pos < length ) { |
1628 | if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) && | 1608 | if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) && |
1629 | parseCloseTag( doc, length, pos ) == "title" ) | 1609 | parseCloseTag( doc, length, pos ) == "title" ) |
1630 | break; | 1610 | break; |
1631 | title += doc[ pos ]; | 1611 | title += doc[ pos ]; |
1632 | ++pos; | 1612 | ++pos; |
1633 | } | 1613 | } |
1634 | attribs.replace( "title", title ); | 1614 | attribs.replace( "title", title ); |
1635 | } | 1615 | } |
1636 | } // end of well-known tag handling | 1616 | } // end of well-known tag handling |
1637 | 1617 | ||
1638 | if ( !custom ) // try generic custom item | 1618 | if ( !custom ) // try generic custom item |
1639 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); | 1619 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); |
1640 | 1620 | ||
1641 | if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it | 1621 | if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it |
1642 | continue; | 1622 | continue; |
1643 | 1623 | ||
1644 | if ( custom ) { | 1624 | if ( custom ) { |
1645 | int index = QMAX( curpar->length(),1) - 1; | 1625 | int index = QMAX( curpar->length(),1) - 1; |
1646 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1626 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1647 | curpar->append( QChar('*') ); | 1627 | curpar->append( QChar('*') ); |
1648 | curpar->setFormat( index, 1, &format ); | 1628 | curpar->setFormat( index, 1, &format ); |
1649 | curpar->at( index )->setCustomItem( custom ); | 1629 | curpar->at( index )->setCustomItem( custom ); |
1650 | if ( !curtag.anchorHref.isEmpty() ) | 1630 | if ( !curtag.anchorHref.isEmpty() ) |
1651 | curpar->at(index)->setAnchor( QString::null, curtag.anchorHref ); | 1631 | curpar->at(index)->setAnchor( QString::null, curtag.anchorHref ); |
1652 | if ( !anchorName.isEmpty() ) { | 1632 | if ( !anchorName.isEmpty() ) { |
1653 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); | 1633 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); |
1654 | anchorName = QString::null; | 1634 | anchorName = QString::null; |
1655 | } | 1635 | } |
1656 | registerCustomItem( custom, curpar ); | 1636 | registerCustomItem( custom, curpar ); |
1657 | hasNewPar = FALSE; | 1637 | hasNewPar = FALSE; |
1658 | } else if ( !emptyTag ) { | 1638 | } else if ( !emptyTag ) { |
1659 | /* if we do nesting, push curtag on the stack, | 1639 | /* if we do nesting, push curtag on the stack, |
1660 | otherwise reinint curag. */ | 1640 | otherwise reinint curag. */ |
1661 | if ( curtag.style->name() != tagname || nstyle->selfNesting() ) { | 1641 | if ( curtag.style->name() != tagname || nstyle->selfNesting() ) { |
1662 | tags.push( curtag ); | 1642 | tags.push( curtag ); |
1663 | } else { | 1643 | } else { |
1664 | if ( !tags.isEmpty() ) | 1644 | if ( !tags.isEmpty() ) |
1665 | curtag = tags.top(); | 1645 | curtag = tags.top(); |
1666 | else | 1646 | else |
1667 | curtag = initag; | 1647 | curtag = initag; |
1668 | } | 1648 | } |
1669 | 1649 | ||
1670 | curtag.name = tagname; | 1650 | curtag.name = tagname; |
1671 | curtag.style = nstyle; | 1651 | curtag.style = nstyle; |
1672 | curtag.name = tagname; | 1652 | curtag.name = tagname; |
1673 | curtag.style = nstyle; | 1653 | curtag.style = nstyle; |
1674 | if ( int(nstyle->whiteSpaceMode()) != QStyleSheetItem::Undefined ) | 1654 | if ( int(nstyle->whiteSpaceMode()) != QStyleSheetItem::Undefined ) |
1675 | curtag.wsm = nstyle->whiteSpaceMode(); | 1655 | curtag.wsm = nstyle->whiteSpaceMode(); |
1676 | 1656 | ||
1677 | /* ignore whitespace for inline elements if there | 1657 | /* ignore whitespace for inline elements if there |
1678 | was already one*/ | 1658 | was already one*/ |
1679 | if ( !textEditMode && curtag.wsm == QStyleSheetItem::WhiteSpaceNormal | 1659 | if ( !textEditMode && curtag.wsm == QStyleSheetItem::WhiteSpaceNormal |
1680 | && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) ) | 1660 | && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) ) |
1681 | eatSpace( doc, length, pos ); | 1661 | eatSpace( doc, length, pos ); |
1682 | 1662 | ||
1683 | curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1663 | curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1684 | if ( nstyle->isAnchor() ) { | 1664 | if ( nstyle->isAnchor() ) { |
1685 | if ( !anchorName.isEmpty() ) | 1665 | if ( !anchorName.isEmpty() ) |
1686 | anchorName += "#" + attr["name"]; | 1666 | anchorName += "#" + attr["name"]; |
1687 | else | 1667 | else |
1688 | anchorName = attr["name"]; | 1668 | anchorName = attr["name"]; |
1689 | curtag.anchorHref = attr["href"]; | 1669 | curtag.anchorHref = attr["href"]; |
1690 | } | 1670 | } |
1691 | 1671 | ||
1692 | if ( nstyle->alignment() != QStyleSheetItem::Undefined ) | 1672 | if ( nstyle->alignment() != QStyleSheetItem::Undefined ) |
1693 | curtag.alignment = nstyle->alignment(); | 1673 | curtag.alignment = nstyle->alignment(); |
1694 | 1674 | ||
1695 | if ( (int) nstyle->listStyle() != QStyleSheetItem::Undefined ) | 1675 | if ( (int) nstyle->listStyle() != QStyleSheetItem::Undefined ) |
1696 | curtag.liststyle = nstyle->listStyle(); | 1676 | curtag.liststyle = nstyle->listStyle(); |
1697 | 1677 | ||
1698 | if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock | 1678 | if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock |
1699 | || nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1679 | || nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1700 | 1680 | ||
1701 | if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") { | 1681 | if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") { |
1702 | QString type = attr["type"]; | 1682 | QString type = attr["type"]; |
1703 | if ( !type.isEmpty() ) { | 1683 | if ( !type.isEmpty() ) { |
1704 | if ( type == "1" ) { | 1684 | if ( type == "1" ) { |
1705 | curtag.liststyle = QStyleSheetItem::ListDecimal; | 1685 | curtag.liststyle = QStyleSheetItem::ListDecimal; |
1706 | } else if ( type == "a" ) { | 1686 | } else if ( type == "a" ) { |
1707 | curtag.liststyle = QStyleSheetItem::ListLowerAlpha; | 1687 | curtag.liststyle = QStyleSheetItem::ListLowerAlpha; |
1708 | } else if ( type == "A" ) { | 1688 | } else if ( type == "A" ) { |
1709 | curtag.liststyle = QStyleSheetItem::ListUpperAlpha; | 1689 | curtag.liststyle = QStyleSheetItem::ListUpperAlpha; |
1710 | } else { | 1690 | } else { |
1711 | type = type.lower(); | 1691 | type = type.lower(); |
1712 | if ( type == "square" ) | 1692 | if ( type == "square" ) |
1713 | curtag.liststyle = QStyleSheetItem::ListSquare; | 1693 | curtag.liststyle = QStyleSheetItem::ListSquare; |
1714 | else if ( type == "disc" ) | 1694 | else if ( type == "disc" ) |
1715 | curtag.liststyle = QStyleSheetItem::ListDisc; | 1695 | curtag.liststyle = QStyleSheetItem::ListDisc; |
1716 | else if ( type == "circle" ) | 1696 | else if ( type == "circle" ) |
1717 | curtag.liststyle = QStyleSheetItem::ListCircle; | 1697 | curtag.liststyle = QStyleSheetItem::ListCircle; |
1718 | } | 1698 | } |
1719 | } | 1699 | } |
1720 | } | 1700 | } |
1721 | 1701 | ||
1722 | 1702 | ||
1723 | /* Internally we treat ordered and bullet | 1703 | /* Internally we treat ordered and bullet |
1724 | lists the same for margin calculations. In | 1704 | lists the same for margin calculations. In |
1725 | order to have fast pointer compares in the | 1705 | order to have fast pointer compares in the |
1726 | xMargin() functions we restrict ourselves to | 1706 | xMargin() functions we restrict ourselves to |
1727 | <ol>. Once we calculate the margins in the | 1707 | <ol>. Once we calculate the margins in the |
1728 | parser rathern than later, the unelegance of | 1708 | parser rathern than later, the unelegance of |
1729 | this approach goes awy | 1709 | this approach goes awy |
1730 | */ | 1710 | */ |
1731 | if ( nstyle->name() == "ul" ) | 1711 | if ( nstyle->name() == "ul" ) |
1732 | curtag.style = sheet_->item( "ol" ); | 1712 | curtag.style = sheet_->item( "ol" ); |
1733 | 1713 | ||
1734 | if ( attr.contains( "align" ) ) { | 1714 | if ( attr.contains( "align" ) ) { |
1735 | QString align = attr["align"]; | 1715 | QString align = attr["align"]; |
1736 | if ( align == "center" ) | 1716 | if ( align == "center" ) |
1737 | curtag.alignment = Qt::AlignCenter; | 1717 | curtag.alignment = Qt::AlignCenter; |
1738 | else if ( align == "right" ) | 1718 | else if ( align == "right" ) |
1739 | curtag.alignment = Qt::AlignRight; | 1719 | curtag.alignment = Qt::AlignRight; |
1740 | else if ( align == "justify" ) | 1720 | else if ( align == "justify" ) |
1741 | curtag.alignment = Qt3::AlignJustify; | 1721 | curtag.alignment = Qt3::AlignJustify; |
1742 | } | 1722 | } |
1743 | if ( attr.contains( "dir" ) ) { | 1723 | if ( attr.contains( "dir" ) ) { |
1744 | QString dir = attr["dir"]; | 1724 | QString dir = attr["dir"]; |
1745 | if ( dir == "rtl" ) | 1725 | if ( dir == "rtl" ) |
1746 | curtag.direction = QChar::DirR; | 1726 | curtag.direction = QChar::DirR; |
1747 | else if ( dir == "ltr" ) | 1727 | else if ( dir == "ltr" ) |
1748 | curtag.direction = QChar::DirL; | 1728 | curtag.direction = QChar::DirL; |
1749 | } | 1729 | } |
1750 | 1730 | ||
1751 | NEWPAR; | 1731 | NEWPAR; |
1752 | 1732 | ||
1753 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1733 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1754 | if ( attr.contains( "value " ) ) | 1734 | if ( attr.contains( "value " ) ) |
1755 | curpar->setListValue( attr["value"].toInt() ); | 1735 | curpar->setListValue( attr["value"].toInt() ); |
1756 | } | 1736 | } |
1757 | 1737 | ||
1758 | if ( attr.contains( "style" ) ) { | 1738 | if ( attr.contains( "style" ) ) { |
1759 | QString a = attr["style"]; | 1739 | QString a = attr["style"]; |
1760 | bool ok = TRUE; | 1740 | bool ok = TRUE; |
1761 | for ( int s = 0; ok && s < a.contains(';')+1; s++ ) { | 1741 | for ( int s = 0; ok && s < a.contains(';')+1; s++ ) { |
1762 | QString style = QTextDocument::section( a, ";", s, s ); | 1742 | QString style = QTextDocument::section( a, ";", s, s ); |
1763 | if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") ) | 1743 | if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") ) |
1764 | curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok); | 1744 | curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok); |
1765 | else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") ) | 1745 | else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") ) |
1766 | curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok); | 1746 | curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok); |
1767 | else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") ) | 1747 | else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") ) |
1768 | curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok); | 1748 | curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok); |
1769 | else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") ) | 1749 | else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") ) |
1770 | curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok); | 1750 | curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok); |
1771 | else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") ) | 1751 | else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") ) |
1772 | curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok); | 1752 | curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok); |
1773 | } | 1753 | } |
1774 | if ( !ok ) // be pressmistic | 1754 | if ( !ok ) // be pressmistic |
1775 | curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0; | 1755 | curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0; |
1776 | } | 1756 | } |
1777 | } | 1757 | } |
1778 | } | 1758 | } |
1779 | } else { | 1759 | } else { |
1780 | QString tagname = parseCloseTag( doc, length, pos ); | 1760 | QString tagname = parseCloseTag( doc, length, pos ); |
1781 | if ( tagname.isEmpty() ) | 1761 | if ( tagname.isEmpty() ) |
1782 | continue; // nothing we could do with this, probably parse error | 1762 | continue; // nothing we could do with this, probably parse error |
1783 | if ( !sheet_->item( tagname ) ) // ignore unknown tags | 1763 | if ( !sheet_->item( tagname ) ) // ignore unknown tags |
1784 | continue; | 1764 | continue; |
1785 | 1765 | ||
1786 | // we close a block item. Since the text may continue, we need to have a new paragraph | 1766 | // we close a block item. Since the text may continue, we need to have a new paragraph |
1787 | bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock | 1767 | bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock |
1788 | || curtag.style->displayMode() == QStyleSheetItem::DisplayListItem; | 1768 | || curtag.style->displayMode() == QStyleSheetItem::DisplayListItem; |
1789 | 1769 | ||
1790 | 1770 | ||
1791 | // html slopiness: handle unbalanched tag closing | 1771 | // html slopiness: handle unbalanched tag closing |
1792 | while ( curtag.name != tagname ) { | 1772 | while ( curtag.name != tagname ) { |
1793 | QString msg; | 1773 | QString msg; |
1794 | msg.sprintf( "QText Warning: Document not valid ( '%s' not closed before '%s' #%d)", | 1774 | msg.sprintf( "QText Warning: Document not valid ( '%s' not closed before '%s' #%d)", |
1795 | curtag.name.ascii(), tagname.ascii(), pos); | 1775 | curtag.name.ascii(), tagname.ascii(), pos); |
1796 | sheet_->error( msg ); | 1776 | sheet_->error( msg ); |
1797 | if ( tags.isEmpty() ) | 1777 | if ( tags.isEmpty() ) |
1798 | break; | 1778 | break; |
1799 | curtag = tags.pop(); | 1779 | curtag = tags.pop(); |
1800 | } | 1780 | } |
1801 | 1781 | ||
1802 | 1782 | ||
1803 | // close the tag | 1783 | // close the tag |
1804 | if ( !tags.isEmpty() ) | 1784 | if ( !tags.isEmpty() ) |
1805 | curtag = tags.pop(); | 1785 | curtag = tags.pop(); |
1806 | else | 1786 | else |
1807 | curtag = initag; | 1787 | curtag = initag; |
1808 | 1788 | ||
1809 | if ( needNewPar ) { | 1789 | if ( needNewPar ) { |
1810 | if ( textEditMode && tagname == "p" ) // preserve empty paragraphs | 1790 | if ( textEditMode && tagname == "p" ) // preserve empty paragraphs |
1811 | hasNewPar = FALSE; | 1791 | hasNewPar = FALSE; |
1812 | NEWPAR; | 1792 | NEWPAR; |
1813 | } | 1793 | } |
1814 | } | 1794 | } |
1815 | } else { | 1795 | } else { |
1816 | // normal contents | 1796 | // normal contents |
1817 | QString s; | 1797 | QString s; |
1818 | QChar c; | 1798 | QChar c; |
1819 | while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){ | 1799 | while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){ |
1820 | if ( textEditMode ) { | 1800 | if ( textEditMode ) { |
1821 | // text edit mode: we handle all white space but ignore newlines | 1801 | // text edit mode: we handle all white space but ignore newlines |
1822 | c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre ); | 1802 | c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre ); |
1823 | if ( c == QChar_linesep ) | 1803 | if ( c == QChar_linesep ) |
1824 | break; | 1804 | break; |
1825 | } else { | 1805 | } else { |
1826 | int l = pos; | 1806 | int l = pos; |
1827 | c = parseChar( doc, length, pos, curtag.wsm ); | 1807 | c = parseChar( doc, length, pos, curtag.wsm ); |
1828 | 1808 | ||
1829 | // in white space pre mode: treat any space as non breakable | 1809 | // in white space pre mode: treat any space as non breakable |
1830 | if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre ) | 1810 | if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre ) |
1831 | c = QChar::nbsp; | 1811 | c = QChar::nbsp; |
1832 | 1812 | ||
1833 | if ( c == ' ' || c == QChar_linesep ) { | 1813 | if ( c == ' ' || c == QChar_linesep ) { |
1834 | /* avoid overlong paragraphs by forcing a new | 1814 | /* avoid overlong paragraphs by forcing a new |
1835 | paragraph after 4096 characters. This case can | 1815 | paragraph after 4096 characters. This case can |
1836 | occur when loading undiscovered plain text | 1816 | occur when loading undiscovered plain text |
1837 | documents in rich text mode. Instead of hanging | 1817 | documents in rich text mode. Instead of hanging |
1838 | forever, we do the trick. | 1818 | forever, we do the trick. |
1839 | */ | 1819 | */ |
1840 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do { | 1820 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do { |
1841 | if ( doc[l] == '\n' ) { | 1821 | if ( doc[l] == '\n' ) { |
1842 | hasNewPar = FALSE; // for a new paragraph ... | 1822 | hasNewPar = FALSE; // for a new paragraph ... |
1843 | NEWPAR; | 1823 | NEWPAR; |
1844 | hasNewPar = FALSE; // ... and make it non-reusable | 1824 | hasNewPar = FALSE; // ... and make it non-reusable |
1845 | c = '\n'; // make sure we break below | 1825 | c = '\n'; // make sure we break below |
1846 | break; | 1826 | break; |
1847 | } | 1827 | } |
1848 | } while ( ++l < pos ); | 1828 | } while ( ++l < pos ); |
1849 | } | 1829 | } |
1850 | } | 1830 | } |
1851 | 1831 | ||
1852 | if ( c == '\n' ) | 1832 | if ( c == '\n' ) |
1853 | break; // break on newlines, pre delievers a QChar_linesep | 1833 | break; // break on newlines, pre delievers a QChar_linesep |
1854 | 1834 | ||
1855 | bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode; | 1835 | bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode; |
1856 | 1836 | ||
1857 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) | 1837 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) |
1858 | continue; | 1838 | continue; |
1859 | if ( c == '\r' ) | 1839 | if ( c == '\r' ) |
1860 | continue; | 1840 | continue; |
1861 | space = c_isSpace; | 1841 | space = c_isSpace; |
1862 | s += c; | 1842 | s += c; |
1863 | } | 1843 | } |
1864 | if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { | 1844 | if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { |
1865 | hasNewPar = FALSE; | 1845 | hasNewPar = FALSE; |
1866 | int index = QMAX( curpar->length(),1) - 1; | 1846 | int index = QMAX( curpar->length(),1) - 1; |
1867 | curpar->append( s ); | 1847 | curpar->append( s ); |
1868 | QTextFormat* f = formatCollection()->format( &curtag.format ); | 1848 | QTextFormat* f = formatCollection()->format( &curtag.format ); |
1869 | curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already | 1849 | curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already |
1870 | f->ref += s.length() -1; // that what friends are for... | 1850 | f->ref += s.length() -1; // that what friends are for... |
1871 | if ( !curtag.anchorHref.isEmpty() ) { | 1851 | if ( !curtag.anchorHref.isEmpty() ) { |
1872 | for ( int i = 0; i < int(s.length()); i++ ) | 1852 | for ( int i = 0; i < int(s.length()); i++ ) |
1873 | curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref ); | 1853 | curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref ); |
1874 | } | 1854 | } |
1875 | if ( !anchorName.isEmpty() ) { | 1855 | if ( !anchorName.isEmpty() ) { |
1876 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); | 1856 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); |
1877 | anchorName = QString::null; | 1857 | anchorName = QString::null; |
1878 | } | 1858 | } |
1879 | } | 1859 | } |
1880 | } | 1860 | } |
1881 | } | 1861 | } |
1882 | if ( hasNewPar && curpar != fParag && !cursor ) { | 1862 | if ( hasNewPar && curpar != fParag && !cursor ) { |
1883 | // cleanup unused last paragraphs | 1863 | // cleanup unused last paragraphs |
1884 | curpar = curpar->p; | 1864 | curpar = curpar->p; |
1885 | delete curpar->n; | 1865 | delete curpar->n; |
1886 | } | 1866 | } |
1887 | if ( !anchorName.isEmpty() ) { | 1867 | if ( !anchorName.isEmpty() ) { |
1888 | curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); | 1868 | curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); |
1889 | anchorName = QString::null; | 1869 | anchorName = QString::null; |
1890 | } | 1870 | } |
1891 | 1871 | ||
1892 | 1872 | ||
1893 | setRichTextMarginsInternal( styles, stylesPar ); | 1873 | setRichTextMarginsInternal( styles, stylesPar ); |
1894 | 1874 | ||
1895 | if ( cursor ) { | 1875 | if ( cursor ) { |
1896 | cursor->gotoPreviousLetter(); | 1876 | cursor->gotoPreviousLetter(); |
1897 | cursor->remove(); | 1877 | cursor->remove(); |
1898 | } | 1878 | } |
1899 | 1879 | ||
1900 | } | 1880 | } |
1901 | 1881 | ||
1902 | void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) | 1882 | void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) |
1903 | { | 1883 | { |
1904 | // margin and line spacing calculation | 1884 | // margin and line spacing calculation |
1905 | QPtrVector<QStyleSheetItem>* prevStyle = 0; | 1885 | QPtrVector<QStyleSheetItem>* prevStyle = 0; |
1906 | QPtrVector<QStyleSheetItem>* curStyle = styles.first(); | 1886 | QPtrVector<QStyleSheetItem>* curStyle = styles.first(); |
1907 | QPtrVector<QStyleSheetItem>* nextStyle = styles.next(); | 1887 | QPtrVector<QStyleSheetItem>* nextStyle = styles.next(); |
1908 | while ( stylesPar ) { | 1888 | while ( stylesPar ) { |
1909 | if ( !curStyle ) { | 1889 | if ( !curStyle ) { |
1910 | stylesPar = stylesPar->next(); | 1890 | stylesPar = stylesPar->next(); |
1911 | prevStyle = curStyle; | 1891 | prevStyle = curStyle; |
1912 | curStyle = nextStyle; | 1892 | curStyle = nextStyle; |
1913 | nextStyle = styles.next(); | 1893 | nextStyle = styles.next(); |
1914 | continue; | 1894 | continue; |
1915 | } | 1895 | } |
1916 | 1896 | ||
1917 | int i, mar; | 1897 | int i, mar; |
1918 | QStyleSheetItem* mainStyle = (*curStyle)[curStyle->size()-1]; | 1898 | QStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0; |
1919 | if ( !mainStyle ) | 1899 | if ( mainStyle && mainStyle->displayMode() == QStyleSheetItem::DisplayListItem ) |
1920 | return; | ||
1921 | |||
1922 | if ( mainStyle->displayMode() == QStyleSheetItem::DisplayListItem ) | ||
1923 | stylesPar->setListItem( TRUE ); | 1900 | stylesPar->setListItem( TRUE ); |
1924 | int numLists = 0; | 1901 | int numLists = 0; |
1925 | for ( i = 0; i < (int)curStyle->size(); ++i ) { | 1902 | for ( i = 0; i < (int)curStyle->size(); ++i ) { |
1926 | if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock | 1903 | if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock |
1927 | && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) | 1904 | && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) |
1928 | numLists++; | 1905 | numLists++; |
1929 | } | 1906 | } |
1930 | stylesPar->ldepth = numLists; | 1907 | stylesPar->ldepth = numLists; |
1931 | if ( stylesPar->next() && nextStyle ) { | 1908 | if ( stylesPar->next() && nextStyle ) { |
1932 | // also set the depth of the next paragraph, required for the margin calculation | 1909 | // also set the depth of the next paragraph, required for the margin calculation |
1933 | numLists = 0; | 1910 | numLists = 0; |
1934 | for ( i = 0; i < (int)nextStyle->size(); ++i ) { | 1911 | for ( i = 0; i < (int)nextStyle->size(); ++i ) { |
1935 | if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock | 1912 | if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock |
1936 | && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) | 1913 | && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) |
1937 | numLists++; | 1914 | numLists++; |
1938 | } | 1915 | } |
1939 | stylesPar->next()->ldepth = numLists; | 1916 | stylesPar->next()->ldepth = numLists; |
1940 | } | 1917 | } |
1941 | 1918 | ||
1942 | // do the top margin | 1919 | // do the top margin |
1943 | QStyleSheetItem* item = mainStyle; | 1920 | QStyleSheetItem* item = mainStyle; |
1944 | int m; | 1921 | int m; |
1945 | if (stylesPar->utm > 0 ) { | 1922 | if (stylesPar->utm > 0 ) { |
1946 | m = stylesPar->utm-1; | 1923 | m = stylesPar->utm-1; |
1947 | stylesPar->utm = 0; | 1924 | stylesPar->utm = 0; |
1948 | } else { | 1925 | } else { |
1949 | m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) ); | 1926 | m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) ); |
1950 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem | 1927 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem |
1951 | && stylesPar->ldepth ) | 1928 | && stylesPar->ldepth ) |
1952 | m /= stylesPar->ldepth; | 1929 | m /= stylesPar->ldepth; |
1953 | } | 1930 | } |
1954 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1931 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1955 | item = (*curStyle)[ i ]; | 1932 | item = (*curStyle)[ i ]; |
1956 | if ( prevStyle && i < (int) prevStyle->size() && | 1933 | if ( prevStyle && i < (int) prevStyle->size() && |
1957 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && | 1934 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && |
1958 | (*prevStyle)[ i ] == item ) ) | 1935 | (*prevStyle)[ i ] == item ) ) |
1959 | break; | 1936 | break; |
1960 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags | 1937 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags |
1961 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && | 1938 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && |
1962 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) | 1939 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) |
1963 | continue; | 1940 | continue; |
1964 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) ); | 1941 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) ); |
1965 | m = QMAX( m, mar ); | 1942 | m = QMAX( m, mar ); |
1966 | } | 1943 | } |
1967 | stylesPar->utm = m - stylesPar->topMargin(); | 1944 | stylesPar->utm = m - stylesPar->topMargin(); |
1968 | 1945 | ||
1969 | // do the bottom margin | 1946 | // do the bottom margin |
1970 | item = mainStyle; | 1947 | item = mainStyle; |
1971 | if (stylesPar->ubm > 0 ) { | 1948 | if (stylesPar->ubm > 0 ) { |
1972 | m = stylesPar->ubm-1; | 1949 | m = stylesPar->ubm-1; |
1973 | stylesPar->ubm = 0; | 1950 | stylesPar->ubm = 0; |
1974 | } else { | 1951 | } else { |
1975 | m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); | 1952 | m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); |
1976 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem | 1953 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem |
1977 | && stylesPar->ldepth ) | 1954 | && stylesPar->ldepth ) |
1978 | m /= stylesPar->ldepth; | 1955 | m /= stylesPar->ldepth; |
1979 | } | 1956 | } |
1980 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1957 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1981 | item = (*curStyle)[ i ]; | 1958 | item = (*curStyle)[ i ]; |
1982 | if ( nextStyle && i < (int) nextStyle->size() && | 1959 | if ( nextStyle && i < (int) nextStyle->size() && |
1983 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && | 1960 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && |
1984 | (*nextStyle)[ i ] == item ) ) | 1961 | (*nextStyle)[ i ] == item ) ) |
1985 | break; | 1962 | break; |
1986 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags | 1963 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags |
1987 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && | 1964 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && |
1988 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) | 1965 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) |
1989 | continue; | 1966 | continue; |
1990 | mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); | 1967 | mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); |
1991 | m = QMAX( m, mar ); | 1968 | m = QMAX( m, mar ); |
1992 | } | 1969 | } |
1993 | stylesPar->ubm = m - stylesPar->bottomMargin(); | 1970 | stylesPar->ubm = m - stylesPar->bottomMargin(); |
1994 | 1971 | ||
1995 | // do the left margin, simplyfied | 1972 | // do the left margin, simplyfied |
1996 | item = mainStyle; | 1973 | item = mainStyle; |
1997 | if (stylesPar->ulm > 0 ) { | 1974 | if (stylesPar->ulm > 0 ) { |
1998 | m = stylesPar->ulm-1; | 1975 | m = stylesPar->ulm-1; |
1999 | stylesPar->ulm = 0; | 1976 | stylesPar->ulm = 0; |
2000 | } else { | 1977 | } else { |
2001 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); | 1978 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); |
2002 | } | 1979 | } |
2003 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1980 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
2004 | item = (*curStyle)[ i ]; | 1981 | item = (*curStyle)[ i ]; |
2005 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); | 1982 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); |
2006 | } | 1983 | } |
2007 | stylesPar->ulm = m - stylesPar->leftMargin(); | 1984 | stylesPar->ulm = m - stylesPar->leftMargin(); |
2008 | 1985 | ||
2009 | // do the right margin, simplyfied | 1986 | // do the right margin, simplyfied |
2010 | item = mainStyle; | 1987 | item = mainStyle; |
2011 | if (stylesPar->urm > 0 ) { | 1988 | if (stylesPar->urm > 0 ) { |
2012 | m = stylesPar->urm-1; | 1989 | m = stylesPar->urm-1; |
2013 | stylesPar->urm = 0; | 1990 | stylesPar->urm = 0; |
2014 | } else { | 1991 | } else { |
2015 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); | 1992 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); |
2016 | } | 1993 | } |
2017 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1994 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
2018 | item = (*curStyle)[ i ]; | 1995 | item = (*curStyle)[ i ]; |
2019 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); | 1996 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); |
2020 | } | 1997 | } |
2021 | stylesPar->urm = m - stylesPar->rightMargin(); | 1998 | stylesPar->urm = m - stylesPar->rightMargin(); |
2022 | 1999 | ||
2023 | // do the first line margin, which really should be called text-indent | 2000 | // do the first line margin, which really should be called text-indent |
2024 | item = mainStyle; | 2001 | item = mainStyle; |
2025 | if (stylesPar->uflm > 0 ) { | 2002 | if (stylesPar->uflm > 0 ) { |
2026 | m = stylesPar->uflm-1; | 2003 | m = stylesPar->uflm-1; |
2027 | stylesPar->uflm = 0; | 2004 | stylesPar->uflm = 0; |
2028 | } else { | 2005 | } else { |
2029 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); | 2006 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); |
2030 | } | 2007 | } |
2031 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 2008 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
2032 | item = (*curStyle)[ i ]; | 2009 | item = (*curStyle)[ i ]; |
2033 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); | 2010 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); |
2034 | m = QMAX( m, mar ); | 2011 | m = QMAX( m, mar ); |
2035 | } | 2012 | } |
2036 | stylesPar->uflm =m - stylesPar->firstLineMargin(); | 2013 | stylesPar->uflm =m - stylesPar->firstLineMargin(); |
2037 | 2014 | ||
2038 | // do the bogus line "spacing", which really is just an extra margin | 2015 | // do the bogus line "spacing", which really is just an extra margin |
2039 | item = mainStyle; | 2016 | item = mainStyle; |
2040 | for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) { | 2017 | for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) { |
2041 | item = (*curStyle)[ i ]; | 2018 | item = (*curStyle)[ i ]; |
2042 | if ( item->lineSpacing() != QStyleSheetItem::Undefined ) { | 2019 | if ( item->lineSpacing() != QStyleSheetItem::Undefined ) { |
2043 | stylesPar->ulinespacing = item->lineSpacing(); | 2020 | stylesPar->ulinespacing = item->lineSpacing(); |
2044 | if ( formatCollection() && | 2021 | if ( formatCollection() && |
2045 | stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() ) | 2022 | stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() ) |
2046 | stylesPar->ulinespacing += formatCollection()->defaultFormat()->height(); | 2023 | stylesPar->ulinespacing += formatCollection()->defaultFormat()->height(); |
2047 | break; | 2024 | break; |
2048 | } | 2025 | } |
2049 | } | 2026 | } |
2050 | 2027 | ||
2051 | stylesPar = stylesPar->next(); | 2028 | stylesPar = stylesPar->next(); |
2052 | prevStyle = curStyle; | 2029 | prevStyle = curStyle; |
2053 | curStyle = nextStyle; | 2030 | curStyle = nextStyle; |
2054 | nextStyle = styles.next(); | 2031 | nextStyle = styles.next(); |
2055 | } | 2032 | } |
2056 | } | 2033 | } |
2057 | 2034 | ||
2058 | void QTextDocument::setText( const QString &text, const QString &context ) | 2035 | void QTextDocument::setText( const QString &text, const QString &context ) |
2059 | { | 2036 | { |
2060 | focusIndicator.parag = 0; | 2037 | focusIndicator.parag = 0; |
2061 | selections.clear(); | 2038 | selections.clear(); |
2062 | if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) || | 2039 | if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) || |
2063 | txtFormat == Qt::RichText ) | 2040 | txtFormat == Qt::RichText ) |
2064 | setRichText( text, context ); | 2041 | setRichText( text, context ); |
2065 | else | 2042 | else |
2066 | setPlainText( text ); | 2043 | setPlainText( text ); |
2067 | } | 2044 | } |
2068 | 2045 | ||
2069 | QString QTextDocument::plainText() const | 2046 | QString QTextDocument::plainText() const |
2070 | { | 2047 | { |
2071 | QString buffer; | 2048 | QString buffer; |
2072 | QString s; | 2049 | QString s; |
2073 | QTextParagraph *p = fParag; | 2050 | QTextParagraph *p = fParag; |
2074 | while ( p ) { | 2051 | while ( p ) { |
2075 | if ( !p->mightHaveCustomItems ) { | 2052 | if ( !p->mightHaveCustomItems ) { |
2076 | s = p->string()->toString(); | 2053 | s = p->string()->toString(); |
2077 | } else { | 2054 | } else { |
2078 | for ( int i = 0; i < p->length() - 1; ++i ) { | 2055 | for ( int i = 0; i < p->length() - 1; ++i ) { |
2079 | if ( p->at( i )->isCustom() ) { | 2056 | if ( p->at( i )->isCustom() ) { |
2080 | if ( p->at( i )->customItem()->isNested() ) { | 2057 | if ( p->at( i )->customItem()->isNested() ) { |
2081 | s += "\n"; | 2058 | s += "\n"; |
2082 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2059 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2083 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2060 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2084 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2061 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2085 | s += c->richText()->plainText() + "\n"; | 2062 | s += c->richText()->plainText() + "\n"; |
2086 | s += "\n"; | 2063 | s += "\n"; |
2087 | } | 2064 | } |
2088 | } else { | 2065 | } else { |
2089 | s += p->at( i )->c; | 2066 | s += p->at( i )->c; |
2090 | } | 2067 | } |
2091 | } | 2068 | } |
2092 | } | 2069 | } |
2093 | s.remove( s.length() - 1, 1 ); | 2070 | s.remove( s.length() - 1, 1 ); |
2094 | if ( p->next() ) | 2071 | if ( p->next() ) |
2095 | s += "\n"; | 2072 | s += "\n"; |
2096 | buffer += s; | 2073 | buffer += s; |
2097 | p = p->next(); | 2074 | p = p->next(); |
2098 | } | 2075 | } |
2099 | return buffer; | 2076 | return buffer; |
2100 | } | 2077 | } |
2101 | 2078 | ||
2102 | static QString align_to_string( int a ) | 2079 | static QString align_to_string( int a ) |
2103 | { | 2080 | { |
2104 | if ( a & Qt::AlignRight ) | 2081 | if ( a & Qt::AlignRight ) |
2105 | return " align=\"right\""; | 2082 | return " align=\"right\""; |
2106 | if ( a & Qt::AlignHCenter ) | 2083 | if ( a & Qt::AlignHCenter ) |
2107 | return " align=\"center\""; | 2084 | return " align=\"center\""; |
2108 | if ( a & Qt3::AlignJustify ) | 2085 | if ( a & Qt3::AlignJustify ) |
2109 | return " align=\"justify\""; | 2086 | return " align=\"justify\""; |
2110 | return QString::null; | 2087 | return QString::null; |
2111 | } | 2088 | } |
2112 | 2089 | ||
2113 | static QString direction_to_string( int d ) | 2090 | static QString direction_to_string( int d ) |
2114 | { | 2091 | { |
2115 | if ( d != QChar::DirON ) | 2092 | if ( d != QChar::DirON ) |
2116 | return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); | 2093 | return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); |
2117 | return QString::null; | 2094 | return QString::null; |
2118 | } | 2095 | } |
2119 | 2096 | ||
2120 | static QString list_value_to_string( int v ) | 2097 | static QString list_value_to_string( int v ) |
2121 | { | 2098 | { |
2122 | if ( v != -1 ) | 2099 | if ( v != -1 ) |
2123 | return " listvalue=\"" + QString::number( v ) + "\""; | 2100 | return " listvalue=\"" + QString::number( v ) + "\""; |
2124 | return QString::null; | 2101 | return QString::null; |
2125 | } | 2102 | } |
2126 | 2103 | ||
2127 | static QString list_style_to_string( int v ) | 2104 | static QString list_style_to_string( int v ) |
2128 | { | 2105 | { |
2129 | switch( v ) { | 2106 | switch( v ) { |
2130 | case QStyleSheetItem::ListDecimal: return "\"1\""; | 2107 | case QStyleSheetItem::ListDecimal: return "\"1\""; |
2131 | case QStyleSheetItem::ListLowerAlpha: return "\"a\""; | 2108 | case QStyleSheetItem::ListLowerAlpha: return "\"a\""; |
2132 | case QStyleSheetItem::ListUpperAlpha: return "\"A\""; | 2109 | case QStyleSheetItem::ListUpperAlpha: return "\"A\""; |
2133 | case QStyleSheetItem::ListDisc: return "\"disc\""; | 2110 | case QStyleSheetItem::ListDisc: return "\"disc\""; |
2134 | case QStyleSheetItem::ListSquare: return "\"square\""; | 2111 | case QStyleSheetItem::ListSquare: return "\"square\""; |
2135 | case QStyleSheetItem::ListCircle: return "\"circle\""; | 2112 | case QStyleSheetItem::ListCircle: return "\"circle\""; |
2136 | default: | 2113 | default: |
2137 | return QString::null; | 2114 | return QString::null; |
2138 | } | 2115 | } |
2139 | } | 2116 | } |
2140 | 2117 | ||
2141 | static inline bool list_is_ordered( int v ) | 2118 | static inline bool list_is_ordered( int v ) |
2142 | { | 2119 | { |
2143 | return v == QStyleSheetItem::ListDecimal || | 2120 | return v == QStyleSheetItem::ListDecimal || |
2144 | v == QStyleSheetItem::ListLowerAlpha || | 2121 | v == QStyleSheetItem::ListLowerAlpha || |
2145 | v == QStyleSheetItem::ListUpperAlpha; | 2122 | v == QStyleSheetItem::ListUpperAlpha; |
2146 | } | 2123 | } |
2147 | 2124 | ||
2148 | 2125 | ||
2149 | static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl ) | 2126 | static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl ) |
2150 | { | 2127 | { |
2151 | QString s; | 2128 | QString s; |
2152 | if ( l > 0 ) | 2129 | if ( l > 0 ) |
2153 | s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px"; | 2130 | s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px"; |
2154 | if ( r > 0 ) | 2131 | if ( r > 0 ) |
2155 | s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px"; | 2132 | s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px"; |
2156 | if ( t > 0 ) | 2133 | if ( t > 0 ) |
2157 | s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px"; | 2134 | s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px"; |
2158 | if ( b > 0 ) | 2135 | if ( b > 0 ) |
2159 | s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px"; | 2136 | s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px"; |
2160 | if ( fl > 0 ) | 2137 | if ( fl > 0 ) |
2161 | s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px"; | 2138 | s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px"; |
2162 | if ( !!s ) | 2139 | if ( !!s ) |
2163 | return " style=\"" + s + "\""; | 2140 | return " style=\"" + s + "\""; |
2164 | return QString::null; | 2141 | return QString::null; |
2165 | } | 2142 | } |
2166 | 2143 | ||
2167 | QString QTextDocument::richText() const | 2144 | QString QTextDocument::richText() const |
2168 | { | 2145 | { |
2169 | QString s = ""; | 2146 | QString s = ""; |
2170 | if ( !par ) { | 2147 | if ( !par ) { |
2171 | s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ; | 2148 | s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ; |
2172 | s += QString::number( formatCollection()->defaultFormat()->font().pointSize() ); | 2149 | s += QString::number( formatCollection()->defaultFormat()->font().pointSize() ); |
2173 | s += "pt;font-family:"; | 2150 | s += "pt;font-family:"; |
2174 | s += formatCollection()->defaultFormat()->font().family(); | 2151 | s += formatCollection()->defaultFormat()->font().family(); |
2175 | s +="\">"; | 2152 | s +="\">"; |
2176 | } | 2153 | } |
2177 | QTextParagraph* p = fParag; | 2154 | QTextParagraph* p = fParag; |
2178 | 2155 | ||
2179 | QStyleSheetItem* item_p = styleSheet()->item("p"); | 2156 | QStyleSheetItem* item_p = styleSheet()->item("p"); |
2180 | QStyleSheetItem* item_ul = styleSheet()->item("ul"); | 2157 | QStyleSheetItem* item_ul = styleSheet()->item("ul"); |
2181 | QStyleSheetItem* item_ol = styleSheet()->item("ol"); | 2158 | QStyleSheetItem* item_ol = styleSheet()->item("ol"); |
2182 | QStyleSheetItem* item_li = styleSheet()->item("li"); | 2159 | QStyleSheetItem* item_li = styleSheet()->item("li"); |
2183 | if ( !item_p || !item_ul || !item_ol || !item_li ) { | 2160 | if ( !item_p || !item_ul || !item_ol || !item_li ) { |
2184 | owarn << "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" << oendl; | 2161 | owarn << "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" << oendl; |
2185 | return QString::null; | 2162 | return QString::null; |
2186 | } | 2163 | } |
2187 | int pastListDepth = 0; | 2164 | int pastListDepth = 0; |
2188 | int listDepth = 0; | 2165 | int listDepth = 0; |
2189 | int futureListDepth = 0; | 2166 | int futureListDepth = 0; |
2190 | QMemArray<int> listStyles(10); | 2167 | QMemArray<int> listStyles(10); |
2191 | 2168 | ||
2192 | while ( p ) { | 2169 | while ( p ) { |
2193 | listDepth = p->listDepth(); | 2170 | listDepth = p->listDepth(); |
2194 | if ( listDepth < pastListDepth ) { | 2171 | if ( listDepth < pastListDepth ) { |
2195 | for ( int i = listDepth+1; i <= pastListDepth; i++ ) | 2172 | for ( int i = listDepth+1; i <= pastListDepth; i++ ) |
2196 | s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>"; | 2173 | s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>"; |
2197 | s += '\n'; | 2174 | s += '\n'; |
2198 | } else if ( listDepth > pastListDepth ) { | 2175 | } else if ( listDepth > pastListDepth ) { |
2199 | s += '\n'; | 2176 | s += '\n'; |
2200 | listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) ); | 2177 | listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) ); |
2201 | QString list_type; | 2178 | QString list_type; |
2202 | listStyles[listDepth] = p->listStyle(); | 2179 | listStyles[listDepth] = p->listStyle(); |
2203 | if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() ) | 2180 | if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() ) |
2204 | list_type = " type=" + list_style_to_string( p->listStyle() ); | 2181 | list_type = " type=" + list_style_to_string( p->listStyle() ); |
2205 | for ( int i = pastListDepth; i < listDepth; i++ ) { | 2182 | for ( int i = pastListDepth; i < listDepth; i++ ) { |
2206 | s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ; | 2183 | s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ; |
2207 | s += list_type + ">"; | 2184 | s += list_type + ">"; |
2208 | } | 2185 | } |
2209 | } else { | 2186 | } else { |
2210 | s += '\n'; | 2187 | s += '\n'; |
2211 | } | 2188 | } |
2212 | 2189 | ||
2213 | QString ps = p->richText(); | 2190 | QString ps = p->richText(); |
2214 | 2191 | ||
2215 | // for the bottom margin we need to know whether we are at the end of a list | 2192 | // for the bottom margin we need to know whether we are at the end of a list |
2216 | futureListDepth = 0; | 2193 | futureListDepth = 0; |
2217 | if ( listDepth > 0 && p->next() ) | 2194 | if ( listDepth > 0 && p->next() ) |
2218 | futureListDepth = p->next()->listDepth(); | 2195 | futureListDepth = p->next()->listDepth(); |
2219 | 2196 | ||
2220 | if ( richTextExportStart && richTextExportStart->paragraph() ==p && | 2197 | if ( richTextExportStart && richTextExportStart->paragraph() ==p && |
2221 | richTextExportStart->index() == 0 ) | 2198 | richTextExportStart->index() == 0 ) |
2222 | s += "<selstart/>"; | 2199 | s += "<selstart/>"; |
2223 | 2200 | ||
2224 | if ( p->isListItem() ) { | 2201 | if ( p->isListItem() ) { |
2225 | s += "<li"; | 2202 | s += "<li"; |
2226 | if ( p->listStyle() != listStyles[listDepth] ) | 2203 | if ( p->listStyle() != listStyles[listDepth] ) |
2227 | s += " type=" + list_style_to_string( p->listStyle() ); | 2204 | s += " type=" + list_style_to_string( p->listStyle() ); |
2228 | s +=align_to_string( p->alignment() ); | 2205 | s +=align_to_string( p->alignment() ); |
2229 | s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); | 2206 | s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); |
2230 | s += list_value_to_string( p->listValue() ); | 2207 | s += list_value_to_string( p->listValue() ); |
2231 | s += direction_to_string( p->direction() ); | 2208 | s += direction_to_string( p->direction() ); |
2232 | s +=">"; | 2209 | s +=">"; |
2233 | s += ps; | 2210 | s += ps; |
2234 | s += "</li>"; | 2211 | s += "</li>"; |
2235 | } else { | 2212 | } else { |
2236 | // normal paragraph item | 2213 | // normal paragraph item |
2237 | s += "<p"; | 2214 | s += "<p"; |
2238 | s += align_to_string( p->alignment() ); | 2215 | s += align_to_string( p->alignment() ); |
2239 | s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); | 2216 | s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); |
2240 | s +=direction_to_string( p->direction() ); | 2217 | s +=direction_to_string( p->direction() ); |
2241 | s += ">"; | 2218 | s += ">"; |
2242 | s += ps; | 2219 | s += ps; |
2243 | s += "</p>"; | 2220 | s += "</p>"; |
2244 | } | 2221 | } |
2245 | pastListDepth = listDepth; | 2222 | pastListDepth = listDepth; |
2246 | p = p->next(); | 2223 | p = p->next(); |
2247 | } | 2224 | } |
2248 | while ( listDepth > 0 ) { | 2225 | while ( listDepth > 0 ) { |
2249 | s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>"; | 2226 | s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>"; |
2250 | listDepth--; | 2227 | listDepth--; |
2251 | } | 2228 | } |
2252 | 2229 | ||
2253 | if ( !par ) | 2230 | if ( !par ) |
2254 | s += "\n</body></html>\n"; | 2231 | s += "\n</body></html>\n"; |
2255 | 2232 | ||
2256 | return s; | 2233 | return s; |
2257 | } | 2234 | } |
2258 | 2235 | ||
2259 | QString QTextDocument::text() const | 2236 | QString QTextDocument::text() const |
2260 | { | 2237 | { |
2261 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) | 2238 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) |
2262 | return richText(); | 2239 | return richText(); |
2263 | return plainText(); | 2240 | return plainText(); |
2264 | } | 2241 | } |
2265 | 2242 | ||
2266 | QString QTextDocument::text( int parag ) const | 2243 | QString QTextDocument::text( int parag ) const |
2267 | { | 2244 | { |
2268 | QTextParagraph *p = paragAt( parag ); | 2245 | QTextParagraph *p = paragAt( parag ); |
2269 | if ( !p ) | 2246 | if ( !p ) |
2270 | return QString::null; | 2247 | return QString::null; |
2271 | 2248 | ||
2272 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) | 2249 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) |
2273 | return p->richText(); | 2250 | return p->richText(); |
2274 | else | 2251 | else |
2275 | return p->string()->toString(); | 2252 | return p->string()->toString(); |
2276 | } | 2253 | } |
2277 | 2254 | ||
2278 | void QTextDocument::invalidate() | 2255 | void QTextDocument::invalidate() |
2279 | { | 2256 | { |
2280 | QTextParagraph *s = fParag; | 2257 | QTextParagraph *s = fParag; |
2281 | while ( s ) { | 2258 | while ( s ) { |
2282 | s->invalidate( 0 ); | 2259 | s->invalidate( 0 ); |
2283 | s = s->next(); | 2260 | s = s->next(); |
2284 | } | 2261 | } |
2285 | } | 2262 | } |
2286 | 2263 | ||
2287 | void QTextDocument::selectionStart( int id, int ¶gId, int &index ) | 2264 | void QTextDocument::selectionStart( int id, int ¶gId, int &index ) |
2288 | { | 2265 | { |
2289 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2266 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2290 | if ( it == selections.end() ) | 2267 | if ( it == selections.end() ) |
2291 | return; | 2268 | return; |
2292 | QTextDocumentSelection &sel = *it; | 2269 | QTextDocumentSelection &sel = *it; |
2293 | paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); | 2270 | paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); |
2294 | index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); | 2271 | index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); |
2295 | } | 2272 | } |
2296 | 2273 | ||
2297 | QTextCursor QTextDocument::selectionStartCursor( int id) | 2274 | QTextCursor QTextDocument::selectionStartCursor( int id) |
2298 | { | 2275 | { |
2299 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2276 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2300 | if ( it == selections.end() ) | 2277 | if ( it == selections.end() ) |
2301 | return QTextCursor( this ); | 2278 | return QTextCursor( this ); |
2302 | QTextDocumentSelection &sel = *it; | 2279 | QTextDocumentSelection &sel = *it; |
2303 | if ( sel.swapped ) | 2280 | if ( sel.swapped ) |
2304 | return sel.endCursor; | 2281 | return sel.endCursor; |
2305 | return sel.startCursor; | 2282 | return sel.startCursor; |
2306 | } | 2283 | } |
2307 | 2284 | ||
2308 | QTextCursor QTextDocument::selectionEndCursor( int id) | 2285 | QTextCursor QTextDocument::selectionEndCursor( int id) |
2309 | { | 2286 | { |
2310 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2287 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2311 | if ( it == selections.end() ) | 2288 | if ( it == selections.end() ) |
2312 | return QTextCursor( this ); | 2289 | return QTextCursor( this ); |
2313 | QTextDocumentSelection &sel = *it; | 2290 | QTextDocumentSelection &sel = *it; |
2314 | if ( !sel.swapped ) | 2291 | if ( !sel.swapped ) |
2315 | return sel.endCursor; | 2292 | return sel.endCursor; |
2316 | return sel.startCursor; | 2293 | return sel.startCursor; |
2317 | } | 2294 | } |
2318 | 2295 | ||
2319 | void QTextDocument::selectionEnd( int id, int ¶gId, int &index ) | 2296 | void QTextDocument::selectionEnd( int id, int ¶gId, int &index ) |
2320 | { | 2297 | { |
2321 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2298 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2322 | if ( it == selections.end() ) | 2299 | if ( it == selections.end() ) |
2323 | return; | 2300 | return; |
2324 | QTextDocumentSelection &sel = *it; | 2301 | QTextDocumentSelection &sel = *it; |
2325 | paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); | 2302 | paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); |
2326 | index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); | 2303 | index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); |
2327 | } | 2304 | } |
2328 | 2305 | ||
2329 | void QTextDocument::addSelection( int id ) | 2306 | void QTextDocument::addSelection( int id ) |
2330 | { | 2307 | { |
2331 | nSelections = QMAX( nSelections, id + 1 ); | 2308 | nSelections = QMAX( nSelections, id + 1 ); |
2332 | } | 2309 | } |
2333 | 2310 | ||
2334 | static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end ) | 2311 | static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end ) |
2335 | { | 2312 | { |
2336 | QTextCursor c1 = start; | 2313 | QTextCursor c1 = start; |
2337 | QTextCursor c2 = end; | 2314 | QTextCursor c2 = end; |
2338 | if ( sel.swapped ) { | 2315 | if ( sel.swapped ) { |
2339 | c1 = end; | 2316 | c1 = end; |
2340 | c2 = start; | 2317 | c2 = start; |
2341 | } | 2318 | } |
2342 | 2319 | ||
2343 | c1.paragraph()->removeSelection( id ); | 2320 | c1.paragraph()->removeSelection( id ); |
2344 | c2.paragraph()->removeSelection( id ); | 2321 | c2.paragraph()->removeSelection( id ); |
2345 | if ( c1.paragraph() != c2.paragraph() ) { | 2322 | if ( c1.paragraph() != c2.paragraph() ) { |
2346 | c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 ); | 2323 | c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 ); |
2347 | c2.paragraph()->setSelection( id, 0, c2.index() ); | 2324 | c2.paragraph()->setSelection( id, 0, c2.index() ); |
2348 | } else { | 2325 | } else { |
2349 | c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); | 2326 | c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); |
2350 | } | 2327 | } |
2351 | 2328 | ||
2352 | sel.startCursor = start; | 2329 | sel.startCursor = start; |
2353 | sel.endCursor = end; | 2330 | sel.endCursor = end; |
2354 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) | 2331 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) |
2355 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); | 2332 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); |
2356 | } | 2333 | } |
2357 | 2334 | ||
2358 | bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor ) | 2335 | bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor ) |
2359 | { | 2336 | { |
2360 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2337 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2361 | if ( it == selections.end() ) | 2338 | if ( it == selections.end() ) |
2362 | return FALSE; | 2339 | return FALSE; |
2363 | QTextDocumentSelection &sel = *it; | 2340 | QTextDocumentSelection &sel = *it; |
2364 | 2341 | ||
2365 | QTextCursor start = sel.startCursor; | 2342 | QTextCursor start = sel.startCursor; |
2366 | QTextCursor end = cursor; | 2343 | QTextCursor end = cursor; |
2367 | 2344 | ||
2368 | if ( start == end ) { | 2345 | if ( start == end ) { |
2369 | removeSelection( id ); | 2346 | removeSelection( id ); |
2370 | setSelectionStart( id, cursor ); | 2347 | setSelectionStart( id, cursor ); |
2371 | return TRUE; | 2348 | return TRUE; |
2372 | } | 2349 | } |
2373 | 2350 | ||
2374 | if ( sel.endCursor.paragraph() == end.paragraph() ) { | 2351 | if ( sel.endCursor.paragraph() == end.paragraph() ) { |
2375 | setSelectionEndHelper( id, sel, start, end ); | 2352 | setSelectionEndHelper( id, sel, start, end ); |
2376 | return TRUE; | 2353 | return TRUE; |
2377 | } | 2354 | } |
2378 | 2355 | ||
2379 | bool inSelection = FALSE; | 2356 | bool inSelection = FALSE; |
2380 | QTextCursor c( this ); | 2357 | QTextCursor c( this ); |
2381 | QTextCursor tmp = sel.startCursor; | 2358 | QTextCursor tmp = sel.startCursor; |
2382 | if ( sel.swapped ) | 2359 | if ( sel.swapped ) |
2383 | tmp = sel.endCursor; | 2360 | tmp = sel.endCursor; |
2384 | tmp.restoreState(); | 2361 | tmp.restoreState(); |
2385 | QTextCursor tmp2 = cursor; | 2362 | QTextCursor tmp2 = cursor; |
2386 | tmp2.restoreState(); | 2363 | tmp2.restoreState(); |
2387 | c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() ); | 2364 | c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() ); |
2388 | bool hadStart = FALSE; | 2365 | bool hadStart = FALSE; |
2389 | bool hadEnd = FALSE; | 2366 | bool hadEnd = FALSE; |
2390 | bool hadStartParag = FALSE; | 2367 | bool hadStartParag = FALSE; |
2391 | bool hadEndParag = FALSE; | 2368 | bool hadEndParag = FALSE; |
2392 | bool hadOldStart = FALSE; | 2369 | bool hadOldStart = FALSE; |
2393 | bool hadOldEnd = FALSE; | 2370 | bool hadOldEnd = FALSE; |
2394 | bool leftSelection = FALSE; | 2371 | bool leftSelection = FALSE; |
2395 | sel.swapped = FALSE; | 2372 | sel.swapped = FALSE; |
2396 | for ( ;; ) { | 2373 | for ( ;; ) { |
2397 | if ( c == start ) | 2374 | if ( c == start ) |
2398 | hadStart = TRUE; | 2375 | hadStart = TRUE; |
2399 | if ( c == end ) | 2376 | if ( c == end ) |
2400 | hadEnd = TRUE; | 2377 | hadEnd = TRUE; |
2401 | if ( c.paragraph() == start.paragraph() ) | 2378 | if ( c.paragraph() == start.paragraph() ) |
2402 | hadStartParag = TRUE; | 2379 | hadStartParag = TRUE; |
2403 | if ( c.paragraph() == end.paragraph() ) | 2380 | if ( c.paragraph() == end.paragraph() ) |
2404 | hadEndParag = TRUE; | 2381 | hadEndParag = TRUE; |
2405 | if ( c == sel.startCursor ) | 2382 | if ( c == sel.startCursor ) |
2406 | hadOldStart = TRUE; | 2383 | hadOldStart = TRUE; |
2407 | if ( c == sel.endCursor ) | 2384 | if ( c == sel.endCursor ) |
2408 | hadOldEnd = TRUE; | 2385 | hadOldEnd = TRUE; |
2409 | 2386 | ||
2410 | if ( !sel.swapped && | 2387 | if ( !sel.swapped && |
2411 | ( hadEnd && !hadStart || | 2388 | ( hadEnd && !hadStart || |
2412 | hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) ) | 2389 | hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) ) |
2413 | sel.swapped = TRUE; | 2390 | sel.swapped = TRUE; |
2414 | 2391 | ||
2415 | if ( c == end && hadStartParag || | 2392 | if ( c == end && hadStartParag || |
2416 | c == start && hadEndParag ) { | 2393 | c == start && hadEndParag ) { |
2417 | QTextCursor tmp = c; | 2394 | QTextCursor tmp = c; |
2418 | tmp.restoreState(); | 2395 | tmp.restoreState(); |
2419 | if ( tmp.paragraph() != c.paragraph() ) { | 2396 | if ( tmp.paragraph() != c.paragraph() ) { |
2420 | int sstart = tmp.paragraph()->selectionStart( id ); | 2397 | int sstart = tmp.paragraph()->selectionStart( id ); |
2421 | tmp.paragraph()->removeSelection( id ); | 2398 | tmp.paragraph()->removeSelection( id ); |
2422 | tmp.paragraph()->setSelection( id, sstart, tmp.index() ); | 2399 | tmp.paragraph()->setSelection( id, sstart, tmp.index() ); |
2423 | } | 2400 | } |
2424 | } | 2401 | } |
2425 | 2402 | ||
2426 | if ( inSelection && | 2403 | if ( inSelection && |
2427 | ( c == end && hadStart || c == start && hadEnd ) ) | 2404 | ( c == end && hadStart || c == start && hadEnd ) ) |
2428 | leftSelection = TRUE; | 2405 | leftSelection = TRUE; |
2429 | else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) | 2406 | else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) |
2430 | inSelection = TRUE; | 2407 | inSelection = TRUE; |
2431 | 2408 | ||
2432 | bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd(); | 2409 | bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd(); |
2433 | c.paragraph()->removeSelection( id ); | 2410 | c.paragraph()->removeSelection( id ); |
2434 | if ( inSelection ) { | 2411 | if ( inSelection ) { |
2435 | if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) { | 2412 | if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) { |
2436 | c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); | 2413 | c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); |
2437 | } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) { | 2414 | } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) { |
2438 | c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 ); | 2415 | c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 ); |
2439 | } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) { | 2416 | } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) { |
2440 | c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 ); | 2417 | c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 ); |
2441 | } else if ( c.paragraph() == end.paragraph() && hadEndParag ) { | 2418 | } else if ( c.paragraph() == end.paragraph() && hadEndParag ) { |
2442 | c.paragraph()->setSelection( id, 0, end.index() ); | 2419 | c.paragraph()->setSelection( id, 0, end.index() ); |
2443 | } else if ( c.paragraph() == start.paragraph() && hadStartParag ) { | 2420 | } else if ( c.paragraph() == start.paragraph() && hadStartParag ) { |
2444 | c.paragraph()->setSelection( id, 0, start.index() ); | 2421 | c.paragraph()->setSelection( id, 0, start.index() ); |
2445 | } else { | 2422 | } else { |
2446 | c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 ); | 2423 | c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 ); |
2447 | } | 2424 | } |
2448 | } | 2425 | } |
2449 | 2426 | ||
2450 | if ( leftSelection ) | 2427 | if ( leftSelection ) |
2451 | inSelection = FALSE; | 2428 | inSelection = FALSE; |
2452 | 2429 | ||
2453 | if ( noSelectionAnymore ) | 2430 | if ( noSelectionAnymore ) |
2454 | break; | 2431 | break; |
2455 | // *ugle*hack optimization | 2432 | // *ugle*hack optimization |
2456 | QTextParagraph *p = c.paragraph(); | 2433 | QTextParagraph *p = c.paragraph(); |
2457 | if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) { | 2434 | if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) { |
2458 | c.gotoNextLetter(); | 2435 | c.gotoNextLetter(); |
2459 | if ( p == lastParagraph() && c.atParagEnd() ) | 2436 | if ( p == lastParagraph() && c.atParagEnd() ) |
2460 | break; | 2437 | break; |
2461 | } else { | 2438 | } else { |
2462 | if ( p->document()->parent() ) | 2439 | if ( p->document()->parent() ) |
2463 | do { | 2440 | do { |
2464 | c.gotoNextLetter(); | 2441 | c.gotoNextLetter(); |
2465 | } while ( c.paragraph() == p ); | 2442 | } while ( c.paragraph() == p ); |
2466 | else | 2443 | else |
2467 | c.setParagraph( p->next() ); | 2444 | c.setParagraph( p->next() ); |
2468 | } | 2445 | } |
2469 | } | 2446 | } |
2470 | 2447 | ||
2471 | if ( !sel.swapped ) | 2448 | if ( !sel.swapped ) |
2472 | sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 ); | 2449 | sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 ); |
2473 | 2450 | ||
2474 | sel.startCursor = start; | 2451 | sel.startCursor = start; |
2475 | sel.endCursor = end; | 2452 | sel.endCursor = end; |
2476 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) | 2453 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) |
2477 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); | 2454 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); |
2478 | 2455 | ||
2479 | setSelectionEndHelper( id, sel, start, end ); | 2456 | setSelectionEndHelper( id, sel, start, end ); |
2480 | 2457 | ||
2481 | return TRUE; | 2458 | return TRUE; |
2482 | } | 2459 | } |
2483 | 2460 | ||
2484 | void QTextDocument::selectAll( int id ) | 2461 | void QTextDocument::selectAll( int id ) |
2485 | { | 2462 | { |
2486 | removeSelection( id ); | 2463 | removeSelection( id ); |
2487 | 2464 | ||
2488 | QTextDocumentSelection sel; | 2465 | QTextDocumentSelection sel; |
2489 | sel.swapped = FALSE; | 2466 | sel.swapped = FALSE; |
2490 | QTextCursor c( this ); | 2467 | QTextCursor c( this ); |
2491 | 2468 | ||
2492 | c.setParagraph( fParag ); | 2469 | c.setParagraph( fParag ); |
2493 | c.setIndex( 0 ); | 2470 | c.setIndex( 0 ); |
2494 | sel.startCursor = c; | 2471 | sel.startCursor = c; |
2495 | 2472 | ||
2496 | c.setParagraph( lParag ); | 2473 | c.setParagraph( lParag ); |
2497 | c.setIndex( lParag->length() - 1 ); | 2474 | c.setIndex( lParag->length() - 1 ); |
2498 | sel.endCursor = c; | 2475 | sel.endCursor = c; |
2499 | 2476 | ||
2500 | selections.insert( id, sel ); | 2477 | selections.insert( id, sel ); |
2501 | 2478 | ||
2502 | QTextParagraph *p = fParag; | 2479 | QTextParagraph *p = fParag; |
2503 | while ( p ) { | 2480 | while ( p ) { |
2504 | p->setSelection( id, 0, p->length() - 1 ); | 2481 | p->setSelection( id, 0, p->length() - 1 ); |
2505 | p = p->next(); | 2482 | p = p->next(); |
2506 | } | 2483 | } |
2507 | 2484 | ||
2508 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 2485 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
2509 | d->selectAll( id ); | 2486 | d->selectAll( id ); |
2510 | } | 2487 | } |
2511 | 2488 | ||
2512 | bool QTextDocument::removeSelection( int id ) | 2489 | bool QTextDocument::removeSelection( int id ) |
2513 | { | 2490 | { |
2514 | if ( !selections.contains( id ) ) | 2491 | if ( !selections.contains( id ) ) |
2515 | return FALSE; | 2492 | return FALSE; |
2516 | 2493 | ||
2517 | QTextDocumentSelection &sel = selections[ id ]; | 2494 | QTextDocumentSelection &sel = selections[ id ]; |
2518 | 2495 | ||
2519 | QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor; | 2496 | QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor; |
2520 | QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor; | 2497 | QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor; |
2521 | QTextParagraph* p = 0; | 2498 | QTextParagraph* p = 0; |
2522 | while ( start != end ) { | 2499 | while ( start != end ) { |
2523 | if ( p != start.paragraph() ) { | 2500 | if ( p != start.paragraph() ) { |
2524 | p = start.paragraph(); | 2501 | p = start.paragraph(); |
2525 | p->removeSelection( id ); | 2502 | p->removeSelection( id ); |
2526 | } | 2503 | } |
2527 | start.gotoNextLetter(); | 2504 | start.gotoNextLetter(); |
2528 | } | 2505 | } |
2529 | selections.remove( id ); | 2506 | selections.remove( id ); |
2530 | return TRUE; | 2507 | return TRUE; |
2531 | } | 2508 | } |
2532 | 2509 | ||
2533 | QString QTextDocument::selectedText( int id, bool asRichText ) const | 2510 | QString QTextDocument::selectedText( int id, bool asRichText ) const |
2534 | { | 2511 | { |
2535 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); | 2512 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); |
2536 | if ( it == selections.end() ) | 2513 | if ( it == selections.end() ) |
2537 | return QString::null; | 2514 | return QString::null; |
2538 | 2515 | ||
2539 | QTextDocumentSelection sel = *it; | 2516 | QTextDocumentSelection sel = *it; |
2540 | 2517 | ||
2541 | 2518 | ||
2542 | QTextCursor c1 = sel.startCursor; | 2519 | QTextCursor c1 = sel.startCursor; |
2543 | QTextCursor c2 = sel.endCursor; | 2520 | QTextCursor c2 = sel.endCursor; |
2544 | if ( sel.swapped ) { | 2521 | if ( sel.swapped ) { |
2545 | c2 = sel.startCursor; | 2522 | c2 = sel.startCursor; |
2546 | c1 = sel.endCursor; | 2523 | c1 = sel.endCursor; |
2547 | } | 2524 | } |
2548 | 2525 | ||
2549 | /* 3.0.3 improvement: Make it possible to get a reasonable | 2526 | /* 3.0.3 improvement: Make it possible to get a reasonable |
2550 | selection inside a table. This approach is very conservative: | 2527 | selection inside a table. This approach is very conservative: |
2551 | make sure that both cursors have the same depth level and point | 2528 | make sure that both cursors have the same depth level and point |
2552 | to paragraphs within the same text document. | 2529 | to paragraphs within the same text document. |
2553 | 2530 | ||
2554 | Meaning if you select text in two table cells, you will get the | 2531 | Meaning if you select text in two table cells, you will get the |
2555 | entire table. This is still far better than the 3.0.2, where | 2532 | entire table. This is still far better than the 3.0.2, where |
2556 | you always got the entire table. | 2533 | you always got the entire table. |
2557 | 2534 | ||
2558 | ### Fix this properly when refactoring | 2535 | ### Fix this properly when refactoring |
2559 | */ | 2536 | */ |
2560 | while ( c2.nestedDepth() > c1.nestedDepth() ) | 2537 | while ( c2.nestedDepth() > c1.nestedDepth() ) |
2561 | c2.oneUp(); | 2538 | c2.oneUp(); |
2562 | while ( c1.nestedDepth() > c2.nestedDepth() ) | 2539 | while ( c1.nestedDepth() > c2.nestedDepth() ) |
2563 | c1.oneUp(); | 2540 | c1.oneUp(); |
2564 | while ( c1.nestedDepth() && c2.nestedDepth() && | 2541 | while ( c1.nestedDepth() && c2.nestedDepth() && |
2565 | c1.paragraph()->document() != c2.paragraph()->document() ) { | 2542 | c1.paragraph()->document() != c2.paragraph()->document() ) { |
2566 | c1.oneUp(); | 2543 | c1.oneUp(); |
2567 | c2.oneUp(); | 2544 | c2.oneUp(); |
2568 | } | 2545 | } |
2569 | // do not trust sel_swapped with tables. Fix this properly when refactoring as well | 2546 | // do not trust sel_swapped with tables. Fix this properly when refactoring as well |
2570 | if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() || | 2547 | if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() || |
2571 | (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) { | 2548 | (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) { |
2572 | QTextCursor tmp = c1; | 2549 | QTextCursor tmp = c1; |
2573 | c2 = c1; | 2550 | c2 = c1; |
2574 | c1 = tmp; | 2551 | c1 = tmp; |
2575 | } | 2552 | } |
2576 | 2553 | ||
2577 | // end selection 3.0.3 improvement | 2554 | // end selection 3.0.3 improvement |
2578 | 2555 | ||
2579 | if ( asRichText && !parent() ) { | 2556 | if ( asRichText && !parent() ) { |
2580 | richTextExportStart = &c1; | 2557 | richTextExportStart = &c1; |
2581 | richTextExportEnd = &c2; | 2558 | richTextExportEnd = &c2; |
2582 | 2559 | ||
2583 | QString sel = richText(); | 2560 | QString sel = richText(); |
2584 | int from = sel.find( "<selstart/>" ); | 2561 | int from = sel.find( "<selstart/>" ); |
2585 | int to = sel.findRev( "<selend/>" ); | 2562 | int to = sel.findRev( "<selend/>" ); |
2586 | if ( from >= 0 && from <= to ) | 2563 | if ( from >= 0 && from <= to ) |
2587 | sel = sel.mid( from, to - from ); | 2564 | sel = sel.mid( from, to - from ); |
2588 | richTextExportStart = richTextExportEnd = 0; | 2565 | richTextExportStart = richTextExportEnd = 0; |
2589 | return sel; | 2566 | return sel; |
2590 | } | 2567 | } |
2591 | 2568 | ||
2592 | QString s; | 2569 | QString s; |
2593 | if ( c1.paragraph() == c2.paragraph() ) { | 2570 | if ( c1.paragraph() == c2.paragraph() ) { |
2594 | QTextParagraph *p = c1.paragraph(); | 2571 | QTextParagraph *p = c1.paragraph(); |
2595 | int end = c2.index(); | 2572 | int end = c2.index(); |
2596 | if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) | 2573 | if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) |
2597 | ++end; | 2574 | ++end; |
2598 | if ( !p->mightHaveCustomItems ) { | 2575 | if ( !p->mightHaveCustomItems ) { |
2599 | s += p->string()->toString().mid( c1.index(), end - c1.index() ); | 2576 | s += p->string()->toString().mid( c1.index(), end - c1.index() ); |
2600 | } else { | 2577 | } else { |
2601 | for ( int i = c1.index(); i < end; ++i ) { | 2578 | for ( int i = c1.index(); i < end; ++i ) { |
2602 | if ( p->at( i )->isCustom() ) { | 2579 | if ( p->at( i )->isCustom() ) { |
2603 | if ( p->at( i )->customItem()->isNested() ) { | 2580 | if ( p->at( i )->customItem()->isNested() ) { |
2604 | s += "\n"; | 2581 | s += "\n"; |
2605 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2582 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2606 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2583 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2607 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2584 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2608 | s += c->richText()->plainText() + "\n"; | 2585 | s += c->richText()->plainText() + "\n"; |
2609 | s += "\n"; | 2586 | s += "\n"; |
2610 | } | 2587 | } |
2611 | } else { | 2588 | } else { |
2612 | s += p->at( i )->c; | 2589 | s += p->at( i )->c; |
2613 | } | 2590 | } |
2614 | } | 2591 | } |
2615 | } | 2592 | } |
2616 | } else { | 2593 | } else { |
2617 | QTextParagraph *p = c1.paragraph(); | 2594 | QTextParagraph *p = c1.paragraph(); |
2618 | int start = c1.index(); | 2595 | int start = c1.index(); |
2619 | while ( p ) { | 2596 | while ( p ) { |
2620 | int end = p == c2.paragraph() ? c2.index() : p->length() - 1; | 2597 | int end = p == c2.paragraph() ? c2.index() : p->length() - 1; |
2621 | if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) | 2598 | if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) |
2622 | ++end; | 2599 | ++end; |
2623 | if ( !p->mightHaveCustomItems ) { | 2600 | if ( !p->mightHaveCustomItems ) { |
2624 | s += p->string()->toString().mid( start, end - start ); | 2601 | s += p->string()->toString().mid( start, end - start ); |
2625 | if ( p != c2.paragraph() ) | 2602 | if ( p != c2.paragraph() ) |
2626 | s += "\n"; | 2603 | s += "\n"; |
2627 | } else { | 2604 | } else { |
2628 | for ( int i = start; i < end; ++i ) { | 2605 | for ( int i = start; i < end; ++i ) { |
2629 | if ( p->at( i )->isCustom() ) { | 2606 | if ( p->at( i )->isCustom() ) { |
2630 | if ( p->at( i )->customItem()->isNested() ) { | 2607 | if ( p->at( i )->customItem()->isNested() ) { |
2631 | s += "\n"; | 2608 | s += "\n"; |
2632 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2609 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2633 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2610 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2634 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2611 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2635 | s += c->richText()->plainText() + "\n"; | 2612 | s += c->richText()->plainText() + "\n"; |
2636 | s += "\n"; | 2613 | s += "\n"; |
2637 | } | 2614 | } |
2638 | } else { | 2615 | } else { |
2639 | s += p->at( i )->c; | 2616 | s += p->at( i )->c; |
2640 | } | 2617 | } |
2641 | } | 2618 | } |
2642 | } | 2619 | } |
2643 | start = 0; | 2620 | start = 0; |
2644 | if ( p == c2.paragraph() ) | 2621 | if ( p == c2.paragraph() ) |
2645 | break; | 2622 | break; |
2646 | p = p->next(); | 2623 | p = p->next(); |
2647 | } | 2624 | } |
2648 | } | 2625 | } |
2649 | // ### workaround for plain text export until we get proper | 2626 | // ### workaround for plain text export until we get proper |
2650 | // mime types: turn unicode line seperators into the more | 2627 | // mime types: turn unicode line seperators into the more |
2651 | // widely understood \n. Makes copy and pasting code snipplets | 2628 | // widely understood \n. Makes copy and pasting code snipplets |
2652 | // from within Assistent possible | 2629 | // from within Assistent possible |
2653 | QChar* uc = (QChar*) s.unicode(); | 2630 | QChar* uc = (QChar*) s.unicode(); |
2654 | for ( uint ii = 0; ii < s.length(); ii++ ) | 2631 | for ( uint ii = 0; ii < s.length(); ii++ ) |
2655 | if ( uc[(int)ii] == QChar_linesep ) | 2632 | if ( uc[(int)ii] == QChar_linesep ) |
2656 | uc[(int)ii] = QChar('\n'); | 2633 | uc[(int)ii] = QChar('\n'); |
2657 | return s; | 2634 | return s; |
2658 | } | 2635 | } |
2659 | 2636 | ||
2660 | void QTextDocument::setFormat( int id, QTextFormat *f, int flags ) | 2637 | void QTextDocument::setFormat( int id, QTextFormat *f, int flags ) |
2661 | { | 2638 | { |
2662 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); | 2639 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); |
2663 | if ( it == selections.end() ) | 2640 | if ( it == selections.end() ) |
2664 | return; | 2641 | return; |
2665 | 2642 | ||
2666 | QTextDocumentSelection sel = *it; | 2643 | QTextDocumentSelection sel = *it; |
2667 | 2644 | ||
2668 | QTextCursor c1 = sel.startCursor; | 2645 | QTextCursor c1 = sel.startCursor; |
2669 | QTextCursor c2 = sel.endCursor; | 2646 | QTextCursor c2 = sel.endCursor; |
2670 | if ( sel.swapped ) { | 2647 | if ( sel.swapped ) { |
2671 | c2 = sel.startCursor; | 2648 | c2 = sel.startCursor; |
2672 | c1 = sel.endCursor; | 2649 | c1 = sel.endCursor; |
2673 | } | 2650 | } |
2674 | 2651 | ||
2675 | c2.restoreState(); | 2652 | c2.restoreState(); |
2676 | c1.restoreState(); | 2653 | c1.restoreState(); |
2677 | 2654 | ||
2678 | if ( c1.paragraph() == c2.paragraph() ) { | 2655 | if ( c1.paragraph() == c2.paragraph() ) { |
2679 | c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); | 2656 | c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); |
2680 | return; | 2657 | return; |
2681 | } | 2658 | } |
2682 | 2659 | ||
2683 | c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags ); | 2660 | c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags ); |
2684 | QTextParagraph *p = c1.paragraph()->next(); | 2661 | QTextParagraph *p = c1.paragraph()->next(); |
2685 | while ( p && p != c2.paragraph() ) { | 2662 | while ( p && p != c2.paragraph() ) { |
2686 | p->setFormat( 0, p->length(), f, TRUE, flags ); | 2663 | p->setFormat( 0, p->length(), f, TRUE, flags ); |
2687 | p = p->next(); | 2664 | p = p->next(); |
2688 | } | 2665 | } |
2689 | c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags ); | 2666 | c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags ); |
2690 | } | 2667 | } |
2691 | 2668 | ||
2692 | void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) | 2669 | void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) |
2693 | { | 2670 | { |
2694 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2671 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2695 | if ( it == selections.end() ) | 2672 | if ( it == selections.end() ) |
2696 | return; | 2673 | return; |
2697 | 2674 | ||
2698 | QTextDocumentSelection sel = *it; | 2675 | QTextDocumentSelection sel = *it; |
2699 | 2676 | ||
2700 | QTextCursor c1 = sel.startCursor; | 2677 | QTextCursor c1 = sel.startCursor; |
2701 | QTextCursor c2 = sel.endCursor; | 2678 | QTextCursor c2 = sel.endCursor; |
2702 | if ( sel.swapped ) { | 2679 | if ( sel.swapped ) { |
2703 | c2 = sel.startCursor; | 2680 | c2 = sel.startCursor; |
2704 | c1 = sel.endCursor; | 2681 | c1 = sel.endCursor; |
2705 | } | 2682 | } |
2706 | 2683 | ||
2707 | // ### no support for editing tables yet | 2684 | // ### no support for editing tables yet |
2708 | if ( c1.nestedDepth() || c2.nestedDepth() ) | 2685 | if ( c1.nestedDepth() || c2.nestedDepth() ) |
2709 | return; | 2686 | return; |
2710 | 2687 | ||
2711 | c2.restoreState(); | 2688 | c2.restoreState(); |
2712 | c1.restoreState(); | 2689 | c1.restoreState(); |
2713 | 2690 | ||
2714 | *cursor = c1; | 2691 | *cursor = c1; |
2715 | removeSelection( id ); | 2692 | removeSelection( id ); |
2716 | 2693 | ||
2717 | if ( c1.paragraph() == c2.paragraph() ) { | 2694 | if ( c1.paragraph() == c2.paragraph() ) { |
2718 | c1.paragraph()->remove( c1.index(), c2.index() - c1.index() ); | 2695 | c1.paragraph()->remove( c1.index(), c2.index() - c1.index() ); |
2719 | return; | 2696 | return; |
2720 | } | 2697 | } |
2721 | 2698 | ||
2722 | if ( c1.paragraph() == fParag && c1.index() == 0 && | 2699 | if ( c1.paragraph() == fParag && c1.index() == 0 && |
2723 | c2.paragraph() == lParag && c2.index() == lParag->length() - 1 ) | 2700 | c2.paragraph() == lParag && c2.index() == lParag->length() - 1 ) |
2724 | cursor->setValid( FALSE ); | 2701 | cursor->setValid( FALSE ); |
2725 | 2702 | ||
2726 | bool didGoLeft = FALSE; | 2703 | bool didGoLeft = FALSE; |
2727 | if ( c1.index() == 0 && c1.paragraph() != fParag ) { | 2704 | if ( c1.index() == 0 && c1.paragraph() != fParag ) { |
2728 | cursor->gotoPreviousLetter(); | 2705 | cursor->gotoPreviousLetter(); |
2729 | if ( cursor->isValid() ) | 2706 | if ( cursor->isValid() ) |
2730 | didGoLeft = TRUE; | 2707 | didGoLeft = TRUE; |
2731 | } | 2708 | } |
2732 | 2709 | ||
2733 | c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() ); | 2710 | c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() ); |
2734 | QTextParagraph *p = c1.paragraph()->next(); | 2711 | QTextParagraph *p = c1.paragraph()->next(); |
2735 | int dy = 0; | 2712 | int dy = 0; |
2736 | QTextParagraph *tmp; | 2713 | QTextParagraph *tmp; |
2737 | while ( p && p != c2.paragraph() ) { | 2714 | while ( p && p != c2.paragraph() ) { |
2738 | tmp = p->next(); | 2715 | tmp = p->next(); |
2739 | dy -= p->rect().height(); | 2716 | dy -= p->rect().height(); |
2740 | delete p; | 2717 | delete p; |
2741 | p = tmp; | 2718 | p = tmp; |
2742 | } | 2719 | } |
2743 | c2.paragraph()->remove( 0, c2.index() ); | 2720 | c2.paragraph()->remove( 0, c2.index() ); |
2744 | while ( p ) { | 2721 | while ( p ) { |
2745 | p->move( dy ); | 2722 | p->move( dy ); |
2746 | p->invalidate( 0 ); | 2723 | p->invalidate( 0 ); |
2747 | p->setEndState( -1 ); | 2724 | p->setEndState( -1 ); |
2748 | p = p->next(); | 2725 | p = p->next(); |
2749 | } | 2726 | } |
2750 | 2727 | ||
2751 | c1.paragraph()->join( c2.paragraph() ); | 2728 | c1.paragraph()->join( c2.paragraph() ); |
2752 | 2729 | ||
2753 | if ( didGoLeft ) | 2730 | if ( didGoLeft ) |
2754 | cursor->gotoNextLetter(); | 2731 | cursor->gotoNextLetter(); |
2755 | } | 2732 | } |
2756 | 2733 | ||
2757 | void QTextDocument::indentSelection( int id ) | 2734 | void QTextDocument::indentSelection( int id ) |
2758 | { | 2735 | { |
2759 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2736 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2760 | if ( it == selections.end() ) | 2737 | if ( it == selections.end() ) |
2761 | return; | 2738 | return; |
2762 | 2739 | ||
2763 | QTextDocumentSelection sel = *it; | 2740 | QTextDocumentSelection sel = *it; |
2764 | QTextParagraph *startParag = sel.startCursor.paragraph(); | 2741 | QTextParagraph *startParag = sel.startCursor.paragraph(); |
2765 | QTextParagraph *endParag = sel.endCursor.paragraph(); | 2742 | QTextParagraph *endParag = sel.endCursor.paragraph(); |
2766 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { | 2743 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { |
2767 | endParag = sel.startCursor.paragraph(); | 2744 | endParag = sel.startCursor.paragraph(); |
2768 | startParag = sel.endCursor.paragraph(); | 2745 | startParag = sel.endCursor.paragraph(); |
2769 | } | 2746 | } |
2770 | 2747 | ||
2771 | QTextParagraph *p = startParag; | 2748 | QTextParagraph *p = startParag; |
2772 | while ( p && p != endParag ) { | 2749 | while ( p && p != endParag ) { |
2773 | p->indent(); | 2750 | p->indent(); |
2774 | p = p->next(); | 2751 | p = p->next(); |
2775 | } | 2752 | } |
2776 | } | 2753 | } |
2777 | 2754 | ||
2778 | void QTextDocument::addCommand( QTextCommand *cmd ) | 2755 | void QTextDocument::addCommand( QTextCommand *cmd ) |
2779 | { | 2756 | { |
2780 | commandHistory->addCommand( cmd ); | 2757 | commandHistory->addCommand( cmd ); |
2781 | } | 2758 | } |
2782 | 2759 | ||
2783 | QTextCursor *QTextDocument::undo( QTextCursor *c ) | 2760 | QTextCursor *QTextDocument::undo( QTextCursor *c ) |
2784 | { | 2761 | { |
2785 | return commandHistory->undo( c ); | 2762 | return commandHistory->undo( c ); |
2786 | } | 2763 | } |
2787 | 2764 | ||
2788 | QTextCursor *QTextDocument::redo( QTextCursor *c ) | 2765 | QTextCursor *QTextDocument::redo( QTextCursor *c ) |
2789 | { | 2766 | { |
2790 | return commandHistory->redo( c ); | 2767 | return commandHistory->redo( c ); |
2791 | } | 2768 | } |
2792 | 2769 | ||
2793 | bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward ) | 2770 | bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward ) |
2794 | { | 2771 | { |
2795 | removeSelection( Standard ); | 2772 | removeSelection( Standard ); |
2796 | QTextParagraph *p = 0; | 2773 | QTextParagraph *p = 0; |
2797 | QString expr = e; | 2774 | QString expr = e; |
2798 | // if we search for 'word only' than we have to be sure that | 2775 | // if we search for 'word only' than we have to be sure that |
2799 | // the expression contains no space or punct character at the | 2776 | // the expression contains no space or punct character at the |
2800 | // beginning or in the end. Otherwise we would run into a | 2777 | // beginning or in the end. Otherwise we would run into a |
2801 | // endlessloop. | 2778 | // endlessloop. |
2802 | if ( wo ) { | 2779 | if ( wo ) { |
2803 | for ( ;; ) { | 2780 | for ( ;; ) { |
2804 | if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() ) | 2781 | if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() ) |
2805 | expr = expr.right( expr.length() - 1 ); | 2782 | expr = expr.right( expr.length() - 1 ); |
2806 | else | 2783 | else |
2807 | break; | 2784 | break; |
2808 | } | 2785 | } |
2809 | for ( ;; ) { | 2786 | for ( ;; ) { |
2810 | if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() ) | 2787 | if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() ) |
2811 | expr = expr.left( expr.length() - 1 ); | 2788 | expr = expr.left( expr.length() - 1 ); |
2812 | else | 2789 | else |
2813 | break; | 2790 | break; |
2814 | } | 2791 | } |
2815 | } | 2792 | } |
2816 | for (;;) { | 2793 | for (;;) { |
2817 | if ( p != cursor.paragraph() ) { | 2794 | if ( p != cursor.paragraph() ) { |
2818 | p = cursor.paragraph(); | 2795 | p = cursor.paragraph(); |
2819 | QString s = cursor.paragraph()->string()->toString(); | 2796 | QString s = cursor.paragraph()->string()->toString(); |
2820 | int start = cursor.index(); | 2797 | int start = cursor.index(); |
2821 | for ( ;; ) { | 2798 | for ( ;; ) { |
2822 | int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); | 2799 | int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); |
2823 | int end = res + expr.length(); | 2800 | int end = res + expr.length(); |
2824 | if ( res == -1 || ( !forward && start < end ) ) | 2801 | if ( res == -1 || ( !forward && start < end ) ) |
2825 | break; | 2802 | break; |
2826 | if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && | 2803 | if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && |
2827 | ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) { | 2804 | ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) { |
2828 | removeSelection( Standard ); | 2805 | removeSelection( Standard ); |
2829 | cursor.setIndex( forward ? end : res ); | 2806 | cursor.setIndex( forward ? end : res ); |
2830 | setSelectionStart( Standard, cursor ); | 2807 | setSelectionStart( Standard, cursor ); |
2831 | cursor.setIndex( forward ? res : end ); | 2808 | cursor.setIndex( forward ? res : end ); |
2832 | setSelectionEnd( Standard, cursor ); | 2809 | setSelectionEnd( Standard, cursor ); |
2833 | return TRUE; | 2810 | return TRUE; |
2834 | } | 2811 | } |
2835 | start = res + (forward ? 1 : -1); | 2812 | start = res + (forward ? 1 : -1); |
2836 | } | 2813 | } |
2837 | } | 2814 | } |
2838 | if ( forward ) { | 2815 | if ( forward ) { |
2839 | if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () ) | 2816 | if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () ) |
2840 | break; | 2817 | break; |
2841 | cursor.gotoNextLetter(); | 2818 | cursor.gotoNextLetter(); |
2842 | } else { | 2819 | } else { |
2843 | if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() ) | 2820 | if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() ) |
2844 | break; | 2821 | break; |
2845 | cursor.gotoPreviousLetter(); | 2822 | cursor.gotoPreviousLetter(); |
2846 | } | 2823 | } |
2847 | } | 2824 | } |
2848 | return FALSE; | 2825 | return FALSE; |
2849 | } | 2826 | } |
2850 | 2827 | ||
2851 | void QTextDocument::setTextFormat( Qt::TextFormat f ) | 2828 | void QTextDocument::setTextFormat( Qt::TextFormat f ) |
2852 | { | 2829 | { |
2853 | txtFormat = f; | 2830 | txtFormat = f; |
2854 | if ( fParag == lParag && fParag->length() <= 1 ) | 2831 | if ( fParag == lParag && fParag->length() <= 1 ) |
2855 | fParag->rtext = ( f == Qt::RichText ); | 2832 | fParag->rtext = ( f == Qt::RichText ); |
2856 | } | 2833 | } |
2857 | 2834 | ||
2858 | Qt::TextFormat QTextDocument::textFormat() const | 2835 | Qt::TextFormat QTextDocument::textFormat() const |
2859 | { | 2836 | { |
2860 | return txtFormat; | 2837 | return txtFormat; |
2861 | } | 2838 | } |
2862 | 2839 | ||
2863 | bool QTextDocument::inSelection( int selId, const QPoint &pos ) const | 2840 | bool QTextDocument::inSelection( int selId, const QPoint &pos ) const |
2864 | { | 2841 | { |
2865 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId ); | 2842 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId ); |
2866 | if ( it == selections.end() ) | 2843 | if ( it == selections.end() ) |
2867 | return FALSE; | 2844 | return FALSE; |
2868 | 2845 | ||
2869 | QTextDocumentSelection sel = *it; | 2846 | QTextDocumentSelection sel = *it; |
2870 | QTextParagraph *startParag = sel.startCursor.paragraph(); | 2847 | QTextParagraph *startParag = sel.startCursor.paragraph(); |
2871 | QTextParagraph *endParag = sel.endCursor.paragraph(); | 2848 | QTextParagraph *endParag = sel.endCursor.paragraph(); |
2872 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() && | 2849 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() && |
2873 | sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) ) | 2850 | sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) ) |
2874 | return FALSE; | 2851 | return FALSE; |
2875 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { | 2852 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { |
2876 | endParag = sel.startCursor.paragraph(); | 2853 | endParag = sel.startCursor.paragraph(); |
2877 | startParag = sel.endCursor.paragraph(); | 2854 | startParag = sel.endCursor.paragraph(); |
2878 | } | 2855 | } |
2879 | 2856 | ||
2880 | QTextParagraph *p = startParag; | 2857 | QTextParagraph *p = startParag; |
2881 | while ( p ) { | 2858 | while ( p ) { |
2882 | if ( p->rect().contains( pos ) ) { | 2859 | if ( p->rect().contains( pos ) ) { |
2883 | bool inSel = FALSE; | 2860 | bool inSel = FALSE; |
2884 | int selStart = p->selectionStart( selId ); | 2861 | int selStart = p->selectionStart( selId ); |
2885 | int selEnd = p->selectionEnd( selId ); | 2862 | int selEnd = p->selectionEnd( selId ); |
2886 | int y = 0; | 2863 | int y = 0; |
2887 | int h = 0; | 2864 | int h = 0; |
2888 | for ( int i = 0; i < p->length(); ++i ) { | 2865 | for ( int i = 0; i < p->length(); ++i ) { |
2889 | if ( i == selStart ) | 2866 | if ( i == selStart ) |
2890 | inSel = TRUE; | 2867 | inSel = TRUE; |
2891 | if ( i == selEnd ) | 2868 | if ( i == selEnd ) |
2892 | break; | 2869 | break; |
2893 | if ( p->at( i )->lineStart ) { | 2870 | if ( p->at( i )->lineStart ) { |
2894 | y = (*p->lineStarts.find( i ))->y; | 2871 | y = (*p->lineStarts.find( i ))->y; |
2895 | h = (*p->lineStarts.find( i ))->h; | 2872 | h = (*p->lineStarts.find( i ))->h; |
2896 | } | 2873 | } |
2897 | if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) { | 2874 | if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) { |
2898 | if ( inSel && pos.x() >= p->at( i )->x && | 2875 | if ( inSel && pos.x() >= p->at( i )->x && |
2899 | pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) ) | 2876 | pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) ) |
2900 | return TRUE; | 2877 | return TRUE; |
2901 | } | 2878 | } |
2902 | } | 2879 | } |
2903 | } | 2880 | } |
2904 | if ( pos.y() < p->rect().y() ) | 2881 | if ( pos.y() < p->rect().y() ) |
2905 | break; | 2882 | break; |
2906 | if ( p == endParag ) | 2883 | if ( p == endParag ) |
2907 | break; | 2884 | break; |
2908 | p = p->next(); | 2885 | p = p->next(); |
2909 | } | 2886 | } |
2910 | 2887 | ||
2911 | return FALSE; | 2888 | return FALSE; |
2912 | } | 2889 | } |
2913 | 2890 | ||
2914 | void QTextDocument::doLayout( QPainter *p, int w ) | 2891 | void QTextDocument::doLayout( QPainter *p, int w ) |
2915 | { | 2892 | { |
2916 | minw = wused = 0; | 2893 | minw = wused = 0; |
2917 | if ( !is_printer( p ) ) | 2894 | if ( !is_printer( p ) ) |
2918 | p = 0; | 2895 | p = 0; |
2919 | withoutDoubleBuffer = ( p != 0 ); | 2896 | withoutDoubleBuffer = ( p != 0 ); |
2920 | QPainter * oldPainter = QTextFormat::painter(); | 2897 | QPainter * oldPainter = QTextFormat::painter(); |
2921 | QTextFormat::setPainter( p ); | 2898 | QTextFormat::setPainter( p ); |
2922 | flow_->setWidth( w ); | 2899 | flow_->setWidth( w ); |
2923 | cw = w; | 2900 | cw = w; |
2924 | vw = w; | 2901 | vw = w; |
2925 | QTextParagraph *parag = fParag; | 2902 | QTextParagraph *parag = fParag; |
2926 | while ( parag ) { | 2903 | while ( parag ) { |
2927 | parag->invalidate( 0 ); | 2904 | parag->invalidate( 0 ); |
2928 | if ( p ) | 2905 | if ( p ) |
2929 | parag->adjustToPainter( p ); | 2906 | parag->adjustToPainter( p ); |
2930 | parag->format(); | 2907 | parag->format(); |
2931 | parag = parag->next(); | 2908 | parag = parag->next(); |
2932 | } | 2909 | } |
2933 | QTextFormat::setPainter( oldPainter ); | 2910 | QTextFormat::setPainter( oldPainter ); |
2934 | } | 2911 | } |
2935 | 2912 | ||
2936 | QPixmap *QTextDocument::bufferPixmap( const QSize &s ) | 2913 | QPixmap *QTextDocument::bufferPixmap( const QSize &s ) |
2937 | { | 2914 | { |
2938 | if ( !buf_pixmap ) | 2915 | if ( !buf_pixmap ) |
2939 | buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) ); | 2916 | buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) ); |
2940 | else if ( buf_pixmap->size() != s ) | 2917 | else if ( buf_pixmap->size() != s ) |
2941 | buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) ); | 2918 | buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) ); |
2942 | return buf_pixmap; | 2919 | return buf_pixmap; |
2943 | } | 2920 | } |
2944 | 2921 | ||
2945 | void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) | 2922 | void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) |
2946 | { | 2923 | { |
2947 | if ( !firstParagraph() ) | 2924 | if ( !firstParagraph() ) |
2948 | return; | 2925 | return; |
2949 | 2926 | ||
2950 | if ( paper ) { | 2927 | if ( paper ) { |
2951 | p->setBrushOrigin( 0, 0 ); | 2928 | p->setBrushOrigin( 0, 0 ); |
2952 | 2929 | ||
2953 | p->fillRect( rect, *paper ); | 2930 | p->fillRect( rect, *paper ); |
2954 | } | 2931 | } |
2955 | 2932 | ||
2956 | if ( formatCollection()->defaultFormat()->color() != cg.text() ) | 2933 | if ( formatCollection()->defaultFormat()->color() != cg.text() ) |
2957 | setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() ); | 2934 | setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() ); |
2958 | 2935 | ||
2959 | QTextParagraph *parag = firstParagraph(); | 2936 | QTextParagraph *parag = firstParagraph(); |
2960 | while ( parag ) { | 2937 | while ( parag ) { |
2961 | if ( !parag->isValid() ) | 2938 | if ( !parag->isValid() ) |
2962 | parag->format(); | 2939 | parag->format(); |
2963 | int y = parag->rect().y(); | 2940 | int y = parag->rect().y(); |
2964 | QRect pr( parag->rect() ); | 2941 | QRect pr( parag->rect() ); |
2965 | pr.setX( 0 ); | 2942 | pr.setX( 0 ); |
2966 | pr.setWidth( QWIDGETSIZE_MAX ); | 2943 | pr.setWidth( QWIDGETSIZE_MAX ); |
2967 | if ( !rect.isNull() && !rect.intersects( pr ) ) { | 2944 | if ( !rect.isNull() && !rect.intersects( pr ) ) { |
2968 | parag = parag->next(); | 2945 | parag = parag->next(); |
2969 | continue; | 2946 | continue; |
2970 | } | 2947 | } |
2971 | p->translate( 0, y ); | 2948 | p->translate( 0, y ); |
2972 | if ( rect.isValid() ) | 2949 | if ( rect.isValid() ) |
2973 | parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() ); | 2950 | parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() ); |
2974 | else | 2951 | else |
2975 | parag->paint( *p, cg, 0, FALSE ); | 2952 | parag->paint( *p, cg, 0, FALSE ); |
2976 | p->translate( 0, -y ); | 2953 | p->translate( 0, -y ); |
2977 | parag = parag->next(); | 2954 | parag = parag->next(); |
2978 | if ( !flow()->isEmpty() ) | 2955 | if ( !flow()->isEmpty() ) |
2979 | flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE ); | 2956 | flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE ); |
2980 | } | 2957 | } |
2981 | } | 2958 | } |
2982 | 2959 | ||
2983 | void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, | 2960 | void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, |
2984 | QPixmap *&doubleBuffer, const QColorGroup &cg, | 2961 | QPixmap *&doubleBuffer, const QColorGroup &cg, |
2985 | bool drawCursor, QTextCursor *cursor, bool resetChanged ) | 2962 | bool drawCursor, QTextCursor *cursor, bool resetChanged ) |
2986 | { | 2963 | { |
2987 | QPainter *painter = 0; | 2964 | QPainter *painter = 0; |
2988 | if ( resetChanged ) | 2965 | if ( resetChanged ) |
2989 | parag->setChanged( FALSE ); | 2966 | parag->setChanged( FALSE ); |
2990 | QRect ir( parag->rect() ); | 2967 | QRect ir( parag->rect() ); |
2991 | bool useDoubleBuffer = !parag->document()->parent(); | 2968 | bool useDoubleBuffer = !parag->document()->parent(); |
2992 | if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered ) | 2969 | if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered ) |
2993 | useDoubleBuffer = TRUE; | 2970 | useDoubleBuffer = TRUE; |
2994 | if ( is_printer( p ) ) | 2971 | if ( is_printer( p ) ) |
2995 | useDoubleBuffer = FALSE; | 2972 | useDoubleBuffer = FALSE; |
2996 | 2973 | ||
2997 | if ( useDoubleBuffer ) { | 2974 | if ( useDoubleBuffer ) { |
2998 | painter = new QPainter; | 2975 | painter = new QPainter; |
2999 | if ( cx >= 0 && cy >= 0 ) | 2976 | if ( cx >= 0 && cy >= 0 ) |
3000 | ir = ir.intersect( QRect( cx, cy, cw, ch ) ); | 2977 | ir = ir.intersect( QRect( cx, cy, cw, ch ) ); |
3001 | if ( !doubleBuffer || | 2978 | if ( !doubleBuffer || |
3002 | ir.width() > doubleBuffer->width() || | 2979 | ir.width() > doubleBuffer->width() || |
3003 | ir.height() > doubleBuffer->height() ) { | 2980 | ir.height() > doubleBuffer->height() ) { |
3004 | doubleBuffer = bufferPixmap( ir.size() ); | 2981 | doubleBuffer = bufferPixmap( ir.size() ); |
3005 | painter->begin( doubleBuffer ); | 2982 | painter->begin( doubleBuffer ); |
3006 | } else { | 2983 | } else { |
3007 | painter->begin( doubleBuffer ); | 2984 | painter->begin( doubleBuffer ); |
3008 | } | 2985 | } |
3009 | } else { | 2986 | } else { |
3010 | painter = p; | 2987 | painter = p; |
3011 | painter->translate( ir.x(), ir.y() ); | 2988 | painter->translate( ir.x(), ir.y() ); |
3012 | } | 2989 | } |
3013 | 2990 | ||
3014 | painter->setBrushOrigin( -ir.x(), -ir.y() ); | 2991 | painter->setBrushOrigin( -ir.x(), -ir.y() ); |
3015 | 2992 | ||
3016 | if ( useDoubleBuffer || is_printer( painter ) ) | 2993 | if ( useDoubleBuffer || is_printer( painter ) ) |
3017 | painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) ); | 2994 | painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) ); |
3018 | else if ( cursor && cursor->paragraph() == parag ) | 2995 | else if ( cursor && cursor->paragraph() == parag ) |
3019 | painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ), | 2996 | painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ), |
3020 | parag->backgroundBrush( cg ) ); | 2997 | parag->backgroundBrush( cg ) ); |
3021 | 2998 | ||
3022 | painter->translate( -( ir.x() - parag->rect().x() ), | 2999 | painter->translate( -( ir.x() - parag->rect().x() ), |
3023 | -( ir.y() - parag->rect().y() ) ); | 3000 | -( ir.y() - parag->rect().y() ) ); |
3024 | parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch ); | 3001 | parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch ); |
3025 | 3002 | ||
3026 | if ( useDoubleBuffer ) { | 3003 | if ( useDoubleBuffer ) { |
3027 | delete painter; | 3004 | delete painter; |
3028 | painter = 0; | 3005 | painter = 0; |
3029 | p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) ); | 3006 | p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) ); |
3030 | } else { | 3007 | } else { |
3031 | painter->translate( -ir.x(), -ir.y() ); | 3008 | painter->translate( -ir.x(), -ir.y() ); |
3032 | } | 3009 | } |
3033 | 3010 | ||
3034 | if ( useDoubleBuffer ) { | 3011 | if ( useDoubleBuffer ) { |
3035 | if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { | 3012 | if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { |
3036 | p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(), | 3013 | p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(), |
3037 | ( parag->document()->x() + parag->document()->width() ) - | 3014 | ( parag->document()->x() + parag->document()->width() ) - |
3038 | ( parag->rect().x() + parag->rect().width() ), | 3015 | ( parag->rect().x() + parag->rect().width() ), |
3039 | parag->rect().height(), cg.brush( QColorGroup::Base ) ); | 3016 | parag->rect().height(), cg.brush( QColorGroup::Base ) ); |
3040 | } | 3017 | } |
3041 | } | 3018 | } |
3042 | 3019 | ||
3043 | parag->document()->nextDoubleBuffered = FALSE; | 3020 | parag->document()->nextDoubleBuffered = FALSE; |
3044 | } | 3021 | } |
3045 | 3022 | ||
3046 | QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, | 3023 | QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, |
3047 | bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) | 3024 | bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) |
3048 | { | 3025 | { |
3049 | if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { | 3026 | if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { |
3050 | withoutDoubleBuffer = TRUE; | 3027 | withoutDoubleBuffer = TRUE; |
3051 | QRect r; | 3028 | QRect r; |
3052 | draw( p, r, cg ); | 3029 | draw( p, r, cg ); |
3053 | return 0; | 3030 | return 0; |
3054 | } | 3031 | } |
3055 | withoutDoubleBuffer = FALSE; | 3032 | withoutDoubleBuffer = FALSE; |
3056 | 3033 | ||
3057 | if ( !firstParagraph() ) | 3034 | if ( !firstParagraph() ) |
3058 | return 0; | 3035 | return 0; |
3059 | 3036 | ||
3060 | if ( cx < 0 && cy < 0 ) { | 3037 | if ( cx < 0 && cy < 0 ) { |
3061 | cx = 0; | 3038 | cx = 0; |
3062 | cy = 0; | 3039 | cy = 0; |
3063 | cw = width(); | 3040 | cw = width(); |
3064 | ch = height(); | 3041 | ch = height(); |
3065 | } | 3042 | } |
3066 | 3043 | ||
3067 | QTextParagraph *lastFormatted = 0; | 3044 | QTextParagraph *lastFormatted = 0; |
3068 | QTextParagraph *parag = firstParagraph(); | 3045 | QTextParagraph *parag = firstParagraph(); |
3069 | 3046 | ||
3070 | QPixmap *doubleBuffer = 0; | 3047 | QPixmap *doubleBuffer = 0; |
3071 | QPainter painter; | 3048 | QPainter painter; |
3072 | 3049 | ||
3073 | bool fullWidthSelection = FALSE; | ||
3074 | while ( parag ) { | 3050 | while ( parag ) { |
3075 | lastFormatted = parag; | 3051 | lastFormatted = parag; |
3076 | if ( !parag->isValid() ) | 3052 | if ( !parag->isValid() ) |
3077 | parag->format(); | 3053 | parag->format(); |
3078 | 3054 | ||
3079 | QRect pr = parag->rect(); | 3055 | QRect pr = parag->rect(); |
3080 | if ( fullWidthSelection ) | ||
3081 | pr.setWidth( parag->document()->width() ); | ||
3082 | if ( pr.y() > cy + ch ) | 3056 | if ( pr.y() > cy + ch ) |
3083 | goto floating; | 3057 | goto floating; |
3084 | if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) { | 3058 | if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) { |
3085 | parag = parag->next(); | 3059 | parag = parag->next(); |
3086 | continue; | 3060 | continue; |
3087 | } | 3061 | } |
3088 | 3062 | ||
3089 | drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); | 3063 | drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); |
3090 | parag = parag->next(); | 3064 | parag = parag->next(); |
3091 | } | 3065 | } |
3092 | 3066 | ||
3093 | parag = lastParagraph(); | 3067 | parag = lastParagraph(); |
3094 | 3068 | ||
3095 | floating: | 3069 | floating: |
3096 | if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { | 3070 | if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { |
3097 | if ( !parag->document()->parent() ) { | 3071 | if ( !parag->document()->parent() ) { |
3098 | p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), | 3072 | p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), |
3099 | parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), | 3073 | parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), |
3100 | cg.brush( QColorGroup::Base ) ); | 3074 | cg.brush( QColorGroup::Base ) ); |
3101 | } | 3075 | } |
3102 | if ( !flow()->isEmpty() ) { | 3076 | if ( !flow()->isEmpty() ) { |
3103 | QRect cr( cx, cy, cw, ch ); | 3077 | QRect cr( cx, cy, cw, ch ); |
3104 | flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); | 3078 | flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); |
3105 | } | 3079 | } |
3106 | } | 3080 | } |
3107 | 3081 | ||
3108 | if ( buf_pixmap && buf_pixmap->height() > 300 ) { | 3082 | if ( buf_pixmap && buf_pixmap->height() > 300 ) { |
3109 | delete buf_pixmap; | 3083 | delete buf_pixmap; |
3110 | buf_pixmap = 0; | 3084 | buf_pixmap = 0; |
3111 | } | 3085 | } |
3112 | 3086 | ||
3113 | return lastFormatted; | 3087 | return lastFormatted; |
3114 | } | 3088 | } |
3115 | 3089 | ||
3116 | /* | 3090 | /* |
3117 | #### this function only sets the default font size in the format collection | 3091 | #### this function only sets the default font size in the format collection |
3118 | */ | 3092 | */ |
3119 | void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) | 3093 | void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) |
3120 | { | 3094 | { |
3121 | bool reformat = font != fCollection->defaultFormat()->font(); | 3095 | bool reformat = font != fCollection->defaultFormat()->font(); |
3122 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 3096 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
3123 | d->setDefaultFormat( font, color ); | 3097 | d->setDefaultFormat( font, color ); |
3124 | fCollection->updateDefaultFormat( font, color, sheet_ ); | 3098 | fCollection->updateDefaultFormat( font, color, sheet_ ); |
3125 | 3099 | ||
3126 | if ( !reformat ) | 3100 | if ( !reformat ) |
3127 | return; | 3101 | return; |
3128 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; | 3102 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; |
3129 | 3103 | ||
3130 | // invalidate paragraphs and custom items | 3104 | // invalidate paragraphs and custom items |
3131 | QTextParagraph *p = fParag; | 3105 | QTextParagraph *p = fParag; |
3132 | while ( p ) { | 3106 | while ( p ) { |
3133 | p->invalidate( 0 ); | 3107 | p->invalidate( 0 ); |
3134 | for ( int i = 0; i < p->length() - 1; ++i ) | 3108 | for ( int i = 0; i < p->length() - 1; ++i ) |
3135 | if ( p->at( i )->isCustom() ) | 3109 | if ( p->at( i )->isCustom() ) |
3136 | p->at( i )->customItem()->invalidate(); | 3110 | p->at( i )->customItem()->invalidate(); |
3137 | p = p->next(); | 3111 | p = p->next(); |
3138 | } | 3112 | } |
3139 | } | 3113 | } |
3140 | 3114 | ||
3141 | void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) | 3115 | void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) |
3142 | { | 3116 | { |
3143 | if ( i && i->placement() != QTextCustomItem::PlaceInline ) { | 3117 | if ( i && i->placement() != QTextCustomItem::PlaceInline ) { |
3144 | flow_->registerFloatingItem( i ); | 3118 | flow_->registerFloatingItem( i ); |
3145 | p->registerFloatingItem( i ); | 3119 | p->registerFloatingItem( i ); |
3146 | i->setParagraph( p ); | 3120 | i->setParagraph( p ); |
3147 | } | 3121 | } |
3148 | p->mightHaveCustomItems = mightHaveCustomItems = TRUE; | 3122 | p->mightHaveCustomItems = mightHaveCustomItems = TRUE; |
3149 | } | 3123 | } |
3150 | 3124 | ||
3151 | void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) | 3125 | void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) |
3152 | { | 3126 | { |
3153 | flow_->unregisterFloatingItem( i ); | 3127 | flow_->unregisterFloatingItem( i ); |
3154 | p->unregisterFloatingItem( i ); | 3128 | p->unregisterFloatingItem( i ); |
3155 | i->setParagraph( 0 ); | 3129 | i->setParagraph( 0 ); |
3156 | } | 3130 | } |
3157 | 3131 | ||
3158 | bool QTextDocument::hasFocusParagraph() const | 3132 | bool QTextDocument::hasFocusParagraph() const |
3159 | { | 3133 | { |
3160 | return !!focusIndicator.parag; | 3134 | return !!focusIndicator.parag; |
3161 | } | 3135 | } |
3162 | 3136 | ||
3163 | QString QTextDocument::focusHref() const | 3137 | QString QTextDocument::focusHref() const |
3164 | { | 3138 | { |
3165 | return focusIndicator.href; | 3139 | return focusIndicator.href; |
3166 | } | 3140 | } |
3167 | 3141 | ||
3168 | bool QTextDocument::focusNextPrevChild( bool next ) | 3142 | bool QTextDocument::focusNextPrevChild( bool next ) |
3169 | { | 3143 | { |
3170 | if ( !focusIndicator.parag ) { | 3144 | if ( !focusIndicator.parag ) { |
3171 | if ( next ) { | 3145 | if ( next ) { |
3172 | focusIndicator.parag = fParag; | 3146 | focusIndicator.parag = fParag; |
3173 | focusIndicator.start = 0; | 3147 | focusIndicator.start = 0; |
3174 | focusIndicator.len = 0; | 3148 | focusIndicator.len = 0; |
3175 | } else { | 3149 | } else { |
3176 | focusIndicator.parag = lParag; | 3150 | focusIndicator.parag = lParag; |
3177 | focusIndicator.start = lParag->length(); | 3151 | focusIndicator.start = lParag->length(); |
3178 | focusIndicator.len = 0; | 3152 | focusIndicator.len = 0; |
3179 | } | 3153 | } |
3180 | } else { | 3154 | } else { |
3181 | focusIndicator.parag->setChanged( TRUE ); | 3155 | focusIndicator.parag->setChanged( TRUE ); |
3182 | } | 3156 | } |
3183 | focusIndicator.href = QString::null; | 3157 | focusIndicator.href = QString::null; |
3184 | 3158 | ||
3185 | if ( next ) { | 3159 | if ( next ) { |
3186 | QTextParagraph *p = focusIndicator.parag; | 3160 | QTextParagraph *p = focusIndicator.parag; |
3187 | int index = focusIndicator.start + focusIndicator.len; | 3161 | int index = focusIndicator.start + focusIndicator.len; |
3188 | while ( p ) { | 3162 | while ( p ) { |
3189 | for ( int i = index; i < p->length(); ++i ) { | 3163 | for ( int i = index; i < p->length(); ++i ) { |
3190 | if ( p->at( i )->isAnchor() ) { | 3164 | if ( p->at( i )->isAnchor() ) { |
3191 | p->setChanged( TRUE ); | 3165 | p->setChanged( TRUE ); |
3192 | focusIndicator.parag = p; | 3166 | focusIndicator.parag = p; |
3193 | focusIndicator.start = i; | 3167 | focusIndicator.start = i; |
3194 | focusIndicator.len = 0; | 3168 | focusIndicator.len = 0; |
3195 | focusIndicator.href = p->at( i )->anchorHref(); | 3169 | focusIndicator.href = p->at( i )->anchorHref(); |
3196 | while ( i < p->length() ) { | 3170 | while ( i < p->length() ) { |
3197 | if ( !p->at( i )->isAnchor() ) | 3171 | if ( !p->at( i )->isAnchor() ) |
3198 | return TRUE; | 3172 | return TRUE; |
3199 | focusIndicator.len++; | 3173 | focusIndicator.len++; |
3200 | i++; | 3174 | i++; |
3201 | } | 3175 | } |
3202 | } else if ( p->at( i )->isCustom() ) { | 3176 | } else if ( p->at( i )->isCustom() ) { |
3203 | if ( p->at( i )->customItem()->isNested() ) { | 3177 | if ( p->at( i )->customItem()->isNested() ) { |
3204 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 3178 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
3205 | QPtrList<QTextTableCell> cells = t->tableCells(); | 3179 | QPtrList<QTextTableCell> cells = t->tableCells(); |
3206 | // first try to continue | 3180 | // first try to continue |
3207 | QTextTableCell *c; | 3181 | QTextTableCell *c; |
3208 | bool resetCells = TRUE; | 3182 | bool resetCells = TRUE; |
3209 | for ( c = cells.first(); c; c = cells.next() ) { | 3183 | for ( c = cells.first(); c; c = cells.next() ) { |
3210 | if ( c->richText()->hasFocusParagraph() ) { | 3184 | if ( c->richText()->hasFocusParagraph() ) { |
3211 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3185 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3212 | p->setChanged( TRUE ); | 3186 | p->setChanged( TRUE ); |
3213 | focusIndicator.parag = p; | 3187 | focusIndicator.parag = p; |
3214 | focusIndicator.start = i; | 3188 | focusIndicator.start = i; |
3215 | focusIndicator.len = 0; | 3189 | focusIndicator.len = 0; |
3216 | focusIndicator.href = c->richText()->focusHref(); | 3190 | focusIndicator.href = c->richText()->focusHref(); |
3217 | return TRUE; | 3191 | return TRUE; |
3218 | } else { | 3192 | } else { |
3219 | resetCells = FALSE; | 3193 | resetCells = FALSE; |
3220 | c = cells.next(); | 3194 | c = cells.next(); |
3221 | break; | 3195 | break; |
3222 | } | 3196 | } |
3223 | } | 3197 | } |
3224 | } | 3198 | } |
3225 | // now really try | 3199 | // now really try |
3226 | if ( resetCells ) | 3200 | if ( resetCells ) |
3227 | c = cells.first(); | 3201 | c = cells.first(); |
3228 | for ( ; c; c = cells.next() ) { | 3202 | for ( ; c; c = cells.next() ) { |
3229 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3203 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3230 | p->setChanged( TRUE ); | 3204 | p->setChanged( TRUE ); |
3231 | focusIndicator.parag = p; | 3205 | focusIndicator.parag = p; |
3232 | focusIndicator.start = i; | 3206 | focusIndicator.start = i; |
3233 | focusIndicator.len = 0; | 3207 | focusIndicator.len = 0; |
3234 | focusIndicator.href = c->richText()->focusHref(); | 3208 | focusIndicator.href = c->richText()->focusHref(); |
3235 | return TRUE; | 3209 | return TRUE; |
3236 | } | 3210 | } |
3237 | } | 3211 | } |
3238 | } | 3212 | } |
3239 | } | 3213 | } |
3240 | } | 3214 | } |
3241 | index = 0; | 3215 | index = 0; |
3242 | p = p->next(); | 3216 | p = p->next(); |
3243 | } | 3217 | } |
3244 | } else { | 3218 | } else { |
3245 | QTextParagraph *p = focusIndicator.parag; | 3219 | QTextParagraph *p = focusIndicator.parag; |
3246 | int index = focusIndicator.start - 1; | 3220 | int index = focusIndicator.start - 1; |
3247 | if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) | 3221 | if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) |
3248 | index++; | 3222 | index++; |
3249 | while ( p ) { | 3223 | while ( p ) { |
3250 | for ( int i = index; i >= 0; --i ) { | 3224 | for ( int i = index; i >= 0; --i ) { |
3251 | if ( p->at( i )->isAnchor() ) { | 3225 | if ( p->at( i )->isAnchor() ) { |
3252 | p->setChanged( TRUE ); | 3226 | p->setChanged( TRUE ); |
3253 | focusIndicator.parag = p; | 3227 | focusIndicator.parag = p; |
3254 | focusIndicator.start = i; | 3228 | focusIndicator.start = i; |
3255 | focusIndicator.len = 0; | 3229 | focusIndicator.len = 0; |
3256 | focusIndicator.href = p->at( i )->anchorHref(); | 3230 | focusIndicator.href = p->at( i )->anchorHref(); |
3257 | while ( i >= -1 ) { | 3231 | while ( i >= -1 ) { |
3258 | if ( i < 0 || !p->at( i )->isAnchor() ) { | 3232 | if ( i < 0 || !p->at( i )->isAnchor() ) { |
3259 | focusIndicator.start++; | 3233 | focusIndicator.start++; |
3260 | return TRUE; | 3234 | return TRUE; |
3261 | } | 3235 | } |
3262 | if ( i < 0 ) | 3236 | if ( i < 0 ) |
3263 | break; | 3237 | break; |
3264 | focusIndicator.len++; | 3238 | focusIndicator.len++; |
3265 | focusIndicator.start--; | 3239 | focusIndicator.start--; |
3266 | i--; | 3240 | i--; |
3267 | } | 3241 | } |
3268 | } else if ( p->at( i )->isCustom() ) { | 3242 | } else if ( p->at( i )->isCustom() ) { |
3269 | if ( p->at( i )->customItem()->isNested() ) { | 3243 | if ( p->at( i )->customItem()->isNested() ) { |
3270 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 3244 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
3271 | QPtrList<QTextTableCell> cells = t->tableCells(); | 3245 | QPtrList<QTextTableCell> cells = t->tableCells(); |
3272 | // first try to continue | 3246 | // first try to continue |
3273 | QTextTableCell *c; | 3247 | QTextTableCell *c; |
3274 | bool resetCells = TRUE; | 3248 | bool resetCells = TRUE; |
3275 | for ( c = cells.last(); c; c = cells.prev() ) { | 3249 | for ( c = cells.last(); c; c = cells.prev() ) { |
3276 | if ( c->richText()->hasFocusParagraph() ) { | 3250 | if ( c->richText()->hasFocusParagraph() ) { |
3277 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3251 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3278 | p->setChanged( TRUE ); | 3252 | p->setChanged( TRUE ); |
3279 | focusIndicator.parag = p; | 3253 | focusIndicator.parag = p; |
3280 | focusIndicator.start = i; | 3254 | focusIndicator.start = i; |
3281 | focusIndicator.len = 0; | 3255 | focusIndicator.len = 0; |
3282 | focusIndicator.href = c->richText()->focusHref(); | 3256 | focusIndicator.href = c->richText()->focusHref(); |
3283 | return TRUE; | 3257 | return TRUE; |
3284 | } else { | 3258 | } else { |
3285 | resetCells = FALSE; | 3259 | resetCells = FALSE; |
3286 | c = cells.prev(); | 3260 | c = cells.prev(); |
3287 | break; | 3261 | break; |
3288 | } | 3262 | } |
3289 | } | 3263 | } |
3290 | if ( cells.at() == 0 ) | 3264 | if ( cells.at() == 0 ) |
3291 | break; | 3265 | break; |
3292 | } | 3266 | } |
3293 | // now really try | 3267 | // now really try |
3294 | if ( resetCells ) | 3268 | if ( resetCells ) |
3295 | c = cells.last(); | 3269 | c = cells.last(); |
3296 | for ( ; c; c = cells.prev() ) { | 3270 | for ( ; c; c = cells.prev() ) { |
3297 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3271 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3298 | p->setChanged( TRUE ); | 3272 | p->setChanged( TRUE ); |
3299 | focusIndicator.parag = p; | 3273 | focusIndicator.parag = p; |
3300 | focusIndicator.start = i; | 3274 | focusIndicator.start = i; |
3301 | focusIndicator.len = 0; | 3275 | focusIndicator.len = 0; |
3302 | focusIndicator.href = c->richText()->focusHref(); | 3276 | focusIndicator.href = c->richText()->focusHref(); |
3303 | return TRUE; | 3277 | return TRUE; |
3304 | } | 3278 | } |
3305 | if ( cells.at() == 0 ) | 3279 | if ( cells.at() == 0 ) |
3306 | break; | 3280 | break; |
3307 | } | 3281 | } |
3308 | } | 3282 | } |
3309 | } | 3283 | } |
3310 | } | 3284 | } |
3311 | p = p->prev(); | 3285 | p = p->prev(); |
3312 | if ( p ) | 3286 | if ( p ) |
3313 | index = p->length() - 1; | 3287 | index = p->length() - 1; |
3314 | } | 3288 | } |
3315 | } | 3289 | } |
3316 | 3290 | ||
3317 | focusIndicator.parag = 0; | 3291 | focusIndicator.parag = 0; |
3318 | 3292 | ||
3319 | return FALSE; | 3293 | return FALSE; |
3320 | } | 3294 | } |
3321 | 3295 | ||
3322 | int QTextDocument::length() const | 3296 | int QTextDocument::length() const |
3323 | { | 3297 | { |
3324 | int l = 0; | 3298 | int l = 0; |
3325 | QTextParagraph *p = fParag; | 3299 | QTextParagraph *p = fParag; |
3326 | while ( p ) { | 3300 | while ( p ) { |
3327 | l += p->length() - 1; // don't count trailing space | 3301 | l += p->length() - 1; // don't count trailing space |
3328 | p = p->next(); | 3302 | p = p->next(); |
3329 | } | 3303 | } |
3330 | return l; | 3304 | return l; |
3331 | } | 3305 | } |
3332 | 3306 | ||
3333 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3307 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3334 | 3308 | ||
3335 | int QTextFormat::width( const QChar &c ) const | 3309 | int QTextFormat::width( const QChar &c ) const |
3336 | { | 3310 | { |
3337 | if ( c.unicode() == 0xad ) // soft hyphen | 3311 | if ( c.unicode() == 0xad ) // soft hyphen |
3338 | return 0; | 3312 | return 0; |
3339 | if ( !pntr || !pntr->isActive() ) { | 3313 | if ( !pntr || !pntr->isActive() ) { |
3340 | if ( c == '\t' ) | 3314 | if ( c == '\t' ) |
3341 | return fm.width( 'x' ) * 8; | 3315 | return fm.width( 'x' ) * 8; |
3342 | if ( ha == AlignNormal ) { | 3316 | if ( ha == AlignNormal ) { |
3343 | int w; | 3317 | int w; |
3344 | if ( c.row() ) | 3318 | if ( c.row() ) |
3345 | w = fm.width( c ); | 3319 | w = fm.width( c ); |
3346 | else | 3320 | else |
3347 | w = widths[ c.unicode() ]; | 3321 | w = widths[ c.unicode() ]; |
3348 | if ( w == 0 && !c.row() ) { | 3322 | if ( w == 0 && !c.row() ) { |
3349 | w = fm.width( c ); | 3323 | w = fm.width( c ); |
3350 | ( (QTextFormat*)this )->widths[ c.unicode() ] = w; | 3324 | ( (QTextFormat*)this )->widths[ c.unicode() ] = w; |
3351 | } | 3325 | } |
3352 | return w; | 3326 | return w; |
3353 | } else { | 3327 | } else { |
3354 | QFont f( fn ); | 3328 | QFont f( fn ); |
3355 | if ( usePixelSizes ) | 3329 | if ( usePixelSizes ) |
3356 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3330 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3357 | else | 3331 | else |
3358 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3332 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3359 | QFontMetrics fm_( f ); | 3333 | QFontMetrics fm_( f ); |
3360 | return fm_.width( c ); | 3334 | return fm_.width( c ); |
3361 | } | 3335 | } |
3362 | } | 3336 | } |
3363 | 3337 | ||
3364 | QFont f( fn ); | 3338 | QFont f( fn ); |
3365 | if ( ha != AlignNormal ) { | 3339 | if ( ha != AlignNormal ) { |
3366 | if ( usePixelSizes ) | 3340 | if ( usePixelSizes ) |
3367 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3341 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3368 | else | 3342 | else |
3369 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3343 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3370 | } | 3344 | } |
3371 | pntr->setFont( f ); | 3345 | pntr->setFont( f ); |
3372 | 3346 | ||
3373 | return pntr->fontMetrics().width( c ); | 3347 | return pntr->fontMetrics().width( c ); |
3374 | } | 3348 | } |
3375 | 3349 | ||
3376 | int QTextFormat::width( const QString &str, int pos ) const | 3350 | int QTextFormat::width( const QString &str, int pos ) const |
3377 | { | 3351 | { |
3378 | int w = 0; | 3352 | int w = 0; |
3379 | if ( str[ pos ].unicode() == 0xad ) | 3353 | if ( str[ pos ].unicode() == 0xad ) |
3380 | return w; | 3354 | return w; |
3381 | if ( !pntr || !pntr->isActive() ) { | 3355 | if ( !pntr || !pntr->isActive() ) { |
3382 | if ( ha == AlignNormal ) { | 3356 | if ( ha == AlignNormal ) { |
3383 | w = fm.width( str[ pos ] ); | 3357 | w = fm.width( str[ pos ] ); |
3384 | } else { | 3358 | } else { |
3385 | QFont f( fn ); | 3359 | QFont f( fn ); |
3386 | if ( usePixelSizes ) | 3360 | if ( usePixelSizes ) |
3387 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3361 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3388 | else | 3362 | else |
3389 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3363 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3390 | QFontMetrics fm_( f ); | 3364 | QFontMetrics fm_( f ); |
3391 | w = fm_.width( str[ pos ] ); | 3365 | w = fm_.width( str[ pos ] ); |
3392 | } | 3366 | } |
3393 | } else { | 3367 | } else { |
3394 | QFont f( fn ); | 3368 | QFont f( fn ); |
3395 | if ( ha != AlignNormal ) { | 3369 | if ( ha != AlignNormal ) { |
3396 | if ( usePixelSizes ) | 3370 | if ( usePixelSizes ) |
3397 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3371 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3398 | else | 3372 | else |
3399 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3373 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3400 | } | 3374 | } |
3401 | pntr->setFont( f ); | 3375 | pntr->setFont( f ); |
3402 | w = pntr->fontMetrics().width( str[ pos ] ); | 3376 | w = pntr->fontMetrics().width( str[ pos ] ); |
3403 | } | 3377 | } |
3404 | return w; | 3378 | return w; |
3405 | } | 3379 | } |
3406 | 3380 | ||
3407 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3381 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3408 | 3382 | ||
3409 | QTextString::QTextString() | 3383 | QTextString::QTextString() |
3410 | { | 3384 | { |
3411 | bidiDirty = FALSE; | 3385 | bidiDirty = FALSE; |
3412 | bidi = FALSE; | 3386 | bidi = FALSE; |
3413 | rightToLeft = FALSE; | 3387 | rightToLeft = FALSE; |
3414 | dir = QChar::DirON; | 3388 | dir = QChar::DirON; |
3415 | } | 3389 | } |
3416 | 3390 | ||
3417 | QTextString::QTextString( const QTextString &s ) | 3391 | QTextString::QTextString( const QTextString &s ) |
3418 | { | 3392 | { |
3419 | bidiDirty = s.bidiDirty; | 3393 | bidiDirty = s.bidiDirty; |
3420 | bidi = s.bidi; | 3394 | bidi = s.bidi; |
3421 | rightToLeft = s.rightToLeft; | 3395 | rightToLeft = s.rightToLeft; |
3422 | dir = s.dir; | 3396 | dir = s.dir; |
3423 | data = s.subString(); | 3397 | data = s.subString(); |
3424 | } | 3398 | } |
3425 | 3399 | ||
3426 | void QTextString::insert( int index, const QString &s, QTextFormat *f ) | 3400 | void QTextString::insert( int index, const QString &s, QTextFormat *f ) |
3427 | { | 3401 | { |
3428 | insert( index, s.unicode(), s.length(), f ); | 3402 | insert( index, s.unicode(), s.length(), f ); |
3429 | } | 3403 | } |
3430 | 3404 | ||
3431 | void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f ) | 3405 | void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f ) |
3432 | { | 3406 | { |
3433 | int os = data.size(); | 3407 | int os = data.size(); |
3434 | data.resize( data.size() + len ); | 3408 | data.resize( data.size() + len ); |
3435 | if ( index < os ) { | 3409 | if ( index < os ) { |
3436 | memmove( data.data() + index + len, data.data() + index, | 3410 | memmove( data.data() + index + len, data.data() + index, |
3437 | sizeof( QTextStringChar ) * ( os - index ) ); | 3411 | sizeof( QTextStringChar ) * ( os - index ) ); |
3438 | } | 3412 | } |
3439 | for ( int i = 0; i < len; ++i ) { | 3413 | for ( int i = 0; i < len; ++i ) { |
3440 | data[ (int)index + i ].x = 0; | 3414 | data[ (int)index + i ].x = 0; |
3441 | data[ (int)index + i ].lineStart = 0; | 3415 | data[ (int)index + i ].lineStart = 0; |
3442 | data[ (int)index + i ].d.format = 0; | 3416 | data[ (int)index + i ].d.format = 0; |
3443 | data[ (int)index + i ].type = QTextStringChar::Regular; | 3417 | data[ (int)index + i ].type = QTextStringChar::Regular; |
3444 | data[ (int)index + i ].rightToLeft = 0; | 3418 | data[ (int)index + i ].rightToLeft = 0; |
3445 | data[ (int)index + i ].startOfRun = 0; | 3419 | data[ (int)index + i ].startOfRun = 0; |
3446 | data[ (int)index + i ].c = unicode[i]; | 3420 | data[ (int)index + i ].c = unicode[i]; |
3447 | data[ (int)index + i ].setFormat( f ); | 3421 | data[ (int)index + i ].setFormat( f ); |
3448 | } | 3422 | } |
3449 | bidiDirty = TRUE; | 3423 | bidiDirty = TRUE; |
3450 | } | 3424 | } |
3451 | 3425 | ||
3452 | QTextString::~QTextString() | 3426 | QTextString::~QTextString() |
3453 | { | 3427 | { |
3454 | clear(); | 3428 | clear(); |
3455 | } | 3429 | } |
3456 | 3430 | ||
3457 | void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat ) | 3431 | void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat ) |
3458 | { | 3432 | { |
3459 | int os = data.size(); | 3433 | int os = data.size(); |
3460 | data.resize( data.size() + 1 ); | 3434 | data.resize( data.size() + 1 ); |
3461 | if ( index < os ) { | 3435 | if ( index < os ) { |
3462 | memmove( data.data() + index + 1, data.data() + index, | 3436 | memmove( data.data() + index + 1, data.data() + index, |
3463 | sizeof( QTextStringChar ) * ( os - index ) ); | 3437 | sizeof( QTextStringChar ) * ( os - index ) ); |
3464 | } | 3438 | } |
3465 | data[ (int)index ].c = c->c; | 3439 | data[ (int)index ].c = c->c; |
3466 | data[ (int)index ].x = 0; | 3440 | data[ (int)index ].x = 0; |
3467 | data[ (int)index ].lineStart = 0; | 3441 | data[ (int)index ].lineStart = 0; |
3468 | data[ (int)index ].rightToLeft = 0; | 3442 | data[ (int)index ].rightToLeft = 0; |
3469 | data[ (int)index ].d.format = 0; | 3443 | data[ (int)index ].d.format = 0; |
3470 | data[ (int)index ].type = QTextStringChar::Regular; | 3444 | data[ (int)index ].type = QTextStringChar::Regular; |
3471 | if ( doAddRefFormat && c->format() ) | 3445 | if ( doAddRefFormat && c->format() ) |
3472 | c->format()->addRef(); | 3446 | c->format()->addRef(); |
3473 | data[ (int)index ].setFormat( c->format() ); | 3447 | data[ (int)index ].setFormat( c->format() ); |
3474 | bidiDirty = TRUE; | 3448 | bidiDirty = TRUE; |
3475 | } | 3449 | } |
3476 | 3450 | ||
3477 | void QTextString::truncate( int index ) | 3451 | void QTextString::truncate( int index ) |
3478 | { | 3452 | { |
3479 | index = QMAX( index, 0 ); | 3453 | index = QMAX( index, 0 ); |
3480 | index = QMIN( index, (int)data.size() - 1 ); | 3454 | index = QMIN( index, (int)data.size() - 1 ); |
3481 | if ( index < (int)data.size() ) { | 3455 | if ( index < (int)data.size() ) { |
3482 | for ( int i = index + 1; i < (int)data.size(); ++i ) { | 3456 | for ( int i = index + 1; i < (int)data.size(); ++i ) { |
3483 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3457 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3484 | delete data[ i ].customItem(); | 3458 | delete data[ i ].customItem(); |
3485 | if ( data[ i ].d.custom->format ) | 3459 | if ( data[ i ].d.custom->format ) |
3486 | data[ i ].d.custom->format->removeRef(); | 3460 | data[ i ].d.custom->format->removeRef(); |
3487 | delete data[ i ].d.custom; | 3461 | delete data[ i ].d.custom; |
3488 | data[ i ].d.custom = 0; | 3462 | data[ i ].d.custom = 0; |
3489 | } else if ( data[ i ].format() ) { | 3463 | } else if ( data[ i ].format() ) { |
3490 | data[ i ].format()->removeRef(); | 3464 | data[ i ].format()->removeRef(); |
3491 | } | 3465 | } |
3492 | } | 3466 | } |
3493 | } | 3467 | } |
3494 | data.truncate( index ); | 3468 | data.truncate( index ); |
3495 | bidiDirty = TRUE; | 3469 | bidiDirty = TRUE; |
3496 | } | 3470 | } |
3497 | 3471 | ||
3498 | void QTextString::remove( int index, int len ) | 3472 | void QTextString::remove( int index, int len ) |
3499 | { | 3473 | { |
3500 | for ( int i = index; i < (int)data.size() && i - index < len; ++i ) { | 3474 | for ( int i = index; i < (int)data.size() && i - index < len; ++i ) { |
3501 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3475 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3502 | delete data[ i ].customItem(); | 3476 | delete data[ i ].customItem(); |
3503 | if ( data[ i ].d.custom->format ) | 3477 | if ( data[ i ].d.custom->format ) |
3504 | data[ i ].d.custom->format->removeRef(); | 3478 | data[ i ].d.custom->format->removeRef(); |
3505 | delete data[ i ].d.custom; | 3479 | delete data[ i ].d.custom; |
3506 | data[ i ].d.custom = 0; | 3480 | data[ i ].d.custom = 0; |
3507 | } else if ( data[ i ].format() ) { | 3481 | } else if ( data[ i ].format() ) { |
3508 | data[ i ].format()->removeRef(); | 3482 | data[ i ].format()->removeRef(); |
3509 | } | 3483 | } |
3510 | } | 3484 | } |
3511 | memmove( data.data() + index, data.data() + index + len, | 3485 | memmove( data.data() + index, data.data() + index + len, |
3512 | sizeof( QTextStringChar ) * ( data.size() - index - len ) ); | 3486 | sizeof( QTextStringChar ) * ( data.size() - index - len ) ); |
3513 | data.resize( data.size() - len ); | 3487 | data.resize( data.size() - len ); |
3514 | bidiDirty = TRUE; | 3488 | bidiDirty = TRUE; |
3515 | } | 3489 | } |
3516 | 3490 | ||
3517 | void QTextString::clear() | 3491 | void QTextString::clear() |
3518 | { | 3492 | { |
3519 | for ( int i = 0; i < (int)data.count(); ++i ) { | 3493 | for ( int i = 0; i < (int)data.count(); ++i ) { |
3520 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3494 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3521 | delete data[ i ].customItem(); | 3495 | delete data[ i ].customItem(); |
3522 | if ( data[ i ].d.custom->format ) | 3496 | if ( data[ i ].d.custom->format ) |
3523 | data[ i ].d.custom->format->removeRef(); | 3497 | data[ i ].d.custom->format->removeRef(); |
3524 | delete data[ i ].d.custom; | 3498 | delete data[ i ].d.custom; |
3525 | data[ i ].d.custom = 0; | 3499 | data[ i ].d.custom = 0; |
3526 | } else if ( data[ i ].format() ) { | 3500 | } else if ( data[ i ].format() ) { |
3527 | data[ i ].format()->removeRef(); | 3501 | data[ i ].format()->removeRef(); |
3528 | } | 3502 | } |
3529 | } | 3503 | } |
3530 | data.resize( 0 ); | 3504 | data.resize( 0 ); |
3531 | } | 3505 | } |
3532 | 3506 | ||
3533 | void QTextString::setFormat( int index, QTextFormat *f, bool useCollection ) | 3507 | void QTextString::setFormat( int index, QTextFormat *f, bool useCollection ) |
3534 | { | 3508 | { |
3535 | if ( useCollection && data[ index ].format() ) | 3509 | if ( useCollection && data[ index ].format() ) |
3536 | data[ index ].format()->removeRef(); | 3510 | data[ index ].format()->removeRef(); |
3537 | data[ index ].setFormat( f ); | 3511 | data[ index ].setFormat( f ); |
3538 | } | 3512 | } |
3539 | 3513 | ||
3540 | void QTextString::checkBidi() const | 3514 | void QTextString::checkBidi() const |
3541 | { | 3515 | { |
3542 | bool rtlKnown = FALSE; | 3516 | bool rtlKnown = FALSE; |
3543 | if ( dir == QChar::DirR ) { | 3517 | if ( dir == QChar::DirR ) { |
3544 | ((QTextString *)this)->bidi = TRUE; | 3518 | ((QTextString *)this)->bidi = TRUE; |
3545 | ((QTextString *)this)->rightToLeft = TRUE; | 3519 | ((QTextString *)this)->rightToLeft = TRUE; |
3546 | rtlKnown = TRUE; | 3520 | rtlKnown = TRUE; |
3547 | return; | 3521 | return; |
3548 | } else if ( dir == QChar::DirL ) { | 3522 | } else if ( dir == QChar::DirL ) { |
3549 | ((QTextString *)this)->rightToLeft = FALSE; | 3523 | ((QTextString *)this)->rightToLeft = FALSE; |
3550 | rtlKnown = TRUE; | 3524 | rtlKnown = TRUE; |
3551 | } else { | 3525 | } else { |
3552 | ((QTextString *)this)->rightToLeft = FALSE; | 3526 | ((QTextString *)this)->rightToLeft = FALSE; |
3553 | } | 3527 | } |
3554 | 3528 | ||
3555 | int len = data.size(); | 3529 | int len = data.size(); |
3556 | const QTextStringChar *c = data.data(); | 3530 | const QTextStringChar *c = data.data(); |
3557 | ((QTextString *)this)->bidi = FALSE; | 3531 | ((QTextString *)this)->bidi = FALSE; |
3558 | while( len ) { | 3532 | while( len ) { |
3559 | if ( !rtlKnown ) { | 3533 | if ( !rtlKnown ) { |
3560 | switch( c->c.direction() ) | 3534 | switch( c->c.direction() ) |
3561 | { | 3535 | { |
3562 | case QChar::DirL: | 3536 | case QChar::DirL: |
3563 | case QChar::DirLRO: | 3537 | case QChar::DirLRO: |
3564 | case QChar::DirLRE: | 3538 | case QChar::DirLRE: |
3565 | ((QTextString *)this)->rightToLeft = FALSE; | 3539 | ((QTextString *)this)->rightToLeft = FALSE; |
3566 | rtlKnown = TRUE; | 3540 | rtlKnown = TRUE; |
3567 | break; | 3541 | break; |
3568 | case QChar::DirR: | 3542 | case QChar::DirR: |
3569 | case QChar::DirAL: | 3543 | case QChar::DirAL: |
3570 | case QChar::DirRLO: | 3544 | case QChar::DirRLO: |
3571 | case QChar::DirRLE: | 3545 | case QChar::DirRLE: |
3572 | ((QTextString *)this)->rightToLeft = TRUE; | 3546 | ((QTextString *)this)->rightToLeft = TRUE; |
3573 | rtlKnown = TRUE; | 3547 | rtlKnown = TRUE; |
3574 | break; | 3548 | break; |
3575 | default: | 3549 | default: |
3576 | break; | 3550 | break; |
3577 | } | 3551 | } |
3578 | } | 3552 | } |
3579 | uchar row = c->c.row(); | 3553 | uchar row = c->c.row(); |
3580 | if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) { | 3554 | if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) { |
3581 | ((QTextString *)this)->bidi = TRUE; | 3555 | ((QTextString *)this)->bidi = TRUE; |
3582 | if ( rtlKnown ) | 3556 | if ( rtlKnown ) |
3583 | return; | 3557 | return; |
3584 | } | 3558 | } |
3585 | len--; | 3559 | len--; |
3586 | ++c; | 3560 | ++c; |
3587 | } | 3561 | } |
3588 | } | 3562 | } |
3589 | 3563 | ||
3590 | void QTextDocument::setStyleSheet( QStyleSheet *s ) | 3564 | void QTextDocument::setStyleSheet( QStyleSheet *s ) |
3591 | { | 3565 | { |
3592 | if ( !s ) | 3566 | if ( !s ) |
3593 | return; | 3567 | return; |
3594 | sheet_ = s; | 3568 | sheet_ = s; |
3595 | list_tm = list_bm = par_tm = par_bm = 12; | 3569 | list_tm = list_bm = par_tm = par_bm = 12; |
3596 | list_lm = 40; | 3570 | list_lm = 40; |
3597 | li_tm = li_bm = 0; | 3571 | li_tm = li_bm = 0; |
3598 | QStyleSheetItem* item = s->item( "ol" ); | 3572 | QStyleSheetItem* item = s->item( "ol" ); |
3599 | if ( item ) { | 3573 | if ( item ) { |
3600 | list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3574 | list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3601 | list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3575 | list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3602 | list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft )); | 3576 | list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft )); |
3603 | } | 3577 | } |
3604 | if ( (item = s->item( "li" ) ) ) { | 3578 | if ( (item = s->item( "li" ) ) ) { |
3605 | li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3579 | li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3606 | li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3580 | li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3607 | } | 3581 | } |
3608 | if ( (item = s->item( "p" ) ) ) { | 3582 | if ( (item = s->item( "p" ) ) ) { |
3609 | par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3583 | par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3610 | par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3584 | par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3611 | } | 3585 | } |
3612 | } | 3586 | } |
3613 | 3587 | ||
3614 | void QTextDocument::setUnderlineLinks( bool b ) { | 3588 | void QTextDocument::setUnderlineLinks( bool b ) { |
3615 | underlLinks = b; | 3589 | underlLinks = b; |
3616 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 3590 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
3617 | d->setUnderlineLinks( b ); | 3591 | d->setUnderlineLinks( b ); |
3618 | } | 3592 | } |
3619 | 3593 | ||
3620 | void QTextStringChar::setFormat( QTextFormat *f ) | 3594 | void QTextStringChar::setFormat( QTextFormat *f ) |
3621 | { | 3595 | { |
3622 | if ( type == Regular ) { | 3596 | if ( type == Regular ) { |
3623 | d.format = f; | 3597 | d.format = f; |
3624 | } else { | 3598 | } else { |
3625 | if ( !d.custom ) { | 3599 | if ( !d.custom ) { |
3626 | d.custom = new CustomData; | 3600 | d.custom = new CustomData; |
3627 | d.custom->custom = 0; | 3601 | d.custom->custom = 0; |
3628 | } | 3602 | } |
3629 | d.custom->format = f; | 3603 | d.custom->format = f; |
3630 | } | 3604 | } |
3631 | } | 3605 | } |
3632 | 3606 | ||
3633 | void QTextStringChar::setCustomItem( QTextCustomItem *i ) | 3607 | void QTextStringChar::setCustomItem( QTextCustomItem *i ) |
3634 | { | 3608 | { |
3635 | if ( type == Regular ) { | 3609 | if ( type == Regular ) { |
3636 | QTextFormat *f = format(); | 3610 | QTextFormat *f = format(); |
3637 | d.custom = new CustomData; | 3611 | d.custom = new CustomData; |
3638 | d.custom->format = f; | 3612 | d.custom->format = f; |
3639 | } else { | 3613 | } else { |
3640 | delete d.custom->custom; | 3614 | delete d.custom->custom; |
3641 | } | 3615 | } |
3642 | d.custom->custom = i; | 3616 | d.custom->custom = i; |
3643 | type = (type == Anchor ? CustomAnchor : Custom); | 3617 | type = (type == Anchor ? CustomAnchor : Custom); |
3644 | } | 3618 | } |
3645 | 3619 | ||
3646 | void QTextStringChar::loseCustomItem() | 3620 | void QTextStringChar::loseCustomItem() |
3647 | { | 3621 | { |
3648 | if ( type == Custom ) { | 3622 | if ( type == Custom ) { |
3649 | QTextFormat *f = d.custom->format; | 3623 | QTextFormat *f = d.custom->format; |
3650 | d.custom->custom = 0; | 3624 | d.custom->custom = 0; |
3651 | delete d.custom; | 3625 | delete d.custom; |
3652 | type = Regular; | 3626 | type = Regular; |
3653 | d.format = f; | 3627 | d.format = f; |
3654 | } else if ( type == CustomAnchor ) { | 3628 | } else if ( type == CustomAnchor ) { |
3655 | d.custom->custom = 0; | 3629 | d.custom->custom = 0; |
3656 | type = Anchor; | 3630 | type = Anchor; |
3657 | } | 3631 | } |
3658 | } | 3632 | } |
3659 | 3633 | ||
3660 | QString QTextStringChar::anchorName() const | 3634 | QString QTextStringChar::anchorName() const |
3661 | { | 3635 | { |
3662 | if ( type == Regular ) | 3636 | if ( type == Regular ) |
3663 | return QString::null; | 3637 | return QString::null; |
3664 | else | 3638 | else |
3665 | return d.custom->anchorName; | 3639 | return d.custom->anchorName; |
3666 | } | 3640 | } |
3667 | 3641 | ||
3668 | QString QTextStringChar::anchorHref() const | 3642 | QString QTextStringChar::anchorHref() const |
3669 | { | 3643 | { |
3670 | if ( type == Regular ) | 3644 | if ( type == Regular ) |
3671 | return QString::null; | 3645 | return QString::null; |
3672 | else | 3646 | else |
3673 | return d.custom->anchorHref; | 3647 | return d.custom->anchorHref; |
3674 | } | 3648 | } |
3675 | 3649 | ||
3676 | void QTextStringChar::setAnchor( const QString& name, const QString& href ) | 3650 | void QTextStringChar::setAnchor( const QString& name, const QString& href ) |
3677 | { | 3651 | { |
3678 | if ( type == Regular ) { | 3652 | if ( type == Regular ) { |
3679 | QTextFormat *f = format(); | 3653 | QTextFormat *f = format(); |
3680 | d.custom = new CustomData; | 3654 | d.custom = new CustomData; |
3681 | d.custom->custom = 0; | 3655 | d.custom->custom = 0; |
3682 | d.custom->format = f; | 3656 | d.custom->format = f; |
3683 | type = Anchor; | 3657 | type = Anchor; |
3684 | } else if ( type == Custom ) { | 3658 | } else if ( type == Custom ) { |
3685 | type = CustomAnchor; | 3659 | type = CustomAnchor; |
3686 | } | 3660 | } |
3687 | d.custom->anchorName = name; | 3661 | d.custom->anchorName = name; |
3688 | d.custom->anchorHref = href; | 3662 | d.custom->anchorHref = href; |
3689 | } | 3663 | } |
3690 | 3664 | ||
3691 | 3665 | ||
3692 | int QTextString::width( int idx ) const | 3666 | int QTextString::width( int idx ) const |
3693 | { | 3667 | { |
3694 | int w = 0; | 3668 | int w = 0; |
3695 | QTextStringChar *c = &at( idx ); | 3669 | QTextStringChar *c = &at( idx ); |
3696 | if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 ) | 3670 | if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 ) |
3697 | return 0; | 3671 | return 0; |
3698 | if( c->isCustom() ) { | 3672 | if( c->isCustom() ) { |
3699 | if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) | 3673 | if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) |
3700 | w = c->customItem()->width; | 3674 | w = c->customItem()->width; |
3701 | } else { | 3675 | } else { |
3702 | int r = c->c.row(); | 3676 | int r = c->c.row(); |
3703 | if( r < 0x06 || r > 0x1f ) | 3677 | if( r < 0x06 || r > 0x1f ) |
3704 | w = c->format()->width( c->c ); | 3678 | w = c->format()->width( c->c ); |
3705 | else { | 3679 | else { |
3706 | // complex text. We need some hacks to get the right metric here | 3680 | // complex text. We need some hacks to get the right metric here |
3707 | QString str; | 3681 | QString str; |
3708 | int pos = 0; | 3682 | int pos = 0; |
3709 | if( idx > 4 ) | 3683 | if( idx > 4 ) |
3710 | pos = idx - 4; | 3684 | pos = idx - 4; |
3711 | int off = idx - pos; | 3685 | int off = idx - pos; |
3712 | int end = QMIN( length(), idx + 4 ); | 3686 | int end = QMIN( length(), idx + 4 ); |
3713 | while ( pos < end ) { | 3687 | while ( pos < end ) { |
3714 | str += at(pos).c; | 3688 | str += at(pos).c; |
3715 | pos++; | 3689 | pos++; |
3716 | } | 3690 | } |
3717 | w = c->format()->width( str, off ); | 3691 | w = c->format()->width( str, off ); |
3718 | } | 3692 | } |
3719 | } | 3693 | } |
3720 | return w; | 3694 | return w; |
3721 | } | 3695 | } |
3722 | 3696 | ||
3723 | QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const | 3697 | QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const |
3724 | { | 3698 | { |
3725 | if ( len == 0xFFFFFF ) | 3699 | if ( len == 0xFFFFFF ) |
3726 | len = data.size(); | 3700 | len = data.size(); |
3727 | QMemArray<QTextStringChar> a; | 3701 | QMemArray<QTextStringChar> a; |
3728 | a.resize( len ); | 3702 | a.resize( len ); |
3729 | for ( int i = 0; i < len; ++i ) { | 3703 | for ( int i = 0; i < len; ++i ) { |
3730 | QTextStringChar *c = &data[ i + start ]; | 3704 | QTextStringChar *c = &data[ i + start ]; |
3731 | a[ i ].c = c->c; | 3705 | a[ i ].c = c->c; |
3732 | a[ i ].x = 0; | 3706 | a[ i ].x = 0; |
3733 | a[ i ].lineStart = 0; | 3707 | a[ i ].lineStart = 0; |
3734 | a[ i ].rightToLeft = 0; | 3708 | a[ i ].rightToLeft = 0; |
3735 | a[ i ].d.format = 0; | 3709 | a[ i ].d.format = 0; |
3736 | a[ i ].type = QTextStringChar::Regular; | 3710 | a[ i ].type = QTextStringChar::Regular; |
3737 | a[ i ].setFormat( c->format() ); | 3711 | a[ i ].setFormat( c->format() ); |
3738 | if ( c->format() ) | 3712 | if ( c->format() ) |
3739 | c->format()->addRef(); | 3713 | c->format()->addRef(); |
3740 | } | 3714 | } |
3741 | return a; | 3715 | return a; |
3742 | } | 3716 | } |
3743 | 3717 | ||
3744 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3718 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3745 | 3719 | ||
3746 | QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) | 3720 | QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) |
3747 | : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), | 3721 | : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), |
3748 | changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE), | 3722 | changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE), |
3749 | lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE), | 3723 | lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE), |
3750 | mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE), | 3724 | mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE), |
3751 | align( 0 ),mSelections( 0 ), | 3725 | align( 0 ),mSelections( 0 ), |
3752 | mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ), | 3726 | mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ), |
3753 | utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ), | 3727 | utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ), |
3754 | tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 ) | 3728 | tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 ) |
3755 | { | 3729 | { |
3756 | lstyle = QStyleSheetItem::ListDisc; | 3730 | lstyle = QStyleSheetItem::ListDisc; |
3757 | if ( !hasdoc ) | 3731 | if ( !hasdoc ) |
3758 | docOrPseudo = new QTextParagraphPseudoDocument; | 3732 | docOrPseudo = new QTextParagraphPseudoDocument; |
3759 | bgcol = 0; | 3733 | bgcol = 0; |
3760 | list_val = -1; | 3734 | list_val = -1; |
3761 | QTextFormat* defFormat = formatCollection()->defaultFormat(); | 3735 | QTextFormat* defFormat = formatCollection()->defaultFormat(); |
3762 | if ( !hasdoc ) { | 3736 | if ( !hasdoc ) { |
3763 | tabStopWidth = defFormat->width( 'x' ) * 8; | 3737 | tabStopWidth = defFormat->width( 'x' ) * 8; |
3764 | pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); | 3738 | pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); |
3765 | } | 3739 | } |
3766 | 3740 | ||
3767 | if ( p ) | 3741 | if ( p ) |
3768 | p->n = this; | 3742 | p->n = this; |
3769 | if ( n ) | 3743 | if ( n ) |
3770 | n->p = this; | 3744 | n->p = this; |
3771 | 3745 | ||
3772 | 3746 | ||
3773 | if ( !p && hasdoc ) | 3747 | if ( !p && hasdoc ) |
3774 | document()->setFirstParagraph( this ); | 3748 | document()->setFirstParagraph( this ); |
3775 | if ( !n && hasdoc ) | 3749 | if ( !n && hasdoc ) |
3776 | document()->setLastParagraph( this ); | 3750 | document()->setLastParagraph( this ); |
3777 | 3751 | ||
3778 | state = -1; | 3752 | state = -1; |
3779 | 3753 | ||
3780 | if ( p ) | 3754 | if ( p ) |
3781 | id = p->id + 1; | 3755 | id = p->id + 1; |
3782 | else | 3756 | else |
3783 | id = 0; | 3757 | id = 0; |
3784 | if ( n && updateIds ) { | 3758 | if ( n && updateIds ) { |
3785 | QTextParagraph *s = n; | 3759 | QTextParagraph *s = n; |
3786 | while ( s ) { | 3760 | while ( s ) { |
3787 | s->id = s->p->id + 1; | 3761 | s->id = s->p->id + 1; |
3788 | s->invalidateStyleCache(); | 3762 | s->invalidateStyleCache(); |
3789 | s = s->n; | 3763 | s = s->n; |
3790 | } | 3764 | } |
3791 | } | 3765 | } |
3792 | 3766 | ||
3793 | str = new QTextString(); | 3767 | str = new QTextString(); |
3794 | str->insert( 0, " ", formatCollection()->defaultFormat() ); | 3768 | str->insert( 0, " ", formatCollection()->defaultFormat() ); |
3795 | } | 3769 | } |
3796 | 3770 | ||
3797 | QTextParagraph::~QTextParagraph() | 3771 | QTextParagraph::~QTextParagraph() |
3798 | { | 3772 | { |
3799 | delete str; | 3773 | delete str; |
3800 | if ( hasdoc ) { | 3774 | if ( hasdoc ) { |
3801 | register QTextDocument *doc = document(); | 3775 | register QTextDocument *doc = document(); |
3802 | if ( this == doc->minwParag ) { | 3776 | if ( this == doc->minwParag ) { |
3803 | doc->minwParag = 0; | 3777 | doc->minwParag = 0; |
3804 | doc->minw = 0; | 3778 | doc->minw = 0; |
3805 | } | 3779 | } |
3806 | if ( this == doc->curParag ) | 3780 | if ( this == doc->curParag ) |
3807 | doc->curParag = 0; | 3781 | doc->curParag = 0; |
3808 | } else { | 3782 | } else { |
3809 | delete pseudoDocument(); | 3783 | delete pseudoDocument(); |
3810 | } | 3784 | } |
3811 | if ( tArray ) | 3785 | if ( tArray ) |
3812 | delete [] tArray; | 3786 | delete [] tArray; |
3813 | delete eData; | 3787 | delete eData; |
3814 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); | 3788 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); |
3815 | for ( ; it != lineStarts.end(); ++it ) | 3789 | for ( ; it != lineStarts.end(); ++it ) |
3816 | delete *it; | 3790 | delete *it; |
3817 | if ( mSelections ) | 3791 | if ( mSelections ) |
3818 | delete mSelections; | 3792 | delete mSelections; |
3819 | if ( mFloatingItems ) | 3793 | if ( mFloatingItems ) |
3820 | delete mFloatingItems; | 3794 | delete mFloatingItems; |
3821 | if ( p ) | 3795 | if ( p ) |
3822 | p->setNext( n ); | 3796 | p->setNext( n ); |
3823 | if ( n ) | 3797 | if ( n ) |
3824 | n->setPrev( p ); | 3798 | n->setPrev( p ); |
3825 | } | 3799 | } |
3826 | 3800 | ||
3827 | void QTextParagraph::setNext( QTextParagraph *s ) | 3801 | void QTextParagraph::setNext( QTextParagraph *s ) |
3828 | { | 3802 | { |
3829 | n = s; | 3803 | n = s; |
3830 | if ( !n && hasdoc ) | 3804 | if ( !n && hasdoc ) |
3831 | document()->setLastParagraph( this ); | 3805 | document()->setLastParagraph( this ); |
3832 | } | 3806 | } |
3833 | 3807 | ||
3834 | void QTextParagraph::setPrev( QTextParagraph *s ) | 3808 | void QTextParagraph::setPrev( QTextParagraph *s ) |
3835 | { | 3809 | { |
3836 | p = s; | 3810 | p = s; |
3837 | if ( !p && hasdoc ) | 3811 | if ( !p && hasdoc ) |
3838 | document()->setFirstParagraph( this ); | 3812 | document()->setFirstParagraph( this ); |
3839 | } | 3813 | } |
3840 | 3814 | ||
3841 | void QTextParagraph::invalidate( int chr ) | 3815 | void QTextParagraph::invalidate( int chr ) |
3842 | { | 3816 | { |
3843 | if ( invalid < 0 ) | 3817 | if ( invalid < 0 ) |
3844 | invalid = chr; | 3818 | invalid = chr; |
3845 | else | 3819 | else |
3846 | invalid = QMIN( invalid, chr ); | 3820 | invalid = QMIN( invalid, chr ); |
3847 | if ( mFloatingItems ) { | 3821 | if ( mFloatingItems ) { |
3848 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) | 3822 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) |
3849 | i->ypos = -1; | 3823 | i->ypos = -1; |
3850 | } | 3824 | } |
3851 | invalidateStyleCache(); | 3825 | invalidateStyleCache(); |
3852 | } | 3826 | } |
3853 | 3827 | ||
3854 | void QTextParagraph::invalidateStyleCache() | 3828 | void QTextParagraph::invalidateStyleCache() |
3855 | { | 3829 | { |
3856 | if ( list_val < 0 ) | 3830 | if ( list_val < 0 ) |
3857 | list_val = -1; | 3831 | list_val = -1; |
3858 | } | 3832 | } |
3859 | 3833 | ||
3860 | 3834 | ||
3861 | void QTextParagraph::insert( int index, const QString &s ) | 3835 | void QTextParagraph::insert( int index, const QString &s ) |
3862 | { | 3836 | { |
3863 | insert( index, s.unicode(), s.length() ); | 3837 | insert( index, s.unicode(), s.length() ); |
3864 | } | 3838 | } |
3865 | 3839 | ||
3866 | void QTextParagraph::insert( int index, const QChar *unicode, int len ) | 3840 | void QTextParagraph::insert( int index, const QChar *unicode, int len ) |
3867 | { | 3841 | { |
3868 | if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) | 3842 | if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) |
3869 | str->insert( index, unicode, len, | 3843 | str->insert( index, unicode, len, |
3870 | document()->preProcessor()->format( QTextPreProcessor::Standard ) ); | 3844 | document()->preProcessor()->format( QTextPreProcessor::Standard ) ); |
3871 | else | 3845 | else |
3872 | str->insert( index, unicode, len, formatCollection()->defaultFormat() ); | 3846 | str->insert( index, unicode, len, formatCollection()->defaultFormat() ); |
3873 | invalidate( index ); | 3847 | invalidate( index ); |
3874 | needPreProcess = TRUE; | 3848 | needPreProcess = TRUE; |
3875 | } | 3849 | } |
3876 | 3850 | ||
3877 | void QTextParagraph::truncate( int index ) | 3851 | void QTextParagraph::truncate( int index ) |
3878 | { | 3852 | { |
3879 | str->truncate( index ); | 3853 | str->truncate( index ); |
3880 | insert( length(), " " ); | 3854 | insert( length(), " " ); |
3881 | needPreProcess = TRUE; | 3855 | needPreProcess = TRUE; |
3882 | } | 3856 | } |
3883 | 3857 | ||
3884 | void QTextParagraph::remove( int index, int len ) | 3858 | void QTextParagraph::remove( int index, int len ) |
3885 | { | 3859 | { |
3886 | if ( index + len - str->length() > 0 ) | 3860 | if ( index + len - str->length() > 0 ) |
3887 | return; | 3861 | return; |
3888 | for ( int i = index; i < index + len; ++i ) { | 3862 | for ( int i = index; i < index + len; ++i ) { |
3889 | QTextStringChar *c = at( i ); | 3863 | QTextStringChar *c = at( i ); |
3890 | if ( hasdoc && c->isCustom() ) { | 3864 | if ( hasdoc && c->isCustom() ) { |
3891 | document()->unregisterCustomItem( c->customItem(), this ); | 3865 | document()->unregisterCustomItem( c->customItem(), this ); |
3892 | } | 3866 | } |
3893 | } | 3867 | } |
3894 | str->remove( index, len ); | 3868 | str->remove( index, len ); |
3895 | invalidate( 0 ); | 3869 | invalidate( 0 ); |
3896 | needPreProcess = TRUE; | 3870 | needPreProcess = TRUE; |
3897 | } | 3871 | } |
3898 | 3872 | ||
3899 | void QTextParagraph::join( QTextParagraph *s ) | 3873 | void QTextParagraph::join( QTextParagraph *s ) |
3900 | { | 3874 | { |
3901 | int oh = r.height() + s->r.height(); | 3875 | int oh = r.height() + s->r.height(); |
3902 | n = s->n; | 3876 | n = s->n; |
3903 | if ( n ) | 3877 | if ( n ) |
3904 | n->p = this; | 3878 | n->p = this; |
3905 | else if ( hasdoc ) | 3879 | else if ( hasdoc ) |
3906 | document()->setLastParagraph( this ); | 3880 | document()->setLastParagraph( this ); |
3907 | 3881 | ||
3908 | int start = str->length(); | 3882 | int start = str->length(); |
3909 | if ( length() > 0 && at( length() - 1 )->c == ' ' ) { | 3883 | if ( length() > 0 && at( length() - 1 )->c == ' ' ) { |
3910 | remove( length() - 1, 1 ); | 3884 | remove( length() - 1, 1 ); |
3911 | --start; | 3885 | --start; |
3912 | } | 3886 | } |
3913 | append( s->str->toString(), TRUE ); | 3887 | append( s->str->toString(), TRUE ); |
3914 | 3888 | ||
3915 | for ( int i = 0; i < s->length(); ++i ) { | 3889 | for ( int i = 0; i < s->length(); ++i ) { |
3916 | if ( !hasdoc || document()->useFormatCollection() ) { | 3890 | if ( !hasdoc || document()->useFormatCollection() ) { |
3917 | s->str->at( i ).format()->addRef(); | 3891 | s->str->at( i ).format()->addRef(); |
3918 | str->setFormat( i + start, s->str->at( i ).format(), TRUE ); | 3892 | str->setFormat( i + start, s->str->at( i ).format(), TRUE ); |
3919 | } | 3893 | } |
3920 | if ( s->str->at( i ).isCustom() ) { | 3894 | if ( s->str->at( i ).isCustom() ) { |
3921 | QTextCustomItem * item = s->str->at( i ).customItem(); | 3895 | QTextCustomItem * item = s->str->at( i ).customItem(); |
3922 | str->at( i + start ).setCustomItem( item ); | 3896 | str->at( i + start ).setCustomItem( item ); |
3923 | s->str->at( i ).loseCustomItem(); | 3897 | s->str->at( i ).loseCustomItem(); |
3924 | if ( hasdoc ) { | 3898 | if ( hasdoc ) { |
3925 | document()->unregisterCustomItem( item, s ); | 3899 | document()->unregisterCustomItem( item, s ); |
3926 | document()->registerCustomItem( item, this ); | 3900 | document()->registerCustomItem( item, this ); |
3927 | } | 3901 | } |
3928 | } | 3902 | } |
3929 | if ( s->str->at( i ).isAnchor() ) { | 3903 | if ( s->str->at( i ).isAnchor() ) { |
3930 | str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), | 3904 | str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), |
3931 | s->str->at( i ).anchorHref() ); | 3905 | s->str->at( i ).anchorHref() ); |
3932 | } | 3906 | } |
3933 | } | 3907 | } |
3934 | 3908 | ||
3935 | if ( !extraData() && s->extraData() ) { | 3909 | if ( !extraData() && s->extraData() ) { |
3936 | setExtraData( s->extraData() ); | 3910 | setExtraData( s->extraData() ); |
3937 | s->setExtraData( 0 ); | 3911 | s->setExtraData( 0 ); |
3938 | } else if ( extraData() && s->extraData() ) { | 3912 | } else if ( extraData() && s->extraData() ) { |
3939 | extraData()->join( s->extraData() ); | 3913 | extraData()->join( s->extraData() ); |
3940 | } | 3914 | } |
3941 | delete s; | 3915 | delete s; |
3942 | invalidate( 0 ); | 3916 | invalidate( 0 ); |
3943 | r.setHeight( oh ); | 3917 | r.setHeight( oh ); |
3944 | needPreProcess = TRUE; | 3918 | needPreProcess = TRUE; |
3945 | if ( n ) { | 3919 | if ( n ) { |
3946 | QTextParagraph *s = n; | 3920 | QTextParagraph *s = n; |
3947 | s->invalidate( 0 ); | 3921 | s->invalidate( 0 ); |
3948 | while ( s ) { | 3922 | while ( s ) { |
3949 | s->id = s->p->id + 1; | 3923 | s->id = s->p->id + 1; |
3950 | s->state = -1; | 3924 | s->state = -1; |
3951 | s->needPreProcess = TRUE; | 3925 | s->needPreProcess = TRUE; |
3952 | s->changed = TRUE; | 3926 | s->changed = TRUE; |
3953 | s->invalidateStyleCache(); | 3927 | s->invalidateStyleCache(); |
3954 | s = s->n; | 3928 | s = s->n; |
3955 | } | 3929 | } |
3956 | } | 3930 | } |
3957 | format(); | 3931 | format(); |
3958 | state = -1; | 3932 | state = -1; |
3959 | } | 3933 | } |
3960 | 3934 | ||
3961 | void QTextParagraph::move( int &dy ) | 3935 | void QTextParagraph::move( int &dy ) |
3962 | { | 3936 | { |
3963 | if ( dy == 0 ) | 3937 | if ( dy == 0 ) |
3964 | return; | 3938 | return; |
3965 | changed = TRUE; | 3939 | changed = TRUE; |
3966 | r.moveBy( 0, dy ); | 3940 | r.moveBy( 0, dy ); |
3967 | if ( mFloatingItems ) { | 3941 | if ( mFloatingItems ) { |
3968 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) | 3942 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) |
3969 | i->ypos += dy; | 3943 | i->ypos += dy; |
3970 | } | 3944 | } |
3971 | if ( p ) | 3945 | if ( p ) |
3972 | p->lastInFrame = TRUE; | 3946 | p->lastInFrame = TRUE; |
3973 | 3947 | ||
3974 | // do page breaks if required | 3948 | // do page breaks if required |
3975 | if ( hasdoc && document()->isPageBreakEnabled() ) { | 3949 | if ( hasdoc && document()->isPageBreakEnabled() ) { |
3976 | int shift; | 3950 | int shift; |
3977 | if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) { | 3951 | if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) { |
3978 | if ( p ) | 3952 | if ( p ) |
3979 | p->setChanged( TRUE ); | 3953 | p->setChanged( TRUE ); |
3980 | dy += shift; | 3954 | dy += shift; |
3981 | } | 3955 | } |
3982 | } | 3956 | } |
3983 | } | 3957 | } |
3984 | 3958 | ||
3985 | void QTextParagraph::format( int start, bool doMove ) | 3959 | void QTextParagraph::format( int start, bool doMove ) |
3986 | { | 3960 | { |
3987 | if ( !str || str->length() == 0 || !formatter() ) | 3961 | if ( !str || str->length() == 0 || !formatter() ) |
3988 | return; | 3962 | return; |
3989 | 3963 | ||
3990 | if ( hasdoc && | 3964 | if ( hasdoc && |
3991 | document()->preProcessor() && | 3965 | document()->preProcessor() && |
3992 | ( needPreProcess || state == -1 ) ) | 3966 | ( needPreProcess || state == -1 ) ) |
3993 | document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid ); | 3967 | document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid ); |
3994 | needPreProcess = FALSE; | 3968 | needPreProcess = FALSE; |
3995 | 3969 | ||
3996 | if ( invalid == -1 ) | 3970 | if ( invalid == -1 ) |
3997 | return; | 3971 | return; |
3998 | 3972 | ||
3999 | r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); | 3973 | r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); |
4000 | if ( p ) | 3974 | if ( p ) |
4001 | p->lastInFrame = FALSE; | 3975 | p->lastInFrame = FALSE; |
4002 | 3976 | ||
4003 | movedDown = FALSE; | 3977 | movedDown = FALSE; |
4004 | bool formattedAgain = FALSE; | 3978 | bool formattedAgain = FALSE; |
4005 | 3979 | ||
4006 | formatAgain: | 3980 | formatAgain: |
4007 | 3981 | ||
4008 | r.setWidth( documentWidth() ); | 3982 | r.setWidth( documentWidth() ); |
4009 | if ( hasdoc && mFloatingItems ) { | 3983 | if ( hasdoc && mFloatingItems ) { |
4010 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { | 3984 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { |
4011 | i->ypos = r.y(); | 3985 | i->ypos = r.y(); |
4012 | if ( i->placement() == QTextCustomItem::PlaceRight ) { | 3986 | if ( i->placement() == QTextCustomItem::PlaceRight ) { |
4013 | i->xpos = r.x() + r.width() - i->width; | 3987 | i->xpos = r.x() + r.width() - i->width; |
4014 | } | 3988 | } |
4015 | } | 3989 | } |
4016 | } | 3990 | } |
4017 | QMap<int, QTextLineStart*> oldLineStarts = lineStarts; | 3991 | QMap<int, QTextLineStart*> oldLineStarts = lineStarts; |
4018 | lineStarts.clear(); | 3992 | lineStarts.clear(); |
4019 | int y = formatter()->format( document(), this, start, oldLineStarts ); | 3993 | int y = formatter()->format( document(), this, start, oldLineStarts ); |
4020 | 3994 | ||
4021 | 3995 | ||
4022 | r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); | 3996 | r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); |
4023 | 3997 | ||
4024 | 3998 | ||
4025 | QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin(); | 3999 | QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin(); |
4026 | 4000 | ||
4027 | for ( ; it != oldLineStarts.end(); ++it ) | 4001 | for ( ; it != oldLineStarts.end(); ++it ) |
4028 | delete *it; | 4002 | delete *it; |
4029 | 4003 | ||
4030 | QTextStringChar *c = 0; | 4004 | QTextStringChar *c = 0; |
4031 | // do not do this on mac, as the paragraph | 4005 | // do not do this on mac, as the paragraph |
4032 | // with has to be the full document width on mac as the selections | 4006 | // with has to be the full document width on mac as the selections |
4033 | // always extend completely to the right. This is a bit unefficient, | 4007 | // always extend completely to the right. This is a bit unefficient, |
4034 | // as this results in a bigger double buffer than needed but ok for | 4008 | // as this results in a bigger double buffer than needed but ok for |
4035 | // now. | 4009 | // now. |
4036 | if ( lineStarts.count() == 1 ) { | 4010 | if ( lineStarts.count() == 1 ) { |
4037 | if ( !string()->isBidi() ) { | 4011 | if ( !string()->isBidi() ) { |
4038 | c = &str->at( str->length() - 1 ); | 4012 | c = &str->at( str->length() - 1 ); |
4039 | r.setWidth( c->x + str->width( str->length() - 1 ) ); | 4013 | r.setWidth( c->x + str->width( str->length() - 1 ) ); |
4040 | } else { | 4014 | } else { |
4041 | r.setWidth( lineStarts[0]->w ); | 4015 | r.setWidth( lineStarts[0]->w ); |
4042 | } | 4016 | } |
4043 | } | 4017 | } |
4044 | 4018 | ||
4045 | if ( !hasdoc ) { // qt_format_text bounding rect handling | 4019 | if ( !hasdoc ) { // qt_format_text bounding rect handling |
4046 | it = lineStarts.begin(); | 4020 | it = lineStarts.begin(); |
4047 | int usedw = 0; | 4021 | int usedw = 0; |
4048 | for ( ; it != lineStarts.end(); ++it ) | 4022 | for ( ; it != lineStarts.end(); ++it ) |
4049 | usedw = QMAX( usedw, (*it)->w ); | 4023 | usedw = QMAX( usedw, (*it)->w ); |
4050 | if ( r.width() <= 0 ) { | 4024 | if ( r.width() <= 0 ) { |
4051 | // if the user specifies an invalid rect, this means that the | 4025 | // if the user specifies an invalid rect, this means that the |
4052 | // bounding box should grow to the width that the text actually | 4026 | // bounding box should grow to the width that the text actually |
4053 | // needs | 4027 | // needs |
4054 | r.setWidth( usedw ); | 4028 | r.setWidth( usedw ); |
4055 | } else { | 4029 | } else { |
4056 | r.setWidth( QMIN( usedw, r.width() ) ); | 4030 | r.setWidth( QMIN( usedw, r.width() ) ); |
4057 | } | 4031 | } |
4058 | } | 4032 | } |
4059 | 4033 | ||
4060 | if ( y != r.height() ) | 4034 | if ( y != r.height() ) |
4061 | r.setHeight( y ); | 4035 | r.setHeight( y ); |
4062 | 4036 | ||
4063 | if ( !visible ) { | 4037 | if ( !visible ) { |
4064 | r.setHeight( 0 ); | 4038 | r.setHeight( 0 ); |
4065 | } else { | 4039 | } else { |
4066 | int minw = formatter()->minimumWidth(); | 4040 | int minw = formatter()->minimumWidth(); |
4067 | int wused = formatter()->widthUsed(); | 4041 | int wused = formatter()->widthUsed(); |
4068 | wused = QMAX( minw, wused ); | 4042 | wused = QMAX( minw, wused ); |
4069 | if ( hasdoc ) { | 4043 | if ( hasdoc ) { |
4070 | document()->setMinimumWidth( minw, wused, this ); | 4044 | document()->setMinimumWidth( minw, wused, this ); |
4071 | } else { | 4045 | } else { |
4072 | pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw ); | 4046 | pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw ); |
4073 | pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused ); | 4047 | pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused ); |
4074 | } | 4048 | } |
4075 | } | 4049 | } |
4076 | 4050 | ||
4077 | // do page breaks if required | 4051 | // do page breaks if required |
4078 | if ( hasdoc && document()->isPageBreakEnabled() ) { | 4052 | if ( hasdoc && document()->isPageBreakEnabled() ) { |
4079 | int shift = document()->formatter()->formatVertically( document(), this ); | 4053 | int shift = document()->formatter()->formatVertically( document(), this ); |
4080 | if ( shift && !formattedAgain ) { | 4054 | if ( shift && !formattedAgain ) { |
4081 | formattedAgain = TRUE; | 4055 | formattedAgain = TRUE; |
4082 | goto formatAgain; | 4056 | goto formatAgain; |
4083 | } | 4057 | } |
4084 | } | 4058 | } |
4085 | 4059 | ||
4086 | if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { | 4060 | if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { |
4087 | int dy = ( r.y() + r.height() ) - n->r.y(); | 4061 | int dy = ( r.y() + r.height() ) - n->r.y(); |
4088 | QTextParagraph *s = n; | 4062 | QTextParagraph *s = n; |
4089 | bool makeInvalid = p && p->lastInFrame; | 4063 | bool makeInvalid = p && p->lastInFrame; |
4090 | while ( s && dy ) { | 4064 | while ( s && dy ) { |
4091 | if ( !s->isFullWidth() ) | 4065 | if ( !s->isFullWidth() ) |
4092 | makeInvalid = TRUE; | 4066 | makeInvalid = TRUE; |
4093 | if ( makeInvalid ) | 4067 | if ( makeInvalid ) |
4094 | s->invalidate( 0 ); | 4068 | s->invalidate( 0 ); |
4095 | s->move( dy ); | 4069 | s->move( dy ); |
4096 | if ( s->lastInFrame ) | 4070 | if ( s->lastInFrame ) |
4097 | makeInvalid = TRUE; | 4071 | makeInvalid = TRUE; |
4098 | s = s->n; | 4072 | s = s->n; |
4099 | } | 4073 | } |
4100 | } | 4074 | } |
4101 | 4075 | ||
4102 | firstFormat = FALSE; | 4076 | firstFormat = FALSE; |
4103 | changed = TRUE; | 4077 | changed = TRUE; |
4104 | invalid = -1; | 4078 | invalid = -1; |
4105 | //##### string()->setTextChanged( FALSE ); | 4079 | //##### string()->setTextChanged( FALSE ); |
4106 | } | 4080 | } |
4107 | 4081 | ||
4108 | int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const | 4082 | int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const |
4109 | { | 4083 | { |
4110 | if ( !isValid() ) | 4084 | if ( !isValid() ) |
4111 | ( (QTextParagraph*)this )->format(); | 4085 | ( (QTextParagraph*)this )->format(); |
4112 | 4086 | ||
4113 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); | 4087 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); |
4114 | --it; | 4088 | --it; |
4115 | for ( ;; ) { | 4089 | for ( ;; ) { |
4116 | if ( i >= it.key() ) { | 4090 | if ( i >= it.key() ) { |
4117 | if ( bl ) | 4091 | if ( bl ) |
4118 | *bl = ( *it )->baseLine; | 4092 | *bl = ( *it )->baseLine; |
4119 | if ( y ) | 4093 | if ( y ) |
4120 | *y = ( *it )->y; | 4094 | *y = ( *it )->y; |
4121 | return ( *it )->h; | 4095 | return ( *it )->h; |
4122 | } | 4096 | } |
4123 | if ( it == lineStarts.begin() ) | 4097 | if ( it == lineStarts.begin() ) |
4124 | break; | 4098 | break; |
4125 | --it; | 4099 | --it; |
4126 | } | 4100 | } |
4127 | 4101 | ||
4128 | owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl; | 4102 | owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl; |
4129 | return 15; | 4103 | return 15; |
4130 | } | 4104 | } |
4131 | 4105 | ||
4132 | QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const | 4106 | QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const |
4133 | { | 4107 | { |
4134 | if ( !isValid() ) | 4108 | if ( !isValid() ) |
4135 | ( (QTextParagraph*)this )->format(); | 4109 | ( (QTextParagraph*)this )->format(); |
4136 | 4110 | ||
4137 | int l = (int)lineStarts.count() - 1; | 4111 | int l = (int)lineStarts.count() - 1; |
4138 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); | 4112 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); |
4139 | --it; | 4113 | --it; |
4140 | for ( ;; ) { | 4114 | for ( ;; ) { |
4141 | if ( i >= it.key() ) { | 4115 | if ( i >= it.key() ) { |
4142 | if ( index ) | 4116 | if ( index ) |
4143 | *index = it.key(); | 4117 | *index = it.key(); |
4144 | if ( line ) | 4118 | if ( line ) |
4145 | *line = l; | 4119 | *line = l; |
4146 | return &str->at( it.key() ); | 4120 | return &str->at( it.key() ); |
4147 | } | 4121 | } |
4148 | if ( it == lineStarts.begin() ) | 4122 | if ( it == lineStarts.begin() ) |
4149 | break; | 4123 | break; |
4150 | --it; | 4124 | --it; |
4151 | --l; | 4125 | --l; |
4152 | } | 4126 | } |
4153 | 4127 | ||
4154 | owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl; | 4128 | owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl; |
4155 | return 0; | 4129 | return 0; |
4156 | } | 4130 | } |
4157 | 4131 | ||
4158 | int QTextParagraph::lines() const | 4132 | int QTextParagraph::lines() const |
4159 | { | 4133 | { |
4160 | if ( !isValid() ) | 4134 | if ( !isValid() ) |
4161 | ( (QTextParagraph*)this )->format(); | 4135 | ( (QTextParagraph*)this )->format(); |
4162 | 4136 | ||
4163 | return (int)lineStarts.count(); | 4137 | return (int)lineStarts.count(); |
4164 | } | 4138 | } |
4165 | 4139 | ||
4166 | QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const | 4140 | QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const |
4167 | { | 4141 | { |
4168 | if ( !isValid() ) | 4142 | if ( !isValid() ) |
4169 | ( (QTextParagraph*)this )->format(); | 4143 | ( (QTextParagraph*)this )->format(); |
4170 | 4144 | ||
4171 | if ( line >= 0 && line < (int)lineStarts.count() ) { | 4145 | if ( line >= 0 && line < (int)lineStarts.count() ) { |
4172 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); | 4146 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); |
4173 | while ( line-- > 0 ) | 4147 | while ( line-- > 0 ) |
4174 | ++it; | 4148 | ++it; |
4175 | int i = it.key(); | 4149 | int i = it.key(); |
4176 | if ( index ) | 4150 | if ( index ) |
4177 | *index = i; | 4151 | *index = i; |
4178 | return &str->at( i ); | 4152 | return &str->at( i ); |
4179 | } | 4153 | } |
4180 | 4154 | ||
4181 | owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl; | 4155 | owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl; |
4182 | return 0; | 4156 | return 0; |
4183 | } | 4157 | } |
4184 | 4158 | ||
4185 | int QTextParagraph::leftGap() const | 4159 | int QTextParagraph::leftGap() const |
4186 | { | 4160 | { |
4187 | if ( !isValid() ) | 4161 | if ( !isValid() ) |
4188 | ( (QTextParagraph*)this )->format(); | 4162 | ( (QTextParagraph*)this )->format(); |
4189 | 4163 | ||
4190 | int line = 0; | 4164 | int line = 0; |
4191 | int x = str->at(0).x; /* set x to x of first char */ | 4165 | int x = str->at(0).x; /* set x to x of first char */ |
4192 | if ( str->isBidi() ) { | 4166 | if ( str->isBidi() ) { |
4193 | for ( int i = 1; i < str->length()-1; ++i ) | 4167 | for ( int i = 1; i < str->length()-1; ++i ) |
4194 | x = QMIN(x, str->at(i).x); | 4168 | x = QMIN(x, str->at(i).x); |
4195 | return x; | 4169 | return x; |
4196 | } | 4170 | } |
4197 | 4171 | ||
4198 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); | 4172 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); |
4199 | while (line < (int)lineStarts.count()) { | 4173 | while (line < (int)lineStarts.count()) { |
4200 | int i = it.key(); /* char index */ | 4174 | int i = it.key(); /* char index */ |
4201 | x = QMIN(x, str->at(i).x); | 4175 | x = QMIN(x, str->at(i).x); |
4202 | ++it; | 4176 | ++it; |
4203 | ++line; | 4177 | ++line; |
4204 | } | 4178 | } |
4205 | return x; | 4179 | return x; |
4206 | } | 4180 | } |
4207 | 4181 | ||
4208 | void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) | 4182 | void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) |
4209 | { | 4183 | { |
4210 | if ( !f ) | 4184 | if ( !f ) |
4211 | return; | 4185 | return; |
4212 | if ( index < 0 ) | 4186 | if ( index < 0 ) |
4213 | index = 0; | 4187 | index = 0; |
4214 | if ( index > str->length() - 1 ) | 4188 | if ( index > str->length() - 1 ) |
4215 | index = str->length() - 1; | 4189 | index = str->length() - 1; |
4216 | if ( index + len >= str->length() ) | 4190 | if ( index + len >= str->length() ) |
4217 | len = str->length() - index; | 4191 | len = str->length() - index; |
4218 | 4192 | ||
4219 | QTextFormatCollection *fc = 0; | 4193 | QTextFormatCollection *fc = 0; |
4220 | if ( useCollection ) | 4194 | if ( useCollection ) |
4221 | fc = formatCollection(); | 4195 | fc = formatCollection(); |
4222 | QTextFormat *of; | 4196 | QTextFormat *of; |
4223 | for ( int i = 0; i < len; ++i ) { | 4197 | for ( int i = 0; i < len; ++i ) { |
4224 | of = str->at( i + index ).format(); | 4198 | of = str->at( i + index ).format(); |
4225 | if ( !changed && f->key() != of->key() ) | 4199 | if ( !changed && f->key() != of->key() ) |
4226 | changed = TRUE; | 4200 | changed = TRUE; |
4227 | if ( invalid == -1 && | 4201 | if ( invalid == -1 && |
4228 | ( f->font().family() != of->font().family() || | 4202 | ( f->font().family() != of->font().family() || |
4229 | f->font().pointSize() != of->font().pointSize() || | 4203 | f->font().pointSize() != of->font().pointSize() || |
4230 | f->font().weight() != of->font().weight() || | 4204 | f->font().weight() != of->font().weight() || |
4231 | f->font().italic() != of->font().italic() || | 4205 | f->font().italic() != of->font().italic() || |
4232 | f->vAlign() != of->vAlign() ) ) { | 4206 | f->vAlign() != of->vAlign() ) ) { |
4233 | invalidate( 0 ); | 4207 | invalidate( 0 ); |
4234 | } | 4208 | } |
4235 | if ( flags == -1 || flags == QTextFormat::Format || !fc ) { | 4209 | if ( flags == -1 || flags == QTextFormat::Format || !fc ) { |
4236 | if ( fc ) | 4210 | if ( fc ) |
4237 | f = fc->format( f ); | 4211 | f = fc->format( f ); |
4238 | str->setFormat( i + index, f, useCollection ); | 4212 | str->setFormat( i + index, f, useCollection ); |
4239 | } else { | 4213 | } else { |
4240 | QTextFormat *fm = fc->format( of, f, flags ); | 4214 | QTextFormat *fm = fc->format( of, f, flags ); |
4241 | str->setFormat( i + index, fm, useCollection ); | 4215 | str->setFormat( i + index, fm, useCollection ); |
4242 | } | 4216 | } |
4243 | } | 4217 | } |
4244 | } | 4218 | } |
4245 | 4219 | ||
4246 | void QTextParagraph::indent( int *oldIndent, int *newIndent ) | 4220 | void QTextParagraph::indent( int *oldIndent, int *newIndent ) |
4247 | { | 4221 | { |
4248 | if ( !hasdoc || !document()->indent() || isListItem() ) { | 4222 | if ( !hasdoc || !document()->indent() || isListItem() ) { |
4249 | if ( oldIndent ) | 4223 | if ( oldIndent ) |
4250 | *oldIndent = 0; | 4224 | *oldIndent = 0; |
4251 | if ( newIndent ) | 4225 | if ( newIndent ) |
4252 | *newIndent = 0; | 4226 | *newIndent = 0; |
4253 | if ( oldIndent && newIndent ) | 4227 | if ( oldIndent && newIndent ) |
4254 | *newIndent = *oldIndent; | 4228 | *newIndent = *oldIndent; |
4255 | return; | 4229 | return; |
4256 | } | 4230 | } |
4257 | document()->indent()->indent( document(), this, oldIndent, newIndent ); | 4231 | document()->indent()->indent( document(), this, oldIndent, newIndent ); |
4258 | } | 4232 | } |
4259 | 4233 | ||
4260 | void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, | 4234 | void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, |
4261 | int clipx, int clipy, int clipw, int cliph ) | 4235 | int clipx, int clipy, int clipw, int cliph ) |
4262 | { | 4236 | { |
4263 | if ( !visible ) | 4237 | if ( !visible ) |
4264 | return; | 4238 | return; |
4265 | QTextStringChar *chr = 0; | 4239 | QTextStringChar *chr = 0; |
4266 | int i, y, h, baseLine, xstart, xend; | 4240 | int i, y, h, baseLine, xstart, xend; |
4267 | i = y =h = baseLine = 0; | 4241 | i = y =h = baseLine = 0; |
4268 | QRect cursorRect; | 4242 | QRect cursorRect; |
4269 | drawSelections &= ( mSelections != 0 ); | 4243 | drawSelections &= ( mSelections != 0 ); |
4270 | // macintosh full-width selection style | 4244 | // macintosh full-width selection style |
4271 | bool fullWidthStyle = FALSE; | 4245 | bool fullWidthStyle = FALSE; |
4272 | int fullSelectionWidth = 0; | 4246 | int fullSelectionWidth = 0; |
4273 | if ( drawSelections && fullWidthStyle ) | 4247 | if ( drawSelections && fullWidthStyle ) |
4274 | fullSelectionWidth = (hasdoc ? document()->width() : r.width()); | 4248 | fullSelectionWidth = (hasdoc ? document()->width() : r.width()); |
4275 | 4249 | ||
4276 | QString qstr = str->toString(); | 4250 | QString qstr = str->toString(); |
4277 | // ### workaround so that \n are not drawn, actually this should | 4251 | // ### workaround so that \n are not drawn, actually this should |
4278 | // be fixed in QFont somewhere (under Windows you get ugly boxes | 4252 | // be fixed in QFont somewhere (under Windows you get ugly boxes |
4279 | // otherwise) | 4253 | // otherwise) |
4280 | QChar* uc = (QChar*) qstr.unicode(); | 4254 | QChar* uc = (QChar*) qstr.unicode(); |
4281 | for ( uint ii = 0; ii < qstr.length(); ii++ ) | 4255 | for ( uint ii = 0; ii < qstr.length(); ii++ ) |
4282 | if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' ) | 4256 | if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' ) |
4283 | uc[(int)ii] = 0x20; | 4257 | uc[(int)ii] = 0x20; |
4284 | 4258 | ||
4285 | int line = -1; | 4259 | int line = -1; |
4286 | int paintStart = 0; | 4260 | int paintStart = 0; |
4287 | int selection = -1; | 4261 | int selection = -1; |
4288 | for ( i = 0; i < length(); i++ ) { | 4262 | for ( i = 0; i < length(); i++ ) { |
4289 | chr = at( i ); | 4263 | chr = at( i ); |
4290 | 4264 | ||
4291 | // we flush at end of document | 4265 | // we flush at end of document |
4292 | bool flush = i== length()-1; | 4266 | bool flush = i== length()-1; |
4293 | bool selectionStateChanged = FALSE; | 4267 | bool selectionStateChanged = FALSE; |
4294 | if ( !flush ) { | 4268 | if ( !flush ) { |
4295 | QTextStringChar *nextchr = at( i+1 ); | 4269 | QTextStringChar *nextchr = at( i+1 ); |
4296 | // we flush at end of line | 4270 | // we flush at end of line |
4297 | flush |= nextchr->lineStart; | 4271 | flush |= nextchr->lineStart; |
4298 | // we flush on format changes | 4272 | // we flush on format changes |
4299 | flush |= ( nextchr->format() != chr->format() ); | 4273 | flush |= ( nextchr->format() != chr->format() ); |
4300 | // we flush on anchor changes | 4274 | // we flush on anchor changes |
4301 | flush |= ( nextchr->isAnchor() != chr->isAnchor() ); | 4275 | flush |= ( nextchr->isAnchor() != chr->isAnchor() ); |
4302 | // we flush on start of run | 4276 | // we flush on start of run |
4303 | flush |= nextchr->startOfRun; | 4277 | flush |= nextchr->startOfRun; |
4304 | // we flush on bidi changes | 4278 | // we flush on bidi changes |
4305 | flush |= ( nextchr->rightToLeft != chr->rightToLeft ); | 4279 | flush |= ( nextchr->rightToLeft != chr->rightToLeft ); |
4306 | // we flush on tab | 4280 | // we flush on tab |
4307 | flush |= ( chr->c == '\t' ); | 4281 | flush |= ( chr->c == '\t' ); |
4308 | // we flush on soft hypens | 4282 | // we flush on soft hypens |
4309 | flush |= ( chr->c.unicode() == 0xad ); | 4283 | flush |= ( chr->c.unicode() == 0xad ); |
4310 | // we flush on custom items | 4284 | // we flush on custom items |
4311 | flush |= chr->isCustom(); | 4285 | flush |= chr->isCustom(); |
4312 | // we flush before custom items | 4286 | // we flush before custom items |
4313 | flush |= nextchr->isCustom(); | 4287 | flush |= nextchr->isCustom(); |
4314 | // when painting justified, we flush on spaces | 4288 | // when painting justified, we flush on spaces |
4315 | if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify ) | 4289 | if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify ) |
4316 | flush |= QTextFormatter::isBreakable( str, i ); | 4290 | flush |= QTextFormatter::isBreakable( str, i ); |
4317 | // we flush when the string is getting too long | 4291 | // we flush when the string is getting too long |
4318 | flush |= ( i - paintStart >= 256 ); | 4292 | flush |= ( i - paintStart >= 256 ); |
4319 | // we flush when the selection state changes | 4293 | // we flush when the selection state changes |
4320 | if ( drawSelections ) { | 4294 | if ( drawSelections ) { |
4321 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); | 4295 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); |
4322 | it != mSelections->end(); ++it ) | 4296 | it != mSelections->end(); ++it ) |
4323 | selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 ); | 4297 | selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 ); |
4324 | flush |= selectionStateChanged; | 4298 | flush |= selectionStateChanged; |
4325 | } | 4299 | } |
4326 | } | 4300 | } |
4327 | 4301 | ||
4328 | // init a new line | 4302 | // init a new line |
4329 | if ( chr->lineStart ) { | 4303 | if ( chr->lineStart ) { |
4330 | if (fullWidthStyle && drawSelections && selection >= 0) | 4304 | if (fullWidthStyle && drawSelections && selection >= 0) |
4331 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, | 4305 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, |
4332 | (selection == QTextDocument::Standard || !hasdoc) ? | 4306 | (selection == QTextDocument::Standard || !hasdoc) ? |
4333 | cg.color( QColorGroup::Highlight ) : | 4307 | cg.color( QColorGroup::Highlight ) : |
4334 | document()->selectionColor( selection ) ); | 4308 | document()->selectionColor( selection ) ); |
4335 | ++line; | 4309 | ++line; |
4336 | paintStart = i; | 4310 | paintStart = i; |
4337 | lineInfo( line, y, h, baseLine ); | 4311 | lineInfo( line, y, h, baseLine ); |
4338 | if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave | 4312 | if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave |
4339 | break; | 4313 | break; |
4340 | } | 4314 | } |
4341 | 4315 | ||
4342 | // if this is the first line and we are a list item, draw the the bullet label | 4316 | // if this is the first line and we are a list item, draw the the bullet label |
4343 | if ( line == 0 && isListItem() ) | 4317 | if ( line == 0 && isListItem() ) |
4344 | drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg ); | 4318 | drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg ); |
4345 | } | 4319 | } |
4346 | 4320 | ||
4347 | // check for cursor mark | 4321 | // check for cursor mark |
4348 | if ( cursor && this == cursor->paragraph() && i == cursor->index() ) { | 4322 | if ( cursor && this == cursor->paragraph() && i == cursor->index() ) { |
4349 | QTextStringChar *c = i == 0 ? chr : chr - 1; | 4323 | QTextStringChar *c = i == 0 ? chr : chr - 1; |
4350 | cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(), | 4324 | cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(), |
4351 | 1, c->format()->height() ); | 4325 | 1, c->format()->height() ); |
4352 | } | 4326 | } |
4353 | 4327 | ||
4354 | // check if we are in a selection and store which one it is | 4328 | // check if we are in a selection and store which one it is |
4355 | selection = -1; | 4329 | selection = -1; |
4356 | if ( drawSelections ) { | 4330 | if ( drawSelections ) { |
4357 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); | 4331 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); |
4358 | it != mSelections->end(); ++it ) | 4332 | it != mSelections->end(); ++it ) |
4359 | if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0 | 4333 | if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0 |
4360 | // exclude the standard selection from printing | 4334 | // exclude the standard selection from printing |
4361 | && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) { | 4335 | && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) { |
4362 | selection = it.key(); | 4336 | selection = it.key(); |
4363 | break; | 4337 | break; |
4364 | } | 4338 | } |
4365 | } | 4339 | } |
4366 | 4340 | ||
4367 | if ( flush ) { // something changed, draw what we have so far | 4341 | if ( flush ) { // something changed, draw what we have so far |
4368 | if ( chr->rightToLeft ) { | 4342 | if ( chr->rightToLeft ) { |
4369 | xstart = chr->x; | 4343 | xstart = chr->x; |
4370 | xend = at( paintStart )->x + str->width( paintStart ); | 4344 | xend = at( paintStart )->x + str->width( paintStart ); |
4371 | } else { | 4345 | } else { |
4372 | xstart = at( paintStart )->x; | 4346 | xstart = at( paintStart )->x; |
4373 | if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart ) | 4347 | if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart ) |
4374 | xend = str->at( i + 1 ).x; | 4348 | xend = str->at( i + 1 ).x; |
4375 | else | 4349 | else |
4376 | xend = chr->x + str->width( i ); | 4350 | xend = chr->x + str->width( i ); |
4377 | } | 4351 | } |
4378 | 4352 | ||
4379 | if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) { | 4353 | if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) { |
4380 | if ( !chr->isCustom() ) | 4354 | if ( !chr->isCustom() ) |
4381 | drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y, | 4355 | drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y, |
4382 | baseLine, xend-xstart, h, selection, | 4356 | baseLine, xend-xstart, h, selection, |
4383 | chr, cg, chr->rightToLeft ); | 4357 | chr, cg, chr->rightToLeft ); |
4384 | else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) | 4358 | else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) |
4385 | chr->customItem()->draw( &painter, chr->x, y, | 4359 | chr->customItem()->draw( &painter, chr->x, y, |
4386 | clipx == -1 ? clipx : (clipx - r.x()), | 4360 | clipx == -1 ? clipx : (clipx - r.x()), |
4387 | clipy == -1 ? clipy : (clipy - r.y()), | 4361 | clipy == -1 ? clipy : (clipy - r.y()), |
4388 | clipw, cliph, cg, selection >= 0 ); | 4362 | clipw, cliph, cg, selection >= 0 ); |
4389 | } | 4363 | } |
4390 | paintStart = i+1; | 4364 | paintStart = i+1; |
4391 | } | 4365 | } |
4392 | 4366 | ||
4393 | } | 4367 | } |
4394 | 4368 | ||
4395 | if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections) | 4369 | if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections) |
4396 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin(); | 4370 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin(); |
4397 | it != next()->mSelections->end(); ++it ) | 4371 | it != next()->mSelections->end(); ++it ) |
4398 | if (((*it).start) == 0) { | 4372 | if (((*it).start) == 0) { |
4399 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, | 4373 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, |
4400 | (selection == QTextDocument::Standard || !hasdoc) ? | 4374 | (selection == QTextDocument::Standard || !hasdoc) ? |
4401 | cg.color( QColorGroup::Highlight ) : | 4375 | cg.color( QColorGroup::Highlight ) : |
4402 | document()->selectionColor( selection ) ); | 4376 | document()->selectionColor( selection ) ); |
4403 | break; | 4377 | break; |
4404 | } | 4378 | } |
4405 | 4379 | ||
4406 | // time to draw the cursor | 4380 | // time to draw the cursor |
4407 | const int cursor_extent = 4; | 4381 | const int cursor_extent = 4; |
4408 | if ( !cursorRect.isNull() && cursor && | 4382 | if ( !cursorRect.isNull() && cursor && |
4409 | ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) { | 4383 | ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) { |
4410 | painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) ); | 4384 | painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) ); |
4411 | painter.save(); | 4385 | painter.save(); |
4412 | if ( string()->isBidi() ) { | 4386 | if ( string()->isBidi() ) { |
4413 | if ( at( cursor->index() )->rightToLeft ) { | 4387 | if ( at( cursor->index() )->rightToLeft ) { |
4414 | painter.setPen( Qt::black ); | 4388 | painter.setPen( Qt::black ); |
4415 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4389 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4416 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4390 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4417 | } else { | 4391 | } else { |
4418 | painter.setPen( Qt::black ); | 4392 | painter.setPen( Qt::black ); |
4419 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4393 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4420 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4394 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4421 | } | 4395 | } |
4422 | } | 4396 | } |
4423 | painter.restore(); | 4397 | painter.restore(); |
4424 | } | 4398 | } |
4425 | } | 4399 | } |
4426 | 4400 | ||
4427 | //#define BIDI_DEBUG | 4401 | //#define BIDI_DEBUG |
4428 | 4402 | ||
4429 | void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart, | 4403 | void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart, |
4430 | int y, int baseLine, int w, int h, int selection, | 4404 | int y, int baseLine, int w, int h, int selection, |
4431 | QTextStringChar *formatChar, const QColorGroup& cg, | 4405 | QTextStringChar *formatChar, const QColorGroup& cg, |
4432 | bool rightToLeft ) | 4406 | bool rightToLeft ) |
4433 | { | 4407 | { |
4434 | int i = start + len - 1; | 4408 | int i = start + len - 1; |
4435 | bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; | 4409 | bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; |
4436 | QTextFormat* format = formatChar->format(); | 4410 | QTextFormat* format = formatChar->format(); |
4437 | QString str( s ); | 4411 | QString str( s ); |
4438 | if ( str[ (int)str.length() - 1 ].unicode() == 0xad ) | 4412 | if ( str[ (int)str.length() - 1 ].unicode() == 0xad ) |
4439 | str.remove( str.length() - 1, 1 ); | 4413 | str.remove( str.length() - 1, 1 ); |
4440 | if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() ) | 4414 | if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() ) |
4441 | painter.setPen( QPen( format->color() ) ); | 4415 | painter.setPen( QPen( format->color() ) ); |
4442 | else | 4416 | else |
4443 | painter.setPen( cg.text() ); | 4417 | painter.setPen( cg.text() ); |
4444 | painter.setFont( format->font() ); | 4418 | painter.setFont( format->font() ); |
4445 | 4419 | ||
4446 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) { | 4420 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) { |
4447 | if ( format->useLinkColor() ) { | 4421 | if ( format->useLinkColor() ) { |
4448 | if ( document()->linkColor.isValid() ) | 4422 | if ( document()->linkColor.isValid() ) |
4449 | painter.setPen( document()->linkColor ); | 4423 | painter.setPen( document()->linkColor ); |
4450 | else | 4424 | else |
4451 | painter.setPen( QPen( Qt::blue ) ); | 4425 | painter.setPen( QPen( Qt::blue ) ); |
4452 | } | 4426 | } |
4453 | if ( document()->underlineLinks() ) { | 4427 | if ( document()->underlineLinks() ) { |
4454 | QFont fn = format->font(); | 4428 | QFont fn = format->font(); |
4455 | fn.setUnderline( TRUE ); | 4429 | fn.setUnderline( TRUE ); |
4456 | painter.setFont( fn ); | 4430 | painter.setFont( fn ); |
4457 | } | 4431 | } |
4458 | } | 4432 | } |
4459 | 4433 | ||
4460 | if ( selection >= 0 ) { | 4434 | if ( selection >= 0 ) { |
4461 | if ( !hasdoc || document()->invertSelectionText( selection ) ) | 4435 | if ( !hasdoc || document()->invertSelectionText( selection ) ) |
4462 | painter.setPen( cg.color( QColorGroup::HighlightedText ) ); | 4436 | painter.setPen( cg.color( QColorGroup::HighlightedText ) ); |
4463 | painter.fillRect( xstart, y, w, h, | 4437 | painter.fillRect( xstart, y, w, h, |
4464 | (selection == QTextDocument::Standard || !hasdoc) ? | 4438 | (selection == QTextDocument::Standard || !hasdoc) ? |
4465 | cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) ); | 4439 | cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) ); |
4466 | } | 4440 | } |
4467 | 4441 | ||
4468 | if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { | 4442 | if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { |
4469 | if ( format->vAlign() == QTextFormat::AlignNormal ) { | 4443 | if ( format->vAlign() == QTextFormat::AlignNormal ) { |
4470 | painter.drawText( xstart, y + baseLine, str.mid( start ), len ); | 4444 | painter.drawText( xstart, y + baseLine, str.mid( start ), len ); |
4471 | #ifdef BIDI_DEBUG | 4445 | #ifdef BIDI_DEBUG |
4472 | painter.save(); | 4446 | painter.save(); |
4473 | painter.setPen ( Qt::red ); | 4447 | painter.setPen ( Qt::red ); |
4474 | painter.drawLine( xstart, y, xstart, y + baseLine ); | 4448 | painter.drawLine( xstart, y, xstart, y + baseLine ); |
4475 | painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 ); | 4449 | painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 ); |
4476 | int w = 0; | 4450 | int w = 0; |
4477 | int i = 0; | 4451 | int i = 0; |
4478 | while( i < len ) | 4452 | while( i < len ) |
4479 | w += painter.fontMetrics().charWidth( str, start + i++ ); | 4453 | w += painter.fontMetrics().charWidth( str, start + i++ ); |
4480 | painter.setPen ( Qt::blue ); | 4454 | painter.setPen ( Qt::blue ); |
4481 | painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine ); | 4455 | painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine ); |
4482 | painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 ); | 4456 | painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 ); |
4483 | painter.restore(); | 4457 | painter.restore(); |
4484 | #endif | 4458 | #endif |
4485 | } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { | 4459 | } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { |
4486 | QFont f( painter.font() ); | 4460 | QFont f( painter.font() ); |
4487 | if ( format->fontSizesInPixels() ) | 4461 | if ( format->fontSizesInPixels() ) |
4488 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 4462 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
4489 | else | 4463 | else |
4490 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 4464 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
4491 | painter.setFont( f ); | 4465 | painter.setFont( f ); |
4492 | painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ), | 4466 | painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ), |
4493 | str.mid( start ), len ); | 4467 | str.mid( start ), len ); |
4494 | } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { | 4468 | } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { |
4495 | QFont f( painter.font() ); | 4469 | QFont f( painter.font() ); |
4496 | if ( format->fontSizesInPixels() ) | 4470 | if ( format->fontSizesInPixels() ) |
4497 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 4471 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
4498 | else | 4472 | else |
4499 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 4473 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
4500 | painter.setFont( f ); | 4474 | painter.setFont( f ); |
4501 | painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); | 4475 | painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); |
4502 | } | 4476 | } |
4503 | } | 4477 | } |
4504 | if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { | 4478 | if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { |
4505 | painter.drawText( xstart + w, y + baseLine, "\xad" ); | 4479 | painter.drawText( xstart + w, y + baseLine, "\xad" ); |
4506 | } | 4480 | } |
4507 | if ( format->isMisspelled() ) { | 4481 | if ( format->isMisspelled() ) { |
4508 | painter.save(); | 4482 | painter.save(); |
4509 | painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); | 4483 | painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); |
4510 | painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 ); | 4484 | painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 ); |
4511 | painter.restore(); | 4485 | painter.restore(); |
4512 | } | 4486 | } |
4513 | 4487 | ||
4514 | i -= len; | 4488 | i -= len; |
4515 | 4489 | ||
4516 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() && | 4490 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() && |
4517 | document()->focusIndicator.parag == this && | 4491 | document()->focusIndicator.parag == this && |
4518 | ( document()->focusIndicator.start >= i && | 4492 | ( document()->focusIndicator.start >= i && |
4519 | document()->focusIndicator.start + document()->focusIndicator.len <= i + len || | 4493 | document()->focusIndicator.start + document()->focusIndicator.len <= i + len || |
4520 | document()->focusIndicator.start <= i && | 4494 | document()->focusIndicator.start <= i && |
4521 | document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { | 4495 | document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { |
4522 | painter.drawWinFocusRect( QRect( xstart, y, w, h ) ); | 4496 | painter.drawWinFocusRect( QRect( xstart, y, w, h ) ); |
4523 | } | 4497 | } |
4524 | 4498 | ||
4525 | } | 4499 | } |
4526 | 4500 | ||
4527 | void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) | 4501 | void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) |
4528 | { | 4502 | { |
4529 | QRect r ( x, y, w, h ); | 4503 | QRect r ( x, y, w, h ); |
4530 | QStyleSheetItem::ListStyle s = listStyle(); | 4504 | QStyleSheetItem::ListStyle s = listStyle(); |
4531 | 4505 | ||
4532 | p->save(); | 4506 | p->save(); |
4533 | QTextFormat *format = at( 0 )->format(); | 4507 | QTextFormat *format = at( 0 )->format(); |
4534 | if ( format ) { | 4508 | if ( format ) { |
4535 | p->setPen( format->color() ); | 4509 | p->setPen( format->color() ); |
4536 | p->setFont( format->font() ); | 4510 | p->setFont( format->font() ); |
4537 | } | 4511 | } |
4538 | QFontMetrics fm( p->fontMetrics() ); | 4512 | QFontMetrics fm( p->fontMetrics() ); |
4539 | int size = fm.lineSpacing() / 3; | 4513 | int size = fm.lineSpacing() / 3; |
4540 | 4514 | ||
4541 | switch ( s ) { | 4515 | switch ( s ) { |
4542 | case QStyleSheetItem::ListDecimal: | 4516 | case QStyleSheetItem::ListDecimal: |
4543 | case QStyleSheetItem::ListLowerAlpha: | 4517 | case QStyleSheetItem::ListLowerAlpha: |
4544 | case QStyleSheetItem::ListUpperAlpha: | 4518 | case QStyleSheetItem::ListUpperAlpha: |
4545 | { | 4519 | { |
4546 | if ( list_val == -1 ) { // uninitialised list value, calcluate the right one | 4520 | if ( list_val == -1 ) { // uninitialised list value, calcluate the right one |
4547 | int depth = listDepth(); | 4521 | int depth = listDepth(); |
4548 | list_val--; | 4522 | list_val--; |
4549 | // ### evil, square and expensive. This needs to be done when formatting, not when painting | 4523 | // ### evil, square and expensive. This needs to be done when formatting, not when painting |
4550 | QTextParagraph* s = prev(); | 4524 | QTextParagraph* s = prev(); |
4551 | int depth_s; | 4525 | int depth_s; |
4552 | while ( s && (depth_s = s->listDepth()) >= depth ) { | 4526 | while ( s && (depth_s = s->listDepth()) >= depth ) { |
4553 | if ( depth_s == depth && s->isListItem() ) | 4527 | if ( depth_s == depth && s->isListItem() ) |
4554 | list_val--; | 4528 | list_val--; |
4555 | s = s->prev(); | 4529 | s = s->prev(); |
4556 | } | 4530 | } |
4557 | } | 4531 | } |
4558 | 4532 | ||
4559 | int n = list_val; | 4533 | int n = list_val; |
4560 | if ( n < -1 ) | 4534 | if ( n < -1 ) |
4561 | n = -n - 1; | 4535 | n = -n - 1; |
4562 | QString l; | 4536 | QString l; |
4563 | switch ( s ) { | 4537 | switch ( s ) { |
4564 | case QStyleSheetItem::ListLowerAlpha: | 4538 | case QStyleSheetItem::ListLowerAlpha: |
4565 | if ( n < 27 ) { | 4539 | if ( n < 27 ) { |
4566 | l = QChar( ('a' + (char) (n-1))); | 4540 | l = QChar( ('a' + (char) (n-1))); |
4567 | break; | 4541 | break; |
4568 | } | 4542 | } |
4569 | case QStyleSheetItem::ListUpperAlpha: | 4543 | case QStyleSheetItem::ListUpperAlpha: |
4570 | if ( n < 27 ) { | 4544 | if ( n < 27 ) { |
4571 | l = QChar( ('A' + (char) (n-1))); | 4545 | l = QChar( ('A' + (char) (n-1))); |
4572 | break; | 4546 | break; |
4573 | } | 4547 | } |
4574 | break; | 4548 | break; |
4575 | default: //QStyleSheetItem::ListDecimal: | 4549 | default: //QStyleSheetItem::ListDecimal: |
4576 | l.setNum( n ); | 4550 | l.setNum( n ); |
4577 | break; | 4551 | break; |
4578 | } | 4552 | } |
4579 | l += QString::fromLatin1(". "); | 4553 | l += QString::fromLatin1(". "); |
4580 | p->drawText( r.right() - fm.width( l ), r.top() + base, l ); | 4554 | p->drawText( r.right() - fm.width( l ), r.top() + base, l ); |
4581 | } | 4555 | } |
4582 | break; | 4556 | break; |
4583 | case QStyleSheetItem::ListSquare: | 4557 | case QStyleSheetItem::ListSquare: |
4584 | { | 4558 | { |
4585 | QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); | 4559 | QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); |
4586 | p->fillRect( er , cg.brush( QColorGroup::Text ) ); | 4560 | p->fillRect( er , cg.brush( QColorGroup::Text ) ); |
4587 | } | 4561 | } |
4588 | break; | 4562 | break; |
4589 | case QStyleSheetItem::ListCircle: | 4563 | case QStyleSheetItem::ListCircle: |
4590 | { | 4564 | { |
4591 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); | 4565 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); |
4592 | p->drawEllipse( er ); | 4566 | p->drawEllipse( er ); |
4593 | } | 4567 | } |
4594 | break; | 4568 | break; |
4595 | case QStyleSheetItem::ListDisc: | 4569 | case QStyleSheetItem::ListDisc: |
4596 | default: | 4570 | default: |
4597 | { | 4571 | { |
4598 | p->setBrush( cg.brush( QColorGroup::Text )); | 4572 | p->setBrush( cg.brush( QColorGroup::Text )); |
4599 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); | 4573 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); |
4600 | p->drawEllipse( er ); | 4574 | p->drawEllipse( er ); |
4601 | p->setBrush( Qt::NoBrush ); | 4575 | p->setBrush( Qt::NoBrush ); |
4602 | } | 4576 | } |
4603 | break; | 4577 | break; |
4604 | } | 4578 | } |
4605 | 4579 | ||
4606 | p->restore(); | 4580 | p->restore(); |
4607 | } | 4581 | } |
4608 | 4582 | ||
4609 | void QTextParagraph::readStyleInformation( QDataStream& stream ) | 4583 | void QTextParagraph::readStyleInformation( QDataStream& stream ) |
4610 | { | 4584 | { |
4611 | int int_align, int_lstyle; | 4585 | int int_align, int_lstyle; |
4612 | uchar uchar_litem, uchar_rtext, uchar_dir; | 4586 | uchar uchar_litem, uchar_rtext, uchar_dir; |
4613 | stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm | 4587 | stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm |
4614 | >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir; | 4588 | >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir; |
4615 | align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle; | 4589 | align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle; |
4616 | litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir ); | 4590 | litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir ); |
4617 | QTextParagraph* s = prev() ? prev() : this; | 4591 | QTextParagraph* s = prev() ? prev() : this; |
4618 | while ( s ) { | 4592 | while ( s ) { |
4619 | s->invalidate( 0 ); | 4593 | s->invalidate( 0 ); |
4620 | s = s->next(); | 4594 | s = s->next(); |
4621 | } | 4595 | } |
4622 | } | 4596 | } |
4623 | 4597 | ||
4624 | void QTextParagraph::writeStyleInformation( QDataStream& stream ) const | 4598 | void QTextParagraph::writeStyleInformation( QDataStream& stream ) const |
4625 | { | 4599 | { |
4626 | stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction(); | 4600 | stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction(); |
4627 | } | 4601 | } |
4628 | 4602 | ||
4629 | 4603 | ||
4630 | 4604 | ||
4631 | void QTextParagraph::setListDepth( int depth ) { | 4605 | void QTextParagraph::setListDepth( int depth ) { |
4632 | if ( !hasdoc || depth == ldepth ) | 4606 | if ( !hasdoc || depth == ldepth ) |
4633 | return; | 4607 | return; |
4634 | ldepth = depth; | 4608 | ldepth = depth; |
4635 | QTextParagraph* s = prev() ? prev() : this; | 4609 | QTextParagraph* s = prev() ? prev() : this; |
4636 | while ( s ) { | 4610 | while ( s ) { |
4637 | s->invalidate( 0 ); | 4611 | s->invalidate( 0 ); |
4638 | s = s->next(); | 4612 | s = s->next(); |
4639 | } | 4613 | } |
4640 | } | 4614 | } |
4641 | 4615 | ||
4642 | int *QTextParagraph::tabArray() const | 4616 | int *QTextParagraph::tabArray() const |
4643 | { | 4617 | { |
4644 | int *ta = tArray; | 4618 | int *ta = tArray; |
4645 | if ( !ta && hasdoc ) | 4619 | if ( !ta && hasdoc ) |
4646 | ta = document()->tabArray(); | 4620 | ta = document()->tabArray(); |
4647 | return ta; | 4621 | return ta; |
4648 | } | 4622 | } |
4649 | 4623 | ||
4650 | int QTextParagraph::nextTab( int, int x ) | 4624 | int QTextParagraph::nextTab( int, int x ) |
4651 | { | 4625 | { |
4652 | int *ta = tArray; | 4626 | int *ta = tArray; |
4653 | if ( hasdoc ) { | 4627 | if ( hasdoc ) { |
4654 | if ( !ta ) | 4628 | if ( !ta ) |
4655 | ta = document()->tabArray(); | 4629 | ta = document()->tabArray(); |
4656 | tabStopWidth = document()->tabStopWidth(); | 4630 | tabStopWidth = document()->tabStopWidth(); |
4657 | } | 4631 | } |
4658 | if ( ta ) { | 4632 | if ( ta ) { |
4659 | int i = 0; | 4633 | int i = 0; |
4660 | while ( ta[ i ] ) { | 4634 | while ( ta[ i ] ) { |
4661 | if ( ta[ i ] >= x ) | 4635 | if ( ta[ i ] >= x ) |
4662 | return tArray[ i ]; | 4636 | return tArray[ i ]; |
4663 | ++i; | 4637 | ++i; |
4664 | } | 4638 | } |
4665 | return tArray[ 0 ]; | 4639 | return tArray[ 0 ]; |
4666 | } else { | 4640 | } else { |
4667 | int d; | 4641 | int d; |
4668 | if ( tabStopWidth != 0 ) | 4642 | if ( tabStopWidth != 0 ) |
4669 | d = x / tabStopWidth; | 4643 | d = x / tabStopWidth; |
4670 | else | 4644 | else |
4671 | return x; | 4645 | return x; |
4672 | return tabStopWidth * ( d + 1 ); | 4646 | return tabStopWidth * ( d + 1 ); |
4673 | } | 4647 | } |
4674 | } | 4648 | } |
4675 | 4649 | ||
4676 | void QTextParagraph::adjustToPainter( QPainter *p ) | 4650 | void QTextParagraph::adjustToPainter( QPainter *p ) |
4677 | { | 4651 | { |
4678 | for ( int i = 0; i < length(); ++i ) { | 4652 | for ( int i = 0; i < length(); ++i ) { |
4679 | if ( at( i )->isCustom() ) | 4653 | if ( at( i )->isCustom() ) |
4680 | at( i )->customItem()->adjustToPainter( p ); | 4654 | at( i )->customItem()->adjustToPainter( p ); |
4681 | } | 4655 | } |
4682 | } | 4656 | } |
4683 | 4657 | ||
4684 | QTextFormatCollection *QTextParagraph::formatCollection() const | 4658 | QTextFormatCollection *QTextParagraph::formatCollection() const |
4685 | { | 4659 | { |
4686 | if ( hasdoc ) | 4660 | if ( hasdoc ) |
4687 | return document()->formatCollection(); | 4661 | return document()->formatCollection(); |
4688 | if ( !qFormatCollection ) { | 4662 | if ( !qFormatCollection ) { |
4689 | qFormatCollection = new QTextFormatCollection; | 4663 | qFormatCollection = new QTextFormatCollection; |
4690 | static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup; | 4664 | static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup; |
4691 | qtfCleanup.set( &qFormatCollection ); | 4665 | qtfCleanup.set( &qFormatCollection ); |
4692 | } | 4666 | } |
4693 | return qFormatCollection; | 4667 | return qFormatCollection; |
4694 | } | 4668 | } |
4695 | 4669 | ||
4696 | QString QTextParagraph::richText() const | 4670 | QString QTextParagraph::richText() const |
4697 | { | 4671 | { |
4698 | QString s; | 4672 | QString s; |
4699 | QTextStringChar *formatChar = 0; | 4673 | QTextStringChar *formatChar = 0; |
4700 | QString spaces; | 4674 | QString spaces; |
4701 | bool doStart = richTextExportStart && richTextExportStart->paragraph() == this; | 4675 | bool doStart = richTextExportStart && richTextExportStart->paragraph() == this; |
4702 | bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this; | 4676 | bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this; |
4703 | int i; | 4677 | int i; |
4704 | for ( i = 0; i < length()-1; ++i ) { | 4678 | for ( i = 0; i < length()-1; ++i ) { |
4705 | if ( doStart && i && richTextExportStart->index() == i ) | 4679 | if ( doStart && i && richTextExportStart->index() == i ) |
4706 | s += "<selstart/>"; | 4680 | s += "<selstart/>"; |
4707 | if ( doEnd && richTextExportEnd->index() == i ) | 4681 | if ( doEnd && richTextExportEnd->index() == i ) |
4708 | s += "<selend/>"; | 4682 | s += "<selend/>"; |
4709 | QTextStringChar *c = &str->at( i ); | 4683 | QTextStringChar *c = &str->at( i ); |
4710 | if ( c->isAnchor() && !c->anchorName().isEmpty() ) { | 4684 | if ( c->isAnchor() && !c->anchorName().isEmpty() ) { |
4711 | if ( c->anchorName().contains( '#' ) ) { | 4685 | if ( c->anchorName().contains( '#' ) ) { |
4712 | QStringList l = QStringList::split( '#', c->anchorName() ); | 4686 | QStringList l = QStringList::split( '#', c->anchorName() ); |
4713 | for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) | 4687 | for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) |
4714 | s += "<a name=\"" + *it + "\"></a>"; | 4688 | s += "<a name=\"" + *it + "\"></a>"; |
4715 | } else { | 4689 | } else { |
4716 | s += "<a name=\"" + c->anchorName() + "\"></a>"; | 4690 | s += "<a name=\"" + c->anchorName() + "\"></a>"; |
4717 | } | 4691 | } |
4718 | } | 4692 | } |
4719 | if ( !formatChar ) { | 4693 | if ( !formatChar ) { |
4720 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), | 4694 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), |
4721 | 0, QString::null, c->anchorHref() ); | 4695 | 0, QString::null, c->anchorHref() ); |
4722 | formatChar = c; | 4696 | formatChar = c; |
4723 | } else if ( ( formatChar->format()->key() != c->format()->key() ) || | 4697 | } else if ( ( formatChar->format()->key() != c->format()->key() ) || |
4724 | (c->anchorHref() != formatChar->anchorHref() ) ) { | 4698 | (c->anchorHref() != formatChar->anchorHref() ) ) { |
4725 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), | 4699 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), |
4726 | formatChar->format() , formatChar->anchorHref(), c->anchorHref() ); | 4700 | formatChar->format() , formatChar->anchorHref(), c->anchorHref() ); |
4727 | formatChar = c; | 4701 | formatChar = c; |
4728 | } | 4702 | } |
4729 | if ( c->c == '<' ) | 4703 | if ( c->c == '<' ) |
4730 | s += "<"; | 4704 | s += "<"; |
4731 | else if ( c->c == '>' ) | 4705 | else if ( c->c == '>' ) |
4732 | s += ">"; | 4706 | s += ">"; |
4733 | else if ( c->isCustom() ) | 4707 | else if ( c->isCustom() ) |
4734 | s += c->customItem()->richText(); | 4708 | s += c->customItem()->richText(); |
4735 | else if ( c->c == '\n' || c->c == QChar_linesep ) | 4709 | else if ( c->c == '\n' || c->c == QChar_linesep ) |
4736 | s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co. | 4710 | s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co. |
4737 | else | 4711 | else |
4738 | s += c->c; | 4712 | s += c->c; |
4739 | } | 4713 | } |
4740 | if ( doEnd && richTextExportEnd->index() == i ) | 4714 | if ( doEnd && richTextExportEnd->index() == i ) |
4741 | s += "<selend/>"; | 4715 | s += "<selend/>"; |
4742 | if ( formatChar ) | 4716 | if ( formatChar ) |
4743 | s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() ); | 4717 | s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() ); |
4744 | return s; | 4718 | return s; |
4745 | } | 4719 | } |
4746 | 4720 | ||
4747 | void QTextParagraph::addCommand( QTextCommand *cmd ) | 4721 | void QTextParagraph::addCommand( QTextCommand *cmd ) |
4748 | { | 4722 | { |
4749 | if ( !hasdoc ) | 4723 | if ( !hasdoc ) |
4750 | pseudoDocument()->commandHistory->addCommand( cmd ); | 4724 | pseudoDocument()->commandHistory->addCommand( cmd ); |
4751 | else | 4725 | else |
4752 | document()->commands()->addCommand( cmd ); | 4726 | document()->commands()->addCommand( cmd ); |
4753 | } | 4727 | } |
4754 | 4728 | ||
4755 | QTextCursor *QTextParagraph::undo( QTextCursor *c ) | 4729 | QTextCursor *QTextParagraph::undo( QTextCursor *c ) |
4756 | { | 4730 | { |
4757 | if ( !hasdoc ) | 4731 | if ( !hasdoc ) |
4758 | return pseudoDocument()->commandHistory->undo( c ); | 4732 | return pseudoDocument()->commandHistory->undo( c ); |
4759 | return document()->commands()->undo( c ); | 4733 | return document()->commands()->undo( c ); |
4760 | } | 4734 | } |
4761 | 4735 | ||
4762 | QTextCursor *QTextParagraph::redo( QTextCursor *c ) | 4736 | QTextCursor *QTextParagraph::redo( QTextCursor *c ) |
4763 | { | 4737 | { |
4764 | if ( !hasdoc ) | 4738 | if ( !hasdoc ) |
4765 | return pseudoDocument()->commandHistory->redo( c ); | 4739 | return pseudoDocument()->commandHistory->redo( c ); |
4766 | return document()->commands()->redo( c ); | 4740 | return document()->commands()->redo( c ); |
4767 | } | 4741 | } |
4768 | 4742 | ||
4769 | int QTextParagraph::topMargin() const | 4743 | int QTextParagraph::topMargin() const |
4770 | { | 4744 | { |
4771 | int m = 0; | 4745 | int m = 0; |
4772 | if ( rtext ) { | 4746 | if ( rtext ) { |
4773 | m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm; | 4747 | m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm; |
4774 | if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) ) | 4748 | if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) ) |
4775 | m = QMAX( m, document()->list_tm ); | 4749 | m = QMAX( m, document()->list_tm ); |
4776 | } | 4750 | } |
4777 | m += utm; | 4751 | m += utm; |
4778 | return scale( m, QTextFormat::painter() ); | 4752 | return scale( m, QTextFormat::painter() ); |
4779 | } | 4753 | } |
4780 | 4754 | ||
4781 | int QTextParagraph::bottomMargin() const | 4755 | int QTextParagraph::bottomMargin() const |
4782 | { | 4756 | { |
4783 | int m = 0; | 4757 | int m = 0; |
4784 | if ( rtext ) { | 4758 | if ( rtext ) { |
4785 | m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm; | 4759 | m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm; |
4786 | if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) ) | 4760 | if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) ) |
4787 | m = QMAX( m, document()->list_bm ); | 4761 | m = QMAX( m, document()->list_bm ); |
4788 | } | 4762 | } |
4789 | m += ubm; | 4763 | m += ubm; |
4790 | return scale( m, QTextFormat::painter() ); | 4764 | return scale( m, QTextFormat::painter() ); |
4791 | } | 4765 | } |
4792 | 4766 | ||
4793 | int QTextParagraph::leftMargin() const | 4767 | int QTextParagraph::leftMargin() const |
4794 | { | 4768 | { |
4795 | int m = ulm; | 4769 | int m = ulm; |
4796 | if ( listDepth() ) | 4770 | if ( listDepth() ) |
4797 | m += listDepth() * document()->list_lm; | 4771 | m += listDepth() * document()->list_lm; |
4798 | return scale( m, QTextFormat::painter() ); | 4772 | return scale( m, QTextFormat::painter() ); |
4799 | } | 4773 | } |
4800 | 4774 | ||
4801 | int QTextParagraph::firstLineMargin() const | 4775 | int QTextParagraph::firstLineMargin() const |
4802 | { | 4776 | { |
4803 | int m = uflm; | 4777 | int m = uflm; |
4804 | return scale( m, QTextFormat::painter() ); | 4778 | return scale( m, QTextFormat::painter() ); |
4805 | } | 4779 | } |
4806 | 4780 | ||
4807 | int QTextParagraph::rightMargin() const | 4781 | int QTextParagraph::rightMargin() const |
4808 | { | 4782 | { |
4809 | int m = urm; | 4783 | int m = urm; |
4810 | return scale( m, QTextFormat::painter() ); | 4784 | return scale( m, QTextFormat::painter() ); |
4811 | } | 4785 | } |
4812 | 4786 | ||
4813 | int QTextParagraph::lineSpacing() const | 4787 | int QTextParagraph::lineSpacing() const |
4814 | { | 4788 | { |
4815 | int l = ulinespacing; | 4789 | int l = ulinespacing; |
4816 | l = scale( l, QTextFormat::painter() ); | 4790 | l = scale( l, QTextFormat::painter() ); |
4817 | return l; | 4791 | return l; |
4818 | } | 4792 | } |
4819 | 4793 | ||
4820 | void QTextParagraph::copyParagData( QTextParagraph *parag ) | 4794 | void QTextParagraph::copyParagData( QTextParagraph *parag ) |
4821 | { | 4795 | { |
4822 | rtext = parag->rtext; | 4796 | rtext = parag->rtext; |
4823 | lstyle = parag->lstyle; | 4797 | lstyle = parag->lstyle; |
4824 | ldepth = parag->ldepth; | 4798 | ldepth = parag->ldepth; |
4825 | litem = parag->litem; | 4799 | litem = parag->litem; |
4826 | align = parag->align; | 4800 | align = parag->align; |
4827 | utm = parag->utm; | 4801 | utm = parag->utm; |
4828 | ubm = parag->ubm; | 4802 | ubm = parag->ubm; |
4829 | urm = parag->urm; | 4803 | urm = parag->urm; |
4830 | ulm = parag->ulm; | 4804 | ulm = parag->ulm; |
4831 | uflm = parag->uflm; | 4805 | uflm = parag->uflm; |
4832 | ulinespacing = parag->ulinespacing; | 4806 | ulinespacing = parag->ulinespacing; |
4833 | QColor *c = parag->backgroundColor(); | 4807 | QColor *c = parag->backgroundColor(); |
4834 | if ( c ) | 4808 | if ( c ) |
4835 | setBackgroundColor( *c ); | 4809 | setBackgroundColor( *c ); |
4836 | str->setDirection( parag->str->direction() ); | 4810 | str->setDirection( parag->str->direction() ); |
4837 | } | 4811 | } |
4838 | 4812 | ||
4839 | void QTextParagraph::show() | 4813 | void QTextParagraph::show() |
4840 | { | 4814 | { |
4841 | if ( visible || !hasdoc ) | 4815 | if ( visible || !hasdoc ) |
4842 | return; | 4816 | return; |
4843 | visible = TRUE; | 4817 | visible = TRUE; |
4844 | } | 4818 | } |
4845 | 4819 | ||
4846 | void QTextParagraph::hide() | 4820 | void QTextParagraph::hide() |
4847 | { | 4821 | { |
4848 | if ( !visible || !hasdoc ) | 4822 | if ( !visible || !hasdoc ) |
4849 | return; | 4823 | return; |
4850 | visible = FALSE; | 4824 | visible = FALSE; |
4851 | } | 4825 | } |
4852 | 4826 | ||
4853 | void QTextParagraph::setDirection( QChar::Direction d ) | 4827 | void QTextParagraph::setDirection( QChar::Direction d ) |
4854 | { | 4828 | { |
4855 | if ( str && str->direction() != d ) { | 4829 | if ( str && str->direction() != d ) { |
4856 | str->setDirection( d ); | 4830 | str->setDirection( d ); |
4857 | invalidate( 0 ); | 4831 | invalidate( 0 ); |
4858 | } | 4832 | } |
4859 | } | 4833 | } |
4860 | 4834 | ||
4861 | QChar::Direction QTextParagraph::direction() const | 4835 | QChar::Direction QTextParagraph::direction() const |
4862 | { | 4836 | { |
4863 | return (str ? str->direction() : QChar::DirON ); | 4837 | return (str ? str->direction() : QChar::DirON ); |
4864 | } | 4838 | } |
4865 | 4839 | ||
4866 | void QTextParagraph::setChanged( bool b, bool recursive ) | 4840 | void QTextParagraph::setChanged( bool b, bool recursive ) |
4867 | { | 4841 | { |
4868 | changed = b; | 4842 | changed = b; |
4869 | if ( recursive ) { | 4843 | if ( recursive ) { |
4870 | if ( document() && document()->parentParagraph() ) | 4844 | if ( document() && document()->parentParagraph() ) |
4871 | document()->parentParagraph()->setChanged( b, recursive ); | 4845 | document()->parentParagraph()->setChanged( b, recursive ); |
4872 | } | 4846 | } |
4873 | } | 4847 | } |
4874 | 4848 | ||
4875 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 4849 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4876 | 4850 | ||
4877 | 4851 | ||
4878 | QTextPreProcessor::QTextPreProcessor() | 4852 | QTextPreProcessor::QTextPreProcessor() |
4879 | { | 4853 | { |
4880 | } | 4854 | } |
4881 | 4855 | ||
4882 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 4856 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4883 | 4857 | ||
4884 | QTextFormatter::QTextFormatter() | 4858 | QTextFormatter::QTextFormatter() |
4885 | : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE ) | 4859 | : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE ) |
4886 | { | 4860 | { |
4887 | } | 4861 | } |
4888 | 4862 | ||
4889 | QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, | 4863 | QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, |
4890 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) | 4864 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) |
4891 | { | 4865 | { |
4892 | #ifndef QT_NO_COMPLEXTEXT | 4866 | #ifndef QT_NO_COMPLEXTEXT |
4893 | if( string->isBidi() ) | 4867 | if( string->isBidi() ) |
4894 | return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); | 4868 | return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); |
4895 | #endif | 4869 | #endif |
4896 | int start = (startChar - &string->at(0)); | 4870 | int start = (startChar - &string->at(0)); |
4897 | int last = (lastChar - &string->at(0) ); | 4871 | int last = (lastChar - &string->at(0) ); |
4898 | // do alignment Auto == Left in this case | 4872 | // do alignment Auto == Left in this case |
4899 | if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) { | 4873 | if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) { |
4900 | if ( align & Qt::AlignHCenter ) | 4874 | if ( align & Qt::AlignHCenter ) |
4901 | space /= 2; | 4875 | space /= 2; |
4902 | for ( int j = start; j <= last; ++j ) | 4876 | for ( int j = start; j <= last; ++j ) |
4903 | string->at( j ).x += space; | 4877 | string->at( j ).x += space; |
4904 | } else if ( align & Qt3::AlignJustify ) { | 4878 | } else if ( align & Qt3::AlignJustify ) { |
4905 | int numSpaces = 0; | 4879 | int numSpaces = 0; |
4906 | // End at "last-1", the last space ends up with a width of 0 | 4880 | // End at "last-1", the last space ends up with a width of 0 |
4907 | for ( int j = last-1; j >= start; --j ) { | 4881 | for ( int j = last-1; j >= start; --j ) { |
4908 | // Start at last tab, if any. | 4882 | // Start at last tab, if any. |
4909 | if ( string->at( j ).c == '\t' ) { | 4883 | if ( string->at( j ).c == '\t' ) { |
4910 | start = j+1; | 4884 | start = j+1; |
4911 | break; | 4885 | break; |
4912 | } | 4886 | } |
4913 | if( isBreakable( string, j ) ) { | 4887 | if( isBreakable( string, j ) ) { |
4914 | numSpaces++; | 4888 | numSpaces++; |
4915 | } | 4889 | } |
4916 | } | 4890 | } |
4917 | int toAdd = 0; | 4891 | int toAdd = 0; |
4918 | for ( int k = start + 1; k <= last; ++k ) { | 4892 | for ( int k = start + 1; k <= last; ++k ) { |
4919 | if( isBreakable( string, k ) && numSpaces ) { | 4893 | if( isBreakable( string, k ) && numSpaces ) { |
4920 | int s = space / numSpaces; | 4894 | int s = space / numSpaces; |
4921 | toAdd += s; | 4895 | toAdd += s; |
4922 | space -= s; | 4896 | space -= s; |
4923 | numSpaces--; | 4897 | numSpaces--; |
4924 | } | 4898 | } |
4925 | string->at( k ).x += toAdd; | 4899 | string->at( k ).x += toAdd; |
4926 | } | 4900 | } |
4927 | } | 4901 | } |
4928 | 4902 | ||
4929 | if ( last >= 0 && last < string->length() ) | 4903 | if ( last >= 0 && last < string->length() ) |
4930 | line->w = string->at( last ).x + string->width( last ); | 4904 | line->w = string->at( last ).x + string->width( last ); |
4931 | else | 4905 | else |
4932 | line->w = 0; | 4906 | line->w = 0; |
4933 | 4907 | ||
4934 | return new QTextLineStart(); | 4908 | return new QTextLineStart(); |
4935 | } | 4909 | } |
4936 | 4910 | ||
4937 | #ifndef QT_NO_COMPLEXTEXT | 4911 | #ifndef QT_NO_COMPLEXTEXT |
4938 | 4912 | ||
4939 | #ifdef BIDI_DEBUG | 4913 | #ifdef BIDI_DEBUG |
4940 | #include <iostream> | 4914 | #include <iostream> |
4941 | #endif | 4915 | #endif |
4942 | 4916 | ||
4943 | // collects one line of the paragraph and transforms it to visual order | 4917 | // collects one line of the paragraph and transforms it to visual order |
4944 | QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line, | 4918 | QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line, |
4945 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) | 4919 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) |
4946 | { | 4920 | { |
4947 | int start = (startChar - &text->at(0)); | 4921 | int start = (startChar - &text->at(0)); |
4948 | int last = (lastChar - &text->at(0) ); | 4922 | int last = (lastChar - &text->at(0) ); |
4949 | 4923 | ||
4950 | QBidiControl *control = new QBidiControl( line->context(), line->status ); | 4924 | QBidiControl *control = new QBidiControl( line->context(), line->status ); |
4951 | QString str; | 4925 | QString str; |
4952 | str.setUnicode( 0, last - start + 1 ); | 4926 | str.setUnicode( 0, last - start + 1 ); |
4953 | // fill string with logically ordered chars. | 4927 | // fill string with logically ordered chars. |
4954 | QTextStringChar *ch = startChar; | 4928 | QTextStringChar *ch = startChar; |
4955 | QChar *qch = (QChar *)str.unicode(); | 4929 | QChar *qch = (QChar *)str.unicode(); |
4956 | while ( ch <= lastChar ) { | 4930 | while ( ch <= lastChar ) { |
4957 | *qch = ch->c; | 4931 | *qch = ch->c; |
4958 | qch++; | 4932 | qch++; |
4959 | ch++; | 4933 | ch++; |
4960 | } | 4934 | } |
4961 | int x = startChar->x; | 4935 | int x = startChar->x; |
4962 | 4936 | ||
4963 | QPtrList<QTextRun> *runs; | 4937 | QPtrList<QTextRun> *runs; |
4964 | runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1, | 4938 | runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1, |
4965 | (text->isRightToLeft() ? QChar::DirR : QChar::DirL) ); | 4939 | (text->isRightToLeft() ? QChar::DirR : QChar::DirL) ); |
4966 | 4940 | ||
4967 | // now construct the reordered string out of the runs... | 4941 | // now construct the reordered string out of the runs... |
4968 | 4942 | ||
4969 | int numSpaces = 0; | 4943 | int numSpaces = 0; |
4970 | // set the correct alignment. This is a bit messy.... | 4944 | // set the correct alignment. This is a bit messy.... |
4971 | if( align == Qt3::AlignAuto ) { | 4945 | if( align == Qt3::AlignAuto ) { |
4972 | // align according to directionality of the paragraph... | 4946 | // align according to directionality of the paragraph... |
4973 | if ( text->isRightToLeft() ) | 4947 | if ( text->isRightToLeft() ) |
4974 | align = Qt::AlignRight; | 4948 | align = Qt::AlignRight; |
4975 | } | 4949 | } |
4976 | 4950 | ||
4977 | if ( align & Qt::AlignHCenter ) | 4951 | if ( align & Qt::AlignHCenter ) |
4978 | x += space/2; | 4952 | x += space/2; |
4979 | else if ( align & Qt::AlignRight ) | 4953 | else if ( align & Qt::AlignRight ) |
4980 | x += space; | 4954 | x += space; |
4981 | else if ( align & Qt3::AlignJustify ) { | 4955 | else if ( align & Qt3::AlignJustify ) { |
4982 | // End at "last-1", the last space ends up with a width of 0 | 4956 | // End at "last-1", the last space ends up with a width of 0 |
4983 | for ( int j = last-1; j >= start; --j ) { | 4957 | for ( int j = last-1; j >= start; --j ) { |
4984 | // Start at last tab, if any. | 4958 | // Start at last tab, if any. |
4985 | if ( text->at( j ).c == '\t' ) { | 4959 | if ( text->at( j ).c == '\t' ) { |
4986 | start = j+1; | 4960 | start = j+1; |
4987 | break; | 4961 | break; |
4988 | } | 4962 | } |
4989 | if( isBreakable( text, j ) ) { | 4963 | if( isBreakable( text, j ) ) { |
4990 | numSpaces++; | 4964 | numSpaces++; |
4991 | } | 4965 | } |
4992 | } | 4966 | } |
4993 | } | 4967 | } |
4994 | int toAdd = 0; | 4968 | int toAdd = 0; |
4995 | bool first = TRUE; | 4969 | bool first = TRUE; |
4996 | QTextRun *r = runs->first(); | 4970 | QTextRun *r = runs->first(); |
4997 | int xmax = -0xffffff; | 4971 | int xmax = -0xffffff; |
4998 | while ( r ) { | 4972 | while ( r ) { |
4999 | if(r->level %2) { | 4973 | if(r->level %2) { |
5000 | // odd level, need to reverse the string | 4974 | // odd level, need to reverse the string |
5001 | int pos = r->stop + start; | 4975 | int pos = r->stop + start; |
5002 | while(pos >= r->start + start) { | 4976 | while(pos >= r->start + start) { |
5003 | QTextStringChar *c = &text->at(pos); | 4977 | QTextStringChar *c = &text->at(pos); |
5004 | if( numSpaces && !first && isBreakable( text, pos ) ) { | 4978 | if( numSpaces && !first && isBreakable( text, pos ) ) { |
5005 | int s = space / numSpaces; | 4979 | int s = space / numSpaces; |
5006 | toAdd += s; | 4980 | toAdd += s; |
5007 | space -= s; | 4981 | space -= s; |
5008 | numSpaces--; | 4982 | numSpaces--; |
5009 | } else if ( first ) { | 4983 | } else if ( first ) { |
5010 | first = FALSE; | 4984 | first = FALSE; |
5011 | if ( c->c == ' ' ) | 4985 | if ( c->c == ' ' ) |
5012 | x -= c->format()->width( ' ' ); | 4986 | x -= c->format()->width( ' ' ); |
5013 | } | 4987 | } |
5014 | c->x = x + toAdd; | 4988 | c->x = x + toAdd; |
5015 | c->rightToLeft = TRUE; | 4989 | c->rightToLeft = TRUE; |
5016 | c->startOfRun = FALSE; | 4990 | c->startOfRun = FALSE; |
5017 | int ww = 0; | 4991 | int ww = 0; |
5018 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) { | 4992 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) { |
5019 | ww = text->width( pos ); | 4993 | ww = text->width( pos ); |
5020 | } else { | 4994 | } else { |
5021 | ww = c->format()->width( ' ' ); | 4995 | ww = c->format()->width( ' ' ); |
5022 | } | 4996 | } |
5023 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; | 4997 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; |
5024 | x += ww; | 4998 | x += ww; |
5025 | pos--; | 4999 | pos--; |
5026 | } | 5000 | } |
5027 | } else { | 5001 | } else { |
5028 | int pos = r->start + start; | 5002 | int pos = r->start + start; |
5029 | while(pos <= r->stop + start) { | 5003 | while(pos <= r->stop + start) { |
5030 | QTextStringChar* c = &text->at(pos); | 5004 | QTextStringChar* c = &text->at(pos); |
5031 | if( numSpaces && !first && isBreakable( text, pos ) ) { | 5005 | if( numSpaces && !first && isBreakable( text, pos ) ) { |
5032 | int s = space / numSpaces; | 5006 | int s = space / numSpaces; |
5033 | toAdd += s; | 5007 | toAdd += s; |
5034 | space -= s; | 5008 | space -= s; |
5035 | numSpaces--; | 5009 | numSpaces--; |
5036 | } else if ( first ) { | 5010 | } else if ( first ) { |
5037 | first = FALSE; | 5011 | first = FALSE; |
5038 | if ( c->c == ' ' ) | 5012 | if ( c->c == ' ' ) |
5039 | x -= c->format()->width( ' ' ); | 5013 | x -= c->format()->width( ' ' ); |
5040 | } | 5014 | } |
5041 | c->x = x + toAdd; | 5015 | c->x = x + toAdd; |
5042 | c->rightToLeft = FALSE; | 5016 | c->rightToLeft = FALSE; |
5043 | c->startOfRun = FALSE; | 5017 | c->startOfRun = FALSE; |
5044 | int ww = 0; | 5018 | int ww = 0; |
5045 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) { | 5019 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) { |
5046 | ww = text->width( pos ); | 5020 | ww = text->width( pos ); |
5047 | } else { | 5021 | } else { |
5048 | ww = c->format()->width( ' ' ); | 5022 | ww = c->format()->width( ' ' ); |
5049 | } | 5023 | } |
5050 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; | 5024 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; |
5051 | x += ww; | 5025 | x += ww; |
5052 | pos++; | 5026 | pos++; |
5053 | } | 5027 | } |
5054 | } | 5028 | } |
5055 | text->at( r->start + start ).startOfRun = TRUE; | 5029 | text->at( r->start + start ).startOfRun = TRUE; |
5056 | r = runs->next(); | 5030 | r = runs->next(); |
5057 | } | 5031 | } |
5058 | 5032 | ||
5059 | line->w = xmax + 10; | 5033 | line->w = xmax + 10; |
5060 | QTextLineStart *ls = new QTextLineStart( control->context, control->status ); | 5034 | QTextLineStart *ls = new QTextLineStart( control->context, control->status ); |
5061 | delete control; | 5035 | delete control; |
5062 | delete runs; | 5036 | delete runs; |
5063 | return ls; | 5037 | return ls; |
5064 | } | 5038 | } |
5065 | #endif | 5039 | #endif |
5066 | 5040 | ||
5067 | bool QTextFormatter::isBreakable( QTextString *string, int pos ) | 5041 | bool QTextFormatter::isBreakable( QTextString *string, int pos ) |
5068 | { | 5042 | { |
5069 | const QChar &c = string->at( pos ).c; | 5043 | const QChar &c = string->at( pos ).c; |
5070 | char ch = c.latin1(); | 5044 | char ch = c.latin1(); |
5071 | if ( c == QChar_linesep ) | 5045 | if ( c == QChar_linesep ) |
5072 | return TRUE; | 5046 | return TRUE; |
5073 | if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) | 5047 | if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) |
5074 | return TRUE; | 5048 | return TRUE; |
5075 | if ( c.unicode() == 0xad ) // soft hyphen | 5049 | if ( c.unicode() == 0xad ) // soft hyphen |
5076 | return TRUE; | 5050 | return TRUE; |
5077 | if ( !ch ) { | 5051 | if ( !ch ) { |
5078 | // not latin1, need to do more sophisticated checks for other scripts | 5052 | // not latin1, need to do more sophisticated checks for other scripts |
5079 | uchar row = c.row(); | 5053 | uchar row = c.row(); |
5080 | if ( row == 0x0e ) { | 5054 | if ( row == 0x0e ) { |
5081 | // 0e00 - 0e7f == Thai | 5055 | // 0e00 - 0e7f == Thai |
5082 | if ( c.cell() < 0x80 ) { | 5056 | if ( c.cell() < 0x80 ) { |
5083 | #ifdef HAVE_THAI_BREAKS | 5057 | #ifdef HAVE_THAI_BREAKS |
5084 | // check for thai | 5058 | // check for thai |
5085 | if( string != cachedString ) { | 5059 | if( string != cachedString ) { |
5086 | // build up string of thai chars | 5060 | // build up string of thai chars |
5087 | QTextCodec *thaiCodec = QTextCodec::codecForMib(2259); | 5061 | QTextCodec *thaiCodec = QTextCodec::codecForMib(2259); |
5088 | if ( !thaiCache ) | 5062 | if ( !thaiCache ) |
5089 | thaiCache = new QCString; | 5063 | thaiCache = new QCString; |
5090 | if ( !thaiIt ) | 5064 | if ( !thaiIt ) |
5091 | thaiIt = ThBreakIterator::createWordInstance(); | 5065 | thaiIt = ThBreakIterator::createWordInstance(); |
5092 | *thaiCache = thaiCodec->fromUnicode( s->string() ); | 5066 | *thaiCache = thaiCodec->fromUnicode( s->string() ); |
5093 | } | 5067 | } |
5094 | thaiIt->setText(thaiCache->data()); | 5068 | thaiIt->setText(thaiCache->data()); |
5095 | for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) { | 5069 | for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) { |
5096 | if( i == pos ) | 5070 | if( i == pos ) |
5097 | return TRUE; | 5071 | return TRUE; |
5098 | if( i > pos ) | 5072 | if( i > pos ) |
5099 | return FALSE; | 5073 | return FALSE; |
5100 | } | 5074 | } |
5101 | return FALSE; | 5075 | return FALSE; |
5102 | #else | 5076 | #else |
5103 | // if we don't have a thai line breaking lib, allow | 5077 | // if we don't have a thai line breaking lib, allow |
5104 | // breaks everywhere except directly before punctuation. | 5078 | // breaks everywhere except directly before punctuation. |
5105 | return TRUE; | 5079 | return TRUE; |
5106 | #endif | 5080 | #endif |
5107 | } else | 5081 | } else |
5108 | return FALSE; | 5082 | return FALSE; |
5109 | } | 5083 | } |
5110 | if ( row < 0x11 ) // no asian font | 5084 | if ( row < 0x11 ) // no asian font |
5111 | return FALSE; | 5085 | return FALSE; |
5112 | if ( row > 0x2d && row < 0xfb || row == 0x11 ) | 5086 | if ( row > 0x2d && row < 0xfb || row == 0x11 ) |
5113 | // asian line breaking. Everywhere allowed except directly | 5087 | // asian line breaking. Everywhere allowed except directly |
5114 | // in front of a punctuation character. | 5088 | // in front of a punctuation character. |
5115 | return TRUE; | 5089 | return TRUE; |
5116 | } | 5090 | } |
5117 | return FALSE; | 5091 | return FALSE; |
5118 | } | 5092 | } |
5119 | 5093 | ||
5120 | void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls ) | 5094 | void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls ) |
5121 | { | 5095 | { |
5122 | if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times | 5096 | if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times |
5123 | parag->lineStartList().insert( index, ls ); | 5097 | parag->lineStartList().insert( index, ls ); |
5124 | return; | 5098 | return; |
5125 | } | 5099 | } |
5126 | QMap<int, QTextLineStart*>::Iterator it; | 5100 | QMap<int, QTextLineStart*>::Iterator it; |
5127 | if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { | 5101 | if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { |
5128 | parag->lineStartList().insert( index, ls ); | 5102 | parag->lineStartList().insert( index, ls ); |
5129 | } else { | 5103 | } else { |
5130 | delete *it; | 5104 | delete *it; |
5131 | parag->lineStartList().remove( it ); | 5105 | parag->lineStartList().remove( it ); |
5132 | parag->lineStartList().insert( index, ls ); | 5106 | parag->lineStartList().insert( index, ls ); |
5133 | } | 5107 | } |
5134 | } | 5108 | } |
5135 | 5109 | ||
5136 | 5110 | ||
5137 | /* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns | 5111 | /* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns |
5138 | the shift of the paragraphs bottom line. | 5112 | the shift of the paragraphs bottom line. |
5139 | */ | 5113 | */ |
5140 | int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag ) | 5114 | int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag ) |
5141 | { | 5115 | { |
5142 | int oldHeight = parag->rect().height(); | 5116 | int oldHeight = parag->rect().height(); |
5143 | QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList(); | 5117 | QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList(); |
5144 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); | 5118 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); |
5145 | int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0; | 5119 | int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0; |
5146 | for ( ; it != lineStarts.end() ; ++it ) { | 5120 | for ( ; it != lineStarts.end() ; ++it ) { |
5147 | QTextLineStart * ls = it.data(); | 5121 | QTextLineStart * ls = it.data(); |
5148 | ls->y = h; | 5122 | ls->y = h; |
5149 | QTextStringChar *c = ¶g->string()->at(it.key()); | 5123 | QTextStringChar *c = ¶g->string()->at(it.key()); |
5150 | if ( c && c->customItem() && c->customItem()->ownLine() ) { | 5124 | if ( c && c->customItem() && c->customItem()->ownLine() ) { |
5151 | int h = c->customItem()->height; | 5125 | int h = c->customItem()->height; |
5152 | c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() ); | 5126 | c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() ); |
5153 | int delta = c->customItem()->height - h; | 5127 | int delta = c->customItem()->height - h; |
5154 | ls->h += delta; | 5128 | ls->h += delta; |
5155 | if ( delta ) | 5129 | if ( delta ) |
5156 | parag->setMovedDown( TRUE ); | 5130 | parag->setMovedDown( TRUE ); |
5157 | } else { | 5131 | } else { |
5158 | int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h ); | 5132 | int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h ); |
5159 | ls->y += shift; | 5133 | ls->y += shift; |
5160 | if ( shift ) | 5134 | if ( shift ) |
5161 | parag->setMovedDown( TRUE ); | 5135 | parag->setMovedDown( TRUE ); |
5162 | } | 5136 | } |
5163 | h = ls->y + ls->h; | 5137 | h = ls->y + ls->h; |
5164 | } | 5138 | } |
5165 | int m = parag->bottomMargin(); | 5139 | int m = parag->bottomMargin(); |
5166 | if ( !parag->next() ) | 5140 | if ( !parag->next() ) |
5167 | m = 0; | 5141 | m = 0; |
5168 | else | 5142 | else |
5169 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5143 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5170 | h += m; | 5144 | h += m; |
5171 | parag->setHeight( h ); | 5145 | parag->setHeight( h ); |
5172 | return h - oldHeight; | 5146 | return h - oldHeight; |
5173 | } | 5147 | } |
5174 | 5148 | ||
5175 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5149 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5176 | 5150 | ||
5177 | QTextFormatterBreakInWords::QTextFormatterBreakInWords() | 5151 | QTextFormatterBreakInWords::QTextFormatterBreakInWords() |
5178 | { | 5152 | { |
5179 | } | 5153 | } |
5180 | 5154 | ||
5181 | #define SPACE(s) doc?(s>0?s:0):s | 5155 | #define SPACE(s) doc?(s>0?s:0):s |
5182 | 5156 | ||
5183 | int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, | 5157 | int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, |
5184 | int start, const QMap<int, QTextLineStart*> & ) | 5158 | int start, const QMap<int, QTextLineStart*> & ) |
5185 | { | 5159 | { |
5186 | QTextStringChar *c = 0; | 5160 | QTextStringChar *c = 0; |
5187 | QTextStringChar *firstChar = 0; | 5161 | QTextStringChar *firstChar = 0; |
5188 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; | 5162 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; |
5189 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); | 5163 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); |
5190 | int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); | 5164 | int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); |
5191 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; | 5165 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; |
5192 | int h = y; | 5166 | int h = y; |
5193 | int len = parag->length(); | 5167 | int len = parag->length(); |
5194 | if ( doc ) | 5168 | if ( doc ) |
5195 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 ); | 5169 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 ); |
5196 | int rm = parag->rightMargin(); | 5170 | int rm = parag->rightMargin(); |
5197 | int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5171 | int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5198 | bool fullWidth = TRUE; | 5172 | bool fullWidth = TRUE; |
5199 | int minw = 0; | 5173 | int minw = 0; |
5200 | int wused = 0; | 5174 | int wused = 0; |
5201 | bool wrapEnabled = isWrapEnabled( parag ); | 5175 | bool wrapEnabled = isWrapEnabled( parag ); |
5202 | 5176 | ||
5203 | start = 0; //######### what is the point with start?! (Matthias) | 5177 | start = 0; //######### what is the point with start?! (Matthias) |
5204 | if ( start == 0 ) | 5178 | if ( start == 0 ) |
5205 | c = ¶g->string()->at( 0 ); | 5179 | c = ¶g->string()->at( 0 ); |
5206 | 5180 | ||
5207 | int i = start; | 5181 | int i = start; |
5208 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); | 5182 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); |
5209 | insertLineStart( parag, 0, lineStart ); | 5183 | insertLineStart( parag, 0, lineStart ); |
5210 | 5184 | ||
5211 | QPainter *painter = QTextFormat::painter(); | 5185 | QPainter *painter = QTextFormat::painter(); |
5212 | 5186 | ||
5213 | int col = 0; | 5187 | int col = 0; |
5214 | int ww = 0; | 5188 | int ww = 0; |
5215 | QChar lastChr; | 5189 | QChar lastChr; |
5216 | for ( ; i < len; ++i, ++col ) { | 5190 | for ( ; i < len; ++i, ++col ) { |
5217 | if ( c ) | 5191 | if ( c ) |
5218 | lastChr = c->c; | 5192 | lastChr = c->c; |
5219 | c = ¶g->string()->at( i ); | 5193 | c = ¶g->string()->at( i ); |
5220 | c->rightToLeft = FALSE; | 5194 | c->rightToLeft = FALSE; |
5221 | // ### the lines below should not be needed | 5195 | // ### the lines below should not be needed |
5222 | if ( painter ) | 5196 | if ( painter ) |
5223 | c->format()->setPainter( painter ); | 5197 | c->format()->setPainter( painter ); |
5224 | if ( i > 0 ) { | 5198 | if ( i > 0 ) { |
5225 | c->lineStart = 0; | 5199 | c->lineStart = 0; |
5226 | } else { | 5200 | } else { |
5227 | c->lineStart = 1; | 5201 | c->lineStart = 1; |
5228 | firstChar = c; | 5202 | firstChar = c; |
5229 | } | 5203 | } |
5230 | if ( c->c.unicode() >= 32 || c->isCustom() ) { | 5204 | if ( c->c.unicode() >= 32 || c->isCustom() ) { |
5231 | ww = parag->string()->width( i ); | 5205 | ww = parag->string()->width( i ); |
5232 | } else if ( c->c == '\t' ) { | 5206 | } else if ( c->c == '\t' ) { |
5233 | int nx = parag->nextTab( i, x - left ) + left; | 5207 | int nx = parag->nextTab( i, x - left ) + left; |
5234 | if ( nx < x ) | 5208 | if ( nx < x ) |
5235 | ww = w - x; | 5209 | ww = w - x; |
5236 | else | 5210 | else |
5237 | ww = nx - x; | 5211 | ww = nx - x; |
5238 | } else { | 5212 | } else { |
5239 | ww = c->format()->width( ' ' ); | 5213 | ww = c->format()->width( ' ' ); |
5240 | } | 5214 | } |
5241 | 5215 | ||
5242 | if ( c->isCustom() && c->customItem()->ownLine() ) { | 5216 | if ( c->isCustom() && c->customItem()->ownLine() ) { |
5243 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5217 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5244 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5218 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5245 | c->customItem()->resize( w - x ); | 5219 | c->customItem()->resize( w - x ); |
5246 | w = dw; | 5220 | w = dw; |
5247 | y += h; | 5221 | y += h; |
5248 | h = c->height(); | 5222 | h = c->height(); |
5249 | lineStart = new QTextLineStart( y, h, h ); | 5223 | lineStart = new QTextLineStart( y, h, h ); |
5250 | insertLineStart( parag, i, lineStart ); | 5224 | insertLineStart( parag, i, lineStart ); |
5251 | c->lineStart = 1; | 5225 | c->lineStart = 1; |
5252 | firstChar = c; | 5226 | firstChar = c; |
5253 | x = 0xffffff; | 5227 | x = 0xffffff; |
5254 | continue; | 5228 | continue; |
5255 | } | 5229 | } |
5256 | 5230 | ||
5257 | if ( wrapEnabled && | 5231 | if ( wrapEnabled && |
5258 | ( wrapAtColumn() == -1 && x + ww > w || | 5232 | ( wrapAtColumn() == -1 && x + ww > w || |
5259 | wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) { | 5233 | wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) { |
5260 | x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5234 | x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5261 | w = dw; | 5235 | w = dw; |
5262 | y += h; | 5236 | y += h; |
5263 | h = c->height(); | 5237 | h = c->height(); |
5264 | lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) ); | 5238 | lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) ); |
5265 | lineStart->y = y; | 5239 | lineStart->y = y; |
5266 | insertLineStart( parag, i, lineStart ); | 5240 | insertLineStart( parag, i, lineStart ); |
5267 | lineStart->baseLine = c->ascent(); | 5241 | lineStart->baseLine = c->ascent(); |
5268 | lineStart->h = c->height(); | 5242 | lineStart->h = c->height(); |
5269 | c->lineStart = 1; | 5243 | c->lineStart = 1; |
5270 | firstChar = c; | 5244 | firstChar = c; |
5271 | col = 0; | 5245 | col = 0; |
5272 | if ( wrapAtColumn() != -1 ) | 5246 | if ( wrapAtColumn() != -1 ) |
5273 | minw = QMAX( minw, w ); | 5247 | minw = QMAX( minw, w ); |
5274 | } else if ( lineStart ) { | 5248 | } else if ( lineStart ) { |
5275 | lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); | 5249 | lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); |
5276 | h = QMAX( h, c->height() ); | 5250 | h = QMAX( h, c->height() ); |
5277 | lineStart->h = h; | 5251 | lineStart->h = h; |
5278 | } | 5252 | } |
5279 | 5253 | ||
5280 | c->x = x; | 5254 | c->x = x; |
5281 | x += ww; | 5255 | x += ww; |
5282 | wused = QMAX( wused, x ); | 5256 | wused = QMAX( wused, x ); |
5283 | } | 5257 | } |
5284 | 5258 | ||
5285 | int m = parag->bottomMargin(); | 5259 | int m = parag->bottomMargin(); |
5286 | if ( !parag->next() ) | 5260 | if ( !parag->next() ) |
5287 | m = 0; | 5261 | m = 0; |
5288 | else | 5262 | else |
5289 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5263 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5290 | parag->setFullWidth( fullWidth ); | 5264 | parag->setFullWidth( fullWidth ); |
5291 | y += h + m; | 5265 | y += h + m; |
5292 | if ( doc ) | 5266 | if ( doc ) |
5293 | minw += doc->rightMargin(); | 5267 | minw += doc->rightMargin(); |
5294 | if ( !wrapEnabled ) | 5268 | if ( !wrapEnabled ) |
5295 | minw = QMAX(minw, wused); | 5269 | minw = QMAX(minw, wused); |
5296 | 5270 | ||
5297 | thisminw = minw; | 5271 | thisminw = minw; |
5298 | thiswused = wused; | 5272 | thiswused = wused; |
5299 | return y; | 5273 | return y; |
5300 | } | 5274 | } |
5301 | 5275 | ||
5302 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5276 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5303 | 5277 | ||
5304 | QTextFormatterBreakWords::QTextFormatterBreakWords() | 5278 | QTextFormatterBreakWords::QTextFormatterBreakWords() |
5305 | { | 5279 | { |
5306 | } | 5280 | } |
5307 | 5281 | ||
5308 | #define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ | 5282 | #define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ |
5309 | int yflow = lineStart->y + parag->rect().y();\ | 5283 | int yflow = lineStart->y + parag->rect().y();\ |
5310 | int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ | 5284 | int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ |
5311 | lineStart->y += shift;\ | 5285 | lineStart->y += shift;\ |
5312 | y += shift;\ | 5286 | y += shift;\ |
5313 | }}while(FALSE) | 5287 | }}while(FALSE) |
5314 | 5288 | ||
5315 | int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, | 5289 | int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, |
5316 | int start, const QMap<int, QTextLineStart*> & ) | 5290 | int start, const QMap<int, QTextLineStart*> & ) |
5317 | { | 5291 | { |
5318 | QTextStringChar *c = 0; | 5292 | QTextStringChar *c = 0; |
5319 | QTextStringChar *firstChar = 0; | 5293 | QTextStringChar *firstChar = 0; |
5320 | QTextString *string = parag->string(); | 5294 | QTextString *string = parag->string(); |
5321 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; | 5295 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; |
5322 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); | 5296 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); |
5323 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; | 5297 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; |
5324 | int h = y; | 5298 | int h = y; |
5325 | int len = parag->length(); | 5299 | int len = parag->length(); |
5326 | if ( doc ) | 5300 | if ( doc ) |
5327 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); | 5301 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); |
5328 | int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 ); | 5302 | int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 ); |
5329 | 5303 | ||
5330 | int curLeft = x; | 5304 | int curLeft = x; |
5331 | int rm = parag->rightMargin(); | 5305 | int rm = parag->rightMargin(); |
5332 | int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; | 5306 | int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; |
5333 | int w = dw - rdiff; | 5307 | int w = dw - rdiff; |
5334 | bool fullWidth = TRUE; | 5308 | bool fullWidth = TRUE; |
5335 | int marg = left + rdiff; | 5309 | int marg = left + rdiff; |
5336 | int minw = 0; | 5310 | int minw = 0; |
5337 | int wused = 0; | 5311 | int wused = 0; |
5338 | int tminw = marg; | 5312 | int tminw = marg; |
5339 | int linespacing = doc ? parag->lineSpacing() : 0; | 5313 | int linespacing = doc ? parag->lineSpacing() : 0; |
5340 | bool wrapEnabled = isWrapEnabled( parag ); | 5314 | bool wrapEnabled = isWrapEnabled( parag ); |
5341 | 5315 | ||
5342 | start = 0; | 5316 | start = 0; |
5343 | if ( start == 0 ) | 5317 | if ( start == 0 ) |
5344 | c = ¶g->string()->at( 0 ); | 5318 | c = ¶g->string()->at( 0 ); |
5345 | 5319 | ||
5346 | int i = start; | 5320 | int i = start; |
5347 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); | 5321 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); |
5348 | insertLineStart( parag, 0, lineStart ); | 5322 | insertLineStart( parag, 0, lineStart ); |
5349 | int lastBreak = -1; | 5323 | int lastBreak = -1; |
5350 | int tmpBaseLine = 0, tmph = 0; | 5324 | int tmpBaseLine = 0, tmph = 0; |
5351 | bool lastWasNonInlineCustom = FALSE; | 5325 | bool lastWasNonInlineCustom = FALSE; |
5352 | 5326 | ||
5353 | int align = parag->alignment(); | 5327 | int align = parag->alignment(); |
5354 | if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) | 5328 | if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) |
5355 | align = doc->alignment(); | 5329 | align = doc->alignment(); |
5356 | 5330 | ||
5357 | align &= Qt3::AlignHorizontal_Mask; | 5331 | align &= Qt3::AlignHorizontal_Mask; |
5358 | 5332 | ||
5359 | QPainter *painter = QTextFormat::painter(); | 5333 | QPainter *painter = QTextFormat::painter(); |
5360 | int col = 0; | 5334 | int col = 0; |
5361 | int ww = 0; | 5335 | int ww = 0; |
5362 | QChar lastChr; | 5336 | QChar lastChr; |
5363 | for ( ; i < len; ++i, ++col ) { | 5337 | for ( ; i < len; ++i, ++col ) { |
5364 | if ( c ) | 5338 | if ( c ) |
5365 | lastChr = c->c; | 5339 | lastChr = c->c; |
5366 | // ### next line should not be needed | 5340 | // ### next line should not be needed |
5367 | if ( c && painter ) | 5341 | if ( painter ) |
5368 | c->format()->setPainter( painter ); | 5342 | c->format()->setPainter( painter ); |
5369 | c = &string->at( i ); | 5343 | c = &string->at( i ); |
5370 | c->rightToLeft = FALSE; | 5344 | c->rightToLeft = FALSE; |
5371 | if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { | 5345 | if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { |
5372 | c->lineStart = 0; | 5346 | c->lineStart = 0; |
5373 | } else { | 5347 | } else { |
5374 | c->lineStart = 1; | 5348 | c->lineStart = 1; |
5375 | firstChar = c; | 5349 | firstChar = c; |
5376 | } | 5350 | } |
5377 | 5351 | ||
5378 | if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) | 5352 | if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) |
5379 | lastWasNonInlineCustom = TRUE; | 5353 | lastWasNonInlineCustom = TRUE; |
5380 | else | 5354 | else |
5381 | lastWasNonInlineCustom = FALSE; | 5355 | lastWasNonInlineCustom = FALSE; |
5382 | 5356 | ||
5383 | if ( c->c.unicode() >= 32 || c->isCustom() ) { | 5357 | if ( c->c.unicode() >= 32 || c->isCustom() ) { |
5384 | ww = string->width( i ); | 5358 | ww = string->width( i ); |
5385 | } else if ( c->c == '\t' ) { | 5359 | } else if ( c->c == '\t' ) { |
5386 | int nx = parag->nextTab( i, x - left ) + left; | 5360 | int nx = parag->nextTab( i, x - left ) + left; |
5387 | if ( nx < x ) | 5361 | if ( nx < x ) |
5388 | ww = w - x; | 5362 | ww = w - x; |
5389 | else | 5363 | else |
5390 | ww = nx - x; | 5364 | ww = nx - x; |
5391 | } else { | 5365 | } else { |
5392 | ww = c->format()->width( ' ' ); | 5366 | ww = c->format()->width( ' ' ); |
5393 | } | 5367 | } |
5394 | 5368 | ||
5395 | // last character ("invisible" space) has no width | 5369 | // last character ("invisible" space) has no width |
5396 | if ( i == len - 1 ) | 5370 | if ( i == len - 1 ) |
5397 | ww = 0; | 5371 | ww = 0; |
5398 | 5372 | ||
5399 | QTextCustomItem* ci = c->customItem(); | 5373 | QTextCustomItem* ci = c->customItem(); |
5400 | if ( c->isCustom() && ci->ownLine() ) { | 5374 | if ( c->isCustom() && ci->ownLine() ) { |
5401 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5375 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5402 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5376 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5403 | QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); | 5377 | QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); |
5404 | ci->resize( w - x); | 5378 | ci->resize( w - x); |
5405 | if ( ci->width < w - x ) { | 5379 | if ( ci->width < w - x ) { |
5406 | if ( align & Qt::AlignHCenter ) | 5380 | if ( align & Qt::AlignHCenter ) |
5407 | x = ( w - ci->width ) / 2; | 5381 | x = ( w - ci->width ) / 2; |
5408 | else if ( align & Qt::AlignRight ) { | 5382 | else if ( align & Qt::AlignRight ) { |
5409 | x = w - ci->width; | 5383 | x = w - ci->width; |
5410 | } | 5384 | } |
5411 | } | 5385 | } |
5412 | c->x = x; | 5386 | c->x = x; |
5413 | curLeft = x; | 5387 | curLeft = x; |
5414 | if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { | 5388 | if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { |
5415 | y += QMAX( h, QMAX( tmph, linespacing ) ); | 5389 | y += QMAX( h, QMAX( tmph, linespacing ) ); |
5416 | tmph = c->height(); | 5390 | tmph = c->height(); |
5417 | h = tmph; | 5391 | h = tmph; |
5418 | lineStart = lineStart2; | 5392 | lineStart = lineStart2; |
5419 | lineStart->y = y; | 5393 | lineStart->y = y; |
5420 | insertLineStart( parag, i, lineStart ); | 5394 | insertLineStart( parag, i, lineStart ); |
5421 | c->lineStart = 1; | 5395 | c->lineStart = 1; |
5422 | firstChar = c; | 5396 | firstChar = c; |
5423 | } else { | 5397 | } else { |
5424 | tmph = c->height(); | 5398 | tmph = c->height(); |
5425 | h = tmph; | 5399 | h = tmph; |
5426 | delete lineStart2; | 5400 | delete lineStart2; |
5427 | } | 5401 | } |
5428 | lineStart->h = h; | 5402 | lineStart->h = h; |
5429 | lineStart->baseLine = h; | 5403 | lineStart->baseLine = h; |
5430 | tmpBaseLine = lineStart->baseLine; | 5404 | tmpBaseLine = lineStart->baseLine; |
5431 | lastBreak = -2; | 5405 | lastBreak = -2; |
5432 | x = 0xffffff; | 5406 | x = 0xffffff; |
5433 | minw = QMAX( minw, tminw ); | 5407 | minw = QMAX( minw, tminw ); |
5434 | 5408 | ||
5435 | int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); | 5409 | int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); |
5436 | if ( tw < QWIDGETSIZE_MAX ) | 5410 | if ( tw < QWIDGETSIZE_MAX ) |
5437 | tminw = tw; | 5411 | tminw = tw; |
5438 | else | 5412 | else |
5439 | tminw = marg; | 5413 | tminw = marg; |
5440 | wused = QMAX( wused, ci->width ); | 5414 | wused = QMAX( wused, ci->width ); |
5441 | continue; | 5415 | continue; |
5442 | } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { | 5416 | } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { |
5443 | int tw = ci->minimumWidth(); | 5417 | int tw = ci->minimumWidth(); |
5444 | if ( tw < QWIDGETSIZE_MAX ) | 5418 | if ( tw < QWIDGETSIZE_MAX ) |
5445 | minw = QMAX( minw, tw ); | 5419 | minw = QMAX( minw, tw ); |
5446 | } | 5420 | } |
5447 | 5421 | ||
5448 | bool lastWasOwnLineCustomItem = lastBreak == -2; | 5422 | bool lastWasOwnLineCustomItem = lastBreak == -2; |
5449 | bool hadBreakableChar = lastBreak != -1; | 5423 | bool hadBreakableChar = lastBreak != -1; |
5450 | bool lastWasHardBreak = lastChr == QChar_linesep; | 5424 | bool lastWasHardBreak = lastChr == QChar_linesep; |
5451 | 5425 | ||
5452 | // we break if | 5426 | // we break if |
5453 | // 1. the last character was a hard break (QChar_linesep) or | 5427 | // 1. the last character was a hard break (QChar_linesep) or |
5454 | // 2. the last charater was a own-line custom item (eg. table or ruler) or | 5428 | // 2. the last charater was a own-line custom item (eg. table or ruler) or |
5455 | // 3. wrapping was enabled, it was not a space and following | 5429 | // 3. wrapping was enabled, it was not a space and following |
5456 | // condition is true: We either had a breakable character | 5430 | // condition is true: We either had a breakable character |
5457 | // previously or we ar allowed to break in words and - either | 5431 | // previously or we ar allowed to break in words and - either |
5458 | // we break at w pixels and the current char would exceed that | 5432 | // we break at w pixels and the current char would exceed that |
5459 | // or - we break at a column and the current character would | 5433 | // or - we break at a column and the current character would |
5460 | // exceed that. | 5434 | // exceed that. |
5461 | if ( lastWasHardBreak || lastWasOwnLineCustomItem || | 5435 | if ( lastWasHardBreak || lastWasOwnLineCustomItem || |
5462 | ( wrapEnabled && | 5436 | ( wrapEnabled && |
5463 | ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && | 5437 | ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && |
5464 | ( (wrapAtColumn() == -1 && x + ww > w) || | 5438 | ( (wrapAtColumn() == -1 && x + ww > w) || |
5465 | (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) ) | 5439 | (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) ) |
5466 | ) | 5440 | ) |
5467 | ) { | 5441 | ) { |
5468 | if ( wrapAtColumn() != -1 ) | 5442 | if ( wrapAtColumn() != -1 ) |
5469 | minw = QMAX( minw, x + ww ); | 5443 | minw = QMAX( minw, x + ww ); |
5470 | // if a break was forced (no breakable char, hard break or own line custom item), break immediately.... | 5444 | // if a break was forced (no breakable char, hard break or own line custom item), break immediately.... |
5471 | if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) { | 5445 | if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) { |
5472 | if ( lineStart ) { | 5446 | if ( lineStart ) { |
5473 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5447 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5474 | h = QMAX( h, tmph ); | 5448 | h = QMAX( h, tmph ); |
5475 | lineStart->h = h; | 5449 | lineStart->h = h; |
5476 | DO_FLOW( lineStart ); | 5450 | DO_FLOW( lineStart ); |
5477 | } | 5451 | } |
5478 | lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); | 5452 | lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); |
5479 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5453 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5480 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5454 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5481 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling | 5455 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling |
5482 | int nx = parag->nextTab( i, x - left ) + left; | 5456 | int nx = parag->nextTab( i, x - left ) + left; |
5483 | if ( nx < x ) | 5457 | if ( nx < x ) |
5484 | ww = w - x; | 5458 | ww = w - x; |
5485 | else | 5459 | else |
5486 | ww = nx - x; | 5460 | ww = nx - x; |
5487 | } | 5461 | } |
5488 | curLeft = x; | 5462 | curLeft = x; |
5489 | y += QMAX( h, linespacing ); | 5463 | y += QMAX( h, linespacing ); |
5490 | tmph = c->height(); | 5464 | tmph = c->height(); |
5491 | h = 0; | 5465 | h = 0; |
5492 | lineStart->y = y; | 5466 | lineStart->y = y; |
5493 | insertLineStart( parag, i, lineStart ); | 5467 | insertLineStart( parag, i, lineStart ); |
5494 | lineStart->baseLine = c->ascent(); | 5468 | lineStart->baseLine = c->ascent(); |
5495 | lineStart->h = c->height(); | 5469 | lineStart->h = c->height(); |
5496 | c->lineStart = 1; | 5470 | c->lineStart = 1; |
5497 | firstChar = c; | 5471 | firstChar = c; |
5498 | tmpBaseLine = lineStart->baseLine; | 5472 | tmpBaseLine = lineStart->baseLine; |
5499 | lastBreak = -1; | 5473 | lastBreak = -1; |
5500 | col = 0; | 5474 | col = 0; |
5501 | } else { // ... otherwise if we had a breakable char, break there | 5475 | } else { // ... otherwise if we had a breakable char, break there |
5502 | DO_FLOW( lineStart ); | 5476 | DO_FLOW( lineStart ); |
5503 | i = lastBreak; | 5477 | i = lastBreak; |
5504 | lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) ); | 5478 | lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) ); |
5505 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5479 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5506 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5480 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5507 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling | 5481 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling |
5508 | int nx = parag->nextTab( i, x - left ) + left; | 5482 | int nx = parag->nextTab( i, x - left ) + left; |
5509 | if ( nx < x ) | 5483 | if ( nx < x ) |
5510 | ww = w - x; | 5484 | ww = w - x; |
5511 | else | 5485 | else |
5512 | ww = nx - x; | 5486 | ww = nx - x; |
5513 | } | 5487 | } |
5514 | curLeft = x; | 5488 | curLeft = x; |
5515 | y += QMAX( h, linespacing ); | 5489 | y += QMAX( h, linespacing ); |
5516 | tmph = c->height(); | 5490 | tmph = c->height(); |
5517 | h = tmph; | 5491 | h = tmph; |
5518 | lineStart->y = y; | 5492 | lineStart->y = y; |
5519 | insertLineStart( parag, i + 1, lineStart ); | 5493 | insertLineStart( parag, i + 1, lineStart ); |
5520 | lineStart->baseLine = c->ascent(); | 5494 | lineStart->baseLine = c->ascent(); |
5521 | lineStart->h = c->height(); | 5495 | lineStart->h = c->height(); |
5522 | c->lineStart = 1; | 5496 | c->lineStart = 1; |
5523 | firstChar = c; | 5497 | firstChar = c; |
5524 | tmpBaseLine = lineStart->baseLine; | 5498 | tmpBaseLine = lineStart->baseLine; |
5525 | lastBreak = -1; | 5499 | lastBreak = -1; |
5526 | col = 0; | 5500 | col = 0; |
5527 | tminw = marg; | 5501 | tminw = marg; |
5528 | continue; | 5502 | continue; |
5529 | } | 5503 | } |
5530 | } else if ( lineStart && isBreakable( string, i ) ) { | 5504 | } else if ( lineStart && isBreakable( string, i ) ) { |
5531 | if ( len <= 2 || i < len - 1 ) { | 5505 | if ( len <= 2 || i < len - 1 ) { |
5532 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); | 5506 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); |
5533 | tmph = QMAX( tmph, c->height() ); | 5507 | tmph = QMAX( tmph, c->height() ); |
5534 | } | 5508 | } |
5535 | minw = QMAX( minw, tminw ); | 5509 | minw = QMAX( minw, tminw ); |
5536 | tminw = marg + ww; | 5510 | tminw = marg + ww; |
5537 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5511 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5538 | h = QMAX( h, tmph ); | 5512 | h = QMAX( h, tmph ); |
5539 | lineStart->h = h; | 5513 | lineStart->h = h; |
5540 | if ( i < len - 2 || c->c != ' ' ) | 5514 | if ( i < len - 2 || c->c != ' ' ) |
5541 | lastBreak = i; | 5515 | lastBreak = i; |
5542 | } else { | 5516 | } else { |
5543 | tminw += ww; | 5517 | tminw += ww; |
5544 | int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() ); | 5518 | int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() ); |
5545 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); | 5519 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); |
5546 | tmph = tmpBaseLine + belowBaseLine; | 5520 | tmph = tmpBaseLine + belowBaseLine; |
5547 | } | 5521 | } |
5548 | 5522 | ||
5549 | c->x = x; | 5523 | c->x = x; |
5550 | x += ww; | 5524 | x += ww; |
5551 | wused = QMAX( wused, x ); | 5525 | wused = QMAX( wused, x ); |
5552 | } | 5526 | } |
5553 | 5527 | ||
5554 | // ### hack. The last char in the paragraph is always invisible, | 5528 | // ### hack. The last char in the paragraph is always invisible, |
5555 | // ### and somehow sometimes has a wrong format. It changes | 5529 | // ### and somehow sometimes has a wrong format. It changes |
5556 | // ### between // layouting and printing. This corrects some | 5530 | // ### between // layouting and printing. This corrects some |
5557 | // ### layouting errors in BiDi mode due to this. | 5531 | // ### layouting errors in BiDi mode due to this. |
5558 | if ( len > 1 && !c->isAnchor() ) { | 5532 | if ( len > 1 && !c->isAnchor() ) { |
5559 | c->format()->removeRef(); | 5533 | c->format()->removeRef(); |
5560 | c->setFormat( string->at( len - 2 ).format() ); | 5534 | c->setFormat( string->at( len - 2 ).format() ); |
5561 | c->format()->addRef(); | 5535 | c->format()->addRef(); |
5562 | } | 5536 | } |
5563 | 5537 | ||
5564 | if ( lineStart ) { | 5538 | if ( lineStart ) { |
5565 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5539 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5566 | h = QMAX( h, tmph ); | 5540 | h = QMAX( h, tmph ); |
5567 | lineStart->h = h; | 5541 | lineStart->h = h; |
5568 | // last line in a paragraph is not justified | 5542 | // last line in a paragraph is not justified |
5569 | if ( align == Qt3::AlignJustify || lastChr == QChar_linesep ) | 5543 | if ( align == Qt3::AlignJustify || lastChr == QChar_linesep ) |
5570 | align = Qt3::AlignAuto; | 5544 | align = Qt3::AlignAuto; |
5571 | DO_FLOW( lineStart ); | 5545 | DO_FLOW( lineStart ); |
5572 | lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) ); | 5546 | lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) ); |
5573 | delete lineStart; | 5547 | delete lineStart; |
5574 | } | 5548 | } |
5575 | 5549 | ||
5576 | minw = QMAX( minw, tminw ); | 5550 | minw = QMAX( minw, tminw ); |
5577 | if ( doc ) | 5551 | if ( doc ) |
5578 | minw += doc->rightMargin(); | 5552 | minw += doc->rightMargin(); |
5579 | 5553 | ||
5580 | int m = parag->bottomMargin(); | 5554 | int m = parag->bottomMargin(); |
5581 | if ( !parag->next() ) | 5555 | if ( !parag->next() ) |
5582 | m = 0; | 5556 | m = 0; |
5583 | else | 5557 | else |
5584 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5558 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5585 | parag->setFullWidth( fullWidth ); | 5559 | parag->setFullWidth( fullWidth ); |
5586 | y += QMAX( h, linespacing ) + m; | 5560 | y += QMAX( h, linespacing ) + m; |
5587 | 5561 | ||
5588 | wused += rm; | 5562 | wused += rm; |
5589 | if ( !wrapEnabled || wrapAtColumn() != -1 ) | 5563 | if ( !wrapEnabled || wrapAtColumn() != -1 ) |
5590 | minw = QMAX(minw, wused); | 5564 | minw = QMAX(minw, wused); |
5591 | 5565 | ||
5592 | // This is the case where we are breaking wherever we darn well please | 5566 | // This is the case where we are breaking wherever we darn well please |
5593 | // in cases like that, the minw should not be the length of the entire | 5567 | // in cases like that, the minw should not be the length of the entire |
5594 | // word, because we necessarily want to show the word on the whole line. | 5568 | // word, because we necessarily want to show the word on the whole line. |
5595 | // example: word wrap in iconview | 5569 | // example: word wrap in iconview |
5596 | if ( allowBreakInWords() && minw > wused ) | 5570 | if ( allowBreakInWords() && minw > wused ) |
5597 | minw = wused; | 5571 | minw = wused; |
5598 | 5572 | ||
5599 | thisminw = minw; | 5573 | thisminw = minw; |
5600 | thiswused = wused; | 5574 | thiswused = wused; |
5601 | return y; | 5575 | return y; |
5602 | } | 5576 | } |
5603 | 5577 | ||
5604 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5578 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5605 | 5579 | ||
5606 | QTextIndent::QTextIndent() | 5580 | QTextIndent::QTextIndent() |
5607 | { | 5581 | { |
5608 | } | 5582 | } |
5609 | 5583 | ||
5610 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5584 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5611 | 5585 | ||
5612 | QTextFormatCollection::QTextFormatCollection() | 5586 | QTextFormatCollection::QTextFormatCollection() |
5613 | : cKey( 307 ) | 5587 | : cKey( 307 ) |
5614 | { | 5588 | { |
5615 | defFormat = new QTextFormat( QApplication::font(), | 5589 | defFormat = new QTextFormat( QApplication::font(), |
5616 | QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); | 5590 | QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); |
5617 | lastFormat = cres = 0; | 5591 | lastFormat = cres = 0; |
5618 | cflags = -1; | 5592 | cflags = -1; |
5619 | cKey.setAutoDelete( TRUE ); | 5593 | cKey.setAutoDelete( TRUE ); |
5620 | cachedFormat = 0; | 5594 | cachedFormat = 0; |
5621 | } | 5595 | } |
5622 | 5596 | ||
5623 | QTextFormatCollection::~QTextFormatCollection() | 5597 | QTextFormatCollection::~QTextFormatCollection() |
5624 | { | 5598 | { |
5625 | delete defFormat; | 5599 | delete defFormat; |
5626 | } | 5600 | } |
5627 | 5601 | ||
5628 | QTextFormat *QTextFormatCollection::format( QTextFormat *f ) | 5602 | QTextFormat *QTextFormatCollection::format( QTextFormat *f ) |
5629 | { | 5603 | { |
5630 | if ( f->parent() == this || f == defFormat ) { | 5604 | if ( f->parent() == this || f == defFormat ) { |
5631 | lastFormat = f; | 5605 | lastFormat = f; |
5632 | lastFormat->addRef(); | 5606 | lastFormat->addRef(); |
5633 | return lastFormat; | 5607 | return lastFormat; |
5634 | } | 5608 | } |
5635 | 5609 | ||
5636 | if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { | 5610 | if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { |
5637 | lastFormat->addRef(); | 5611 | lastFormat->addRef(); |
5638 | return lastFormat; | 5612 | return lastFormat; |
5639 | } | 5613 | } |
5640 | 5614 | ||
5641 | QTextFormat *fm = cKey.find( f->key() ); | 5615 | QTextFormat *fm = cKey.find( f->key() ); |
5642 | if ( fm ) { | 5616 | if ( fm ) { |
5643 | lastFormat = fm; | 5617 | lastFormat = fm; |
5644 | lastFormat->addRef(); | 5618 | lastFormat->addRef(); |
5645 | return lastFormat; | 5619 | return lastFormat; |
5646 | } | 5620 | } |
5647 | 5621 | ||
5648 | if ( f->key() == defFormat->key() ) | 5622 | if ( f->key() == defFormat->key() ) |
5649 | return defFormat; | 5623 | return defFormat; |
5650 | 5624 | ||
5651 | lastFormat = createFormat( *f ); | 5625 | lastFormat = createFormat( *f ); |
5652 | lastFormat->collection = this; | 5626 | lastFormat->collection = this; |
5653 | cKey.insert( lastFormat->key(), lastFormat ); | 5627 | cKey.insert( lastFormat->key(), lastFormat ); |
5654 | return lastFormat; | 5628 | return lastFormat; |
5655 | } | 5629 | } |
5656 | 5630 | ||
5657 | QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) | 5631 | QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) |
5658 | { | 5632 | { |
5659 | if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { | 5633 | if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { |
5660 | cres->addRef(); | 5634 | cres->addRef(); |
5661 | return cres; | 5635 | return cres; |
5662 | } | 5636 | } |
5663 | 5637 | ||
5664 | cres = createFormat( *of ); | 5638 | cres = createFormat( *of ); |
5665 | kof = of->key(); | 5639 | kof = of->key(); |
5666 | knf = nf->key(); | 5640 | knf = nf->key(); |
5667 | cflags = flags; | 5641 | cflags = flags; |
5668 | if ( flags & QTextFormat::Bold ) | 5642 | if ( flags & QTextFormat::Bold ) |
5669 | cres->fn.setBold( nf->fn.bold() ); | 5643 | cres->fn.setBold( nf->fn.bold() ); |
5670 | if ( flags & QTextFormat::Italic ) | 5644 | if ( flags & QTextFormat::Italic ) |
5671 | cres->fn.setItalic( nf->fn.italic() ); | 5645 | cres->fn.setItalic( nf->fn.italic() ); |
5672 | if ( flags & QTextFormat::Underline ) | 5646 | if ( flags & QTextFormat::Underline ) |
5673 | cres->fn.setUnderline( nf->fn.underline() ); | 5647 | cres->fn.setUnderline( nf->fn.underline() ); |
5674 | if ( flags & QTextFormat::StrikeOut ) | 5648 | if ( flags & QTextFormat::StrikeOut ) |
5675 | cres->fn.setStrikeOut( nf->fn.strikeOut() ); | 5649 | cres->fn.setStrikeOut( nf->fn.strikeOut() ); |
5676 | if ( flags & QTextFormat::Family ) | 5650 | if ( flags & QTextFormat::Family ) |
5677 | cres->fn.setFamily( nf->fn.family() ); | 5651 | cres->fn.setFamily( nf->fn.family() ); |
5678 | if ( flags & QTextFormat::Size ) { | 5652 | if ( flags & QTextFormat::Size ) { |
5679 | if ( of->usePixelSizes ) | 5653 | if ( of->usePixelSizes ) |
5680 | cres->fn.setPixelSize( nf->fn.pixelSize() ); | 5654 | cres->fn.setPixelSize( nf->fn.pixelSize() ); |
5681 | else | 5655 | else |
5682 | cres->fn.setPointSize( nf->fn.pointSize() ); | 5656 | cres->fn.setPointSize( nf->fn.pointSize() ); |
5683 | } | 5657 | } |
5684 | if ( flags & QTextFormat::Color ) | 5658 | if ( flags & QTextFormat::Color ) |
5685 | cres->col = nf->col; | 5659 | cres->col = nf->col; |
5686 | if ( flags & QTextFormat::Misspelled ) | 5660 | if ( flags & QTextFormat::Misspelled ) |
5687 | cres->missp = nf->missp; | 5661 | cres->missp = nf->missp; |
5688 | if ( flags & QTextFormat::VAlign ) | 5662 | if ( flags & QTextFormat::VAlign ) |
5689 | cres->ha = nf->ha; | 5663 | cres->ha = nf->ha; |
5690 | cres->update(); | 5664 | cres->update(); |
5691 | 5665 | ||
5692 | QTextFormat *fm = cKey.find( cres->key() ); | 5666 | QTextFormat *fm = cKey.find( cres->key() ); |
5693 | if ( !fm ) { | 5667 | if ( !fm ) { |
5694 | cres->collection = this; | 5668 | cres->collection = this; |
5695 | cKey.insert( cres->key(), cres ); | 5669 | cKey.insert( cres->key(), cres ); |
5696 | } else { | 5670 | } else { |
5697 | delete cres; | 5671 | delete cres; |
5698 | cres = fm; | 5672 | cres = fm; |
5699 | cres->addRef(); | 5673 | cres->addRef(); |
5700 | } | 5674 | } |
5701 | 5675 | ||
5702 | return cres; | 5676 | return cres; |
5703 | } | 5677 | } |
5704 | 5678 | ||
5705 | QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) | 5679 | QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) |
5706 | { | 5680 | { |
5707 | if ( cachedFormat && cfont == f && ccol == c ) { | 5681 | if ( cachedFormat && cfont == f && ccol == c ) { |
5708 | cachedFormat->addRef(); | 5682 | cachedFormat->addRef(); |
5709 | return cachedFormat; | 5683 | return cachedFormat; |
5710 | } | 5684 | } |
5711 | 5685 | ||
5712 | QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal ); | 5686 | QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal ); |
5713 | cachedFormat = cKey.find( key ); | 5687 | cachedFormat = cKey.find( key ); |
5714 | cfont = f; | 5688 | cfont = f; |
5715 | ccol = c; | 5689 | ccol = c; |
5716 | 5690 | ||
5717 | if ( cachedFormat ) { | 5691 | if ( cachedFormat ) { |
5718 | cachedFormat->addRef(); | 5692 | cachedFormat->addRef(); |
5719 | return cachedFormat; | 5693 | return cachedFormat; |
5720 | } | 5694 | } |
5721 | 5695 | ||
5722 | if ( key == defFormat->key() ) | 5696 | if ( key == defFormat->key() ) |
5723 | return defFormat; | 5697 | return defFormat; |
5724 | 5698 | ||
5725 | cachedFormat = createFormat( f, c ); | 5699 | cachedFormat = createFormat( f, c ); |
5726 | cachedFormat->collection = this; | 5700 | cachedFormat->collection = this; |
5727 | cKey.insert( cachedFormat->key(), cachedFormat ); | 5701 | cKey.insert( cachedFormat->key(), cachedFormat ); |
5728 | if ( cachedFormat->key() != key ) | 5702 | if ( cachedFormat->key() != key ) |
5729 | owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl; | 5703 | owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl; |
5730 | return cachedFormat; | 5704 | return cachedFormat; |
5731 | } | 5705 | } |
5732 | 5706 | ||
5733 | void QTextFormatCollection::remove( QTextFormat *f ) | 5707 | void QTextFormatCollection::remove( QTextFormat *f ) |
5734 | { | 5708 | { |
5735 | if ( lastFormat == f ) | 5709 | if ( lastFormat == f ) |
5736 | lastFormat = 0; | 5710 | lastFormat = 0; |
5737 | if ( cres == f ) | 5711 | if ( cres == f ) |
5738 | cres = 0; | 5712 | cres = 0; |
5739 | if ( cachedFormat == f ) | 5713 | if ( cachedFormat == f ) |
5740 | cachedFormat = 0; | 5714 | cachedFormat = 0; |
5741 | cKey.remove( f->key() ); | 5715 | cKey.remove( f->key() ); |
5742 | } | 5716 | } |
5743 | 5717 | ||
5744 | #define UPDATE( up, lo, rest ) \ | 5718 | #define UPDATE( up, lo, rest ) \ |
5745 | if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \ | 5719 | if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \ |
5746 | fm->fn.set##up##rest( font.lo##rest() ) | 5720 | fm->fn.set##up##rest( font.lo##rest() ) |
5747 | 5721 | ||
5748 | void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet ) | 5722 | void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet ) |
5749 | { | 5723 | { |
5750 | QDictIterator<QTextFormat> it( cKey ); | 5724 | QDictIterator<QTextFormat> it( cKey ); |
5751 | QTextFormat *fm; | 5725 | QTextFormat *fm; |
5752 | bool usePixels = font.pointSize() == -1; | 5726 | bool usePixels = font.pointSize() == -1; |
5753 | bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() : | 5727 | bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() : |
5754 | font.pointSize() != defFormat->fn.pointSize(); | 5728 | font.pointSize() != defFormat->fn.pointSize(); |
5755 | int base = usePixels ? font.pixelSize() : font.pointSize(); | 5729 | int base = usePixels ? font.pixelSize() : font.pointSize(); |
5756 | while ( ( fm = it.current() ) ) { | 5730 | while ( ( fm = it.current() ) ) { |
5757 | ++it; | 5731 | ++it; |
5758 | UPDATE( F, f, amily ); | 5732 | UPDATE( F, f, amily ); |
5759 | UPDATE( W, w, eight ); | 5733 | UPDATE( W, w, eight ); |
5760 | UPDATE( B, b, old ); | 5734 | UPDATE( B, b, old ); |
5761 | UPDATE( I, i, talic ); | 5735 | UPDATE( I, i, talic ); |
5762 | UPDATE( U, u, nderline ); | 5736 | UPDATE( U, u, nderline ); |
5763 | if ( changeSize ) { | 5737 | if ( changeSize ) { |
5764 | fm->stdSize = base; | 5738 | fm->stdSize = base; |
5765 | fm->usePixelSizes = usePixels; | 5739 | fm->usePixelSizes = usePixels; |
5766 | if ( usePixels ) | 5740 | if ( usePixels ) |
5767 | fm->fn.setPixelSize( fm->stdSize ); | 5741 | fm->fn.setPixelSize( fm->stdSize ); |
5768 | else | 5742 | else |
5769 | fm->fn.setPointSize( fm->stdSize ); | 5743 | fm->fn.setPointSize( fm->stdSize ); |
5770 | sheet->scaleFont( fm->fn, fm->logicalFontSize ); | 5744 | sheet->scaleFont( fm->fn, fm->logicalFontSize ); |
5771 | } | 5745 | } |
5772 | if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col ) | 5746 | if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col ) |
5773 | fm->col = color; | 5747 | fm->col = color; |
5774 | fm->update(); | 5748 | fm->update(); |
5775 | } | 5749 | } |
5776 | 5750 | ||
5777 | defFormat->fn = font; | 5751 | defFormat->fn = font; |
5778 | defFormat->col = color; | 5752 | defFormat->col = color; |
5779 | defFormat->update(); | 5753 | defFormat->update(); |
5780 | defFormat->stdSize = base; | 5754 | defFormat->stdSize = base; |
5781 | defFormat->usePixelSizes = usePixels; | 5755 | defFormat->usePixelSizes = usePixels; |
5782 | 5756 | ||
5783 | updateKeys(); | 5757 | updateKeys(); |
5784 | } | 5758 | } |
5785 | 5759 | ||
5786 | // the keys in cKey have changed, rebuild the hashtable | 5760 | // the keys in cKey have changed, rebuild the hashtable |
5787 | void QTextFormatCollection::updateKeys() | 5761 | void QTextFormatCollection::updateKeys() |
5788 | { | 5762 | { |
5789 | if ( cKey.isEmpty() ) | 5763 | if ( cKey.isEmpty() ) |
5790 | return; | 5764 | return; |
5791 | cKey.setAutoDelete( FALSE ); | 5765 | cKey.setAutoDelete( FALSE ); |
5792 | QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ]; | 5766 | QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ]; |
5793 | QTextFormat **f = formats; | 5767 | QTextFormat **f = formats; |
5794 | QDictIterator<QTextFormat> it( cKey ); | 5768 | QDictIterator<QTextFormat> it( cKey ); |
5795 | while ( ( *f = it.current() ) ) { | 5769 | while ( ( *f = it.current() ) ) { |
5796 | ++it; | 5770 | ++it; |
5797 | ++f; | 5771 | ++f; |
5798 | } | 5772 | } |
5799 | cKey.clear(); | 5773 | cKey.clear(); |
5800 | for ( f = formats; *f; f++ ) | 5774 | for ( f = formats; *f; f++ ) |
5801 | cKey.insert( (*f)->key(), *f ); | 5775 | cKey.insert( (*f)->key(), *f ); |
5802 | cKey.setAutoDelete( TRUE ); | 5776 | cKey.setAutoDelete( TRUE ); |
5803 | delete [] formats; | 5777 | delete [] formats; |
5804 | } | 5778 | } |
5805 | 5779 | ||
5806 | 5780 | ||
5807 | 5781 | ||
5808 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5782 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5809 | 5783 | ||
5810 | void QTextFormat::setBold( bool b ) | 5784 | void QTextFormat::setBold( bool b ) |
5811 | { | 5785 | { |
5812 | if ( b == fn.bold() ) | 5786 | if ( b == fn.bold() ) |
5813 | return; | 5787 | return; |
5814 | fn.setBold( b ); | 5788 | fn.setBold( b ); |
5815 | update(); | 5789 | update(); |
5816 | } | 5790 | } |
5817 | 5791 | ||
5818 | void QTextFormat::setMisspelled( bool b ) | 5792 | void QTextFormat::setMisspelled( bool b ) |
5819 | { | 5793 | { |
5820 | if ( b == (bool)missp ) | 5794 | if ( b == (bool)missp ) |
5821 | return; | 5795 | return; |
5822 | missp = b; | 5796 | missp = b; |
5823 | update(); | 5797 | update(); |
5824 | } | 5798 | } |
5825 | 5799 | ||
5826 | void QTextFormat::setVAlign( VerticalAlignment a ) | 5800 | void QTextFormat::setVAlign( VerticalAlignment a ) |
5827 | { | 5801 | { |
5828 | if ( a == ha ) | 5802 | if ( a == ha ) |
5829 | return; | 5803 | return; |
5830 | ha = a; | 5804 | ha = a; |
5831 | update(); | 5805 | update(); |
5832 | } | 5806 | } |
5833 | 5807 | ||
5834 | void QTextFormat::setItalic( bool b ) | 5808 | void QTextFormat::setItalic( bool b ) |
5835 | { | 5809 | { |
5836 | if ( b == fn.italic() ) | 5810 | if ( b == fn.italic() ) |
5837 | return; | 5811 | return; |
5838 | fn.setItalic( b ); | 5812 | fn.setItalic( b ); |
5839 | update(); | 5813 | update(); |
5840 | } | 5814 | } |
5841 | 5815 | ||
5842 | void QTextFormat::setUnderline( bool b ) | 5816 | void QTextFormat::setUnderline( bool b ) |
5843 | { | 5817 | { |
5844 | if ( b == fn.underline() ) | 5818 | if ( b == fn.underline() ) |
5845 | return; | 5819 | return; |
5846 | fn.setUnderline( b ); | 5820 | fn.setUnderline( b ); |
5847 | update(); | 5821 | update(); |
5848 | } | 5822 | } |
5849 | 5823 | ||
5850 | void QTextFormat::setStrikeOut( bool b ) | 5824 | void QTextFormat::setStrikeOut( bool b ) |
5851 | { | 5825 | { |
5852 | if ( b == fn.strikeOut() ) | 5826 | if ( b == fn.strikeOut() ) |
5853 | return; | 5827 | return; |
5854 | fn.setStrikeOut( b ); | 5828 | fn.setStrikeOut( b ); |
5855 | update(); | 5829 | update(); |
5856 | } | 5830 | } |
5857 | 5831 | ||
5858 | void QTextFormat::setFamily( const QString &f ) | 5832 | void QTextFormat::setFamily( const QString &f ) |
5859 | { | 5833 | { |
5860 | if ( f == fn.family() ) | 5834 | if ( f == fn.family() ) |
5861 | return; | 5835 | return; |
5862 | fn.setFamily( f ); | 5836 | fn.setFamily( f ); |
5863 | update(); | 5837 | update(); |
5864 | } | 5838 | } |
5865 | 5839 | ||
5866 | void QTextFormat::setPointSize( int s ) | 5840 | void QTextFormat::setPointSize( int s ) |
5867 | { | 5841 | { |
5868 | if ( s == fn.pointSize() ) | 5842 | if ( s == fn.pointSize() ) |
5869 | return; | 5843 | return; |
5870 | fn.setPointSize( s ); | 5844 | fn.setPointSize( s ); |
5871 | usePixelSizes = FALSE; | 5845 | usePixelSizes = FALSE; |
5872 | update(); | 5846 | update(); |
5873 | } | 5847 | } |
5874 | 5848 | ||
5875 | void QTextFormat::setFont( const QFont &f ) | 5849 | void QTextFormat::setFont( const QFont &f ) |
5876 | { | 5850 | { |
5877 | if ( f == fn && !k.isEmpty() ) | 5851 | if ( f == fn && !k.isEmpty() ) |
5878 | return; | 5852 | return; |
5879 | fn = f; | 5853 | fn = f; |
5880 | update(); | 5854 | update(); |
5881 | } | 5855 | } |
5882 | 5856 | ||
5883 | void QTextFormat::setColor( const QColor &c ) | 5857 | void QTextFormat::setColor( const QColor &c ) |
5884 | { | 5858 | { |
5885 | if ( c == col ) | 5859 | if ( c == col ) |
5886 | return; | 5860 | return; |
5887 | col = c; | 5861 | col = c; |
5888 | update(); | 5862 | update(); |
5889 | } | 5863 | } |
5890 | 5864 | ||
5891 | QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, | 5865 | QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, |
5892 | const QString& oldAnchorHref, const QString& anchorHref ) const | 5866 | const QString& oldAnchorHref, const QString& anchorHref ) const |
5893 | { | 5867 | { |
5894 | QString tag; | 5868 | QString tag; |
5895 | if ( f ) | 5869 | if ( f ) |
5896 | tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref ); | 5870 | tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref ); |
5897 | 5871 | ||
5898 | if ( !anchorHref.isEmpty() ) | 5872 | if ( !anchorHref.isEmpty() ) |
5899 | tag += "<a href=\"" + anchorHref + "\">"; | 5873 | tag += "<a href=\"" + anchorHref + "\">"; |
5900 | 5874 | ||
5901 | if ( font() != defaultFormat->font() | 5875 | if ( font() != defaultFormat->font() |
5902 | || vAlign() != defaultFormat->vAlign() | 5876 | || vAlign() != defaultFormat->vAlign() |
5903 | || color().rgb() != defaultFormat->color().rgb() ) { | 5877 | || color().rgb() != defaultFormat->color().rgb() ) { |
5904 | QString s; | 5878 | QString s; |
5905 | if ( font().family() != defaultFormat->font().family() ) | 5879 | if ( font().family() != defaultFormat->font().family() ) |
5906 | s += QString(!!s?";":"") + "font-family:" + fn.family(); | 5880 | s += QString(!!s?";":"") + "font-family:" + fn.family(); |
5907 | if ( font().italic() && font().italic() != defaultFormat->font().italic() ) | 5881 | if ( font().italic() && font().italic() != defaultFormat->font().italic() ) |
5908 | s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal"); | 5882 | s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal"); |
5909 | if ( font().pointSize() != defaultFormat->font().pointSize() ) | 5883 | if ( font().pointSize() != defaultFormat->font().pointSize() ) |
5910 | s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt"; | 5884 | s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt"; |
5911 | if ( font().weight() != defaultFormat->font().weight() ) | 5885 | if ( font().weight() != defaultFormat->font().weight() ) |
5912 | s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 ); | 5886 | s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 ); |
5913 | if ( font().underline() != defaultFormat->font().underline() ) | 5887 | if ( font().underline() != defaultFormat->font().underline() ) |
5914 | s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none"); | 5888 | s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none"); |
5915 | if ( vAlign() != defaultFormat->vAlign() ) { | 5889 | if ( vAlign() != defaultFormat->vAlign() ) { |
5916 | s += QString(!!s?";":"") + "vertical-align:"; | 5890 | s += QString(!!s?";":"") + "vertical-align:"; |
5917 | if ( vAlign() == QTextFormat::AlignSuperScript ) | 5891 | if ( vAlign() == QTextFormat::AlignSuperScript ) |
5918 | s += "super"; | 5892 | s += "super"; |
5919 | else if ( vAlign() == QTextFormat::AlignSubScript ) | 5893 | else if ( vAlign() == QTextFormat::AlignSubScript ) |
5920 | s += "sub"; | 5894 | s += "sub"; |
5921 | else | 5895 | else |
5922 | s += "normal"; | 5896 | s += "normal"; |
5923 | } | 5897 | } |
5924 | if ( color().rgb() != defaultFormat->color().rgb() ) | 5898 | if ( color().rgb() != defaultFormat->color().rgb() ) |
5925 | s += QString(!!s?";":"") + "color:" + col.name(); | 5899 | s += QString(!!s?";":"") + "color:" + col.name(); |
5926 | if ( !s.isEmpty() ) | 5900 | if ( !s.isEmpty() ) |
5927 | tag += "<span style=\"" + s + "\">"; | 5901 | tag += "<span style=\"" + s + "\">"; |
5928 | } | 5902 | } |
5929 | 5903 | ||
5930 | return tag; | 5904 | return tag; |
5931 | } | 5905 | } |
5932 | 5906 | ||
5933 | QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const | 5907 | QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const |
5934 | { | 5908 | { |
5935 | QString tag; | 5909 | QString tag; |
5936 | if ( font().family() != defaultFormat->font().family() | 5910 | if ( font().family() != defaultFormat->font().family() |
5937 | || font().pointSize() != defaultFormat->font().pointSize() | 5911 | || font().pointSize() != defaultFormat->font().pointSize() |
5938 | || font().weight() != defaultFormat->font().weight() | 5912 | || font().weight() != defaultFormat->font().weight() |
5939 | || font().italic() != defaultFormat->font().italic() | 5913 | || font().italic() != defaultFormat->font().italic() |
5940 | || font().underline() != defaultFormat->font().underline() | 5914 | || font().underline() != defaultFormat->font().underline() |
5941 | || font().strikeOut() != defaultFormat->font().strikeOut() | 5915 | || font().strikeOut() != defaultFormat->font().strikeOut() |
5942 | || vAlign() != defaultFormat->vAlign() | 5916 | || vAlign() != defaultFormat->vAlign() |
5943 | || color().rgb() != defaultFormat->color().rgb() ) | 5917 | || color().rgb() != defaultFormat->color().rgb() ) |
5944 | tag += "</span>"; | 5918 | tag += "</span>"; |
5945 | if ( !anchorHref.isEmpty() ) | 5919 | if ( !anchorHref.isEmpty() ) |
5946 | tag += "</a>"; | 5920 | tag += "</a>"; |
5947 | return tag; | 5921 | return tag; |
5948 | } | 5922 | } |
5949 | 5923 | ||
5950 | QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const | 5924 | QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const |
5951 | { | 5925 | { |
5952 | QTextFormat format(*this); | 5926 | QTextFormat format(*this); |
5953 | if (!style ) | 5927 | if (!style ) |
5954 | return format; | 5928 | return format; |
5955 | 5929 | ||
5956 | if ( !style->isAnchor() && style->color().isValid() ) { | 5930 | if ( !style->isAnchor() && style->color().isValid() ) { |
5957 | // the style is not an anchor and defines a color. | 5931 | // the style is not an anchor and defines a color. |
5958 | // It might be used inside an anchor and it should | 5932 | // It might be used inside an anchor and it should |
5959 | // override the link color. | 5933 | // override the link color. |
5960 | format.linkColor = FALSE; | 5934 | format.linkColor = FALSE; |
5961 | } | 5935 | } |
5962 | switch ( style->verticalAlignment() ) { | 5936 | switch ( style->verticalAlignment() ) { |
5963 | case QStyleSheetItem::VAlignBaseline: | 5937 | case QStyleSheetItem::VAlignBaseline: |
5964 | format.setVAlign( QTextFormat::AlignNormal ); | 5938 | format.setVAlign( QTextFormat::AlignNormal ); |
5965 | break; | 5939 | break; |
5966 | case QStyleSheetItem::VAlignSuper: | 5940 | case QStyleSheetItem::VAlignSuper: |
5967 | format.setVAlign( QTextFormat::AlignSuperScript ); | 5941 | format.setVAlign( QTextFormat::AlignSuperScript ); |
5968 | break; | 5942 | break; |
5969 | case QStyleSheetItem::VAlignSub: | 5943 | case QStyleSheetItem::VAlignSub: |
5970 | format.setVAlign( QTextFormat::AlignSubScript ); | 5944 | format.setVAlign( QTextFormat::AlignSubScript ); |
5971 | break; | 5945 | break; |
5972 | } | 5946 | } |
5973 | 5947 | ||
5974 | if ( style->fontWeight() != QStyleSheetItem::Undefined ) | 5948 | if ( style->fontWeight() != QStyleSheetItem::Undefined ) |
5975 | format.fn.setWeight( style->fontWeight() ); | 5949 | format.fn.setWeight( style->fontWeight() ); |
5976 | if ( style->fontSize() != QStyleSheetItem::Undefined ) { | 5950 | if ( style->fontSize() != QStyleSheetItem::Undefined ) { |
5977 | format.fn.setPointSize( style->fontSize() ); | 5951 | format.fn.setPointSize( style->fontSize() ); |
5978 | } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { | 5952 | } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { |
5979 | format.logicalFontSize = style->logicalFontSize(); | 5953 | format.logicalFontSize = style->logicalFontSize(); |
5980 | if ( format.usePixelSizes ) | 5954 | if ( format.usePixelSizes ) |
5981 | format.fn.setPixelSize( format.stdSize ); | 5955 | format.fn.setPixelSize( format.stdSize ); |
5982 | else | 5956 | else |
5983 | format.fn.setPointSize( format.stdSize ); | 5957 | format.fn.setPointSize( format.stdSize ); |
5984 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 5958 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
5985 | } else if ( style->logicalFontSizeStep() ) { | 5959 | } else if ( style->logicalFontSizeStep() ) { |
5986 | format.logicalFontSize += style->logicalFontSizeStep(); | 5960 | format.logicalFontSize += style->logicalFontSizeStep(); |
5987 | if ( format.usePixelSizes ) | 5961 | if ( format.usePixelSizes ) |
5988 | format.fn.setPixelSize( format.stdSize ); | 5962 | format.fn.setPixelSize( format.stdSize ); |
5989 | else | 5963 | else |
5990 | format.fn.setPointSize( format.stdSize ); | 5964 | format.fn.setPointSize( format.stdSize ); |
5991 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 5965 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
5992 | } | 5966 | } |
5993 | if ( !style->fontFamily().isEmpty() ) | 5967 | if ( !style->fontFamily().isEmpty() ) |
5994 | format.fn.setFamily( style->fontFamily() ); | 5968 | format.fn.setFamily( style->fontFamily() ); |
5995 | if ( style->color().isValid() ) | 5969 | if ( style->color().isValid() ) |
5996 | format.col = style->color(); | 5970 | format.col = style->color(); |
5997 | if ( style->definesFontItalic() ) | 5971 | if ( style->definesFontItalic() ) |
5998 | format.fn.setItalic( style->fontItalic() ); | 5972 | format.fn.setItalic( style->fontItalic() ); |
5999 | if ( style->definesFontUnderline() ) | 5973 | if ( style->definesFontUnderline() ) |
6000 | format.fn.setUnderline( style->fontUnderline() ); | 5974 | format.fn.setUnderline( style->fontUnderline() ); |
6001 | if ( style->definesFontStrikeOut() ) | 5975 | if ( style->definesFontStrikeOut() ) |
6002 | format.fn.setStrikeOut( style->fontStrikeOut() ); | 5976 | format.fn.setStrikeOut( style->fontStrikeOut() ); |
6003 | 5977 | ||
6004 | 5978 | ||
6005 | if ( style->name() == "font") { | 5979 | if ( style->name() == "font") { |
6006 | if ( attr.contains("color") ) { | 5980 | if ( attr.contains("color") ) { |
6007 | QString s = attr["color"]; | 5981 | QString s = attr["color"]; |
6008 | if ( !s.isEmpty() ) { | 5982 | if ( !s.isEmpty() ) { |
6009 | format.col.setNamedColor( s ); | 5983 | format.col.setNamedColor( s ); |
6010 | format.linkColor = FALSE; | 5984 | format.linkColor = FALSE; |
6011 | } | 5985 | } |
6012 | } | 5986 | } |
6013 | if ( attr.contains("face") ) { | 5987 | if ( attr.contains("face") ) { |
6014 | QString a = attr["face"]; | 5988 | QString a = attr["face"]; |
6015 | QString family = QTextDocument::section( a, ",", 0, 0 ); | 5989 | QString family = QTextDocument::section( a, ",", 0, 0 ); |
6016 | if ( !!family ) | 5990 | if ( !!family ) |
6017 | format.fn.setFamily( family ); | 5991 | format.fn.setFamily( family ); |
6018 | } | 5992 | } |
6019 | if ( attr.contains("size") ) { | 5993 | if ( attr.contains("size") ) { |
6020 | QString a = attr["size"]; | 5994 | QString a = attr["size"]; |
6021 | int n = a.toInt(); | 5995 | int n = a.toInt(); |
6022 | if ( a[0] == '+' || a[0] == '-' ) | 5996 | if ( a[0] == '+' || a[0] == '-' ) |
6023 | n += format.logicalFontSize; | 5997 | n += format.logicalFontSize; |
6024 | format.logicalFontSize = n; | 5998 | format.logicalFontSize = n; |
6025 | if ( format.usePixelSizes ) | 5999 | if ( format.usePixelSizes ) |
6026 | format.fn.setPixelSize( format.stdSize ); | 6000 | format.fn.setPixelSize( format.stdSize ); |
6027 | else | 6001 | else |
6028 | format.fn.setPointSize( format.stdSize ); | 6002 | format.fn.setPointSize( format.stdSize ); |
6029 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 6003 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
6030 | } | 6004 | } |
6031 | } | 6005 | } |
6032 | if ( attr.contains("style" ) ) { | 6006 | if ( attr.contains("style" ) ) { |
6033 | QString a = attr["style"]; | 6007 | QString a = attr["style"]; |
6034 | for ( int s = 0; s < a.contains(';')+1; s++ ) { | 6008 | for ( int s = 0; s < a.contains(';')+1; s++ ) { |
6035 | QString style = QTextDocument::section( a, ";", s, s ); | 6009 | QString style = QTextDocument::section( a, ";", s, s ); |
6036 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { | 6010 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { |
6037 | format.logicalFontSize = 0; | 6011 | format.logicalFontSize = 0; |
6038 | format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) ); | 6012 | format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) ); |
6039 | } if ( style.startsWith("font-style:" ) ) { | 6013 | } if ( style.startsWith("font-style:" ) ) { |
6040 | QString s = style.mid( 11 ).stripWhiteSpace(); | 6014 | QString s = style.mid( 11 ).stripWhiteSpace(); |
6041 | if ( s == "normal" ) | 6015 | if ( s == "normal" ) |
6042 | format.fn.setItalic( FALSE ); | 6016 | format.fn.setItalic( FALSE ); |
6043 | else if ( s == "italic" || s == "oblique" ) | 6017 | else if ( s == "italic" || s == "oblique" ) |
6044 | format.fn.setItalic( TRUE ); | 6018 | format.fn.setItalic( TRUE ); |
6045 | } else if ( style.startsWith("font-weight:" ) ) { | 6019 | } else if ( style.startsWith("font-weight:" ) ) { |
6046 | QString s = style.mid( 12 ); | 6020 | QString s = style.mid( 12 ); |
6047 | bool ok = TRUE; | 6021 | bool ok = TRUE; |
6048 | int n = s.toInt( &ok ); | 6022 | int n = s.toInt( &ok ); |
6049 | if ( ok ) | 6023 | if ( ok ) |
6050 | format.fn.setWeight( n/8 ); | 6024 | format.fn.setWeight( n/8 ); |
6051 | } else if ( style.startsWith("font-family:" ) ) { | 6025 | } else if ( style.startsWith("font-family:" ) ) { |
6052 | format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() ); | 6026 | format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() ); |
6053 | } else if ( style.startsWith("text-decoration:" ) ) { | 6027 | } else if ( style.startsWith("text-decoration:" ) ) { |
6054 | QString s = style.mid( 16 ).stripWhiteSpace(); | 6028 | QString s = style.mid( 16 ).stripWhiteSpace(); |
6055 | format.fn.setUnderline( s == "underline" ); | 6029 | format.fn.setUnderline( s == "underline" ); |
6056 | } else if ( style.startsWith("vertical-align:" ) ) { | 6030 | } else if ( style.startsWith("vertical-align:" ) ) { |
6057 | QString s = style.mid( 15 ).stripWhiteSpace(); | 6031 | QString s = style.mid( 15 ).stripWhiteSpace(); |
6058 | if ( s == "sub" ) | 6032 | if ( s == "sub" ) |
6059 | format.setVAlign( QTextFormat::AlignSubScript ); | 6033 | format.setVAlign( QTextFormat::AlignSubScript ); |
6060 | else if ( s == "super" ) | 6034 | else if ( s == "super" ) |
6061 | format.setVAlign( QTextFormat::AlignSuperScript ); | 6035 | format.setVAlign( QTextFormat::AlignSuperScript ); |
6062 | else | 6036 | else |
6063 | format.setVAlign( QTextFormat::AlignNormal ); | 6037 | format.setVAlign( QTextFormat::AlignNormal ); |
6064 | } else if ( style.startsWith("color:" ) ) { | 6038 | } else if ( style.startsWith("color:" ) ) { |
6065 | format.col.setNamedColor( style.mid(6) ); | 6039 | format.col.setNamedColor( style.mid(6) ); |
6066 | format.linkColor = FALSE; | 6040 | format.linkColor = FALSE; |
6067 | } | 6041 | } |
6068 | } | 6042 | } |
6069 | } | 6043 | } |
6070 | 6044 | ||
6071 | format.update(); | 6045 | format.update(); |
6072 | return format; | 6046 | return format; |
6073 | } | 6047 | } |
6074 | 6048 | ||
6075 | struct QPixmapInt | 6049 | struct QPixmapInt |
6076 | { | 6050 | { |
6077 | QPixmapInt() : ref( 0 ) {} | 6051 | QPixmapInt() : ref( 0 ) {} |
6078 | QPixmap pm; | 6052 | QPixmap pm; |
6079 | int ref; | 6053 | int ref; |
6080 | }; | 6054 | }; |
6081 | 6055 | ||
6082 | static QMap<QString, QPixmapInt> *pixmap_map = 0; | 6056 | static QMap<QString, QPixmapInt> *pixmap_map = 0; |
6083 | 6057 | ||
6084 | QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context, | 6058 | QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context, |
6085 | QMimeSourceFactory &factory ) | 6059 | QMimeSourceFactory &factory ) |
6086 | : QTextCustomItem( p ), reg( 0 ) | 6060 | : QTextCustomItem( p ), reg( 0 ) |
6087 | { | 6061 | { |
6088 | width = height = 0; | 6062 | width = height = 0; |
6089 | if ( attr.contains("width") ) | 6063 | if ( attr.contains("width") ) |
6090 | width = attr["width"].toInt(); | 6064 | width = attr["width"].toInt(); |
6091 | if ( attr.contains("height") ) | 6065 | if ( attr.contains("height") ) |
6092 | height = attr["height"].toInt(); | 6066 | height = attr["height"].toInt(); |
6093 | 6067 | ||
6094 | QString imageName = attr["src"]; | 6068 | QString imageName = attr["src"]; |
6095 | 6069 | ||
6096 | if (!imageName) | 6070 | if (!imageName) |
6097 | imageName = attr["source"]; | 6071 | imageName = attr["source"]; |
6098 | 6072 | ||
6099 | if ( !imageName.isEmpty() ) { | 6073 | if ( !imageName.isEmpty() ) { |
6100 | imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); | 6074 | imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); |
6101 | if ( !pixmap_map ) | 6075 | if ( !pixmap_map ) |
6102 | pixmap_map = new QMap<QString, QPixmapInt>; | 6076 | pixmap_map = new QMap<QString, QPixmapInt>; |
6103 | if ( pixmap_map->contains( imgId ) ) { | 6077 | if ( pixmap_map->contains( imgId ) ) { |
6104 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6078 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6105 | pm = pmi.pm; | 6079 | pm = pmi.pm; |
6106 | pmi.ref++; | 6080 | pmi.ref++; |
6107 | width = pm.width(); | 6081 | width = pm.width(); |
6108 | height = pm.height(); | 6082 | height = pm.height(); |
6109 | } else { | 6083 | } else { |
6110 | QImage img; | 6084 | QImage img; |
6111 | const QMimeSource* m = | 6085 | const QMimeSource* m = |
6112 | factory.data( imageName, context ); | 6086 | factory.data( imageName, context ); |
6113 | if ( !m ) { | 6087 | if ( !m ) { |
6114 | owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl; | 6088 | owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl; |
6115 | } | 6089 | } |
6116 | else { | 6090 | else { |
6117 | if ( !QImageDrag::decode( m, img ) ) { | 6091 | if ( !QImageDrag::decode( m, img ) ) { |
6118 | owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl; | 6092 | owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl; |
6119 | } | 6093 | } |
6120 | } | 6094 | } |
6121 | 6095 | ||
6122 | if ( !img.isNull() ) { | 6096 | if ( !img.isNull() ) { |
6123 | if ( width == 0 ) { | 6097 | if ( width == 0 ) { |
6124 | width = img.width(); | 6098 | width = img.width(); |
6125 | if ( height != 0 ) { | 6099 | if ( height != 0 ) { |
6126 | width = img.width() * height / img.height(); | 6100 | width = img.width() * height / img.height(); |
6127 | } | 6101 | } |
6128 | } | 6102 | } |
6129 | if ( height == 0 ) { | 6103 | if ( height == 0 ) { |
6130 | height = img.height(); | 6104 | height = img.height(); |
6131 | if ( width != img.width() ) { | 6105 | if ( width != img.width() ) { |
6132 | height = img.height() * width / img.width(); | 6106 | height = img.height() * width / img.width(); |
6133 | } | 6107 | } |
6134 | } | 6108 | } |
6135 | if ( img.width() != width || img.height() != height ){ | 6109 | if ( img.width() != width || img.height() != height ){ |
6136 | #ifndef QT_NO_IMAGE_SMOOTHSCALE | 6110 | #ifndef QT_NO_IMAGE_SMOOTHSCALE |
6137 | img = img.smoothScale(width, height); | 6111 | img = img.smoothScale(width, height); |
6138 | #endif | 6112 | #endif |
6139 | width = img.width(); | 6113 | width = img.width(); |
6140 | height = img.height(); | 6114 | height = img.height(); |
6141 | } | 6115 | } |
6142 | pm.convertFromImage( img ); | 6116 | pm.convertFromImage( img ); |
6143 | } | 6117 | } |
6144 | if ( !pm.isNull() ) { | 6118 | if ( !pm.isNull() ) { |
6145 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6119 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6146 | pmi.pm = pm; | 6120 | pmi.pm = pm; |
6147 | pmi.ref++; | 6121 | pmi.ref++; |
6148 | } | 6122 | } |
6149 | } | 6123 | } |
6150 | if ( pm.mask() ) { | 6124 | if ( pm.mask() ) { |
6151 | QRegion mask( *pm.mask() ); | 6125 | QRegion mask( *pm.mask() ); |
6152 | QRegion all( 0, 0, pm.width(), pm.height() ); | 6126 | QRegion all( 0, 0, pm.width(), pm.height() ); |
6153 | reg = new QRegion( all.subtract( mask ) ); | 6127 | reg = new QRegion( all.subtract( mask ) ); |
6154 | } | 6128 | } |
6155 | } | 6129 | } |
6156 | 6130 | ||
6157 | if ( pm.isNull() && (width*height)==0 ) | 6131 | if ( pm.isNull() && (width*height)==0 ) |
6158 | width = height = 50; | 6132 | width = height = 50; |
6159 | 6133 | ||
6160 | place = PlaceInline; | 6134 | place = PlaceInline; |
6161 | if ( attr["align"] == "left" ) | 6135 | if ( attr["align"] == "left" ) |
6162 | place = PlaceLeft; | 6136 | place = PlaceLeft; |
6163 | else if ( attr["align"] == "right" ) | 6137 | else if ( attr["align"] == "right" ) |
6164 | place = PlaceRight; | 6138 | place = PlaceRight; |
6165 | 6139 | ||
6166 | tmpwidth = width; | 6140 | tmpwidth = width; |
6167 | tmpheight = height; | 6141 | tmpheight = height; |
6168 | 6142 | ||
6169 | attributes = attr; | 6143 | attributes = attr; |
6170 | } | 6144 | } |
6171 | 6145 | ||
6172 | QTextImage::~QTextImage() | 6146 | QTextImage::~QTextImage() |
6173 | { | 6147 | { |
6174 | delete reg; | 6148 | delete reg; |
6175 | if ( pixmap_map && pixmap_map->contains( imgId ) ) { | 6149 | if ( pixmap_map && pixmap_map->contains( imgId ) ) { |
6176 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6150 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6177 | pmi.ref--; | 6151 | pmi.ref--; |
6178 | if ( !pmi.ref ) { | 6152 | if ( !pmi.ref ) { |
6179 | pixmap_map->remove( imgId ); | 6153 | pixmap_map->remove( imgId ); |
6180 | if ( pixmap_map->isEmpty() ) { | 6154 | if ( pixmap_map->isEmpty() ) { |
6181 | delete pixmap_map; | 6155 | delete pixmap_map; |
6182 | pixmap_map = 0; | 6156 | pixmap_map = 0; |
6183 | } | 6157 | } |
6184 | } | 6158 | } |
6185 | } | 6159 | } |
6186 | } | 6160 | } |
6187 | 6161 | ||
6188 | QString QTextImage::richText() const | 6162 | QString QTextImage::richText() const |
6189 | { | 6163 | { |
6190 | QString s; | 6164 | QString s; |
6191 | s += "<img "; | 6165 | s += "<img "; |
6192 | QMap<QString, QString>::ConstIterator it = attributes.begin(); | 6166 | QMap<QString, QString>::ConstIterator it = attributes.begin(); |
6193 | for ( ; it != attributes.end(); ++it ) | 6167 | for ( ; it != attributes.end(); ++it ) |
6194 | s += it.key() + "=" + *it + " "; | 6168 | s += it.key() + "=" + *it + " "; |
6195 | s += ">"; | 6169 | s += ">"; |
6196 | return s; | 6170 | return s; |
6197 | } | 6171 | } |
6198 | 6172 | ||
6199 | void QTextImage::adjustToPainter( QPainter* p ) | 6173 | void QTextImage::adjustToPainter( QPainter* p ) |
6200 | { | 6174 | { |
6201 | width = scale( tmpwidth, p ); | 6175 | width = scale( tmpwidth, p ); |
6202 | height = scale( tmpheight, p ); | 6176 | height = scale( tmpheight, p ); |
6203 | } | 6177 | } |
6204 | 6178 | ||
6205 | #if !defined(Q_WS_X11) | 6179 | #if !defined(Q_WS_X11) |
6206 | #include <qbitmap.h> | 6180 | #include <qbitmap.h> |
6207 | #include "qcleanuphandler.h" | 6181 | #include "qcleanuphandler.h" |
6208 | static QPixmap *qrt_selection = 0; | 6182 | static QPixmap *qrt_selection = 0; |
6209 | static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap; | 6183 | static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap; |
6210 | static void qrt_createSelectionPixmap( const QColorGroup &cg ) | 6184 | static void qrt_createSelectionPixmap( const QColorGroup &cg ) |
6211 | { | 6185 | { |
6212 | qrt_selection = new QPixmap( 2, 2 ); | 6186 | qrt_selection = new QPixmap( 2, 2 ); |
6213 | qrt_cleanup_pixmap.set( &qrt_selection ); | 6187 | qrt_cleanup_pixmap.set( &qrt_selection ); |
6214 | qrt_selection->fill( Qt::color0 ); | 6188 | qrt_selection->fill( Qt::color0 ); |
6215 | QBitmap m( 2, 2 ); | 6189 | QBitmap m( 2, 2 ); |
6216 | m.fill( Qt::color1 ); | 6190 | m.fill( Qt::color1 ); |
6217 | QPainter p( &m ); | 6191 | QPainter p( &m ); |
6218 | p.setPen( Qt::color0 ); | 6192 | p.setPen( Qt::color0 ); |
6219 | for ( int j = 0; j < 2; ++j ) { | 6193 | for ( int j = 0; j < 2; ++j ) { |
6220 | p.drawPoint( j % 2, j ); | 6194 | p.drawPoint( j % 2, j ); |
6221 | } | 6195 | } |
6222 | p.end(); | 6196 | p.end(); |
6223 | qrt_selection->setMask( m ); | 6197 | qrt_selection->setMask( m ); |
6224 | qrt_selection->fill( cg.highlight() ); | 6198 | qrt_selection->fill( cg.highlight() ); |
6225 | } | 6199 | } |
6226 | #endif | 6200 | #endif |
6227 | 6201 | ||
6228 | void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) | 6202 | void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) |
6229 | { | 6203 | { |
6230 | if ( placement() != PlaceInline ) { | 6204 | if ( placement() != PlaceInline ) { |
6231 | x = xpos; | 6205 | x = xpos; |
6232 | y = ypos; | 6206 | y = ypos; |
6233 | } | 6207 | } |
6234 | 6208 | ||
6235 | if ( pm.isNull() ) { | 6209 | if ( pm.isNull() ) { |
6236 | p->fillRect( x , y, width, height, cg.dark() ); | 6210 | p->fillRect( x , y, width, height, cg.dark() ); |
6237 | return; | 6211 | return; |
6238 | } | 6212 | } |
6239 | 6213 | ||
6240 | if ( is_printer( p ) ) { | 6214 | if ( is_printer( p ) ) { |
6241 | p->drawPixmap( x, y, pm ); | 6215 | p->drawPixmap( x, y, pm ); |
6242 | return; | 6216 | return; |
6243 | } | 6217 | } |
6244 | 6218 | ||
6245 | if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) | 6219 | if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) |
6246 | return; | 6220 | return; |
6247 | 6221 | ||
6248 | if ( placement() == PlaceInline ) | 6222 | if ( placement() == PlaceInline ) |
6249 | p->drawPixmap( x , y, pm ); | 6223 | p->drawPixmap( x , y, pm ); |
6250 | else | 6224 | else |
6251 | p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch ); | 6225 | p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch ); |
6252 | 6226 | ||
6253 | if ( selected && placement() == PlaceInline && is_printer( p ) ) { | 6227 | if ( selected && placement() == PlaceInline && is_printer( p ) ) { |
6254 | #if defined(Q_WS_X11) | 6228 | #if defined(Q_WS_X11) |
6255 | p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); | 6229 | p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); |
6256 | #else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it | 6230 | #else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it |
6257 | if ( !qrt_selection ) | 6231 | if ( !qrt_selection ) |
6258 | qrt_createSelectionPixmap( cg ); | 6232 | qrt_createSelectionPixmap( cg ); |
6259 | p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection ); | 6233 | p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection ); |
6260 | #endif | 6234 | #endif |
6261 | } | 6235 | } |
6262 | } | 6236 | } |
6263 | 6237 | ||
6264 | void QTextHorizontalLine::adjustToPainter( QPainter* p ) | 6238 | void QTextHorizontalLine::adjustToPainter( QPainter* p ) |
6265 | { | 6239 | { |
6266 | height = scale( tmpheight, p ); | 6240 | height = scale( tmpheight, p ); |
6267 | } | 6241 | } |
6268 | 6242 | ||
6269 | 6243 | ||
6270 | QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, | 6244 | QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, |
6271 | const QString &, | 6245 | const QString &, |
6272 | QMimeSourceFactory & ) | 6246 | QMimeSourceFactory & ) |
6273 | : QTextCustomItem( p ) | 6247 | : QTextCustomItem( p ) |
6274 | { | 6248 | { |
6275 | height = tmpheight = 8; | 6249 | height = tmpheight = 8; |
6276 | if ( attr.find( "color" ) != attr.end() ) | 6250 | if ( attr.find( "color" ) != attr.end() ) |
6277 | color = QColor( *attr.find( "color" ) ); | 6251 | color = QColor( *attr.find( "color" ) ); |
6278 | } | 6252 | } |
6279 | 6253 | ||
6280 | QTextHorizontalLine::~QTextHorizontalLine() | 6254 | QTextHorizontalLine::~QTextHorizontalLine() |
6281 | { | 6255 | { |
6282 | } | 6256 | } |
6283 | 6257 | ||
6284 | QString QTextHorizontalLine::richText() const | 6258 | QString QTextHorizontalLine::richText() const |
6285 | { | 6259 | { |
6286 | return "<hr>"; | 6260 | return "<hr>"; |
6287 | } | 6261 | } |
6288 | 6262 | ||
6289 | void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected ) | 6263 | void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected ) |
6290 | { | 6264 | { |
6291 | QRect r( x, y, width, height); | 6265 | QRect r( x, y, width, height); |
6292 | if ( is_printer( p ) ) { | 6266 | if ( is_printer( p ) ) { |
6293 | QPen oldPen = p->pen(); | 6267 | QPen oldPen = p->pen(); |
6294 | if ( !color.isValid() ) | 6268 | if ( !color.isValid() ) |
6295 | p->setPen( QPen( cg.text(), height/8 ) ); | 6269 | p->setPen( QPen( cg.text(), height/8 ) ); |
6296 | else | 6270 | else |
6297 | p->setPen( QPen( color, height/8 ) ); | 6271 | p->setPen( QPen( color, height/8 ) ); |
6298 | p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 ); | 6272 | p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 ); |
6299 | p->setPen( oldPen ); | 6273 | p->setPen( oldPen ); |
6300 | } else { | 6274 | } else { |
6301 | QColorGroup g( cg ); | 6275 | QColorGroup g( cg ); |
6302 | if ( color.isValid() ) | 6276 | if ( color.isValid() ) |
6303 | g.setColor( QColorGroup::Dark, color ); | 6277 | g.setColor( QColorGroup::Dark, color ); |
6304 | if ( selected ) | 6278 | if ( selected ) |
6305 | p->fillRect( r.left(), y, r.right(), y + height, g.highlight() ); | 6279 | p->fillRect( r.left(), y, r.right(), y + height, g.highlight() ); |
6306 | qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 ); | 6280 | qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 ); |
6307 | } | 6281 | } |
6308 | } | 6282 | } |
6309 | 6283 | ||
6310 | 6284 | ||
6311 | /*****************************************************************/ | 6285 | /*****************************************************************/ |
6312 | // Small set of utility functions to make the parser a bit simpler | 6286 | // Small set of utility functions to make the parser a bit simpler |
6313 | // | 6287 | // |
6314 | 6288 | ||
6315 | bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c) | 6289 | bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c) |
6316 | { | 6290 | { |
6317 | if ( pos >= length ) | 6291 | if ( pos >= length ) |
6318 | return FALSE; | 6292 | return FALSE; |
6319 | return doc[ pos ].lower() == c.lower(); | 6293 | return doc[ pos ].lower() == c.lower(); |
6320 | } | 6294 | } |
6321 | 6295 | ||
6322 | bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s ) | 6296 | bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s ) |
6323 | { | 6297 | { |
6324 | if ( pos + (int) s.length() >= length ) | 6298 | if ( pos + (int) s.length() >= length ) |
6325 | return FALSE; | 6299 | return FALSE; |
6326 | for ( int i = 0; i < (int)s.length(); i++ ) { | 6300 | for ( int i = 0; i < (int)s.length(); i++ ) { |
6327 | if ( doc[ pos + i ].lower() != s[ i ].lower() ) | 6301 | if ( doc[ pos + i ].lower() != s[ i ].lower() ) |
6328 | return FALSE; | 6302 | return FALSE; |
6329 | } | 6303 | } |
6330 | return TRUE; | 6304 | return TRUE; |
6331 | } | 6305 | } |
6332 | 6306 | ||
6333 | static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col ) | 6307 | static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col ) |
6334 | { | 6308 | { |
6335 | for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) { | 6309 | for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) { |
6336 | if ( row >= c->row() && row < c->row() + c->rowspan() | 6310 | if ( row >= c->row() && row < c->row() + c->rowspan() |
6337 | && col >= c->column() && col < c->column() + c->colspan() ) | 6311 | && col >= c->column() && col < c->column() + c->colspan() ) |
6338 | return TRUE; | 6312 | return TRUE; |
6339 | } | 6313 | } |
6340 | return FALSE; | 6314 | return FALSE; |
6341 | } | 6315 | } |
6342 | 6316 | ||
6343 | QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, | 6317 | QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, |
6344 | const QChar* doc, int length, int& pos, QTextParagraph *curpar ) | 6318 | const QChar* doc, int length, int& pos, QTextParagraph *curpar ) |
6345 | { | 6319 | { |
6346 | 6320 | ||
6347 | QTextTable* table = new QTextTable( this, attr ); | 6321 | QTextTable* table = new QTextTable( this, attr ); |
6348 | int row = -1; | 6322 | int row = -1; |
6349 | int col = -1; | 6323 | int col = -1; |
6350 | 6324 | ||
6351 | QString rowbgcolor; | 6325 | QString rowbgcolor; |
6352 | QString rowalign; | 6326 | QString rowalign; |
6353 | QString tablebgcolor = attr["bgcolor"]; | 6327 | QString tablebgcolor = attr["bgcolor"]; |
6354 | 6328 | ||
6355 | QPtrList<QTextTableCell> multicells; | 6329 | QPtrList<QTextTableCell> multicells; |
6356 | 6330 | ||
6357 | QString tagname; | 6331 | QString tagname; |
6358 | (void) eatSpace(doc, length, pos); | 6332 | (void) eatSpace(doc, length, pos); |
6359 | while ( pos < length) { | 6333 | while ( pos < length) { |
6360 | if (hasPrefix(doc, length, pos, QChar('<')) ){ | 6334 | if (hasPrefix(doc, length, pos, QChar('<')) ){ |
6361 | if (hasPrefix(doc, length, pos+1, QChar('/'))) { | 6335 | if (hasPrefix(doc, length, pos+1, QChar('/'))) { |
6362 | tagname = parseCloseTag( doc, length, pos ); | 6336 | tagname = parseCloseTag( doc, length, pos ); |
6363 | if ( tagname == "table" ) { | 6337 | if ( tagname == "table" ) { |
6364 | return table; | 6338 | return table; |
6365 | } | 6339 | } |
6366 | } else { | 6340 | } else { |
6367 | QMap<QString, QString> attr2; | 6341 | QMap<QString, QString> attr2; |
6368 | bool emptyTag = FALSE; | 6342 | bool emptyTag = FALSE; |
6369 | tagname = parseOpenTag( doc, length, pos, attr2, emptyTag ); | 6343 | tagname = parseOpenTag( doc, length, pos, attr2, emptyTag ); |
6370 | if ( tagname == "tr" ) { | 6344 | if ( tagname == "tr" ) { |
6371 | rowbgcolor = attr2["bgcolor"]; | 6345 | rowbgcolor = attr2["bgcolor"]; |
6372 | rowalign = attr2["align"]; | 6346 | rowalign = attr2["align"]; |
6373 | row++; | 6347 | row++; |
6374 | col = -1; | 6348 | col = -1; |
6375 | } | 6349 | } |
6376 | else if ( tagname == "td" || tagname == "th" ) { | 6350 | else if ( tagname == "td" || tagname == "th" ) { |
6377 | col++; | 6351 | col++; |
6378 | while ( qt_is_cell_in_use( multicells, row, col ) ) { | 6352 | while ( qt_is_cell_in_use( multicells, row, col ) ) { |
6379 | col++; | 6353 | col++; |
6380 | } | 6354 | } |
6381 | 6355 | ||
6382 | if ( row >= 0 && col >= 0 ) { | 6356 | if ( row >= 0 && col >= 0 ) { |
6383 | const QStyleSheetItem* s = sheet_->item(tagname); | 6357 | const QStyleSheetItem* s = sheet_->item(tagname); |
6384 | if ( !attr2.contains("bgcolor") ) { | 6358 | if ( !attr2.contains("bgcolor") ) { |
6385 | if (!rowbgcolor.isEmpty() ) | 6359 | if (!rowbgcolor.isEmpty() ) |
6386 | attr2["bgcolor"] = rowbgcolor; | 6360 | attr2["bgcolor"] = rowbgcolor; |
6387 | else if (!tablebgcolor.isEmpty() ) | 6361 | else if (!tablebgcolor.isEmpty() ) |
6388 | attr2["bgcolor"] = tablebgcolor; | 6362 | attr2["bgcolor"] = tablebgcolor; |
6389 | } | 6363 | } |
6390 | if ( !attr2.contains("align") ) { | 6364 | if ( !attr2.contains("align") ) { |
6391 | if (!rowalign.isEmpty() ) | 6365 | if (!rowalign.isEmpty() ) |
6392 | attr2["align"] = rowalign; | 6366 | attr2["align"] = rowalign; |
6393 | } | 6367 | } |
6394 | 6368 | ||
6395 | // extract the cell contents | 6369 | // extract the cell contents |
6396 | int end = pos; | 6370 | int end = pos; |
6397 | while ( end < length | 6371 | while ( end < length |
6398 | && !hasPrefix( doc, length, end, "</td") | 6372 | && !hasPrefix( doc, length, end, "</td") |
6399 | && !hasPrefix( doc, length, end, "<td") | 6373 | && !hasPrefix( doc, length, end, "<td") |
6400 | && !hasPrefix( doc, length, end, "</th") | 6374 | && !hasPrefix( doc, length, end, "</th") |
6401 | && !hasPrefix( doc, length, end, "<th") | 6375 | && !hasPrefix( doc, length, end, "<th") |
6402 | && !hasPrefix( doc, length, end, "<td") | 6376 | && !hasPrefix( doc, length, end, "<td") |
6403 | && !hasPrefix( doc, length, end, "</tr") | 6377 | && !hasPrefix( doc, length, end, "</tr") |
6404 | && !hasPrefix( doc, length, end, "<tr") | 6378 | && !hasPrefix( doc, length, end, "<tr") |
6405 | && !hasPrefix( doc, length, end, "</table") ) { | 6379 | && !hasPrefix( doc, length, end, "</table") ) { |
6406 | if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table | 6380 | if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table |
6407 | int nested = 1; | 6381 | int nested = 1; |
6408 | ++end; | 6382 | ++end; |
6409 | while ( end < length && nested != 0 ) { | 6383 | while ( end < length && nested != 0 ) { |
6410 | if ( hasPrefix( doc, length, end, "</table" ) ) | 6384 | if ( hasPrefix( doc, length, end, "</table" ) ) |
6411 | nested--; | 6385 | nested--; |
6412 | if ( hasPrefix( doc, length, end, "<table" ) ) | 6386 | if ( hasPrefix( doc, length, end, "<table" ) ) |
6413 | nested++; | 6387 | nested++; |
6414 | end++; | 6388 | end++; |
6415 | } | 6389 | } |
6416 | } | 6390 | } |
6417 | end++; | 6391 | end++; |
6418 | } | 6392 | } |
6419 | QTextTableCell* cell = new QTextTableCell( table, row, col, | 6393 | QTextTableCell* cell = new QTextTableCell( table, row, col, |
6420 | attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ), | 6394 | attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ), |
6421 | contxt, *factory_, sheet_, | 6395 | contxt, *factory_, sheet_, |
6422 | QString( doc, length).mid( pos, end - pos ) ); | 6396 | QString( doc, length).mid( pos, end - pos ) ); |
6423 | cell->richText()->parentPar = curpar; | 6397 | cell->richText()->parentPar = curpar; |
6424 | if ( cell->colspan() > 1 || cell->rowspan() > 1 ) | 6398 | if ( cell->colspan() > 1 || cell->rowspan() > 1 ) |
6425 | multicells.append( cell ); | 6399 | multicells.append( cell ); |
6426 | col += cell->colspan()-1; | 6400 | col += cell->colspan()-1; |
6427 | pos = end; | 6401 | pos = end; |
6428 | } | 6402 | } |
6429 | } | 6403 | } |
6430 | } | 6404 | } |
6431 | 6405 | ||
6432 | } else { | 6406 | } else { |
6433 | ++pos; | 6407 | ++pos; |
6434 | } | 6408 | } |
6435 | } | 6409 | } |
6436 | return table; | 6410 | return table; |
6437 | } | 6411 | } |
6438 | 6412 | ||
6439 | bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp ) | 6413 | bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp ) |
6440 | { | 6414 | { |
6441 | int old_pos = pos; | 6415 | int old_pos = pos; |
6442 | while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) ) | 6416 | while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) ) |
6443 | pos++; | 6417 | pos++; |
6444 | return old_pos < pos; | 6418 | return old_pos < pos; |
6445 | } | 6419 | } |
6446 | 6420 | ||
6447 | bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c) | 6421 | bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c) |
6448 | { | 6422 | { |
6449 | bool ok = pos < length && doc[pos] == c; | 6423 | bool ok = pos < length && doc[pos] == c; |
6450 | if ( ok ) | 6424 | if ( ok ) |
6451 | pos++; | 6425 | pos++; |
6452 | return ok; | 6426 | return ok; |
6453 | } | 6427 | } |
6454 | /*****************************************************************/ | 6428 | /*****************************************************************/ |
6455 | 6429 | ||
6456 | struct Entity { | 6430 | struct Entity { |
6457 | const char * name; | 6431 | const char * name; |
6458 | Q_UINT16 code; | 6432 | Q_UINT16 code; |
6459 | }; | 6433 | }; |
6460 | 6434 | ||
6461 | static const Entity entitylist [] = { | 6435 | static const Entity entitylist [] = { |
6462 | { "AElig", 0x00c6 }, | 6436 | { "AElig", 0x00c6 }, |
6463 | { "Aacute", 0x00c1 }, | 6437 | { "Aacute", 0x00c1 }, |
6464 | { "Acirc", 0x00c2 }, | 6438 | { "Acirc", 0x00c2 }, |
6465 | { "Agrave", 0x00c0 }, | 6439 | { "Agrave", 0x00c0 }, |
6466 | { "Alpha", 0x0391 }, | 6440 | { "Alpha", 0x0391 }, |
6467 | { "AMP", 38 }, | 6441 | { "AMP", 38 }, |
6468 | { "Aring", 0x00c5 }, | 6442 | { "Aring", 0x00c5 }, |
6469 | { "Atilde", 0x00c3 }, | 6443 | { "Atilde", 0x00c3 }, |
6470 | { "Auml", 0x00c4 }, | 6444 | { "Auml", 0x00c4 }, |
6471 | { "Beta", 0x0392 }, | 6445 | { "Beta", 0x0392 }, |
6472 | { "Ccedil", 0x00c7 }, | 6446 | { "Ccedil", 0x00c7 }, |
6473 | { "Chi", 0x03a7 }, | 6447 | { "Chi", 0x03a7 }, |
6474 | { "Dagger", 0x2021 }, | 6448 | { "Dagger", 0x2021 }, |
6475 | { "Delta", 0x0394 }, | 6449 | { "Delta", 0x0394 }, |
6476 | { "ETH", 0x00d0 }, | 6450 | { "ETH", 0x00d0 }, |
6477 | { "Eacute", 0x00c9 }, | 6451 | { "Eacute", 0x00c9 }, |
6478 | { "Ecirc", 0x00ca }, | 6452 | { "Ecirc", 0x00ca }, |
6479 | { "Egrave", 0x00c8 }, | 6453 | { "Egrave", 0x00c8 }, |
6480 | { "Epsilon", 0x0395 }, | 6454 | { "Epsilon", 0x0395 }, |
6481 | { "Eta", 0x0397 }, | 6455 | { "Eta", 0x0397 }, |
6482 | { "Euml", 0x00cb }, | 6456 | { "Euml", 0x00cb }, |
6483 | { "Gamma", 0x0393 }, | 6457 | { "Gamma", 0x0393 }, |
6484 | { "GT", 62 }, | 6458 | { "GT", 62 }, |
6485 | { "Iacute", 0x00cd }, | 6459 | { "Iacute", 0x00cd }, |
6486 | { "Icirc", 0x00ce }, | 6460 | { "Icirc", 0x00ce }, |
6487 | { "Igrave", 0x00cc }, | 6461 | { "Igrave", 0x00cc }, |
6488 | { "Iota", 0x0399 }, | 6462 | { "Iota", 0x0399 }, |
6489 | { "Iuml", 0x00cf }, | 6463 | { "Iuml", 0x00cf }, |
6490 | { "Kappa", 0x039a }, | 6464 | { "Kappa", 0x039a }, |
6491 | { "Lambda", 0x039b }, | 6465 | { "Lambda", 0x039b }, |
6492 | { "LT", 60 }, | 6466 | { "LT", 60 }, |
6493 | { "Mu", 0x039c }, | 6467 | { "Mu", 0x039c }, |
6494 | { "Ntilde", 0x00d1 }, | 6468 | { "Ntilde", 0x00d1 }, |
6495 | { "Nu", 0x039d }, | 6469 | { "Nu", 0x039d }, |
6496 | { "OElig", 0x0152 }, | 6470 | { "OElig", 0x0152 }, |
6497 | { "Oacute", 0x00d3 }, | 6471 | { "Oacute", 0x00d3 }, |
6498 | { "Ocirc", 0x00d4 }, | 6472 | { "Ocirc", 0x00d4 }, |
6499 | { "Ograve", 0x00d2 }, | 6473 | { "Ograve", 0x00d2 }, |
6500 | { "Omega", 0x03a9 }, | 6474 | { "Omega", 0x03a9 }, |
6501 | { "Omicron", 0x039f }, | 6475 | { "Omicron", 0x039f }, |
6502 | { "Oslash", 0x00d8 }, | 6476 | { "Oslash", 0x00d8 }, |
6503 | { "Otilde", 0x00d5 }, | 6477 | { "Otilde", 0x00d5 }, |
6504 | { "Ouml", 0x00d6 }, | 6478 | { "Ouml", 0x00d6 }, |
6505 | { "Phi", 0x03a6 }, | 6479 | { "Phi", 0x03a6 }, |
6506 | { "Pi", 0x03a0 }, | 6480 | { "Pi", 0x03a0 }, |
6507 | { "Prime", 0x2033 }, | 6481 | { "Prime", 0x2033 }, |
6508 | { "Psi", 0x03a8 }, | 6482 | { "Psi", 0x03a8 }, |
6509 | { "QUOT", 34 }, | 6483 | { "QUOT", 34 }, |
6510 | { "Rho", 0x03a1 }, | 6484 | { "Rho", 0x03a1 }, |
6511 | { "Scaron", 0x0160 }, | 6485 | { "Scaron", 0x0160 }, |
6512 | { "Sigma", 0x03a3 }, | 6486 | { "Sigma", 0x03a3 }, |
6513 | { "THORN", 0x00de }, | 6487 | { "THORN", 0x00de }, |
6514 | { "Tau", 0x03a4 }, | 6488 | { "Tau", 0x03a4 }, |
6515 | { "Theta", 0x0398 }, | 6489 | { "Theta", 0x0398 }, |
6516 | { "Uacute", 0x00da }, | 6490 | { "Uacute", 0x00da }, |
6517 | { "Ucirc", 0x00db }, | 6491 | { "Ucirc", 0x00db }, |
6518 | { "Ugrave", 0x00d9 }, | 6492 | { "Ugrave", 0x00d9 }, |
6519 | { "Upsilon", 0x03a5 }, | 6493 | { "Upsilon", 0x03a5 }, |
6520 | { "Uuml", 0x00dc }, | 6494 | { "Uuml", 0x00dc }, |
6521 | { "Xi", 0x039e }, | 6495 | { "Xi", 0x039e }, |
6522 | { "Yacute", 0x00dd }, | 6496 | { "Yacute", 0x00dd }, |
6523 | { "Yuml", 0x0178 }, | 6497 | { "Yuml", 0x0178 }, |
6524 | { "Zeta", 0x0396 }, | 6498 | { "Zeta", 0x0396 }, |
6525 | { "aacute", 0x00e1 }, | 6499 | { "aacute", 0x00e1 }, |
6526 | { "acirc", 0x00e2 }, | 6500 | { "acirc", 0x00e2 }, |
6527 | { "acute", 0x00b4 }, | 6501 | { "acute", 0x00b4 }, |
6528 | { "aelig", 0x00e6 }, | 6502 | { "aelig", 0x00e6 }, |
6529 | { "agrave", 0x00e0 }, | 6503 | { "agrave", 0x00e0 }, |
6530 | { "alefsym", 0x2135 }, | 6504 | { "alefsym", 0x2135 }, |
6531 | { "alpha", 0x03b1 }, | 6505 | { "alpha", 0x03b1 }, |
6532 | { "amp", 38 }, | 6506 | { "amp", 38 }, |
6533 | { "and", 0x22a5 }, | 6507 | { "and", 0x22a5 }, |
6534 | { "ang", 0x2220 }, | 6508 | { "ang", 0x2220 }, |
6535 | { "apos", 0x0027 }, | 6509 | { "apos", 0x0027 }, |
6536 | { "aring", 0x00e5 }, | 6510 | { "aring", 0x00e5 }, |
6537 | { "asymp", 0x2248 }, | 6511 | { "asymp", 0x2248 }, |
6538 | { "atilde", 0x00e3 }, | 6512 | { "atilde", 0x00e3 }, |
6539 | { "auml", 0x00e4 }, | 6513 | { "auml", 0x00e4 }, |
6540 | { "bdquo", 0x201e }, | 6514 | { "bdquo", 0x201e }, |
6541 | { "beta", 0x03b2 }, | 6515 | { "beta", 0x03b2 }, |
6542 | { "brvbar", 0x00a6 }, | 6516 | { "brvbar", 0x00a6 }, |
6543 | { "bull", 0x2022 }, | 6517 | { "bull", 0x2022 }, |
6544 | { "cap", 0x2229 }, | 6518 | { "cap", 0x2229 }, |
6545 | { "ccedil", 0x00e7 }, | 6519 | { "ccedil", 0x00e7 }, |
6546 | { "cedil", 0x00b8 }, | 6520 | { "cedil", 0x00b8 }, |
6547 | { "cent", 0x00a2 }, | 6521 | { "cent", 0x00a2 }, |
6548 | { "chi", 0x03c7 }, | 6522 | { "chi", 0x03c7 }, |
6549 | { "circ", 0x02c6 }, | 6523 | { "circ", 0x02c6 }, |
6550 | { "clubs", 0x2663 }, | 6524 | { "clubs", 0x2663 }, |
6551 | { "cong", 0x2245 }, | 6525 | { "cong", 0x2245 }, |
6552 | { "copy", 0x00a9 }, | 6526 | { "copy", 0x00a9 }, |
6553 | { "crarr", 0x21b5 }, | 6527 | { "crarr", 0x21b5 }, |
6554 | { "cup", 0x222a }, | 6528 | { "cup", 0x222a }, |
6555 | { "curren", 0x00a4 }, | 6529 | { "curren", 0x00a4 }, |
6556 | { "dArr", 0x21d3 }, | 6530 | { "dArr", 0x21d3 }, |
6557 | { "dagger", 0x2020 }, | 6531 | { "dagger", 0x2020 }, |
6558 | { "darr", 0x2193 }, | 6532 | { "darr", 0x2193 }, |
6559 | { "deg", 0x00b0 }, | 6533 | { "deg", 0x00b0 }, |
6560 | { "delta", 0x03b4 }, | 6534 | { "delta", 0x03b4 }, |
6561 | { "diams", 0x2666 }, | 6535 | { "diams", 0x2666 }, |
6562 | { "divide", 0x00f7 }, | 6536 | { "divide", 0x00f7 }, |
6563 | { "eacute", 0x00e9 }, | 6537 | { "eacute", 0x00e9 }, |
6564 | { "ecirc", 0x00ea }, | 6538 | { "ecirc", 0x00ea }, |
6565 | { "egrave", 0x00e8 }, | 6539 | { "egrave", 0x00e8 }, |
6566 | { "empty", 0x2205 }, | 6540 | { "empty", 0x2205 }, |
6567 | { "emsp", 0x2003 }, | 6541 | { "emsp", 0x2003 }, |
6568 | { "ensp", 0x2002 }, | 6542 | { "ensp", 0x2002 }, |
6569 | { "epsilon", 0x03b5 }, | 6543 | { "epsilon", 0x03b5 }, |
6570 | { "equiv", 0x2261 }, | 6544 | { "equiv", 0x2261 }, |
6571 | { "eta", 0x03b7 }, | 6545 | { "eta", 0x03b7 }, |
6572 | { "eth", 0x00f0 }, | 6546 | { "eth", 0x00f0 }, |
6573 | { "euml", 0x00eb }, | 6547 | { "euml", 0x00eb }, |
6574 | { "euro", 0x20ac }, | 6548 | { "euro", 0x20ac }, |
6575 | { "exist", 0x2203 }, | 6549 | { "exist", 0x2203 }, |
6576 | { "fnof", 0x0192 }, | 6550 | { "fnof", 0x0192 }, |
6577 | { "forall", 0x2200 }, | 6551 | { "forall", 0x2200 }, |
6578 | { "frac12", 0x00bd }, | 6552 | { "frac12", 0x00bd }, |
6579 | { "frac14", 0x00bc }, | 6553 | { "frac14", 0x00bc }, |
6580 | { "frac34", 0x00be }, | 6554 | { "frac34", 0x00be }, |
6581 | { "frasl", 0x2044 }, | 6555 | { "frasl", 0x2044 }, |
6582 | { "gamma", 0x03b3 }, | 6556 | { "gamma", 0x03b3 }, |
6583 | { "ge", 0x2265 }, | 6557 | { "ge", 0x2265 }, |
6584 | { "gt", 62 }, | 6558 | { "gt", 62 }, |
6585 | { "hArr", 0x21d4 }, | 6559 | { "hArr", 0x21d4 }, |
6586 | { "harr", 0x2194 }, | 6560 | { "harr", 0x2194 }, |
6587 | { "hearts", 0x2665 }, | 6561 | { "hearts", 0x2665 }, |
6588 | { "hellip", 0x2026 }, | 6562 | { "hellip", 0x2026 }, |
6589 | { "iacute", 0x00ed }, | 6563 | { "iacute", 0x00ed }, |
6590 | { "icirc", 0x00ee }, | 6564 | { "icirc", 0x00ee }, |
6591 | { "iexcl", 0x00a1 }, | 6565 | { "iexcl", 0x00a1 }, |
6592 | { "igrave", 0x00ec }, | 6566 | { "igrave", 0x00ec }, |
6593 | { "image", 0x2111 }, | 6567 | { "image", 0x2111 }, |
6594 | { "infin", 0x221e }, | 6568 | { "infin", 0x221e }, |
6595 | { "int", 0x222b }, | 6569 | { "int", 0x222b }, |
6596 | { "iota", 0x03b9 }, | 6570 | { "iota", 0x03b9 }, |
6597 | { "iquest", 0x00bf }, | 6571 | { "iquest", 0x00bf }, |
6598 | { "isin", 0x2208 }, | 6572 | { "isin", 0x2208 }, |
6599 | { "iuml", 0x00ef }, | 6573 | { "iuml", 0x00ef }, |
6600 | { "kappa", 0x03ba }, | 6574 | { "kappa", 0x03ba }, |
6601 | { "lArr", 0x21d0 }, | 6575 | { "lArr", 0x21d0 }, |
6602 | { "lambda", 0x03bb }, | 6576 | { "lambda", 0x03bb }, |
6603 | { "lang", 0x2329 }, | 6577 | { "lang", 0x2329 }, |
6604 | { "laquo", 0x00ab }, | 6578 | { "laquo", 0x00ab }, |
6605 | { "larr", 0x2190 }, | 6579 | { "larr", 0x2190 }, |
6606 | { "lceil", 0x2308 }, | 6580 | { "lceil", 0x2308 }, |
6607 | { "ldquo", 0x201c }, | 6581 | { "ldquo", 0x201c }, |
6608 | { "le", 0x2264 }, | 6582 | { "le", 0x2264 }, |
6609 | { "lfloor", 0x230a }, | 6583 | { "lfloor", 0x230a }, |
6610 | { "lowast", 0x2217 }, | 6584 | { "lowast", 0x2217 }, |
6611 | { "loz", 0x25ca }, | 6585 | { "loz", 0x25ca }, |
6612 | { "lrm", 0x200e }, | 6586 | { "lrm", 0x200e }, |
6613 | { "lsaquo", 0x2039 }, | 6587 | { "lsaquo", 0x2039 }, |
6614 | { "lsquo", 0x2018 }, | 6588 | { "lsquo", 0x2018 }, |
6615 | { "lt", 60 }, | 6589 | { "lt", 60 }, |
6616 | { "macr", 0x00af }, | 6590 | { "macr", 0x00af }, |
6617 | { "mdash", 0x2014 }, | 6591 | { "mdash", 0x2014 }, |
6618 | { "micro", 0x00b5 }, | 6592 | { "micro", 0x00b5 }, |
6619 | { "middot", 0x00b7 }, | 6593 | { "middot", 0x00b7 }, |
6620 | { "minus", 0x2212 }, | 6594 | { "minus", 0x2212 }, |
6621 | { "mu", 0x03bc }, | 6595 | { "mu", 0x03bc }, |
6622 | { "nabla", 0x2207 }, | 6596 | { "nabla", 0x2207 }, |
6623 | { "nbsp", 0x00a0 }, | 6597 | { "nbsp", 0x00a0 }, |
6624 | { "ndash", 0x2013 }, | 6598 | { "ndash", 0x2013 }, |
6625 | { "ne", 0x2260 }, | 6599 | { "ne", 0x2260 }, |
6626 | { "ni", 0x220b }, | 6600 | { "ni", 0x220b }, |
6627 | { "not", 0x00ac }, | 6601 | { "not", 0x00ac }, |
6628 | { "notin", 0x2209 }, | 6602 | { "notin", 0x2209 }, |
6629 | { "nsub", 0x2284 }, | 6603 | { "nsub", 0x2284 }, |
6630 | { "ntilde", 0x00f1 }, | 6604 | { "ntilde", 0x00f1 }, |
6631 | { "nu", 0x03bd }, | 6605 | { "nu", 0x03bd }, |
6632 | { "oacute", 0x00f3 }, | 6606 | { "oacute", 0x00f3 }, |
6633 | { "ocirc", 0x00f4 }, | 6607 | { "ocirc", 0x00f4 }, |
6634 | { "oelig", 0x0153 }, | 6608 | { "oelig", 0x0153 }, |
6635 | { "ograve", 0x00f2 }, | 6609 | { "ograve", 0x00f2 }, |
6636 | { "oline", 0x203e }, | 6610 | { "oline", 0x203e }, |
6637 | { "omega", 0x03c9 }, | 6611 | { "omega", 0x03c9 }, |
6638 | { "omicron", 0x03bf }, | 6612 | { "omicron", 0x03bf }, |
6639 | { "oplus", 0x2295 }, | 6613 | { "oplus", 0x2295 }, |
6640 | { "or", 0x22a6 }, | 6614 | { "or", 0x22a6 }, |
6641 | { "ordf", 0x00aa }, | 6615 | { "ordf", 0x00aa }, |
6642 | { "ordm", 0x00ba }, | 6616 | { "ordm", 0x00ba }, |
6643 | { "oslash", 0x00f8 }, | 6617 | { "oslash", 0x00f8 }, |
6644 | { "otilde", 0x00f5 }, | 6618 | { "otilde", 0x00f5 }, |
6645 | { "otimes", 0x2297 }, | 6619 | { "otimes", 0x2297 }, |
6646 | { "ouml", 0x00f6 }, | 6620 | { "ouml", 0x00f6 }, |
6647 | { "para", 0x00b6 }, | 6621 | { "para", 0x00b6 }, |
6648 | { "part", 0x2202 }, | 6622 | { "part", 0x2202 }, |
6649 | { "percnt", 0x0025 }, | 6623 | { "percnt", 0x0025 }, |
6650 | { "permil", 0x2030 }, | 6624 | { "permil", 0x2030 }, |
6651 | { "perp", 0x22a5 }, | 6625 | { "perp", 0x22a5 }, |
6652 | { "phi", 0x03c6 }, | 6626 | { "phi", 0x03c6 }, |
6653 | { "pi", 0x03c0 }, | 6627 | { "pi", 0x03c0 }, |
6654 | { "piv", 0x03d6 }, | 6628 | { "piv", 0x03d6 }, |
6655 | { "plusmn", 0x00b1 }, | 6629 | { "plusmn", 0x00b1 }, |
6656 | { "pound", 0x00a3 }, | 6630 | { "pound", 0x00a3 }, |
6657 | { "prime", 0x2032 }, | 6631 | { "prime", 0x2032 }, |
6658 | { "prod", 0x220f }, | 6632 | { "prod", 0x220f }, |
6659 | { "prop", 0x221d }, | 6633 | { "prop", 0x221d }, |
6660 | { "psi", 0x03c8 }, | 6634 | { "psi", 0x03c8 }, |
6661 | { "quot", 34 }, | 6635 | { "quot", 34 }, |
6662 | { "rArr", 0x21d2 }, | 6636 | { "rArr", 0x21d2 }, |
6663 | { "radic", 0x221a }, | 6637 | { "radic", 0x221a }, |
6664 | { "rang", 0x232a }, | 6638 | { "rang", 0x232a }, |
6665 | { "raquo", 0x00bb }, | 6639 | { "raquo", 0x00bb }, |
6666 | { "rarr", 0x2192 }, | 6640 | { "rarr", 0x2192 }, |
6667 | { "rceil", 0x2309 }, | 6641 | { "rceil", 0x2309 }, |
6668 | { "rdquo", 0x201d }, | 6642 | { "rdquo", 0x201d }, |
6669 | { "real", 0x211c }, | 6643 | { "real", 0x211c }, |
6670 | { "reg", 0x00ae }, | 6644 | { "reg", 0x00ae }, |
6671 | { "rfloor", 0x230b }, | 6645 | { "rfloor", 0x230b }, |
6672 | { "rho", 0x03c1 }, | 6646 | { "rho", 0x03c1 }, |
6673 | { "rlm", 0x200f }, | 6647 | { "rlm", 0x200f }, |
6674 | { "rsaquo", 0x203a }, | 6648 | { "rsaquo", 0x203a }, |
6675 | { "rsquo", 0x2019 }, | 6649 | { "rsquo", 0x2019 }, |
6676 | { "sbquo", 0x201a }, | 6650 | { "sbquo", 0x201a }, |
6677 | { "scaron", 0x0161 }, | 6651 | { "scaron", 0x0161 }, |
6678 | { "sdot", 0x22c5 }, | 6652 | { "sdot", 0x22c5 }, |
6679 | { "sect", 0x00a7 }, | 6653 | { "sect", 0x00a7 }, |
6680 | { "shy", 0x00ad }, | 6654 | { "shy", 0x00ad }, |
6681 | { "sigma", 0x03c3 }, | 6655 | { "sigma", 0x03c3 }, |
6682 | { "sigmaf", 0x03c2 }, | 6656 | { "sigmaf", 0x03c2 }, |
6683 | { "sim", 0x223c }, | 6657 | { "sim", 0x223c }, |
6684 | { "spades", 0x2660 }, | 6658 | { "spades", 0x2660 }, |
6685 | { "sub", 0x2282 }, | 6659 | { "sub", 0x2282 }, |
6686 | { "sube", 0x2286 }, | 6660 | { "sube", 0x2286 }, |
6687 | { "sum", 0x2211 }, | 6661 | { "sum", 0x2211 }, |
6688 | { "sup1", 0x00b9 }, | 6662 | { "sup1", 0x00b9 }, |
6689 | { "sup2", 0x00b2 }, | 6663 | { "sup2", 0x00b2 }, |
6690 | { "sup3", 0x00b3 }, | 6664 | { "sup3", 0x00b3 }, |
6691 | { "sup", 0x2283 }, | 6665 | { "sup", 0x2283 }, |
6692 | { "supe", 0x2287 }, | 6666 | { "supe", 0x2287 }, |
6693 | { "szlig", 0x00df }, | 6667 | { "szlig", 0x00df }, |
6694 | { "tau", 0x03c4 }, | 6668 | { "tau", 0x03c4 }, |
6695 | { "there4", 0x2234 }, | 6669 | { "there4", 0x2234 }, |
6696 | { "theta", 0x03b8 }, | 6670 | { "theta", 0x03b8 }, |
6697 | { "thetasym", 0x03d1 }, | 6671 | { "thetasym", 0x03d1 }, |
6698 | { "thinsp", 0x2009 }, | 6672 | { "thinsp", 0x2009 }, |
6699 | { "thorn", 0x00fe }, | 6673 | { "thorn", 0x00fe }, |
6700 | { "tilde", 0x02dc }, | 6674 | { "tilde", 0x02dc }, |
6701 | { "times", 0x00d7 }, | 6675 | { "times", 0x00d7 }, |
6702 | { "trade", 0x2122 }, | 6676 | { "trade", 0x2122 }, |
6703 | { "uArr", 0x21d1 }, | 6677 | { "uArr", 0x21d1 }, |
6704 | { "uacute", 0x00fa }, | 6678 | { "uacute", 0x00fa }, |
6705 | { "uarr", 0x2191 }, | 6679 | { "uarr", 0x2191 }, |
6706 | { "ucirc", 0x00fb }, | 6680 | { "ucirc", 0x00fb }, |
6707 | { "ugrave", 0x00f9 }, | 6681 | { "ugrave", 0x00f9 }, |
6708 | { "uml", 0x00a8 }, | 6682 | { "uml", 0x00a8 }, |
6709 | { "upsih", 0x03d2 }, | 6683 | { "upsih", 0x03d2 }, |
6710 | { "upsilon", 0x03c5 }, | 6684 | { "upsilon", 0x03c5 }, |
6711 | { "uuml", 0x00fc }, | 6685 | { "uuml", 0x00fc }, |
6712 | { "weierp", 0x2118 }, | 6686 | { "weierp", 0x2118 }, |
6713 | { "xi", 0x03be }, | 6687 | { "xi", 0x03be }, |
6714 | { "yacute", 0x00fd }, | 6688 | { "yacute", 0x00fd }, |
6715 | { "yen", 0x00a5 }, | 6689 | { "yen", 0x00a5 }, |
6716 | { "yuml", 0x00ff }, | 6690 | { "yuml", 0x00ff }, |
6717 | { "zeta", 0x03b6 }, | 6691 | { "zeta", 0x03b6 }, |
6718 | { "zwj", 0x200d }, | 6692 | { "zwj", 0x200d }, |
6719 | { "zwnj", 0x200c }, | 6693 | { "zwnj", 0x200c }, |
6720 | { "", 0x0000 } | 6694 | { "", 0x0000 } |
6721 | }; | 6695 | }; |
6722 | 6696 | ||
6723 | 6697 | ||
6724 | 6698 | ||
6725 | 6699 | ||
6726 | 6700 | ||
6727 | static QMap<QCString, QChar> *html_map = 0; | 6701 | static QMap<QCString, QChar> *html_map = 0; |
6728 | static void qt_cleanup_html_map() | 6702 | static void qt_cleanup_html_map() |
6729 | { | 6703 | { |
6730 | delete html_map; | 6704 | delete html_map; |
6731 | html_map = 0; | 6705 | html_map = 0; |
6732 | } | 6706 | } |
6733 | 6707 | ||
6734 | static QMap<QCString, QChar> *htmlMap() | 6708 | static QMap<QCString, QChar> *htmlMap() |
6735 | { | 6709 | { |
6736 | if ( !html_map ) { | 6710 | if ( !html_map ) { |
6737 | html_map = new QMap<QCString, QChar>; | 6711 | html_map = new QMap<QCString, QChar>; |
6738 | qAddPostRoutine( qt_cleanup_html_map ); | 6712 | qAddPostRoutine( qt_cleanup_html_map ); |
6739 | 6713 | ||
6740 | const Entity *ent = entitylist; | 6714 | const Entity *ent = entitylist; |
6741 | while( ent->code ) { | 6715 | while( ent->code ) { |
6742 | html_map->insert( ent->name, QChar(ent->code) ); | 6716 | html_map->insert( ent->name, QChar(ent->code) ); |
6743 | ent++; | 6717 | ent++; |
6744 | } | 6718 | } |
6745 | } | 6719 | } |
6746 | return html_map; | 6720 | return html_map; |
6747 | } | 6721 | } |
6748 | 6722 | ||
6749 | QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos) | 6723 | QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos) |
6750 | { | 6724 | { |
6751 | QCString s; | 6725 | QCString s; |
6752 | pos++; | 6726 | pos++; |
6753 | int recoverpos = pos; | 6727 | int recoverpos = pos; |
6754 | while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) { | 6728 | while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) { |
6755 | s += doc[pos]; | 6729 | s += doc[pos]; |
6756 | pos++; | 6730 | pos++; |
6757 | } | 6731 | } |
6758 | if (doc[pos] != ';' && !doc[pos].isSpace() ) { | 6732 | if (doc[pos] != ';' && !doc[pos].isSpace() ) { |
6759 | pos = recoverpos; | 6733 | pos = recoverpos; |
6760 | return '&'; | 6734 | return '&'; |
6761 | } | 6735 | } |
6762 | pos++; | 6736 | pos++; |
6763 | 6737 | ||
6764 | if ( s.length() > 1 && s[0] == '#') { | 6738 | if ( s.length() > 1 && s[0] == '#') { |
6765 | int num = s.mid(1).toInt(); | 6739 | int num = s.mid(1).toInt(); |
6766 | if ( num == 151 ) // ### hack for designer manual | 6740 | if ( num == 151 ) // ### hack for designer manual |
6767 | return '-'; | 6741 | return '-'; |
6768 | return num; | 6742 | return num; |
6769 | } | 6743 | } |
6770 | 6744 | ||
6771 | QMap<QCString, QChar>::Iterator it = htmlMap()->find(s); | 6745 | QMap<QCString, QChar>::Iterator it = htmlMap()->find(s); |
6772 | if ( it != htmlMap()->end() ) { | 6746 | if ( it != htmlMap()->end() ) { |
6773 | return *it; | 6747 | return *it; |
6774 | } | 6748 | } |
6775 | 6749 | ||
6776 | pos = recoverpos; | 6750 | pos = recoverpos; |
6777 | return '&'; | 6751 | return '&'; |
6778 | } | 6752 | } |
6779 | 6753 | ||
6780 | QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower) | 6754 | QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower) |
6781 | { | 6755 | { |
6782 | QString s; | 6756 | QString s; |
6783 | 6757 | ||
6784 | if (doc[pos] == '"') { | 6758 | if (doc[pos] == '"') { |
6785 | pos++; | 6759 | pos++; |
6786 | while ( pos < length && doc[pos] != '"' ) { | 6760 | while ( pos < length && doc[pos] != '"' ) { |
6787 | s += doc[pos]; | 6761 | s += doc[pos]; |
6788 | pos++; | 6762 | pos++; |
6789 | } | 6763 | } |
6790 | eat(doc, length, pos, '"'); | 6764 | eat(doc, length, pos, '"'); |
6791 | } else { | 6765 | } else { |
6792 | static QString term = QString::fromLatin1("/>"); | 6766 | static QString term = QString::fromLatin1("/>"); |
6793 | while( pos < length && | 6767 | while( pos < length && |
6794 | (doc[pos] != '>' && !hasPrefix( doc, length, pos, term)) | 6768 | (doc[pos] != '>' && !hasPrefix( doc, length, pos, term)) |
6795 | && doc[pos] != '<' | 6769 | && doc[pos] != '<' |
6796 | && doc[pos] != '=' | 6770 | && doc[pos] != '=' |
6797 | && !doc[pos].isSpace()) | 6771 | && !doc[pos].isSpace()) |
6798 | { | 6772 | { |
6799 | if ( doc[pos] == '&') | 6773 | if ( doc[pos] == '&') |
6800 | s += parseHTMLSpecialChar( doc, length, pos ); | 6774 | s += parseHTMLSpecialChar( doc, length, pos ); |
6801 | else { | 6775 | else { |
6802 | s += doc[pos]; | 6776 | s += doc[pos]; |
6803 | pos++; | 6777 | pos++; |
6804 | } | 6778 | } |
6805 | } | 6779 | } |
6806 | if (lower) | 6780 | if (lower) |
6807 | s = s.lower(); | 6781 | s = s.lower(); |
6808 | } | 6782 | } |
6809 | return s; | 6783 | return s; |
6810 | } | 6784 | } |
6811 | 6785 | ||
6812 | QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ) | 6786 | QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ) |
6813 | { | 6787 | { |
6814 | if ( pos >= length ) | 6788 | if ( pos >= length ) |
6815 | return QChar::null; | 6789 | return QChar::null; |
6816 | 6790 | ||
6817 | QChar c = doc[pos++]; | 6791 | QChar c = doc[pos++]; |
6818 | 6792 | ||
6819 | if (c == '<' ) | 6793 | if (c == '<' ) |
6820 | return QChar::null; | 6794 | return QChar::null; |
6821 | 6795 | ||
6822 | if ( c.isSpace() && c != QChar::nbsp ) { | 6796 | if ( c.isSpace() && c != QChar::nbsp ) { |
6823 | if ( wsm == QStyleSheetItem::WhiteSpacePre ) { | 6797 | if ( wsm == QStyleSheetItem::WhiteSpacePre ) { |
6824 | if ( c == '\n' ) | 6798 | if ( c == '\n' ) |
6825 | return QChar_linesep; | 6799 | return QChar_linesep; |
6826 | else | 6800 | else |
6827 | return c; | 6801 | return c; |
6828 | } else { // non-pre mode: collapse whitespace except nbsp | 6802 | } else { // non-pre mode: collapse whitespace except nbsp |
6829 | while ( pos< length && | 6803 | while ( pos< length && |
6830 | doc[pos].isSpace() && doc[pos] != QChar::nbsp ) | 6804 | doc[pos].isSpace() && doc[pos] != QChar::nbsp ) |
6831 | pos++; | 6805 | pos++; |
6832 | if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap ) | 6806 | if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap ) |
6833 | return QChar::nbsp; | 6807 | return QChar::nbsp; |
6834 | else | 6808 | else |
6835 | return ' '; | 6809 | return ' '; |
6836 | } | 6810 | } |
6837 | } | 6811 | } |
6838 | else if ( c == '&' ) | 6812 | else if ( c == '&' ) |
6839 | return parseHTMLSpecialChar( doc, length, --pos ); | 6813 | return parseHTMLSpecialChar( doc, length, --pos ); |
6840 | else | 6814 | else |
6841 | return c; | 6815 | return c; |
6842 | } | 6816 | } |
6843 | 6817 | ||
6844 | QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos, | 6818 | QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos, |
6845 | QMap<QString, QString> &attr, bool& emptyTag) | 6819 | QMap<QString, QString> &attr, bool& emptyTag) |
6846 | { | 6820 | { |
6847 | emptyTag = FALSE; | 6821 | emptyTag = FALSE; |
6848 | pos++; | 6822 | pos++; |
6849 | if ( hasPrefix(doc, length, pos, '!') ) { | 6823 | if ( hasPrefix(doc, length, pos, '!') ) { |
6850 | if ( hasPrefix( doc, length, pos+1, "--")) { | 6824 | if ( hasPrefix( doc, length, pos+1, "--")) { |
6851 | pos += 3; | 6825 | pos += 3; |
6852 | // eat comments | 6826 | // eat comments |
6853 | QString pref = QString::fromLatin1("-->"); | 6827 | QString pref = QString::fromLatin1("-->"); |
6854 | while ( !hasPrefix(doc, length, pos, pref ) && pos < length ) | 6828 | while ( !hasPrefix(doc, length, pos, pref ) && pos < length ) |
6855 | pos++; | 6829 | pos++; |
6856 | if ( hasPrefix(doc, length, pos, pref ) ) { | 6830 | if ( hasPrefix(doc, length, pos, pref ) ) { |
6857 | pos += 3; | 6831 | pos += 3; |
6858 | eatSpace(doc, length, pos, TRUE); | 6832 | eatSpace(doc, length, pos, TRUE); |
6859 | } | 6833 | } |
6860 | emptyTag = TRUE; | 6834 | emptyTag = TRUE; |
6861 | return QString::null; | 6835 | return QString::null; |
6862 | } | 6836 | } |
6863 | else { | 6837 | else { |
6864 | // eat strange internal tags | 6838 | // eat strange internal tags |
6865 | while ( !hasPrefix(doc, length, pos, '>') && pos < length ) | 6839 | while ( !hasPrefix(doc, length, pos, '>') && pos < length ) |
6866 | pos++; | 6840 | pos++; |
6867 | if ( hasPrefix(doc, length, pos, '>') ) { | 6841 | if ( hasPrefix(doc, length, pos, '>') ) { |
6868 | pos++; | 6842 | pos++; |
6869 | eatSpace(doc, length, pos, TRUE); | 6843 | eatSpace(doc, length, pos, TRUE); |
6870 | } | 6844 | } |
6871 | return QString::null; | 6845 | return QString::null; |
6872 | } | 6846 | } |
6873 | } | 6847 | } |
6874 | 6848 | ||
6875 | QString tag = parseWord(doc, length, pos ); | 6849 | QString tag = parseWord(doc, length, pos ); |
6876 | eatSpace(doc, length, pos, TRUE); | 6850 | eatSpace(doc, length, pos, TRUE); |
6877 | static QString term = QString::fromLatin1("/>"); | 6851 | static QString term = QString::fromLatin1("/>"); |
6878 | static QString s_TRUE = QString::fromLatin1("TRUE"); | 6852 | static QString s_TRUE = QString::fromLatin1("TRUE"); |
6879 | 6853 | ||
6880 | while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) { | 6854 | while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) { |
6881 | QString key = parseWord(doc, length, pos ); | 6855 | QString key = parseWord(doc, length, pos ); |
6882 | eatSpace(doc, length, pos, TRUE); | 6856 | eatSpace(doc, length, pos, TRUE); |
6883 | if ( key.isEmpty()) { | 6857 | if ( key.isEmpty()) { |
6884 | // error recovery | 6858 | // error recovery |
6885 | while ( pos < length && doc[pos] != '>' ) | 6859 | while ( pos < length && doc[pos] != '>' ) |
6886 | pos++; | 6860 | pos++; |
6887 | break; | 6861 | break; |
6888 | } | 6862 | } |
6889 | QString value; | 6863 | QString value; |
6890 | if (hasPrefix(doc, length, pos, '=') ){ | 6864 | if (hasPrefix(doc, length, pos, '=') ){ |
6891 | pos++; | 6865 | pos++; |
6892 | eatSpace(doc, length, pos); | 6866 | eatSpace(doc, length, pos); |
6893 | value = parseWord(doc, length, pos, FALSE); | 6867 | value = parseWord(doc, length, pos, FALSE); |
6894 | } | 6868 | } |
6895 | else | 6869 | else |
6896 | value = s_TRUE; | 6870 | value = s_TRUE; |
6897 | attr.insert(key.lower(), value ); | 6871 | attr.insert(key.lower(), value ); |
6898 | eatSpace(doc, length, pos, TRUE); | 6872 | eatSpace(doc, length, pos, TRUE); |
6899 | } | 6873 | } |
6900 | 6874 | ||
6901 | if (emptyTag) { | 6875 | if (emptyTag) { |
6902 | eat(doc, length, pos, '/'); | 6876 | eat(doc, length, pos, '/'); |
6903 | eat(doc, length, pos, '>'); | 6877 | eat(doc, length, pos, '>'); |