summaryrefslogtreecommitdiff
authorerik <erik>2007-02-08 01:46:35 (UTC)
committer erik <erik>2007-02-08 01:46:35 (UTC)
commit41dce553a418765d5075fc249c636104a2a82329 (patch) (unidiff)
treeca9b39611b17355cf2cb1c890d68f3a008e38866
parent2e497f7cae45184184e2416114887095735958f5 (diff)
downloadopie-41dce553a418765d5075fc249c636104a2a82329.zip
opie-41dce553a418765d5075fc249c636104a2a82329.tar.gz
opie-41dce553a418765d5075fc249c636104a2a82329.tar.bz2
Removal of useless code based on a conditional that is never set to anything
but false.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp44
1 files changed, 9 insertions, 35 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,436 +1,427 @@
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>
42using namespace Opie::Core; 42using 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
53using namespace Qt3; 53using namespace Qt3;
54 54
55static QTextCursor* richTextExportStart = 0; 55static QTextCursor* richTextExportStart = 0;
56static QTextCursor* richTextExportEnd = 0; 56static QTextCursor* richTextExportEnd = 0;
57 57
58static QTextFormatCollection *qFormatCollection = 0; 58static QTextFormatCollection *qFormatCollection = 0;
59 59
60const int border_tolerance = 2; 60const 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
68static inline bool is_printer( QPainter *p ) 68static 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
75static inline int scale( int value, QPainter *painter ) 75static 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
98void QTextCommandHistory::addCommand( QTextCommand *cmd ) 98void 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
123QTextCursor *QTextCommandHistory::undo( QTextCursor *c ) 123QTextCursor *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
133QTextCursor *QTextCommandHistory::redo( QTextCursor *c ) 133QTextCursor *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
149bool QTextCommandHistory::isUndoAvailable() 149bool QTextCommandHistory::isUndoAvailable()
150{ 150{
151 return current > -1; 151 return current > -1;
152} 152}
153 153
154bool QTextCommandHistory::isRedoAvailable() 154bool 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
161QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, 161QTextDeleteCommand::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
171QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str ) 171QTextDeleteCommand::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
180QTextDeleteCommand::~QTextDeleteCommand() 180QTextDeleteCommand::~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
189QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) 189QTextCursor *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
220QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) 217QTextCursor *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
269QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, 260QTextFormatCommand::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
280QTextFormatCommand::~QTextFormatCommand() 271QTextFormatCommand::~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
289QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) 280QTextCursor *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
313QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) 304QTextCursor *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
357QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange ) 348QTextStyleCommand::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
364QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag ) 355QByteArray 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
380void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style ) 371void 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
394QTextCursor *QTextStyleCommand::execute( QTextCursor *c ) 385QTextCursor *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
400QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c ) 391QTextCursor *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
408QTextCursor::QTextCursor( QTextDocument *d ) 399QTextCursor::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
415QTextCursor::QTextCursor( const QTextCursor &c ) 406QTextCursor::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
429QTextCursor &QTextCursor::operator=( const QTextCursor &c ) 420QTextCursor &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;
@@ -1212,414 +1203,403 @@ void QTextDocument::init()
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
1242QTextDocument::~QTextDocument() 1233QTextDocument::~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
1260void QTextDocument::clear( bool createEmptyParag ) 1251void 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
1277int QTextDocument::widthUsed() const 1268int QTextDocument::widthUsed() const
1278{ 1269{
1279 return wused + border_tolerance; 1270 return wused + border_tolerance;
1280} 1271}
1281 1272
1282int QTextDocument::height() const 1273int 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
1293QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) 1284QTextParagraph *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
1298bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p ) 1289bool 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
1319void QTextDocument::setPlainText( const QString &text ) 1310void 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
1361struct Q_EXPORT QTextDocumentTag { 1352struct 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) { \
1406 if ( !curpar ) { \
1407 owarn << "no current paragraph" << oendl; \
1408 return; \
1409 } \
1410 if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ 1396 if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \
1411 curpar->remove( curpar->length()-2, 1 ); \ 1397 curpar->remove( curpar->length()-2, 1 ); \
1412 curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); \ 1398 curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \
1413 if ( !curpar ) { \
1414 owarn << "failed in creating a new paragraph" << oendl; \
1415 return; \
1416 } \
1417 vec = 0; \
1418 } \
1419 hasNewPar = TRUE; \ 1399 hasNewPar = TRUE; \
1420 curpar->rtext = TRUE; \ 1400 curpar->rtext = TRUE; \
1421 curpar->align = curtag.alignment; \ 1401 curpar->align = curtag.alignment; \
1422 curpar->lstyle = curtag.liststyle; \ 1402 curpar->lstyle = curtag.liststyle; \
1423 curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ 1403 curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \
1424 curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ 1404 curpar->str->setDirection( (QChar::Direction)curtag.direction ); \
1425 space = TRUE; \ 1405 space = TRUE; \
1426 delete vec; \ 1406 delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
1427 vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
1428 int i = 0; \ 1407 int i = 0; \
1429 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ 1408 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
1430 vec->insert( i++, (*it).style ); \ 1409 vec->insert( i++, (*it).style ); \
1431 vec->insert( i, curtag.style ); \ 1410 vec->insert( i, curtag.style ); \
1432 } while ( FALSE ) 1411 } while ( FALSE )
1433 1412
1413
1434void QTextDocument::setRichText( const QString &text, const QString &context ) 1414void 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
1446void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) 1426void 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" ) {
@@ -1726,389 +1706,386 @@ void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* curso
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
1902void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) 1882void 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
2058void QTextDocument::setText( const QString &text, const QString &context ) 2035void 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
2069QString QTextDocument::plainText() const 2046QString 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
2102static QString align_to_string( int a ) 2079static 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
2113static QString direction_to_string( int d ) 2090static QString direction_to_string( int d )
2114{ 2091{
@@ -2881,393 +2858,390 @@ bool QTextDocument::inSelection( int selId, const QPoint &pos ) const
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
2914void QTextDocument::doLayout( QPainter *p, int w ) 2891void 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
2936QPixmap *QTextDocument::bufferPixmap( const QSize &s ) 2913QPixmap *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
2945void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) 2922void 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
2983void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, 2960void 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
3046QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, 3023QTextParagraph *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 */
3119void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) 3093void 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
3141void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) 3115void 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
3151void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) 3125void 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
3158bool QTextDocument::hasFocusParagraph() const 3132bool QTextDocument::hasFocusParagraph() const
3159{ 3133{
3160 return !!focusIndicator.parag; 3134 return !!focusIndicator.parag;
3161} 3135}
3162 3136
3163QString QTextDocument::focusHref() const 3137QString QTextDocument::focusHref() const
3164{ 3138{
3165 return focusIndicator.href; 3139 return focusIndicator.href;
3166} 3140}
3167 3141
3168bool QTextDocument::focusNextPrevChild( bool next ) 3142bool 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;
@@ -5175,385 +5149,385 @@ int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag
5175// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5149// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5176 5150
5177QTextFormatterBreakInWords::QTextFormatterBreakInWords() 5151QTextFormatterBreakInWords::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
5183int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, 5157int 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 = &parag->string()->at( 0 ); 5179 c = &parag->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 = &parag->string()->at( i ); 5193 c = &parag->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
5304QTextFormatterBreakWords::QTextFormatterBreakWords() 5278QTextFormatterBreakWords::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
5315int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, 5289int 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 = &parag->string()->at( 0 ); 5318 c = &parag->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();