summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-write
authorerik <erik>2007-02-08 01:45:16 (UTC)
committer erik <erik>2007-02-08 01:45:16 (UTC)
commit2e497f7cae45184184e2416114887095735958f5 (patch) (unidiff)
treea6b399d9bce5854dc7ad6c985b48965cf20680b0 /noncore/apps/opie-write
parent853b61f97e718359bef95147ab3c7beb0705acda (diff)
downloadopie-2e497f7cae45184184e2416114887095735958f5.zip
opie-2e497f7cae45184184e2416114887095735958f5.tar.gz
opie-2e497f7cae45184184e2416114887095735958f5.tar.bz2
Each file in this commit has a problem where it is possible to dereference
a pointer without that pointer being valid. This commit fixes each instance of that.
Diffstat (limited to 'noncore/apps/opie-write') (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp41
1 files changed, 32 insertions, 9 deletions
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp
index f040f1e..768da44 100644
--- a/noncore/apps/opie-write/qrichtext.cpp
+++ b/noncore/apps/opie-write/qrichtext.cpp
@@ -96,236 +96,245 @@ static inline int scale( int value, QPainter *painter )
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 ) { 192 if ( !s && doc ) {
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;
195 } 198 }
196 199
197 cursor.setParagraph( s ); 200 cursor.setParagraph( s );
198 cursor.setIndex( index ); 201 cursor.setIndex( index );
199 int len = text.size(); 202 int len = text.size();
200 if ( c ) 203 if ( c )
201 *c = cursor; 204 *c = cursor;
202 if ( doc ) { 205 if ( doc ) {
203 doc->setSelectionStart( QTextDocument::Temp, cursor ); 206 doc->setSelectionStart( QTextDocument::Temp, cursor );
204 for ( int i = 0; i < len; ++i ) 207 for ( int i = 0; i < len; ++i )
205 cursor.gotoNextLetter(); 208 cursor.gotoNextLetter();
206 doc->setSelectionEnd( QTextDocument::Temp, cursor ); 209 doc->setSelectionEnd( QTextDocument::Temp, cursor );
207 doc->removeSelectedText( QTextDocument::Temp, &cursor ); 210 doc->removeSelectedText( QTextDocument::Temp, &cursor );
208 if ( c ) 211 if ( c )
209 *c = cursor; 212 *c = cursor;
210 } else { 213 } else {
211 s->remove( index, len ); 214 s->remove( index, len );
212 } 215 }
213 216
214 return c; 217 return c;
215} 218}
216 219
217QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) 220QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
218{ 221{
219 QTextParagraph *s = doc ? doc->paragAt( id ) : parag; 222 QTextParagraph *s = doc ? doc->paragAt( id ) : parag;
220 if ( !s ) { 223 if ( !s && doc ) {
221 owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; 224 owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl;
222 return 0; 225 return 0;
226 } else if ( !doc ) {
227 owarn << "No valid doc" << oendl;
228 return 0;
223 } 229 }
224 230
225 cursor.setParagraph( s ); 231 cursor.setParagraph( s );
226 cursor.setIndex( index ); 232 cursor.setIndex( index );
227 QString str = QTextString::toString( text ); 233 QString str = QTextString::toString( text );
228 cursor.insert( str, TRUE, &text ); 234 cursor.insert( str, TRUE, &text );
229 cursor.setParagraph( s ); 235 cursor.setParagraph( s );
230 cursor.setIndex( index ); 236 cursor.setIndex( index );
231 if ( c ) { 237 if ( c ) {
232 c->setParagraph( s ); 238 c->setParagraph( s );
233 c->setIndex( index ); 239 c->setIndex( index );
234 for ( int i = 0; i < (int)text.size(); ++i ) 240 for ( int i = 0; i < (int)text.size(); ++i )
235 c->gotoNextLetter(); 241 c->gotoNextLetter();
242 } else {
243 owarn << "No valid cursor" << oendl;
244 return 0;
236 } 245 }
237 246
238 if ( !styleInformation.isEmpty() ) { 247 if ( !styleInformation.isEmpty() ) {
239 QDataStream styleStream( styleInformation, IO_ReadOnly ); 248 QDataStream styleStream( styleInformation, IO_ReadOnly );
240 int num; 249 int num;
241 styleStream >> num; 250 styleStream >> num;
242 QTextParagraph *p = s; 251 QTextParagraph *p = s;
243 while ( num-- && p ) { 252 while ( num-- && p ) {
244 p->readStyleInformation( styleStream ); 253 p->readStyleInformation( styleStream );
245 p = p->next(); 254 p = p->next();
246 } 255 }
247 } 256 }
248 s = cursor.paragraph(); 257 s = cursor.paragraph();
249 while ( s ) { 258 while ( s ) {
250 s->format(); 259 s->format();
251 s->setChanged( TRUE ); 260 s->setChanged( TRUE );
252 if ( s == c->paragraph() ) 261 if ( s == c->paragraph() )
253 break; 262 break;
254 s = s->next(); 263 s = s->next();
255 } 264 }
256 265
257 return &cursor; 266 return &cursor;
258} 267}
259 268
260QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, 269QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx,
261 const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl ) 270 const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl )
262 : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl ) 271 : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl )
263{ 272{
264 format = d->formatCollection()->format( f ); 273 format = d->formatCollection()->format( f );
265 for ( int j = 0; j < (int)oldFormats.size(); ++j ) { 274 for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
266 if ( oldFormats[ j ].format() ) 275 if ( oldFormats[ j ].format() )
267 oldFormats[ j ].format()->addRef(); 276 oldFormats[ j ].format()->addRef();
268 } 277 }
269} 278}
270 279
271QTextFormatCommand::~QTextFormatCommand() 280QTextFormatCommand::~QTextFormatCommand()
272{ 281{
273 format->removeRef(); 282 format->removeRef();
274 for ( int j = 0; j < (int)oldFormats.size(); ++j ) { 283 for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
275 if ( oldFormats[ j ].format() ) 284 if ( oldFormats[ j ].format() )
276 oldFormats[ j ].format()->removeRef(); 285 oldFormats[ j ].format()->removeRef();
277 } 286 }
278} 287}
279 288
280QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) 289QTextCursor *QTextFormatCommand::execute( QTextCursor *c )
281{ 290{
282 QTextParagraph *sp = doc->paragAt( startId ); 291 QTextParagraph *sp = doc->paragAt( startId );
283 QTextParagraph *ep = doc->paragAt( endId ); 292 QTextParagraph *ep = doc->paragAt( endId );
284 if ( !sp || !ep ) 293 if ( !sp || !ep )
285 return c; 294 return c;
286 295
287 QTextCursor start( doc ); 296 QTextCursor start( doc );
288 start.setParagraph( sp ); 297 start.setParagraph( sp );
289 start.setIndex( startIndex ); 298 start.setIndex( startIndex );
290 QTextCursor end( doc ); 299 QTextCursor end( doc );
291 end.setParagraph( ep ); 300 end.setParagraph( ep );
292 end.setIndex( endIndex ); 301 end.setIndex( endIndex );
293 302
294 doc->setSelectionStart( QTextDocument::Temp, start ); 303 doc->setSelectionStart( QTextDocument::Temp, start );
295 doc->setSelectionEnd( QTextDocument::Temp, end ); 304 doc->setSelectionEnd( QTextDocument::Temp, end );
296 doc->setFormat( QTextDocument::Temp, format, flags ); 305 doc->setFormat( QTextDocument::Temp, format, flags );
297 doc->removeSelection( QTextDocument::Temp ); 306 doc->removeSelection( QTextDocument::Temp );
298 if ( endIndex == ep->length() ) 307 if ( endIndex == ep->length() )
299 end.gotoLeft(); 308 end.gotoLeft();
300 *c = end; 309 *c = end;
301 return c; 310 return c;
302} 311}
303 312
304QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) 313QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
305{ 314{
306 QTextParagraph *sp = doc->paragAt( startId ); 315 QTextParagraph *sp = doc->paragAt( startId );
307 QTextParagraph *ep = doc->paragAt( endId ); 316 QTextParagraph *ep = doc->paragAt( endId );
308 if ( !sp || !ep ) 317 if ( !sp || !ep )
309 return 0; 318 return 0;
310 319
311 int idx = startIndex; 320 int idx = startIndex;
312 int fIndex = 0; 321 int fIndex = 0;
313 for ( ;; ) { 322 for ( ;; ) {
314 if ( oldFormats.at( fIndex ).c == '\n' ) { 323 if ( oldFormats.at( fIndex ).c == '\n' ) {
315 if ( idx > 0 ) { 324 if ( idx > 0 ) {
316 if ( idx < sp->length() && fIndex > 0 ) 325 if ( idx < sp->length() && fIndex > 0 )
317 sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() ); 326 sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() );
318 if ( sp == ep ) 327 if ( sp == ep )
319 break; 328 break;
320 sp = sp->next(); 329 sp = sp->next();
321 idx = 0; 330 idx = 0;
322 } 331 }
323 fIndex++; 332 fIndex++;
324 } 333 }
325 if ( oldFormats.at( fIndex ).format() ) 334 if ( oldFormats.at( fIndex ).format() )
326 sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() ); 335 sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() );
327 idx++; 336 idx++;
328 fIndex++; 337 fIndex++;
329 if ( fIndex >= (int)oldFormats.size() ) 338 if ( fIndex >= (int)oldFormats.size() )
330 break; 339 break;
331 if ( idx >= sp->length() ) { 340 if ( idx >= sp->length() ) {
@@ -1299,211 +1308,222 @@ bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p )
1299 } else if ( needed > minw ) { 1308 } else if ( needed > minw ) {
1300 minw = needed; 1309 minw = needed;
1301 minwParag = p; 1310 minwParag = p;
1302 emit minimumWidthChanged( minw ); 1311 emit minimumWidthChanged( minw );
1303 } 1312 }
1304 wused = QMAX( wused, used ); 1313 wused = QMAX( wused, used );
1305 wused = QMAX( wused, minw ); 1314 wused = QMAX( wused, minw );
1306 cw = QMAX( minw, cw ); 1315 cw = QMAX( minw, cw );
1307 return TRUE; 1316 return TRUE;
1308} 1317}
1309 1318
1310void QTextDocument::setPlainText( const QString &text ) 1319void QTextDocument::setPlainText( const QString &text )
1311{ 1320{
1312 clear(); 1321 clear();
1313 preferRichText = FALSE; 1322 preferRichText = FALSE;
1314 oTextValid = TRUE; 1323 oTextValid = TRUE;
1315 oText = text; 1324 oText = text;
1316 1325
1317 int lastNl = 0; 1326 int lastNl = 0;
1318 int nl = text.find( '\n' ); 1327 int nl = text.find( '\n' );
1319 if ( nl == -1 ) { 1328 if ( nl == -1 ) {
1320 lParag = createParagraph( this, lParag, 0 ); 1329 lParag = createParagraph( this, lParag, 0 );
1321 if ( !fParag ) 1330 if ( !fParag )
1322 fParag = lParag; 1331 fParag = lParag;
1323 QString s = text; 1332 QString s = text;
1324 if ( !s.isEmpty() ) { 1333 if ( !s.isEmpty() ) {
1325 if ( s[ (int)s.length() - 1 ] == '\r' ) 1334 if ( s[ (int)s.length() - 1 ] == '\r' )
1326 s.remove( s.length() - 1, 1 ); 1335 s.remove( s.length() - 1, 1 );
1327 lParag->append( s ); 1336 lParag->append( s );
1328 } 1337 }
1329 } else { 1338 } else {
1330 for (;;) { 1339 for (;;) {
1331 lParag = createParagraph( this, lParag, 0 ); 1340 lParag = createParagraph( this, lParag, 0 );
1332 if ( !fParag ) 1341 if ( !fParag )
1333 fParag = lParag; 1342 fParag = lParag;
1334 QString s = text.mid( lastNl, nl - lastNl ); 1343 QString s = text.mid( lastNl, nl - lastNl );
1335 if ( !s.isEmpty() ) { 1344 if ( !s.isEmpty() ) {
1336 if ( s[ (int)s.length() - 1 ] == '\r' ) 1345 if ( s[ (int)s.length() - 1 ] == '\r' )
1337 s.remove( s.length() - 1, 1 ); 1346 s.remove( s.length() - 1, 1 );
1338 lParag->append( s ); 1347 lParag->append( s );
1339 } 1348 }
1340 if ( nl == 0xffffff ) 1349 if ( nl == 0xffffff )
1341 break; 1350 break;
1342 lastNl = nl + 1; 1351 lastNl = nl + 1;
1343 nl = text.find( '\n', nl + 1 ); 1352 nl = text.find( '\n', nl + 1 );
1344 if ( nl == -1 ) 1353 if ( nl == -1 )
1345 nl = 0xffffff; 1354 nl = 0xffffff;
1346 } 1355 }
1347 } 1356 }
1348 if ( !lParag ) 1357 if ( !lParag )
1349 lParag = fParag = createParagraph( this, 0, 0 ); 1358 lParag = fParag = createParagraph( this, 0, 0 );
1350} 1359}
1351 1360
1352struct Q_EXPORT QTextDocumentTag { 1361struct Q_EXPORT QTextDocumentTag {
1353 QTextDocumentTag(){} 1362 QTextDocumentTag(){}
1354 QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f ) 1363 QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f )
1355 :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) { 1364 :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) {
1356 wsm = QStyleSheetItem::WhiteSpaceNormal; 1365 wsm = QStyleSheetItem::WhiteSpaceNormal;
1357 } 1366 }
1358 QString name; 1367 QString name;
1359 const QStyleSheetItem* style; 1368 const QStyleSheetItem* style;
1360 QString anchorHref; 1369 QString anchorHref;
1361 QStyleSheetItem::WhiteSpaceMode wsm; 1370 QStyleSheetItem::WhiteSpaceMode wsm;
1362 QTextFormat format; 1371 QTextFormat format;
1363 int alignment : 16; 1372 int alignment : 16;
1364 int direction : 5; 1373 int direction : 5;
1365 QStyleSheetItem::ListStyle liststyle; 1374 QStyleSheetItem::ListStyle liststyle;
1366 1375
1367 QTextDocumentTag( const QTextDocumentTag& t ) { 1376 QTextDocumentTag( const QTextDocumentTag& t ) {
1368 name = t.name; 1377 name = t.name;
1369 style = t.style; 1378 style = t.style;
1370 anchorHref = t.anchorHref; 1379 anchorHref = t.anchorHref;
1371 wsm = t.wsm; 1380 wsm = t.wsm;
1372 format = t.format; 1381 format = t.format;
1373 alignment = t.alignment; 1382 alignment = t.alignment;
1374 direction = t.direction; 1383 direction = t.direction;
1375 liststyle = t.liststyle; 1384 liststyle = t.liststyle;
1376 } 1385 }
1377 QTextDocumentTag& operator=(const QTextDocumentTag& t) { 1386 QTextDocumentTag& operator=(const QTextDocumentTag& t) {
1378 name = t.name; 1387 name = t.name;
1379 style = t.style; 1388 style = t.style;
1380 anchorHref = t.anchorHref; 1389 anchorHref = t.anchorHref;
1381 wsm = t.wsm; 1390 wsm = t.wsm;
1382 format = t.format; 1391 format = t.format;
1383 alignment = t.alignment; 1392 alignment = t.alignment;
1384 direction = t.direction; 1393 direction = t.direction;
1385 liststyle = t.liststyle; 1394 liststyle = t.liststyle;
1386 return *this; 1395 return *this;
1387 } 1396 }
1388 1397
1389#if defined(Q_FULL_TEMPLATE_INSTANTIATION) 1398#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
1390 bool operator==( const QTextDocumentTag& ) const { return FALSE; } 1399 bool operator==( const QTextDocumentTag& ) const { return FALSE; }
1391#endif 1400#endif
1392}; 1401};
1393 1402
1394 1403
1395#define NEWPAR do{ if ( !hasNewPar) { \ 1404#define NEWPAR do { \
1405 if ( !hasNewPar) { \
1406 if ( !curpar ) { \
1407 owarn << "no current paragraph" << oendl; \
1408 return; \
1409 } \
1396 if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ 1410 if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \
1397 curpar->remove( curpar->length()-2, 1 ); \ 1411 curpar->remove( curpar->length()-2, 1 ); \
1398 curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \ 1412 curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); \
1413 if ( !curpar ) { \
1414 owarn << "failed in creating a new paragraph" << oendl; \
1415 return; \
1416 } \
1417 vec = 0; \
1418 } \
1399 hasNewPar = TRUE; \ 1419 hasNewPar = TRUE; \
1400 curpar->rtext = TRUE; \ 1420 curpar->rtext = TRUE; \
1401 curpar->align = curtag.alignment; \ 1421 curpar->align = curtag.alignment; \
1402 curpar->lstyle = curtag.liststyle; \ 1422 curpar->lstyle = curtag.liststyle; \
1403 curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ 1423 curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \
1404 curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ 1424 curpar->str->setDirection( (QChar::Direction)curtag.direction ); \
1405 space = TRUE; \ 1425 space = TRUE; \
1406 delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \ 1426 delete vec; \
1427 vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
1407 int i = 0; \ 1428 int i = 0; \
1408 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ 1429 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
1409 vec->insert( i++, (*it).style ); \ 1430 vec->insert( i++, (*it).style ); \
1410 vec->insert( i, curtag.style ); \ 1431 vec->insert( i, curtag.style ); \
1411 }while(FALSE) 1432 }while(FALSE)
1412 1433
1413
1414void QTextDocument::setRichText( const QString &text, const QString &context ) 1434void QTextDocument::setRichText( const QString &text, const QString &context )
1415{ 1435{
1416 if ( !context.isEmpty() ) 1436 if ( !context.isEmpty() )
1417 setContext( context ); 1437 setContext( context );
1418 clear(); 1438 clear();
1419 fParag = lParag = createParagraph( this ); 1439 fParag = lParag = createParagraph( this );
1420 oTextValid = TRUE; 1440 oTextValid = TRUE;
1421 oText = text; 1441 oText = text;
1422 setRichTextInternal( text ); 1442 setRichTextInternal( text );
1423 fParag->rtext = TRUE; 1443 fParag->rtext = TRUE;
1424} 1444}
1425 1445
1426void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) 1446void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor )
1427{ 1447{
1428 QTextParagraph* curpar = lParag; 1448 QTextParagraph* curpar = lParag;
1429 int pos = 0; 1449 int pos = 0;
1430 QValueStack<QTextDocumentTag> tags; 1450 QValueStack<QTextDocumentTag> tags;
1431 QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); 1451 QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() );
1432 QTextDocumentTag curtag = initag; 1452 QTextDocumentTag curtag = initag;
1433 bool space = TRUE; 1453 bool space = TRUE;
1434 bool canMergeLi = FALSE; 1454 bool canMergeLi = FALSE;
1435 1455
1436 bool textEditMode = FALSE; 1456 bool textEditMode = FALSE;
1437 1457
1438 const QChar* doc = text.unicode(); 1458 const QChar* doc = text.unicode();
1439 int length = text.length(); 1459 int length = text.length();
1440 bool hasNewPar = curpar->length() <= 1; 1460 bool hasNewPar = curpar->length() <= 1;
1441 QString anchorName; 1461 QString anchorName;
1442 1462
1443 // style sheet handling for margin and line spacing calculation below 1463 // style sheet handling for margin and line spacing calculation below
1444 QTextParagraph* stylesPar = curpar; 1464 QTextParagraph* stylesPar = curpar;
1445 QPtrVector<QStyleSheetItem>* vec = 0; 1465 QPtrVector<QStyleSheetItem>* vec = 0;
1446 QPtrList< QPtrVector<QStyleSheetItem> > styles; 1466 QPtrList< QPtrVector<QStyleSheetItem> > styles;
1447 styles.setAutoDelete( TRUE ); 1467 styles.setAutoDelete( TRUE );
1448 1468
1449 if ( cursor ) { 1469 if ( cursor ) {
1450 cursor->splitAndInsertEmptyParagraph(); 1470 cursor->splitAndInsertEmptyParagraph();
1451 QTextCursor tmp = *cursor; 1471 QTextCursor tmp = *cursor;
1452 tmp.gotoPreviousLetter(); 1472 tmp.gotoPreviousLetter();
1453 stylesPar = curpar = tmp.paragraph(); 1473 stylesPar = curpar = tmp.paragraph();
1454 hasNewPar = TRUE; 1474 hasNewPar = TRUE;
1455 textEditMode = TRUE; 1475 textEditMode = TRUE;
1456 } else { 1476 } else {
1457 NEWPAR; 1477 NEWPAR;
1458 } 1478 }
1459 1479
1460 // set rtext spacing to FALSE for the initial paragraph. 1480 // set rtext spacing to FALSE for the initial paragraph.
1461 curpar->rtext = FALSE; 1481 curpar->rtext = FALSE;
1462 1482
1463 QString wellKnownTags = "br hr wsp table qt body meta title"; 1483 QString wellKnownTags = "br hr wsp table qt body meta title";
1464 1484
1465 while ( pos < length ) { 1485 while ( pos < length ) {
1466 if ( hasPrefix(doc, length, pos, '<' ) ){ 1486 if ( hasPrefix(doc, length, pos, '<' ) ){
1467 if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { 1487 if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) {
1468 // open tag 1488 // open tag
1469 QMap<QString, QString> attr; 1489 QMap<QString, QString> attr;
1470 bool emptyTag = FALSE; 1490 bool emptyTag = FALSE;
1471 QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag); 1491 QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
1472 if ( tagname.isEmpty() ) 1492 if ( tagname.isEmpty() )
1473 continue; // nothing we could do with this, probably parse error 1493 continue; // nothing we could do with this, probably parse error
1474 1494
1475 const QStyleSheetItem* nstyle = sheet_->item(tagname); 1495 const QStyleSheetItem* nstyle = sheet_->item(tagname);
1476 1496
1477 if ( nstyle ) { 1497 if ( nstyle ) {
1478 // we might have to close some 'forgotten' tags 1498 // we might have to close some 'forgotten' tags
1479 while ( !nstyle->allowedInContext( curtag.style ) ) { 1499 while ( !nstyle->allowedInContext( curtag.style ) ) {
1480 QString msg; 1500 QString msg;
1481 msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)", 1501 msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)",
1482 tagname.ascii(), curtag.style->name().ascii(), pos); 1502 tagname.ascii(), curtag.style->name().ascii(), pos);
1483 sheet_->error( msg ); 1503 sheet_->error( msg );
1484 if ( tags.isEmpty() ) 1504 if ( tags.isEmpty() )
1485 break; 1505 break;
1486 curtag = tags.pop(); 1506 curtag = tags.pop();
1487 } 1507 }
1488 1508
1489 /* special handling for p and li for HTML 1509 /* special handling for p and li for HTML
1490 compatibility. We do not want to embed blocks in 1510 compatibility. We do not want to embed blocks in
1491 p, and we do not want new blocks inside non-empty 1511 p, and we do not want new blocks inside non-empty
1492 lis. Plus we want to merge empty lis sometimes. */ 1512 lis. Plus we want to merge empty lis sometimes. */
1493 if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { 1513 if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) {
1494 canMergeLi = TRUE; 1514 canMergeLi = TRUE;
1495 } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { 1515 } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) {
1496 while ( curtag.style->name() == "p" ) { 1516 while ( curtag.style->name() == "p" ) {
1497 if ( tags.isEmpty() ) 1517 if ( tags.isEmpty() )
1498 break; 1518 break;
1499 curtag = tags.pop(); 1519 curtag = tags.pop();
1500 } 1520 }
1501 1521
1502 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { 1522 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1503 // we are in a li and a new block comes along 1523 // we are in a li and a new block comes along
1504 if ( nstyle->name() == "ul" || nstyle->name() == "ol" ) 1524 if ( nstyle->name() == "ul" || nstyle->name() == "ol" )
1505 hasNewPar = FALSE; // we want an empty li (like most browsers) 1525 hasNewPar = FALSE; // we want an empty li (like most browsers)
1506 if ( !hasNewPar ) { 1526 if ( !hasNewPar ) {
1507 /* do not add new blocks inside 1527 /* do not add new blocks inside
1508 non-empty lis */ 1528 non-empty lis */
1509 while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { 1529 while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
@@ -1802,194 +1822,197 @@ void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* curso
1802 c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre ); 1822 c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre );
1803 if ( c == QChar_linesep ) 1823 if ( c == QChar_linesep )
1804 break; 1824 break;
1805 } else { 1825 } else {
1806 int l = pos; 1826 int l = pos;
1807 c = parseChar( doc, length, pos, curtag.wsm ); 1827 c = parseChar( doc, length, pos, curtag.wsm );
1808 1828
1809 // in white space pre mode: treat any space as non breakable 1829 // in white space pre mode: treat any space as non breakable
1810 if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre ) 1830 if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre )
1811 c = QChar::nbsp; 1831 c = QChar::nbsp;
1812 1832
1813 if ( c == ' ' || c == QChar_linesep ) { 1833 if ( c == ' ' || c == QChar_linesep ) {
1814 /* avoid overlong paragraphs by forcing a new 1834 /* avoid overlong paragraphs by forcing a new
1815 paragraph after 4096 characters. This case can 1835 paragraph after 4096 characters. This case can
1816 occur when loading undiscovered plain text 1836 occur when loading undiscovered plain text
1817 documents in rich text mode. Instead of hanging 1837 documents in rich text mode. Instead of hanging
1818 forever, we do the trick. 1838 forever, we do the trick.
1819 */ 1839 */
1820 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do { 1840 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do {
1821 if ( doc[l] == '\n' ) { 1841 if ( doc[l] == '\n' ) {
1822 hasNewPar = FALSE; // for a new paragraph ... 1842 hasNewPar = FALSE; // for a new paragraph ...
1823 NEWPAR; 1843 NEWPAR;
1824 hasNewPar = FALSE; // ... and make it non-reusable 1844 hasNewPar = FALSE; // ... and make it non-reusable
1825 c = '\n'; // make sure we break below 1845 c = '\n'; // make sure we break below
1826 break; 1846 break;
1827 } 1847 }
1828 } while ( ++l < pos ); 1848 } while ( ++l < pos );
1829 } 1849 }
1830 } 1850 }
1831 1851
1832 if ( c == '\n' ) 1852 if ( c == '\n' )
1833 break; // break on newlines, pre delievers a QChar_linesep 1853 break; // break on newlines, pre delievers a QChar_linesep
1834 1854
1835 bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode; 1855 bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode;
1836 1856
1837 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) 1857 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space )
1838 continue; 1858 continue;
1839 if ( c == '\r' ) 1859 if ( c == '\r' )
1840 continue; 1860 continue;
1841 space = c_isSpace; 1861 space = c_isSpace;
1842 s += c; 1862 s += c;
1843 } 1863 }
1844 if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { 1864 if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) {
1845 hasNewPar = FALSE; 1865 hasNewPar = FALSE;
1846 int index = QMAX( curpar->length(),1) - 1; 1866 int index = QMAX( curpar->length(),1) - 1;
1847 curpar->append( s ); 1867 curpar->append( s );
1848 QTextFormat* f = formatCollection()->format( &curtag.format ); 1868 QTextFormat* f = formatCollection()->format( &curtag.format );
1849 curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already 1869 curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already
1850 f->ref += s.length() -1; // that what friends are for... 1870 f->ref += s.length() -1; // that what friends are for...
1851 if ( !curtag.anchorHref.isEmpty() ) { 1871 if ( !curtag.anchorHref.isEmpty() ) {
1852 for ( int i = 0; i < int(s.length()); i++ ) 1872 for ( int i = 0; i < int(s.length()); i++ )
1853 curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref ); 1873 curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref );
1854 } 1874 }
1855 if ( !anchorName.isEmpty() ) { 1875 if ( !anchorName.isEmpty() ) {
1856 curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); 1876 curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() );
1857 anchorName = QString::null; 1877 anchorName = QString::null;
1858 } 1878 }
1859 } 1879 }
1860 } 1880 }
1861 } 1881 }
1862 if ( hasNewPar && curpar != fParag && !cursor ) { 1882 if ( hasNewPar && curpar != fParag && !cursor ) {
1863 // cleanup unused last paragraphs 1883 // cleanup unused last paragraphs
1864 curpar = curpar->p; 1884 curpar = curpar->p;
1865 delete curpar->n; 1885 delete curpar->n;
1866 } 1886 }
1867 if ( !anchorName.isEmpty() ) { 1887 if ( !anchorName.isEmpty() ) {
1868 curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); 1888 curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() );
1869 anchorName = QString::null; 1889 anchorName = QString::null;
1870 } 1890 }
1871 1891
1872 1892
1873 setRichTextMarginsInternal( styles, stylesPar ); 1893 setRichTextMarginsInternal( styles, stylesPar );
1874 1894
1875 if ( cursor ) { 1895 if ( cursor ) {
1876 cursor->gotoPreviousLetter(); 1896 cursor->gotoPreviousLetter();
1877 cursor->remove(); 1897 cursor->remove();
1878 } 1898 }
1879 1899
1880} 1900}
1881 1901
1882void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) 1902void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar )
1883{ 1903{
1884 // margin and line spacing calculation 1904 // margin and line spacing calculation
1885 QPtrVector<QStyleSheetItem>* prevStyle = 0; 1905 QPtrVector<QStyleSheetItem>* prevStyle = 0;
1886 QPtrVector<QStyleSheetItem>* curStyle = styles.first(); 1906 QPtrVector<QStyleSheetItem>* curStyle = styles.first();
1887 QPtrVector<QStyleSheetItem>* nextStyle = styles.next(); 1907 QPtrVector<QStyleSheetItem>* nextStyle = styles.next();
1888 while ( stylesPar ) { 1908 while ( stylesPar ) {
1889 if ( !curStyle ) { 1909 if ( !curStyle ) {
1890 stylesPar = stylesPar->next(); 1910 stylesPar = stylesPar->next();
1891 prevStyle = curStyle; 1911 prevStyle = curStyle;
1892 curStyle = nextStyle; 1912 curStyle = nextStyle;
1893 nextStyle = styles.next(); 1913 nextStyle = styles.next();
1894 continue; 1914 continue;
1895 } 1915 }
1896 1916
1897 int i, mar; 1917 int i, mar;
1898 QStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0; 1918 QStyleSheetItem* mainStyle = (*curStyle)[curStyle->size()-1];
1899 if ( mainStyle && mainStyle->displayMode() == QStyleSheetItem::DisplayListItem ) 1919 if ( !mainStyle )
1920 return;
1921
1922 if ( mainStyle->displayMode() == QStyleSheetItem::DisplayListItem )
1900 stylesPar->setListItem( TRUE ); 1923 stylesPar->setListItem( TRUE );
1901 int numLists = 0; 1924 int numLists = 0;
1902 for ( i = 0; i < (int)curStyle->size(); ++i ) { 1925 for ( i = 0; i < (int)curStyle->size(); ++i ) {
1903 if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock 1926 if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
1904 && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) 1927 && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
1905 numLists++; 1928 numLists++;
1906 } 1929 }
1907 stylesPar->ldepth = numLists; 1930 stylesPar->ldepth = numLists;
1908 if ( stylesPar->next() && nextStyle ) { 1931 if ( stylesPar->next() && nextStyle ) {
1909 // also set the depth of the next paragraph, required for the margin calculation 1932 // also set the depth of the next paragraph, required for the margin calculation
1910 numLists = 0; 1933 numLists = 0;
1911 for ( i = 0; i < (int)nextStyle->size(); ++i ) { 1934 for ( i = 0; i < (int)nextStyle->size(); ++i ) {
1912 if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock 1935 if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
1913 && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) 1936 && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
1914 numLists++; 1937 numLists++;
1915 } 1938 }
1916 stylesPar->next()->ldepth = numLists; 1939 stylesPar->next()->ldepth = numLists;
1917 } 1940 }
1918 1941
1919 // do the top margin 1942 // do the top margin
1920 QStyleSheetItem* item = mainStyle; 1943 QStyleSheetItem* item = mainStyle;
1921 int m; 1944 int m;
1922 if (stylesPar->utm > 0 ) { 1945 if (stylesPar->utm > 0 ) {
1923 m = stylesPar->utm-1; 1946 m = stylesPar->utm-1;
1924 stylesPar->utm = 0; 1947 stylesPar->utm = 0;
1925 } else { 1948 } else {
1926 m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) ); 1949 m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) );
1927 if ( item->displayMode() == QStyleSheetItem::DisplayListItem 1950 if ( item->displayMode() == QStyleSheetItem::DisplayListItem
1928 && stylesPar->ldepth ) 1951 && stylesPar->ldepth )
1929 m /= stylesPar->ldepth; 1952 m /= stylesPar->ldepth;
1930 } 1953 }
1931 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 1954 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1932 item = (*curStyle)[ i ]; 1955 item = (*curStyle)[ i ];
1933 if ( prevStyle && i < (int) prevStyle->size() && 1956 if ( prevStyle && i < (int) prevStyle->size() &&
1934 ( item->displayMode() == QStyleSheetItem::DisplayBlock && 1957 ( item->displayMode() == QStyleSheetItem::DisplayBlock &&
1935 (*prevStyle)[ i ] == item ) ) 1958 (*prevStyle)[ i ] == item ) )
1936 break; 1959 break;
1937 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags 1960 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
1938 if ( int(item->listStyle()) != QStyleSheetItem::Undefined && 1961 if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
1939 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) 1962 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
1940 continue; 1963 continue;
1941 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) ); 1964 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) );
1942 m = QMAX( m, mar ); 1965 m = QMAX( m, mar );
1943 } 1966 }
1944 stylesPar->utm = m - stylesPar->topMargin(); 1967 stylesPar->utm = m - stylesPar->topMargin();
1945 1968
1946 // do the bottom margin 1969 // do the bottom margin
1947 item = mainStyle; 1970 item = mainStyle;
1948 if (stylesPar->ubm > 0 ) { 1971 if (stylesPar->ubm > 0 ) {
1949 m = stylesPar->ubm-1; 1972 m = stylesPar->ubm-1;
1950 stylesPar->ubm = 0; 1973 stylesPar->ubm = 0;
1951 } else { 1974 } else {
1952 m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); 1975 m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
1953 if ( item->displayMode() == QStyleSheetItem::DisplayListItem 1976 if ( item->displayMode() == QStyleSheetItem::DisplayListItem
1954 && stylesPar->ldepth ) 1977 && stylesPar->ldepth )
1955 m /= stylesPar->ldepth; 1978 m /= stylesPar->ldepth;
1956 } 1979 }
1957 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 1980 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1958 item = (*curStyle)[ i ]; 1981 item = (*curStyle)[ i ];
1959 if ( nextStyle && i < (int) nextStyle->size() && 1982 if ( nextStyle && i < (int) nextStyle->size() &&
1960 ( item->displayMode() == QStyleSheetItem::DisplayBlock && 1983 ( item->displayMode() == QStyleSheetItem::DisplayBlock &&
1961 (*nextStyle)[ i ] == item ) ) 1984 (*nextStyle)[ i ] == item ) )
1962 break; 1985 break;
1963 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags 1986 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
1964 if ( int(item->listStyle()) != QStyleSheetItem::Undefined && 1987 if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
1965 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) 1988 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
1966 continue; 1989 continue;
1967 mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); 1990 mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
1968 m = QMAX( m, mar ); 1991 m = QMAX( m, mar );
1969 } 1992 }
1970 stylesPar->ubm = m - stylesPar->bottomMargin(); 1993 stylesPar->ubm = m - stylesPar->bottomMargin();
1971 1994
1972 // do the left margin, simplyfied 1995 // do the left margin, simplyfied
1973 item = mainStyle; 1996 item = mainStyle;
1974 if (stylesPar->ulm > 0 ) { 1997 if (stylesPar->ulm > 0 ) {
1975 m = stylesPar->ulm-1; 1998 m = stylesPar->ulm-1;
1976 stylesPar->ulm = 0; 1999 stylesPar->ulm = 0;
1977 } else { 2000 } else {
1978 m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); 2001 m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1979 } 2002 }
1980 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 2003 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1981 item = (*curStyle)[ i ]; 2004 item = (*curStyle)[ i ];
1982 m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); 2005 m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1983 } 2006 }
1984 stylesPar->ulm = m - stylesPar->leftMargin(); 2007 stylesPar->ulm = m - stylesPar->leftMargin();
1985 2008
1986 // do the right margin, simplyfied 2009 // do the right margin, simplyfied
1987 item = mainStyle; 2010 item = mainStyle;
1988 if (stylesPar->urm > 0 ) { 2011 if (stylesPar->urm > 0 ) {
1989 m = stylesPar->urm-1; 2012 m = stylesPar->urm-1;
1990 stylesPar->urm = 0; 2013 stylesPar->urm = 0;
1991 } else { 2014 } else {
1992 m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); 2015 m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
1993 } 2016 }
1994 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 2017 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1995 item = (*curStyle)[ i ]; 2018 item = (*curStyle)[ i ];
@@ -5248,193 +5271,193 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag
5248 col = 0; 5271 col = 0;
5249 if ( wrapAtColumn() != -1 ) 5272 if ( wrapAtColumn() != -1 )
5250 minw = QMAX( minw, w ); 5273 minw = QMAX( minw, w );
5251 } else if ( lineStart ) { 5274 } else if ( lineStart ) {
5252 lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); 5275 lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() );
5253 h = QMAX( h, c->height() ); 5276 h = QMAX( h, c->height() );
5254 lineStart->h = h; 5277 lineStart->h = h;
5255 } 5278 }
5256 5279
5257 c->x = x; 5280 c->x = x;
5258 x += ww; 5281 x += ww;
5259 wused = QMAX( wused, x ); 5282 wused = QMAX( wused, x );
5260 } 5283 }
5261 5284
5262 int m = parag->bottomMargin(); 5285 int m = parag->bottomMargin();
5263 if ( !parag->next() ) 5286 if ( !parag->next() )
5264 m = 0; 5287 m = 0;
5265 else 5288 else
5266 m = QMAX(m, parag->next()->topMargin() ) / 2; 5289 m = QMAX(m, parag->next()->topMargin() ) / 2;
5267 parag->setFullWidth( fullWidth ); 5290 parag->setFullWidth( fullWidth );
5268 y += h + m; 5291 y += h + m;
5269 if ( doc ) 5292 if ( doc )
5270 minw += doc->rightMargin(); 5293 minw += doc->rightMargin();
5271 if ( !wrapEnabled ) 5294 if ( !wrapEnabled )
5272 minw = QMAX(minw, wused); 5295 minw = QMAX(minw, wused);
5273 5296
5274 thisminw = minw; 5297 thisminw = minw;
5275 thiswused = wused; 5298 thiswused = wused;
5276 return y; 5299 return y;
5277} 5300}
5278 5301
5279// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5302// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5280 5303
5281QTextFormatterBreakWords::QTextFormatterBreakWords() 5304QTextFormatterBreakWords::QTextFormatterBreakWords()
5282{ 5305{
5283} 5306}
5284 5307
5285#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ 5308#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \
5286 int yflow = lineStart->y + parag->rect().y();\ 5309 int yflow = lineStart->y + parag->rect().y();\
5287 int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ 5310 int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \
5288 lineStart->y += shift;\ 5311 lineStart->y += shift;\
5289 y += shift;\ 5312 y += shift;\
5290 }}while(FALSE) 5313 }}while(FALSE)
5291 5314
5292int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, 5315int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag,
5293 int start, const QMap<int, QTextLineStart*> & ) 5316 int start, const QMap<int, QTextLineStart*> & )
5294{ 5317{
5295 QTextStringChar *c = 0; 5318 QTextStringChar *c = 0;
5296 QTextStringChar *firstChar = 0; 5319 QTextStringChar *firstChar = 0;
5297 QTextString *string = parag->string(); 5320 QTextString *string = parag->string();
5298 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; 5321 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
5299 int x = left + ( doc ? parag->firstLineMargin() : 0 ); 5322 int x = left + ( doc ? parag->firstLineMargin() : 0 );
5300 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; 5323 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
5301 int h = y; 5324 int h = y;
5302 int len = parag->length(); 5325 int len = parag->length();
5303 if ( doc ) 5326 if ( doc )
5304 x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); 5327 x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 );
5305 int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 ); 5328 int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 );
5306 5329
5307 int curLeft = x; 5330 int curLeft = x;
5308 int rm = parag->rightMargin(); 5331 int rm = parag->rightMargin();
5309 int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; 5332 int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0;
5310 int w = dw - rdiff; 5333 int w = dw - rdiff;
5311 bool fullWidth = TRUE; 5334 bool fullWidth = TRUE;
5312 int marg = left + rdiff; 5335 int marg = left + rdiff;
5313 int minw = 0; 5336 int minw = 0;
5314 int wused = 0; 5337 int wused = 0;
5315 int tminw = marg; 5338 int tminw = marg;
5316 int linespacing = doc ? parag->lineSpacing() : 0; 5339 int linespacing = doc ? parag->lineSpacing() : 0;
5317 bool wrapEnabled = isWrapEnabled( parag ); 5340 bool wrapEnabled = isWrapEnabled( parag );
5318 5341
5319 start = 0; 5342 start = 0;
5320 if ( start == 0 ) 5343 if ( start == 0 )
5321 c = &parag->string()->at( 0 ); 5344 c = &parag->string()->at( 0 );
5322 5345
5323 int i = start; 5346 int i = start;
5324 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); 5347 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
5325 insertLineStart( parag, 0, lineStart ); 5348 insertLineStart( parag, 0, lineStart );
5326 int lastBreak = -1; 5349 int lastBreak = -1;
5327 int tmpBaseLine = 0, tmph = 0; 5350 int tmpBaseLine = 0, tmph = 0;
5328 bool lastWasNonInlineCustom = FALSE; 5351 bool lastWasNonInlineCustom = FALSE;
5329 5352
5330 int align = parag->alignment(); 5353 int align = parag->alignment();
5331 if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) 5354 if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto )
5332 align = doc->alignment(); 5355 align = doc->alignment();
5333 5356
5334 align &= Qt3::AlignHorizontal_Mask; 5357 align &= Qt3::AlignHorizontal_Mask;
5335 5358
5336 QPainter *painter = QTextFormat::painter(); 5359 QPainter *painter = QTextFormat::painter();
5337 int col = 0; 5360 int col = 0;
5338 int ww = 0; 5361 int ww = 0;
5339 QChar lastChr; 5362 QChar lastChr;
5340 for ( ; i < len; ++i, ++col ) { 5363 for ( ; i < len; ++i, ++col ) {
5341 if ( c ) 5364 if ( c )
5342 lastChr = c->c; 5365 lastChr = c->c;
5343 // ### next line should not be needed 5366 // ### next line should not be needed
5344 if ( painter ) 5367 if ( c && painter )
5345 c->format()->setPainter( painter ); 5368 c->format()->setPainter( painter );
5346 c = &string->at( i ); 5369 c = &string->at( i );
5347 c->rightToLeft = FALSE; 5370 c->rightToLeft = FALSE;
5348 if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { 5371 if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) {
5349 c->lineStart = 0; 5372 c->lineStart = 0;
5350 } else { 5373 } else {
5351 c->lineStart = 1; 5374 c->lineStart = 1;
5352 firstChar = c; 5375 firstChar = c;
5353 } 5376 }
5354 5377
5355 if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) 5378 if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline )
5356 lastWasNonInlineCustom = TRUE; 5379 lastWasNonInlineCustom = TRUE;
5357 else 5380 else
5358 lastWasNonInlineCustom = FALSE; 5381 lastWasNonInlineCustom = FALSE;
5359 5382
5360 if ( c->c.unicode() >= 32 || c->isCustom() ) { 5383 if ( c->c.unicode() >= 32 || c->isCustom() ) {
5361 ww = string->width( i ); 5384 ww = string->width( i );
5362 } else if ( c->c == '\t' ) { 5385 } else if ( c->c == '\t' ) {
5363 int nx = parag->nextTab( i, x - left ) + left; 5386 int nx = parag->nextTab( i, x - left ) + left;
5364 if ( nx < x ) 5387 if ( nx < x )
5365 ww = w - x; 5388 ww = w - x;
5366 else 5389 else
5367 ww = nx - x; 5390 ww = nx - x;
5368 } else { 5391 } else {
5369 ww = c->format()->width( ' ' ); 5392 ww = c->format()->width( ' ' );
5370 } 5393 }
5371 5394
5372 // last character ("invisible" space) has no width 5395 // last character ("invisible" space) has no width
5373 if ( i == len - 1 ) 5396 if ( i == len - 1 )
5374 ww = 0; 5397 ww = 0;
5375 5398
5376 QTextCustomItem* ci = c->customItem(); 5399 QTextCustomItem* ci = c->customItem();
5377 if ( c->isCustom() && ci->ownLine() ) { 5400 if ( c->isCustom() && ci->ownLine() ) {
5378 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5401 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
5379 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); 5402 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5380 QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); 5403 QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
5381 ci->resize( w - x); 5404 ci->resize( w - x);
5382 if ( ci->width < w - x ) { 5405 if ( ci->width < w - x ) {
5383 if ( align & Qt::AlignHCenter ) 5406 if ( align & Qt::AlignHCenter )
5384 x = ( w - ci->width ) / 2; 5407 x = ( w - ci->width ) / 2;
5385 else if ( align & Qt::AlignRight ) { 5408 else if ( align & Qt::AlignRight ) {
5386 x = w - ci->width; 5409 x = w - ci->width;
5387 } 5410 }
5388 } 5411 }
5389 c->x = x; 5412 c->x = x;
5390 curLeft = x; 5413 curLeft = x;
5391 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { 5414 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) {
5392 y += QMAX( h, QMAX( tmph, linespacing ) ); 5415 y += QMAX( h, QMAX( tmph, linespacing ) );
5393 tmph = c->height(); 5416 tmph = c->height();
5394 h = tmph; 5417 h = tmph;
5395 lineStart = lineStart2; 5418 lineStart = lineStart2;
5396 lineStart->y = y; 5419 lineStart->y = y;
5397 insertLineStart( parag, i, lineStart ); 5420 insertLineStart( parag, i, lineStart );
5398 c->lineStart = 1; 5421 c->lineStart = 1;
5399 firstChar = c; 5422 firstChar = c;
5400 } else { 5423 } else {
5401 tmph = c->height(); 5424 tmph = c->height();
5402 h = tmph; 5425 h = tmph;
5403 delete lineStart2; 5426 delete lineStart2;
5404 } 5427 }
5405 lineStart->h = h; 5428 lineStart->h = h;
5406 lineStart->baseLine = h; 5429 lineStart->baseLine = h;
5407 tmpBaseLine = lineStart->baseLine; 5430 tmpBaseLine = lineStart->baseLine;
5408 lastBreak = -2; 5431 lastBreak = -2;
5409 x = 0xffffff; 5432 x = 0xffffff;
5410 minw = QMAX( minw, tminw ); 5433 minw = QMAX( minw, tminw );
5411 5434
5412 int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); 5435 int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
5413 if ( tw < QWIDGETSIZE_MAX ) 5436 if ( tw < QWIDGETSIZE_MAX )
5414 tminw = tw; 5437 tminw = tw;
5415 else 5438 else
5416 tminw = marg; 5439 tminw = marg;
5417 wused = QMAX( wused, ci->width ); 5440 wused = QMAX( wused, ci->width );
5418 continue; 5441 continue;
5419 } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { 5442 } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) {
5420 int tw = ci->minimumWidth(); 5443 int tw = ci->minimumWidth();
5421 if ( tw < QWIDGETSIZE_MAX ) 5444 if ( tw < QWIDGETSIZE_MAX )
5422 minw = QMAX( minw, tw ); 5445 minw = QMAX( minw, tw );
5423 } 5446 }
5424 5447
5425 bool lastWasOwnLineCustomItem = lastBreak == -2; 5448 bool lastWasOwnLineCustomItem = lastBreak == -2;
5426 bool hadBreakableChar = lastBreak != -1; 5449 bool hadBreakableChar = lastBreak != -1;
5427 bool lastWasHardBreak = lastChr == QChar_linesep; 5450 bool lastWasHardBreak = lastChr == QChar_linesep;
5428 5451
5429 // we break if 5452 // we break if
5430 // 1. the last character was a hard break (QChar_linesep) or 5453 // 1. the last character was a hard break (QChar_linesep) or
5431 // 2. the last charater was a own-line custom item (eg. table or ruler) or 5454 // 2. the last charater was a own-line custom item (eg. table or ruler) or
5432 // 3. wrapping was enabled, it was not a space and following 5455 // 3. wrapping was enabled, it was not a space and following
5433 // condition is true: We either had a breakable character 5456 // condition is true: We either had a breakable character
5434 // previously or we ar allowed to break in words and - either 5457 // previously or we ar allowed to break in words and - either
5435 // we break at w pixels and the current char would exceed that 5458 // we break at w pixels and the current char would exceed that
5436 // or - we break at a column and the current character would 5459 // or - we break at a column and the current character would
5437 // exceed that. 5460 // exceed that.
5438 if ( lastWasHardBreak || lastWasOwnLineCustomItem || 5461 if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
5439 ( wrapEnabled && 5462 ( wrapEnabled &&
5440 ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && 5463 ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&