summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-write/qrichtext.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-write/qrichtext.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp4311
1 files changed, 2035 insertions, 2276 deletions
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp
index 7901000..3b044c3 100644
--- a/noncore/apps/opie-write/qrichtext.cpp
+++ b/noncore/apps/opie-write/qrichtext.cpp
@@ -43,5 +43,3 @@
43#include "qfile.h" 43#include "qfile.h"
44#include "qregexp.h"
45#include "qapplication.h" 44#include "qapplication.h"
46#include "qclipboard.h"
47#include "qmap.h" 45#include "qmap.h"
@@ -50,3 +48,2 @@
50#include "qmime.h" 48#include "qmime.h"
51#include "qregexp.h"
52#include "qimage.h" 49#include "qimage.h"
@@ -66,5 +63,4 @@ using namespace Qt3;
66 63
67//#define PARSER_DEBUG 64static QTextCursor* richTextExportStart = 0;
68//#define DEBUG_COLLECTION// ---> also in qrichtext_p.h 65static QTextCursor* richTextExportEnd = 0;
69//#define DEBUG_TABLE_RENDERING
70 66
@@ -72,11 +68,4 @@ static QTextFormatCollection *qFormatCollection = 0;
72 68
73const int QStyleSheetItem_WhiteSpaceNoCompression = 3; // ### belongs in QStyleSheetItem, fix 3.1
74const int QStyleSheetItem_WhiteSpaceNormalWithNewlines = 4; // ### belongs in QStyleSheetItem, fix 3.1
75
76const int border_tolerance = 2; 69const int border_tolerance = 2;
77 70
78#if defined(PARSER_DEBUG)
79static QString debug_indent;
80#endif
81
82#ifdef Q_WS_WIN 71#ifdef Q_WS_WIN
@@ -85,2 +74,4 @@ static QString debug_indent;
85 74
75#define QChar_linesep QChar(0x2028U)
76
86static inline bool is_printer( QPainter *p ) 77static inline bool is_printer( QPainter *p )
@@ -179,6 +170,4 @@ bool QTextCommandHistory::isRedoAvailable()
179QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, 170QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
180 const QValueList< QPtrVector<QStyleSheetItem> > &os, 171 const QByteArray& oldStyleInfo )
181 const QValueList<QStyleSheetItem::ListStyle> &ols, 172 : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo )
182 const QMemArray<int> &oas)
183 : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), oldStyles( os ), oldListStyles( ols ), oldAligns( oas )
184{ 173{
@@ -190,3 +179,3 @@ QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const
190 179
191QTextDeleteCommand::QTextDeleteCommand( QTextParag *p, int idx, const QMemArray<QTextStringChar> &str ) 180QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str )
192 : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str ) 181 : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str )
@@ -210,5 +199,5 @@ QTextCursor *QTextDeleteCommand::execute( QTextCursor *c )
210{ 199{
211 QTextParag *s = doc ? doc->paragAt( id ) : parag; 200 QTextParagraph *s = doc ? doc->paragAt( id ) : parag;
212 if ( !s ) { 201 if ( !s ) {
213 qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParag()->paragId() ); 202 qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
214 return 0; 203 return 0;
@@ -216,3 +205,3 @@ QTextCursor *QTextDeleteCommand::execute( QTextCursor *c )
216 205
217 cursor.setParag( s ); 206 cursor.setParagraph( s );
218 cursor.setIndex( index ); 207 cursor.setIndex( index );
@@ -222,6 +211,6 @@ QTextCursor *QTextDeleteCommand::execute( QTextCursor *c )
222 if ( doc ) { 211 if ( doc ) {
223 doc->setSelectionStart( QTextDocument::Temp, &cursor ); 212 doc->setSelectionStart( QTextDocument::Temp, cursor );
224 for ( int i = 0; i < len; ++i ) 213 for ( int i = 0; i < len; ++i )
225 cursor.gotoNextLetter(); 214 cursor.gotoNextLetter();
226 doc->setSelectionEnd( QTextDocument::Temp, &cursor ); 215 doc->setSelectionEnd( QTextDocument::Temp, cursor );
227 doc->removeSelectedText( QTextDocument::Temp, &cursor ); 216 doc->removeSelectedText( QTextDocument::Temp, &cursor );
@@ -238,5 +227,5 @@ QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
238{ 227{
239 QTextParag *s = doc ? doc->paragAt( id ) : parag; 228 QTextParagraph *s = doc ? doc->paragAt( id ) : parag;
240 if ( !s ) { 229 if ( !s ) {
241 qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParag()->paragId() ); 230 qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
242 return 0; 231 return 0;
@@ -244,3 +233,3 @@ QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
244 233
245 cursor.setParag( s ); 234 cursor.setParagraph( s );
246 cursor.setIndex( index ); 235 cursor.setIndex( index );
@@ -248,6 +237,6 @@ QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
248 cursor.insert( str, TRUE, &text ); 237 cursor.insert( str, TRUE, &text );
249 cursor.setParag( s ); 238 cursor.setParagraph( s );
250 cursor.setIndex( index ); 239 cursor.setIndex( index );
251 if ( c ) { 240 if ( c ) {
252 c->setParag( s ); 241 c->setParagraph( s );
253 c->setIndex( index ); 242 c->setIndex( index );
@@ -257,29 +246,13 @@ QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
257 246
258 QValueList< QPtrVector<QStyleSheetItem> >::Iterator it = oldStyles.begin(); 247 if ( !styleInformation.isEmpty() ) {
259 QValueList<QStyleSheetItem::ListStyle>::Iterator lit = oldListStyles.begin(); 248 QDataStream styleStream( styleInformation, IO_ReadOnly );
260 int i = 0; 249 int num;
261 QTextParag *p = s; 250 styleStream >> num;
262 bool end = FALSE; 251 QTextParagraph *p = s;
263 while ( p ) { 252 while ( num-- && p ) {
264 if ( it != oldStyles.end() ) 253 p->readStyleInformation( styleStream );
265 p->setStyleSheetItems( *it ); 254 p = p->next();
266 else 255 }
267 end = TRUE;
268 if ( lit != oldListStyles.end() )
269 p->setListStyle( *lit );
270 else
271 end = TRUE;
272 if ( i < (int)oldAligns.size() )
273 p->setAlignment( oldAligns.at( i ) );
274 else
275 end = TRUE;
276 if ( end )
277 break;
278 p = p->next();
279 ++it;
280 ++lit;
281 ++i;
282 } 256 }
283 257 s = cursor.paragraph();
284 s = cursor.parag();
285 while ( s ) { 258 while ( s ) {
@@ -287,3 +260,3 @@ QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
287 s->setChanged( TRUE ); 260 s->setChanged( TRUE );
288 if ( s == c->parag() ) 261 if ( s == c->paragraph() )
289 break; 262 break;
@@ -317,4 +290,4 @@ QTextCursor *QTextFormatCommand::execute( QTextCursor *c )
317{ 290{
318 QTextParag *sp = doc->paragAt( startId ); 291 QTextParagraph *sp = doc->paragAt( startId );
319 QTextParag *ep = doc->paragAt( endId ); 292 QTextParagraph *ep = doc->paragAt( endId );
320 if ( !sp || !ep ) 293 if ( !sp || !ep )
@@ -323,10 +296,10 @@ QTextCursor *QTextFormatCommand::execute( QTextCursor *c )
323 QTextCursor start( doc ); 296 QTextCursor start( doc );
324 start.setParag( sp ); 297 start.setParagraph( sp );
325 start.setIndex( startIndex ); 298 start.setIndex( startIndex );
326 QTextCursor end( doc ); 299 QTextCursor end( doc );
327 end.setParag( ep ); 300 end.setParagraph( ep );
328 end.setIndex( endIndex ); 301 end.setIndex( endIndex );
329 302
330 doc->setSelectionStart( QTextDocument::Temp, &start ); 303 doc->setSelectionStart( QTextDocument::Temp, start );
331 doc->setSelectionEnd( QTextDocument::Temp, &end ); 304 doc->setSelectionEnd( QTextDocument::Temp, end );
332 doc->setFormat( QTextDocument::Temp, format, flags ); 305 doc->setFormat( QTextDocument::Temp, format, flags );
@@ -341,4 +314,4 @@ QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
341{ 314{
342 QTextParag *sp = doc->paragAt( startId ); 315 QTextParagraph *sp = doc->paragAt( startId );
343 QTextParag *ep = doc->paragAt( endId ); 316 QTextParagraph *ep = doc->paragAt( endId );
344 if ( !sp || !ep ) 317 if ( !sp || !ep )
@@ -375,3 +348,3 @@ QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
375 QTextCursor end( doc ); 348 QTextCursor end( doc );
376 end.setParag( ep ); 349 end.setParagraph( ep );
377 end.setIndex( endIndex ); 350 end.setIndex( endIndex );
@@ -383,56 +356,42 @@ QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
383 356
384QTextAlignmentCommand::QTextAlignmentCommand( QTextDocument *d, int fParag, int lParag, int na, const QMemArray<int> &oa ) 357QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange )
385 : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), newAlign( na ), oldAligns( oa ) 358 : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange )
386{ 359{
360 after = readStyleInformation( d, fParag, lParag );
387} 361}
388 362
389QTextCursor *QTextAlignmentCommand::execute( QTextCursor *c ) 363
364QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag )
390{ 365{
391 QTextParag *p = doc->paragAt( firstParag ); 366 QByteArray style;
367 QTextParagraph *p = doc->paragAt( fParag );
392 if ( !p ) 368 if ( !p )
393 return c; 369 return style;
394 while ( p ) { 370 QDataStream styleStream( style, IO_WriteOnly );
395 p->setAlignment( newAlign ); 371 int num = lParag - fParag + 1;
396 if ( p->paragId() == lastParag ) 372 styleStream << num;
397 break; 373 while ( num -- && p ) {
374 p->writeStyleInformation( styleStream );
398 p = p->next(); 375 p = p->next();
399 } 376 }
400 return c; 377 return style;
401} 378}
402 379
403QTextCursor *QTextAlignmentCommand::unexecute( QTextCursor *c ) 380void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style )
404{ 381{
405 QTextParag *p = doc->paragAt( firstParag ); 382 QTextParagraph *p = doc->paragAt( fParag );
406 if ( !p ) 383 if ( !p )
407 return c; 384 return;
408 int i = 0; 385 QDataStream styleStream( style, IO_ReadOnly );
409 while ( p ) { 386 int num;
410 if ( i < (int)oldAligns.size() ) 387 styleStream >> num;
411 p->setAlignment( oldAligns.at( i ) ); 388 while ( num-- && p ) {
412 if ( p->paragId() == lastParag ) 389 p->readStyleInformation( styleStream );
413 break;
414 p = p->next(); 390 p = p->next();
415 ++i;
416 } 391 }
417 return c;
418}
419
420QTextParagTypeCommand::QTextParagTypeCommand( QTextDocument *d, int fParag, int lParag, bool l,
421 QStyleSheetItem::ListStyle s, const QValueList< QPtrVector<QStyleSheetItem> > &os,
422 const QValueList<QStyleSheetItem::ListStyle> &ols )
423 : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), list( l ), listStyle( s ), oldStyles( os ), oldListStyles( ols )
424{
425} 392}
426 393
427QTextCursor *QTextParagTypeCommand::execute( QTextCursor *c ) 394QTextCursor *QTextStyleCommand::execute( QTextCursor *c )
428{ 395{
429 QTextParag *p = doc->paragAt( firstParag ); 396 writeStyleInformation( doc, firstParag, after );
430 if ( !p )
431 return c;
432 while ( p ) {
433 p->setList( list, (int)listStyle );
434 if ( p->paragId() == lastParag )
435 break;
436 p = p->next();
437 }
438 return c; 397 return c;
@@ -440,20 +399,5 @@ QTextCursor *QTextParagTypeCommand::execute( QTextCursor *c )
440 399
441QTextCursor *QTextParagTypeCommand::unexecute( QTextCursor *c ) 400QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c )
442{ 401{
443 QTextParag *p = doc->paragAt( firstParag ); 402 writeStyleInformation( doc, firstParag, before );
444 if ( !p )
445 return c;
446 QValueList< QPtrVector<QStyleSheetItem> >::Iterator it = oldStyles.begin();
447 QValueList<QStyleSheetItem::ListStyle>::Iterator lit = oldListStyles.begin();
448 while ( p ) {
449 if ( it != oldStyles.end() )
450 p->setStyleSheetItems( *it );
451 if ( lit != oldListStyles.end() )
452 p->setListStyle( *lit );
453 if ( p->paragId() == lastParag )
454 break;
455 p = p->next();
456 ++it;
457 ++lit;
458 }
459 return c; 403 return c;
@@ -464,13 +408,6 @@ QTextCursor *QTextParagTypeCommand::unexecute( QTextCursor *c )
464QTextCursor::QTextCursor( QTextDocument *d ) 408QTextCursor::QTextCursor( QTextDocument *d )
465 : doc( d ), ox( 0 ), oy( 0 ) 409 : idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ),
466{ 410 valid( TRUE )
467 nested = FALSE;
468 idx = 0;
469 string = doc ? doc->firstParag() : 0;
470 tmpIndex = -1;
471 valid = TRUE;
472}
473
474QTextCursor::QTextCursor()
475{ 411{
412 para = d ? d->firstParagraph() : 0;
476} 413}
@@ -479,11 +416,9 @@ QTextCursor::QTextCursor( const QTextCursor &c )
479{ 416{
480 doc = c.doc;
481 ox = c.ox; 417 ox = c.ox;
482 oy = c.oy; 418 oy = c.oy;
483 nested = c.nested;
484 idx = c.idx; 419 idx = c.idx;
485 string = c.string; 420 para = c.para;
486 tmpIndex = c.tmpIndex; 421 tmpIndex = c.tmpIndex;
487 indices = c.indices; 422 indices = c.indices;
488 parags = c.parags; 423 paras = c.paras;
489 xOffsets = c.xOffsets; 424 xOffsets = c.xOffsets;
@@ -495,11 +430,9 @@ QTextCursor &QTextCursor::operator=( const QTextCursor &c )
495{ 430{
496 doc = c.doc;
497 ox = c.ox; 431 ox = c.ox;
498 oy = c.oy; 432 oy = c.oy;
499 nested = c.nested;
500 idx = c.idx; 433 idx = c.idx;
501 string = c.string; 434 para = c.para;
502 tmpIndex = c.tmpIndex; 435 tmpIndex = c.tmpIndex;
503 indices = c.indices; 436 indices = c.indices;
504 parags = c.parags; 437 paras = c.paras;
505 xOffsets = c.xOffsets; 438 xOffsets = c.xOffsets;
@@ -513,3 +446,3 @@ bool QTextCursor::operator==( const QTextCursor &c ) const
513{ 446{
514 return doc == c.doc && string == c.string && idx == c.idx; 447 return para == c.para && idx == c.idx;
515} 448}
@@ -518,7 +451,4 @@ int QTextCursor::totalOffsetX() const
518{ 451{
519 if ( !nested )
520 return 0;
521 QValueStack<int>::ConstIterator xit = xOffsets.begin();
522 int xoff = ox; 452 int xoff = ox;
523 for ( ; xit != xOffsets.end(); ++xit ) 453 for ( QValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit )
524 xoff += *xit; 454 xoff += *xit;
@@ -529,7 +459,4 @@ int QTextCursor::totalOffsetY() const
529{ 459{
530 if ( !nested )
531 return 0;
532 QValueStack<int>::ConstIterator yit = yOffsets.begin();
533 int yoff = oy; 460 int yoff = oy;
534 for ( ; yit != yOffsets.end(); ++yit ) 461 for ( QValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit )
535 yoff += *yit; 462 yoff += *yit;
@@ -540,3 +467,3 @@ void QTextCursor::gotoIntoNested( const QPoint &globalPos )
540{ 467{
541 if ( !doc ) 468 if ( !para )
542 return; 469 return;
@@ -545,9 +472,10 @@ void QTextCursor::gotoIntoNested( const QPoint &globalPos )
545 int bl, y; 472 int bl, y;
546 string->lineHeightOfChar( idx, &bl, &y ); 473 para->lineHeightOfChar( idx, &bl, &y );
547 oy = y + string->rect().y(); 474 oy = y + para->rect().y();
548 nested = TRUE;
549 QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() ); 475 QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() );
550 Q_ASSERT( string->at( idx )->isCustom() ); 476 Q_ASSERT( para->at( idx )->isCustom() );
551 ox = string->at( idx )->x; 477 ox = para->at( idx )->x;
552 string->at( idx )->customItem()->enterAt( this, doc, string, idx, ox, oy, p ); 478
479 QTextDocument* doc = document();
480 para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, p );
553} 481}
@@ -556,12 +484,10 @@ void QTextCursor::invalidateNested()
556{ 484{
557 if ( nested ) { 485 QValueStack<QTextParagraph*>::Iterator it = paras.begin();
558 QValueStack<QTextParag*>::Iterator it = parags.begin(); 486 QValueStack<int>::Iterator it2 = indices.begin();
559 QValueStack<int>::Iterator it2 = indices.begin(); 487 for ( ; it != paras.end(); ++it, ++it2 ) {
560 for ( ; it != parags.end(); ++it, ++it2 ) { 488 if ( *it == para )
561 if ( *it == string ) 489 continue;
562 continue; 490 (*it)->invalidate( 0 );
563 (*it)->invalidate( 0 ); 491 if ( (*it)->at( *it2 )->isCustom() )
564 if ( (*it)->at( *it2 )->isCustom() ) 492 (*it)->at( *it2 )->customItem()->invalidate();
565 (*it)->at( *it2 )->customItem()->invalidate();
566 }
567 } 493 }
@@ -575,4 +501,7 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
575#if defined(Q_WS_WIN) 501#if defined(Q_WS_WIN)
576 if ( checkNewLine ) 502 if ( checkNewLine ) {
577 s = s.replace( QRegExp( "\\r" ), "" ); 503 int i = 0;
504 while ( ( i = s.find( '\r', i ) ) != -1 )
505 s.remove( i ,1 );
506 }
578#endif 507#endif
@@ -580,4 +509,4 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
580 justInsert = s.find( '\n' ) == -1; 509 justInsert = s.find( '\n' ) == -1;
581 if ( justInsert ) { 510 if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index
582 string->insert( idx, s ); 511 para->insert( idx, s.unicode(), s.length() );
583 if ( formatting ) { 512 if ( formatting ) {
@@ -586,3 +515,3 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
586 formatting->at( i ).format()->addRef(); 515 formatting->at( i ).format()->addRef();
587 string->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE ); 516 para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE );
588 } 517 }
@@ -591,27 +520,17 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
591 idx += s.length(); 520 idx += s.length();
592 } else { 521 } else { // we split at new lines
593 QStringList lst = QStringList::split( '\n', s, TRUE ); 522 int start = -1;
594 QStringList::Iterator it = lst.begin(); 523 int end;
595 int y = string->rect().y() + string->rect().height(); 524 int y = para->rect().y() + para->rect().height();
596 int lastIndex = 0; 525 int lastIndex = 0;
597 QTextFormat *lastFormat = 0; 526 do {
598 for ( ; it != lst.end(); ) { 527 end = s.find( '\n', start + 1 ); // find line break
599 if ( it != lst.begin() ) { 528 if ( end == -1 ) // didn't find one, so end of line is end of string
600 splitAndInsertEmptyParag( FALSE, TRUE ); 529 end = s.length();
601 string->setEndState( -1 ); 530 int len = (start == -1 ? end : end - start - 1);
602 string->prev()->format( -1, FALSE ); 531 if ( len > 0 ) // insert the line
603 if ( lastFormat && formatting && string->prev() ) { 532 para->insert( idx, s.unicode() + start + 1, len );
604 lastFormat->addRef();
605 string->prev()->string()->setFormat( string->prev()->length() - 1, lastFormat, TRUE );
606 }
607 }
608 lastFormat = 0;
609 QString s = *it;
610 ++it;
611 if ( !s.isEmpty() )
612 string->insert( idx, s );
613 else 533 else
614 string->invalidate( 0 ); 534 para->invalidate( 0 );
615 if ( formatting ) { 535 if ( formatting ) { // set formats to the chars of the line
616 int len = s.length();
617 for ( int i = 0; i < len; ++i ) { 536 for ( int i = 0; i < len; ++i ) {
@@ -619,17 +538,22 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
619 formatting->at( i + lastIndex ).format()->addRef(); 538 formatting->at( i + lastIndex ).format()->addRef();
620 string->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE ); 539 para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE );
621 } 540 }
622 } 541 }
623 if ( it != lst.end() )
624 lastFormat = formatting->at( len + lastIndex ).format();
625 ++len;
626 lastIndex += len; 542 lastIndex += len;
627 } 543 }
544 start = end; // next start is at the end of this line
545 idx += len; // increase the index of the cursor to the end of the inserted text
546 if ( s[end] == '\n' ) { // if at the end was a line break, break the line
547 splitAndInsertEmptyParagraph( FALSE, TRUE );
548 para->setEndState( -1 );
549 para->prev()->format( -1, FALSE );
550 lastIndex++;
551 }
628 552
629 idx += s.length(); 553 } while ( end < (int)s.length() );
630 } 554
631 string->format( -1, FALSE ); 555 para->format( -1, FALSE );
632 int dy = string->rect().y() + string->rect().height() - y; 556 int dy = para->rect().y() + para->rect().height() - y;
633 QTextParag *p = string; 557 QTextParagraph *p = para;
634 p->setParagId( p->prev()->paragId() + 1 ); 558 p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 );
635 p = p->next(); 559 p = p->next();
@@ -644,8 +568,8 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
644 568
645 int h = string->rect().height(); 569 int h = para->rect().height();
646 string->format( -1, TRUE ); 570 para->format( -1, TRUE );
647 if ( h != string->rect().height() ) 571 if ( h != para->rect().height() )
648 invalidateNested(); 572 invalidateNested();
649 else if ( doc && doc->parent() ) 573 else if ( para->document() && para->document()->parent() )
650 doc->nextDoubleBuffered = TRUE; 574 para->document()->nextDoubleBuffered = TRUE;
651} 575}
@@ -654,3 +578,3 @@ void QTextCursor::gotoLeft()
654{ 578{
655 if ( string->string()->isRightToLeft() ) 579 if ( para->string()->isRightToLeft() )
656 gotoNextLetter(); 580 gotoNextLetter();
@@ -666,22 +590,20 @@ void QTextCursor::gotoPreviousLetter()
666 idx--; 590 idx--;
667 } else if ( string->prev() ) { 591 const QTextStringChar *tsc = para->at( idx );
668 QTextParag *s = string->prev(); 592 if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() )
669 while ( s && !s->isVisible() ) 593 processNesting( EnterEnd );
670 s = s->prev(); 594 } else if ( para->prev() ) {
671 if ( s ) { 595 para = para->prev();
672 string = s; 596 while ( !para->isVisible() && para->prev() )
673 idx = string->length() - 1; 597 para = para->prev();
674 } 598 idx = para->length() - 1;
675 } else { 599 } else if ( nestedDepth() ) {
676 if ( nested ) { 600 pop();
601 processNesting( Prev );
602 if ( idx == -1 ) {
677 pop(); 603 pop();
678 processNesting( Prev ); 604 if ( idx > 0 ) {
679 if ( idx == -1 ) { 605 idx--;
680 pop(); 606 } else if ( para->prev() ) {
681 if ( idx > 0 ) { 607 para = para->prev();
682 idx--; 608 idx = para->length() - 1;
683 } else if ( string->prev() ) {
684 string = string->prev();
685 idx = string->length() - 1;
686 }
687 } 609 }
@@ -689,7 +611,2 @@ void QTextCursor::gotoPreviousLetter()
689 } 611 }
690
691 const QTextStringChar *tsc = string->at( idx );
692 if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) {
693 processNesting( EnterEnd );
694 }
695} 612}
@@ -699,6 +616,5 @@ void QTextCursor::push()
699 indices.push( idx ); 616 indices.push( idx );
700 parags.push( string ); 617 paras.push( para );
701 xOffsets.push( ox ); 618 xOffsets.push( ox );
702 yOffsets.push( oy ); 619 yOffsets.push( oy );
703 nestedStack.push( nested );
704} 620}
@@ -707,11 +623,8 @@ void QTextCursor::pop()
707{ 623{
708 if ( !doc ) 624 if ( indices.isEmpty() )
709 return; 625 return;
710 idx = indices.pop(); 626 idx = indices.pop();
711 string = parags.pop(); 627 para = paras.pop();
712 ox = xOffsets.pop(); 628 ox = xOffsets.pop();
713 oy = yOffsets.pop(); 629 oy = yOffsets.pop();
714 if ( doc->parent() )
715 doc = doc->parent();
716 nested = nestedStack.pop();
717} 630}
@@ -724,3 +637,3 @@ void QTextCursor::restoreState()
724 637
725bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link ) 638bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link )
726{ 639{
@@ -728,3 +641,3 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
728 QRect r; 641 QRect r;
729 QTextParag *str = s; 642 QTextParagraph *str = s;
730 if ( pos.y() < s->rect().y() ) 643 if ( pos.y() < s->rect().y() )
@@ -733,3 +646,3 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
733 r = s->rect(); 646 r = s->rect();
734 r.setWidth( doc ? doc->width() : QWIDGETSIZE_MAX ); 647 r.setWidth( document() ? document()->width() : QWIDGETSIZE_MAX );
735 if ( s->isVisible() ) 648 if ( s->isVisible() )
@@ -746,3 +659,3 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
746 659
747 setParag( s, FALSE ); 660 setParagraph( s );
748 int y = s->rect().y(); 661 int y = s->rect().y();
@@ -760,3 +673,3 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
760 return FALSE; 673 return FALSE;
761 if ( pos.y() >= y + cy && pos.y() <= y + cy + ch ) 674 if ( pos.y() <= y + cy + ch )
762 break; 675 break;
@@ -800,11 +713,11 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
800 } 713 }
801 setIndex( curpos, FALSE ); 714 setIndex( curpos );
802 715
803 if ( inCustom && doc && parag()->at( curpos )->isCustom() && parag()->at( curpos )->customItem()->isNested() ) { 716 if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) {
804 QTextDocument *oldDoc = doc; 717 QTextDocument *oldDoc = para->document();
805 gotoIntoNested( pos ); 718 gotoIntoNested( pos );
806 if ( oldDoc == doc ) 719 if ( oldDoc == para->document() )
807 return TRUE; 720 return TRUE;
808 QPoint p( pos.x() - offsetX(), pos.y() - offsetY() ); 721 QPoint p( pos.x() - offsetX(), pos.y() - offsetY() );
809 if ( !place( p, document()->firstParag(), link ) ) 722 if ( !place( p, document()->firstParagraph(), link ) )
810 pop(); 723 pop();
@@ -816,10 +729,10 @@ void QTextCursor::processNesting( Operation op )
816{ 729{
817 if ( !doc ) 730 if ( !para->document() )
818 return; 731 return;
732 QTextDocument* doc = para->document();
819 push(); 733 push();
820 ox = string->at( idx )->x; 734 ox = para->at( idx )->x;
821 int bl, y; 735 int bl, y;
822 string->lineHeightOfChar( idx, &bl, &y ); 736 para->lineHeightOfChar( idx, &bl, &y );
823 oy = y + string->rect().y(); 737 oy = y + para->rect().y();
824 nested = TRUE;
825 bool ok = FALSE; 738 bool ok = FALSE;
@@ -828,18 +741,18 @@ void QTextCursor::processNesting( Operation op )
828 case EnterBegin: 741 case EnterBegin:
829 ok = string->at( idx )->customItem()->enter( this, doc, string, idx, ox, oy ); 742 ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy );
830 break; 743 break;
831 case EnterEnd: 744 case EnterEnd:
832 ok = string->at( idx )->customItem()->enter( this, doc, string, idx, ox, oy, TRUE ); 745 ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE );
833 break; 746 break;
834 case Next: 747 case Next:
835 ok = string->at( idx )->customItem()->next( this, doc, string, idx, ox, oy ); 748 ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy );
836 break; 749 break;
837 case Prev: 750 case Prev:
838 ok = string->at( idx )->customItem()->prev( this, doc, string, idx, ox, oy ); 751 ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy );
839 break; 752 break;
840 case Down: 753 case Down:
841 ok = string->at( idx )->customItem()->down( this, doc, string, idx, ox, oy ); 754 ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy );
842 break; 755 break;
843 case Up: 756 case Up:
844 ok = string->at( idx )->customItem()->up( this, doc, string, idx, ox, oy ); 757 ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy );
845 break; 758 break;
@@ -852,3 +765,3 @@ void QTextCursor::gotoRight()
852{ 765{
853 if ( string->string()->isRightToLeft() ) 766 if ( para->string()->isRightToLeft() )
854 gotoPreviousLetter(); 767 gotoPreviousLetter();
@@ -862,3 +775,3 @@ void QTextCursor::gotoNextLetter()
862 775
863 const QTextStringChar *tsc = string->at( idx ); 776 const QTextStringChar *tsc = para->at( idx );
864 if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) { 777 if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) {
@@ -868,24 +781,19 @@ void QTextCursor::gotoNextLetter()
868 781
869 if ( idx < string->length() - 1 ) { 782 if ( idx < para->length() - 1 ) {
870 idx++; 783 idx++;
871 } else if ( string->next() ) { 784 } else if ( para->next() ) {
872 QTextParag *s = string->next(); 785 para = para->next();
873 while ( s && !s->isVisible() ) 786 while ( !para->isVisible() && para->next() )
874 s = s->next(); 787 para = para->next();
875 if ( s ) { 788 idx = 0;
876 string = s; 789 } else if ( nestedDepth() ) {
877 idx = 0; 790 pop();
878 } 791 processNesting( Next );
879 } else { 792 if ( idx == -1 ) {
880 if ( nested ) {
881 pop(); 793 pop();
882 processNesting( Next ); 794 if ( idx < para->length() - 1 ) {
883 if ( idx == -1 ) { 795 idx++;
884 pop(); 796 } else if ( para->next() ) {
885 if ( idx < string->length() - 1 ) { 797 para = para->next();
886 idx++; 798 idx = 0;
887 } else if ( string->next() ) {
888 string = string->next();
889 idx = 0;
890 }
891 } 799 }
@@ -899,3 +807,3 @@ void QTextCursor::gotoUp()
899 int line; 807 int line;
900 QTextStringChar *c = string->lineStartOfChar( idx, &indexOfLineStart, &line ); 808 QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
901 if ( !c ) 809 if ( !c )
@@ -905,4 +813,4 @@ void QTextCursor::gotoUp()
905 if ( indexOfLineStart == 0 ) { 813 if ( indexOfLineStart == 0 ) {
906 if ( !string->prev() ) { 814 if ( !para->prev() ) {
907 if ( !nested ) 815 if ( !nestedDepth() )
908 return; 816 return;
@@ -912,3 +820,3 @@ void QTextCursor::gotoUp()
912 pop(); 820 pop();
913 if ( !string->prev() ) 821 if ( !para->prev() )
914 return; 822 return;
@@ -920,14 +828,14 @@ void QTextCursor::gotoUp()
920 } 828 }
921 QTextParag *s = string->prev(); 829 QTextParagraph *p = para->prev();
922 while ( s && !s->isVisible() ) 830 while ( p && !p->isVisible() )
923 s = s->prev(); 831 p = p->prev();
924 if ( s ) 832 if ( p )
925 string = s; 833 para = p;
926 int lastLine = string->lines() - 1; 834 int lastLine = para->lines() - 1;
927 if ( !string->lineStartOfLine( lastLine, &indexOfLineStart ) ) 835 if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) )
928 return; 836 return;
929 if ( indexOfLineStart + tmpIndex < string->length() ) 837 if ( indexOfLineStart + tmpIndex < para->length() )
930 idx = indexOfLineStart + tmpIndex; 838 idx = indexOfLineStart + tmpIndex;
931 else 839 else
932 idx = string->length() - 1; 840 idx = para->length() - 1;
933 } else { 841 } else {
@@ -935,3 +843,3 @@ void QTextCursor::gotoUp()
935 int oldIndexOfLineStart = indexOfLineStart; 843 int oldIndexOfLineStart = indexOfLineStart;
936 if ( !string->lineStartOfLine( line, &indexOfLineStart ) ) 844 if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
937 return; 845 return;
@@ -948,3 +856,3 @@ void QTextCursor::gotoDown()
948 int line; 856 int line;
949 QTextStringChar *c = string->lineStartOfChar( idx, &indexOfLineStart, &line ); 857 QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
950 if ( !c ) 858 if ( !c )
@@ -953,5 +861,5 @@ void QTextCursor::gotoDown()
953 tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); 861 tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart );
954 if ( line == string->lines() - 1 ) { 862 if ( line == para->lines() - 1 ) {
955 if ( !string->next() ) { 863 if ( !para->next() ) {
956 if ( !nested ) 864 if ( !nestedDepth() )
957 return; 865 return;
@@ -961,3 +869,3 @@ void QTextCursor::gotoDown()
961 pop(); 869 pop();
962 if ( !string->next() ) 870 if ( !para->next() )
963 return; 871 return;
@@ -969,3 +877,3 @@ void QTextCursor::gotoDown()
969 } 877 }
970 QTextParag *s = string->next(); 878 QTextParagraph *s = para->next();
971 while ( s && !s->isVisible() ) 879 while ( s && !s->isVisible() )
@@ -973,10 +881,10 @@ void QTextCursor::gotoDown()
973 if ( s ) 881 if ( s )
974 string = s; 882 para = s;
975 if ( !string->lineStartOfLine( 0, &indexOfLineStart ) ) 883 if ( !para->lineStartOfLine( 0, &indexOfLineStart ) )
976 return; 884 return;
977 int end; 885 int end;
978 if ( string->lines() == 1 ) 886 if ( para->lines() == 1 )
979 end = string->length(); 887 end = para->length();
980 else 888 else
981 string->lineStartOfLine( 1, &end ); 889 para->lineStartOfLine( 1, &end );
982 if ( indexOfLineStart + tmpIndex < end ) 890 if ( indexOfLineStart + tmpIndex < end )
@@ -988,7 +896,7 @@ void QTextCursor::gotoDown()
988 int end; 896 int end;
989 if ( line == string->lines() - 1 ) 897 if ( line == para->lines() - 1 )
990 end = string->length(); 898 end = para->length();
991 else 899 else
992 string->lineStartOfLine( line + 1, &end ); 900 para->lineStartOfLine( line + 1, &end );
993 if ( !string->lineStartOfLine( line, &indexOfLineStart ) ) 901 if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
994 return; 902 return;
@@ -1006,3 +914,3 @@ void QTextCursor::gotoLineEnd()
1006 int line; 914 int line;
1007 QTextStringChar *c = string->lineStartOfChar( idx, &indexOfLineStart, &line ); 915 QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
1008 if ( !c ) 916 if ( !c )
@@ -1010,6 +918,6 @@ void QTextCursor::gotoLineEnd()
1010 918
1011 if ( line == string->lines() - 1 ) { 919 if ( line == para->lines() - 1 ) {
1012 idx = string->length() - 1; 920 idx = para->length() - 1;
1013 } else { 921 } else {
1014 c = string->lineStartOfLine( ++line, &indexOfLineStart ); 922 c = para->lineStartOfLine( ++line, &indexOfLineStart );
1015 indexOfLineStart--; 923 indexOfLineStart--;
@@ -1024,3 +932,3 @@ void QTextCursor::gotoLineStart()
1024 int line; 932 int line;
1025 QTextStringChar *c = string->lineStartOfChar( idx, &indexOfLineStart, &line ); 933 QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
1026 if ( !c ) 934 if ( !c )
@@ -1033,6 +941,6 @@ void QTextCursor::gotoHome()
1033{ 941{
1034 tmpIndex = -1; 942 if ( topParagraph()->document() )
1035 if ( doc ) 943 gotoPosition( topParagraph()->document()->firstParagraph() );
1036 string = doc->firstParag(); 944 else
1037 idx = 0; 945 gotoLineStart();
1038} 946}
@@ -1041,9 +949,7 @@ void QTextCursor::gotoEnd()
1041{ 949{
1042 if ( doc && !doc->lastParag()->isValid() ) 950 if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() )
1043 return; 951 gotoPosition( topParagraph()->document()->lastParagraph(),
1044 952 topParagraph()->document()->lastParagraph()->length() - 1);
1045 tmpIndex = -1; 953 else
1046 if ( doc ) 954 gotoLineEnd();
1047 string = doc->lastParag();
1048 idx = string->length() - 1;
1049} 955}
@@ -1052,17 +958,8 @@ void QTextCursor::gotoPageUp( int visibleHeight )
1052{ 958{
1053 tmpIndex = -1; 959 int targetY = globalY() - visibleHeight;
1054 QTextParag *s = string; 960 QTextParagraph* old; int index;
1055 int h = visibleHeight; 961 do {
1056 int y = s->rect().y(); 962 old = para; index = idx;
1057 while ( s ) { 963 gotoUp();
1058 if ( y - s->rect().y() >= h ) 964 } while ( (old != para || index != idx) && globalY() > targetY );
1059 break;
1060 s = s->prev();
1061 }
1062
1063 if ( !s && doc )
1064 s = doc->firstParag();
1065
1066 string = s;
1067 idx = 0;
1068} 965}
@@ -1071,24 +968,8 @@ void QTextCursor::gotoPageDown( int visibleHeight )
1071{ 968{
1072 tmpIndex = -1; 969 int targetY = globalY() + visibleHeight;
1073 QTextParag *s = string; 970 QTextParagraph* old; int index;
1074 int h = visibleHeight; 971 do {
1075 int y = s->rect().y(); 972 old = para; index = idx;
1076 while ( s ) { 973 gotoDown();
1077 if ( s->rect().y() - y >= h ) 974 } while ( (old != para || index != idx) && globalY() < targetY );
1078 break;
1079 s = s->next();
1080 }
1081
1082 if ( !s && doc ) {
1083 s = doc->lastParag();
1084 string = s;
1085 idx = string->length() - 1;
1086 return;
1087 }
1088
1089 if ( !s->isValid() )
1090 return;
1091
1092 string = s;
1093 idx = 0;
1094} 975}
@@ -1097,3 +978,3 @@ void QTextCursor::gotoWordRight()
1097{ 978{
1098 if ( string->string()->isRightToLeft() ) 979 if ( para->string()->isRightToLeft() )
1099 gotoPreviousWord(); 980 gotoPreviousWord();
@@ -1105,3 +986,3 @@ void QTextCursor::gotoWordLeft()
1105{ 986{
1106 if ( string->string()->isRightToLeft() ) 987 if ( para->string()->isRightToLeft() )
1107 gotoNextWord(); 988 gotoNextWord();
@@ -1115,3 +996,3 @@ void QTextCursor::gotoPreviousWord()
1115 tmpIndex = -1; 996 tmpIndex = -1;
1116 QTextString *s = string->string(); 997 QTextString *s = para->string();
1117 bool allowSame = FALSE; 998 bool allowSame = FALSE;
@@ -1137,3 +1018,3 @@ void QTextCursor::gotoNextWord()
1137 tmpIndex = -1; 1018 tmpIndex = -1;
1138 QTextString *s = string->string(); 1019 QTextString *s = para->string();
1139 bool allowSame = FALSE; 1020 bool allowSame = FALSE;
@@ -1155,8 +1036,8 @@ void QTextCursor::gotoNextWord()
1155 gotoLineEnd(); 1036 gotoLineEnd();
1156 } else if ( string->next() ) { 1037 } else if ( para->next() ) {
1157 QTextParag *s = string->next(); 1038 QTextParagraph *p = para->next();
1158 while ( s && !s->isVisible() ) 1039 while ( p && !p->isVisible() )
1159 s = s->next(); 1040 p = p->next();
1160 if ( s ) { 1041 if ( s ) {
1161 string = s; 1042 para = p;
1162 idx = 0; 1043 idx = 0;
@@ -1175,8 +1056,8 @@ bool QTextCursor::atParagEnd()
1175{ 1056{
1176 return idx == string->length() - 1; 1057 return idx == para->length() - 1;
1177} 1058}
1178 1059
1179void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds ) 1060void QTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds )
1180{ 1061{
1181 if ( !doc ) 1062 if ( !para->document() )
1182 return; 1063 return;
@@ -1184,9 +1065,9 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1184 QTextFormat *f = 0; 1065 QTextFormat *f = 0;
1185 if ( doc->useFormatCollection() ) { 1066 if ( para->document()->useFormatCollection() ) {
1186 f = string->at( idx )->format(); 1067 f = para->at( idx )->format();
1187 if ( idx == string->length() - 1 && idx > 0 ) 1068 if ( idx == para->length() - 1 && idx > 0 )
1188 f = string->at( idx - 1 )->format(); 1069 f = para->at( idx - 1 )->format();
1189 if ( f->isMisspelled() ) { 1070 if ( f->isMisspelled() ) {
1190 f->removeRef(); 1071 f->removeRef();
1191 f = doc->formatCollection()->format( f->font(), f->color() ); 1072 f = para->document()->formatCollection()->format( f->font(), f->color() );
1192 } 1073 }
@@ -1195,7 +1076,7 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1195 if ( atParagEnd() ) { 1076 if ( atParagEnd() ) {
1196 QTextParag *n = string->next(); 1077 QTextParagraph *n = para->next();
1197 QTextParag *s = doc->createParag( doc, string, n, updateIds ); 1078 QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
1198 if ( f ) 1079 if ( f )
1199 s->setFormat( 0, 1, f, TRUE ); 1080 s->setFormat( 0, 1, f, TRUE );
1200 s->copyParagData( string ); 1081 s->copyParagData( para );
1201 if ( ind ) { 1082 if ( ind ) {
@@ -1203,6 +1084,6 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1203 s->indent( &oi, &ni ); 1084 s->indent( &oi, &ni );
1204 string = s; 1085 para = s;
1205 idx = ni; 1086 idx = ni;
1206 } else { 1087 } else {
1207 string = s; 1088 para = s;
1208 idx = 0; 1089 idx = 0;
@@ -1210,7 +1091,7 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1210 } else if ( atParagStart() ) { 1091 } else if ( atParagStart() ) {
1211 QTextParag *p = string->prev(); 1092 QTextParagraph *p = para->prev();
1212 QTextParag *s = doc->createParag( doc, p, string, updateIds ); 1093 QTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds );
1213 if ( f ) 1094 if ( f )
1214 s->setFormat( 0, 1, f, TRUE ); 1095 s->setFormat( 0, 1, f, TRUE );
1215 s->copyParagData( string ); 1096 s->copyParagData( para );
1216 if ( ind ) { 1097 if ( ind ) {
@@ -1219,9 +1100,9 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1219 indent(); 1100 indent();
1220 string->format(); 1101 para->format();
1221 } 1102 }
1222 } else { 1103 } else {
1223 QString str = string->string()->toString().mid( idx, 0xFFFFFF ); 1104 QString str = para->string()->toString().mid( idx, 0xFFFFFF );
1224 QTextParag *n = string->next(); 1105 QTextParagraph *n = para->next();
1225 QTextParag *s = doc->createParag( doc, string, n, updateIds ); 1106 QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
1226 s->copyParagData( string ); 1107 s->copyParagData( para );
1227 s->remove( 0, 1 ); 1108 s->remove( 0, 1 );
@@ -1229,10 +1110,14 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1229 for ( uint i = 0; i < str.length(); ++i ) { 1110 for ( uint i = 0; i < str.length(); ++i ) {
1230 s->setFormat( i, 1, string->at( idx + i )->format(), TRUE ); 1111 QTextStringChar* tsc = para->at( idx + i );
1231 if ( string->at( idx + i )->isCustom() ) { 1112 s->setFormat( i, 1, tsc->format(), TRUE );
1232 QTextCustomItem * item = string->at( idx + i )->customItem(); 1113 if ( tsc->isCustom() ) {
1114 QTextCustomItem * item = tsc->customItem();
1233 s->at( i )->setCustomItem( item ); 1115 s->at( i )->setCustomItem( item );
1234 string->at( idx + i )->loseCustomItem(); 1116 tsc->loseCustomItem();
1235 } 1117 }
1118 if ( tsc->isAnchor() )
1119 s->at( i )->setAnchor( tsc->anchorName(),
1120 tsc->anchorHref() );
1236 } 1121 }
1237 string->truncate( idx ); 1122 para->truncate( idx );
1238 if ( ind ) { 1123 if ( ind ) {
@@ -1240,6 +1125,6 @@ void QTextCursor::splitAndInsertEmptyParag( bool ind, bool updateIds )
1240 s->indent( &oi, &ni ); 1125 s->indent( &oi, &ni );
1241 string = s; 1126 para = s;
1242 idx = ni; 1127 idx = ni;
1243 } else { 1128 } else {
1244 string = s; 1129 para = s;
1245 idx = 0; 1130 idx = 0;
@@ -1255,31 +1140,12 @@ bool QTextCursor::remove()
1255 if ( !atParagEnd() ) { 1140 if ( !atParagEnd() ) {
1256 string->remove( idx, 1 ); 1141 para->remove( idx, 1 );
1257 int h = string->rect().height(); 1142 int h = para->rect().height();
1258 string->format( -1, TRUE ); 1143 para->format( -1, TRUE );
1259 if ( h != string->rect().height() ) 1144 if ( h != para->rect().height() )
1260 invalidateNested(); 1145 invalidateNested();
1261 else if ( doc && doc->parent() ) 1146 else if ( para->document() && para->document()->parent() )
1262 doc->nextDoubleBuffered = TRUE; 1147 para->document()->nextDoubleBuffered = TRUE;
1263 return FALSE; 1148 return FALSE;
1264 } else if ( string->next() ) { 1149 } else if ( para->next() ) {
1265 if ( string->length() == 1 ) { 1150 para->join( para->next() );
1266 string->next()->setPrev( string->prev() );
1267 if ( string->prev() )
1268 string->prev()->setNext( string->next() );
1269 QTextParag *p = string->next();
1270 delete string;
1271 string = p;
1272 string->invalidate( 0 );
1273 QTextParag *s = string;
1274 while ( s ) {
1275 s->id = s->p ? s->p->id + 1 : 0;
1276 s->state = -1;
1277 s->needPreProcess = TRUE;
1278 s->changed = TRUE;
1279 s = s->n;
1280 }
1281 string->format();
1282 } else {
1283 string->join( string->next() );
1284 }
1285 invalidateNested(); 1151 invalidateNested();
@@ -1290,15 +1156,2 @@ bool QTextCursor::remove()
1290 1156
1291void QTextCursor::killLine()
1292{
1293 if ( atParagEnd() )
1294 return;
1295 string->remove( idx, string->length() - idx - 1 );
1296 int h = string->rect().height();
1297 string->format( -1, TRUE );
1298 if ( h != string->rect().height() )
1299 invalidateNested();
1300 else if ( doc && doc->parent() )
1301 doc->nextDoubleBuffered = TRUE;
1302}
1303
1304void QTextCursor::indent() 1157void QTextCursor::indent()
@@ -1306,3 +1159,3 @@ void QTextCursor::indent()
1306 int oi = 0, ni = 0; 1159 int oi = 0, ni = 0;
1307 string->indent( &oi, &ni ); 1160 para->indent( &oi, &ni );
1308 if ( oi == ni ) 1161 if ( oi == ni )
@@ -1316,12 +1169,2 @@ void QTextCursor::indent()
1316 1169
1317void QTextCursor::setDocument( QTextDocument *d )
1318{
1319 doc = d;
1320 string = d->firstParag();
1321 idx = 0;
1322 nested = FALSE;
1323 restoreState();
1324 tmpIndex = -1;
1325}
1326
1327// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1170// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1329,3 +1172,3 @@ void QTextCursor::setDocument( QTextDocument *d )
1329QTextDocument::QTextDocument( QTextDocument *p ) 1172QTextDocument::QTextDocument( QTextDocument *p )
1330 : par( p ), parParag( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) 1173 : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 )
1331{ 1174{
@@ -1336,3 +1179,3 @@ QTextDocument::QTextDocument( QTextDocument *p )
1336QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f ) 1179QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f )
1337 : par( p ), parParag( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) 1180 : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 )
1338{ 1181{
@@ -1344,5 +1187,2 @@ void QTextDocument::init()
1344{ 1187{
1345#if defined(PARSER_DEBUG)
1346 qDebug( debug_indent + "new QTextDocument (%p)", this );
1347#endif
1348 oTextValid = TRUE; 1188 oTextValid = TRUE;
@@ -1365,8 +1205,6 @@ void QTextDocument::init()
1365 nSelections = 1; 1205 nSelections = 1;
1366 addMargs = FALSE;
1367 1206
1368 sheet_ = QStyleSheet::defaultSheet(); 1207 setStyleSheet( QStyleSheet::defaultSheet() );
1369 factory_ = QMimeSourceFactory::defaultFactory(); 1208 factory_ = QMimeSourceFactory::defaultFactory();
1370 contxt = QString::null; 1209 contxt = QString::null;
1371 fCollection->setStyleSheet( sheet_ );
1372 1210
@@ -1382,4 +1220,3 @@ void QTextDocument::init()
1382 1220
1383 lParag = fParag = createParag( this, 0, 0 ); 1221 lParag = fParag = createParagraph( this, 0, 0 );
1384 tmpCursor = 0;
1385 1222
@@ -1395,2 +1232,4 @@ void QTextDocument::init()
1395 leftmargin = rightmargin = 4; 1232 leftmargin = rightmargin = 4;
1233 scaleFontsFactor = 1;
1234
1396 1235
@@ -1425,3 +1264,3 @@ void QTextDocument::clear( bool createEmptyParag )
1425 while ( fParag ) { 1264 while ( fParag ) {
1426 QTextParag *p = fParag->next(); 1265 QTextParagraph *p = fParag->next();
1427 delete fParag; 1266 delete fParag;
@@ -1431,4 +1270,6 @@ void QTextDocument::clear( bool createEmptyParag )
1431 if ( createEmptyParag ) 1270 if ( createEmptyParag )
1432 fParag = lParag = createParag( this ); 1271 fParag = lParag = createParagraph( this );
1433 selections.clear(); 1272 selections.clear();
1273 oText = QString::null;
1274 oTextValid = TRUE;
1434} 1275}
@@ -1451,8 +1292,8 @@ int QTextDocument::height() const
1451 1292
1452QTextParag *QTextDocument::createParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool updateIds ) 1293QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds )
1453{ 1294{
1454 return new QTextParag( d, pr, nx, updateIds ); 1295 return new QTextParagraph( d, pr, nx, updateIds );
1455} 1296}
1456 1297
1457bool QTextDocument::setMinimumWidth( int needed, int used, QTextParag *p ) 1298bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p )
1458{ 1299{
@@ -1487,3 +1328,3 @@ void QTextDocument::setPlainText( const QString &text )
1487 if ( nl == -1 ) { 1328 if ( nl == -1 ) {
1488 lParag = createParag( this, lParag, 0 ); 1329 lParag = createParagraph( this, lParag, 0 );
1489 if ( !fParag ) 1330 if ( !fParag )
@@ -1498,3 +1339,3 @@ void QTextDocument::setPlainText( const QString &text )
1498 for (;;) { 1339 for (;;) {
1499 lParag = createParag( this, lParag, 0 ); 1340 lParag = createParagraph( this, lParag, 0 );
1500 if ( !fParag ) 1341 if ( !fParag )
@@ -1516,3 +1357,3 @@ void QTextDocument::setPlainText( const QString &text )
1516 if ( !lParag ) 1357 if ( !lParag )
1517 lParag = fParag = createParag( this, 0, 0 ); 1358 lParag = fParag = createParagraph( this, 0, 0 );
1518} 1359}
@@ -1561,14 +1402,20 @@ struct Q_EXPORT QTextDocumentTag {
1561 1402
1562#define NEWPAR do{ if ( !hasNewPar ) curpar = createParag( this, curpar ); \ 1403
1563 if ( curpar->isBr ) curpar->isBr = FALSE; \ 1404#define NEWPAR do{ if ( !hasNewPar) { \
1405 if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \
1406 curpar->remove( curpar->length()-2, 1 ); \
1407 curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \
1564 hasNewPar = TRUE; \ 1408 hasNewPar = TRUE; \
1565 curpar->setAlignment( curtag.alignment ); \ 1409 curpar->rtext = TRUE; \
1566 curpar->setDirection( (QChar::Direction)curtag.direction ); \ 1410 curpar->align = curtag.alignment; \
1411 curpar->lstyle = curtag.liststyle; \
1412 curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \
1413 curpar->str->setDirection( (QChar::Direction)curtag.direction ); \
1567 space = TRUE; \ 1414 space = TRUE; \
1568 QPtrVector<QStyleSheetItem> vec( (uint)tags.count() + 1); \ 1415 delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
1569 int i = 0; \ 1416 int i = 0; \
1570 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ 1417 for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
1571 vec.insert( i++, (*it).style ); \ 1418 vec->insert( i++, (*it).style ); \
1572 vec.insert( i, curtag.style ); \ 1419 vec->insert( i, curtag.style ); \
1573 curpar->setStyleSheetItems( vec ); }while(FALSE) 1420 }while(FALSE)
1574 1421
@@ -1577,3 +1424,2 @@ void QTextDocument::setRichText( const QString &text, const QString &context )
1577{ 1424{
1578 setTextFormat( Qt::RichText );
1579 if ( !context.isEmpty() ) 1425 if ( !context.isEmpty() )
@@ -1581,40 +1427,12 @@ void QTextDocument::setRichText( const QString &text, const QString &context )
1581 clear(); 1427 clear();
1582 fParag = lParag = createParag( this ); 1428 fParag = lParag = createParagraph( this );
1429 oTextValid = TRUE;
1430 oText = text;
1583 setRichTextInternal( text ); 1431 setRichTextInternal( text );
1432 fParag->rtext = TRUE;
1584} 1433}
1585 1434
1586static QStyleSheetItem::ListStyle chooseListStyle( const QStyleSheetItem *nstyle, 1435void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor )
1587 const QMap<QString, QString> &attr,
1588 QStyleSheetItem::ListStyle curListStyle )
1589{
1590 if ( nstyle->name() == "ol" || nstyle->name() == "ul" ) {
1591 curListStyle = nstyle->listStyle();
1592 QMap<QString, QString>::ConstIterator it = attr.find( "type" );
1593 if ( it != attr.end() ) {
1594 QString sl = *it;
1595 if ( sl == "1" ) {
1596 curListStyle = QStyleSheetItem::ListDecimal;
1597 } else if ( sl == "a" ) {
1598 curListStyle = QStyleSheetItem::ListLowerAlpha;
1599 } else if ( sl == "A" ) {
1600 curListStyle = QStyleSheetItem::ListUpperAlpha;
1601 } else {
1602 sl = sl.lower();
1603 if ( sl == "square" )
1604 curListStyle = QStyleSheetItem::ListSquare;
1605 else if ( sl == "disc" )
1606 curListStyle = QStyleSheetItem::ListDisc;
1607 else if ( sl == "circle" )
1608 curListStyle = QStyleSheetItem::ListCircle;
1609 }
1610 }
1611 }
1612 return curListStyle;
1613}
1614
1615void QTextDocument::setRichTextInternal( const QString &text )
1616{ 1436{
1617 oTextValid = TRUE; 1437 QTextParagraph* curpar = lParag;
1618 oText = text;
1619 QTextParag* curpar = lParag;
1620 int pos = 0; 1438 int pos = 0;
@@ -1624,2 +1442,5 @@ void QTextDocument::setRichTextInternal( const QString &text )
1624 bool space = TRUE; 1442 bool space = TRUE;
1443 bool canMergeLi = FALSE;
1444
1445 bool textEditMode = FALSE;
1625 1446
@@ -1628,4 +1449,26 @@ void QTextDocument::setRichTextInternal( const QString &text )
1628 bool hasNewPar = curpar->length() <= 1; 1449 bool hasNewPar = curpar->length() <= 1;
1629 QString lastClose;
1630 QString anchorName; 1450 QString anchorName;
1451
1452 // style sheet handling for margin and line spacing calculation below
1453 QTextParagraph* stylesPar = curpar;
1454 QPtrVector<QStyleSheetItem>* vec = 0;
1455 QPtrList< QPtrVector<QStyleSheetItem> > styles;
1456 styles.setAutoDelete( TRUE );
1457
1458 if ( cursor ) {
1459 cursor->splitAndInsertEmptyParagraph();
1460 QTextCursor tmp = *cursor;
1461 tmp.gotoPreviousLetter();
1462 stylesPar = curpar = tmp.paragraph();
1463 hasNewPar = TRUE;
1464 textEditMode = TRUE;
1465 } else {
1466 NEWPAR;
1467 }
1468
1469 // set rtext spacing to FALSE for the initial paragraph.
1470 curpar->rtext = FALSE;
1471
1472 QString wellKnownTags = "br hr wsp table qt body meta title";
1473
1631 while ( pos < length ) { 1474 while ( pos < length ) {
@@ -1640,29 +1483,4 @@ void QTextDocument::setRichTextInternal( const QString &text )
1640 1483
1641 if ( tagname == "title" ) {
1642 QString title;
1643 while ( pos < length ) {
1644 if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) &&
1645 parseCloseTag( doc, length, pos ) == "title" )
1646 break;
1647 title += doc[ pos ];
1648 ++pos;
1649 }
1650 attribs.replace( "title", title );
1651 }
1652
1653 const QStyleSheetItem* nstyle = sheet_->item(tagname); 1484 const QStyleSheetItem* nstyle = sheet_->item(tagname);
1654 1485
1655 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1656 // if ( tagname == "br" ) {
1657 // // our standard br emty-tag handling breaks
1658 // // inside list items, we would get another
1659 // // list item in this case. As workaround, fake
1660 // // a new paragraph instead
1661 // tagname = "p";
1662 // nstyle = sheet_->item( tagname );
1663 // }
1664 if ( nstyle )
1665 hasNewPar = FALSE; // we want empty paragraphs in this case
1666 }
1667
1668 if ( nstyle ) { 1486 if ( nstyle ) {
@@ -1679,4 +1497,9 @@ void QTextDocument::setRichTextInternal( const QString &text )
1679 1497
1680 // special handling for p. We do not want to nest there for HTML compatibility 1498 /* special handling for p and li for HTML
1681 if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { 1499 compatibility. We do not want to embed blocks in
1500 p, and we do not want new blocks inside non-empty
1501 lis. Plus we want to merge empty lis sometimes. */
1502 if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) {
1503 canMergeLi = TRUE;
1504 } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) {
1682 while ( curtag.style->name() == "p" ) { 1505 while ( curtag.style->name() == "p" ) {
@@ -1686,4 +1509,23 @@ void QTextDocument::setRichTextInternal( const QString &text )
1686 } 1509 }
1687 }
1688 1510
1511 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1512 // we are in a li and a new block comes along
1513 if ( nstyle->name() == "ul" || nstyle->name() == "ol" )
1514 hasNewPar = FALSE; // we want an empty li (like most browsers)
1515 if ( !hasNewPar ) {
1516 /* do not add new blocks inside
1517 non-empty lis */
1518 while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1519 if ( tags.isEmpty() )
1520 break;
1521 curtag = tags.pop();
1522 }
1523 } else if ( canMergeLi ) {
1524 /* we have an empty li and a block
1525 comes along, merge them */
1526 nstyle = curtag.style;
1527 }
1528 canMergeLi = FALSE;
1529 }
1530 }
1689 } 1531 }
@@ -1691,41 +1533,34 @@ void QTextDocument::setRichTextInternal( const QString &text )
1691 QTextCustomItem* custom = 0; 1533 QTextCustomItem* custom = 0;
1692 // some well-known empty tags 1534
1693 if ( tagname == "br" ) { 1535 // some well-known tags, some have a nstyle, some not
1694 emptyTag = TRUE; 1536 if ( wellKnownTags.find( tagname ) != -1 ) {
1695 hasNewPar = FALSE; 1537 if ( tagname == "br" ) {
1696 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { 1538 emptyTag = space = TRUE;
1697 // when linebreaking a list item, we do not 1539 int index = QMAX( curpar->length(),1) - 1;
1698 // actually want a new list item but just a 1540 QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
1699 // new line. Fake this by pushing a paragraph 1541 curpar->append( QChar_linesep );
1700 // onto the stack 1542 curpar->setFormat( index, 1, &format );
1701 tags.push( curtag ); 1543 } else if ( tagname == "hr" ) {
1702 curtag.name = tagname; 1544 emptyTag = space = TRUE;
1703 curtag.style = nstyle; 1545 custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
1704 } 1546 NEWPAR;
1705 NEWPAR; 1547 } else if ( tagname == "table" ) {
1706 curpar->isBr = TRUE; 1548 emptyTag = space = TRUE;
1707 curpar->setAlignment( curtag.alignment ); 1549 QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
1708 } else if ( tagname == "hr" ) { 1550 curpar->setAlignment( curtag.alignment );
1709 emptyTag = TRUE; 1551 custom = parseTable( attr, format, doc, length, pos, curpar );
1710 custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); 1552 } else if ( tagname == "qt" || tagname == "body" ) {
1711 NEWPAR; 1553 if ( attr.contains( "bgcolor" ) ) {
1712 } else if ( tagname == "table" ) { 1554 QBrush *b = new QBrush( QColor( attr["bgcolor"] ) );
1713 QTextFormat format = curtag.format.makeTextFormat( nstyle, attr );
1714 curpar->setAlignment( curtag.alignment );
1715 custom = parseTable( attr, format, doc, length, pos, curpar );
1716 (void)eatSpace( doc, length, pos );
1717 emptyTag = TRUE;
1718 } else if ( tagname == "qt" ) {
1719 for ( QMap<QString, QString>::Iterator it = attr.begin(); it != attr.end(); ++it ) {
1720 if ( it.key() == "bgcolor" ) {
1721 QBrush *b = new QBrush( QColor( *it ) );
1722 setPaper( b ); 1555 setPaper( b );
1723 } else if ( it.key() == "background" ) { 1556 }
1557 if ( attr.contains( "background" ) ) {
1724 QImage img; 1558 QImage img;
1725 const QMimeSource* m = factory_->data( *it, contxt ); 1559 QString bg = attr["background"];
1560 const QMimeSource* m = factory_->data( bg, contxt );
1726 if ( !m ) { 1561 if ( !m ) {
1727 qWarning("QRichText: no mimesource for %s", (*it).latin1() ); 1562 qWarning("QRichText: no mimesource for %s", bg.latin1() );
1728 } else { 1563 } else {
1729 if ( !QImageDrag::decode( m, img ) ) { 1564 if ( !QImageDrag::decode( m, img ) ) {
1730 qWarning("QTextImage: cannot decode %s", (*it).latin1() ); 1565 qWarning("QTextImage: cannot decode %s", bg.latin1() );
1731 } 1566 }
@@ -1738,4 +1573,5 @@ void QTextDocument::setRichTextInternal( const QString &text )
1738 } 1573 }
1739 } else if ( it.key() == "text" ) { 1574 }
1740 QColor c( *it ); 1575 if ( attr.contains( "text" ) ) {
1576 QColor c( attr["text"] );
1741 if ( formatCollection()->defaultFormat()->color() != c ) { 1577 if ( formatCollection()->defaultFormat()->color() != c ) {
@@ -1754,11 +1590,40 @@ void QTextDocument::setRichTextInternal( const QString &text )
1754 } 1590 }
1755 } else if ( it.key() == "link" ) {
1756 linkColor = QColor( *it );
1757 } else if ( it.key() == "title" ) {
1758 attribs.replace( it.key(), *it );
1759 } 1591 }
1592 if ( attr.contains( "link" ) )
1593 linkColor = QColor( attr["link"] );
1594 if ( attr.contains( "title" ) )
1595 attribs.replace( "title", attr["title"] );
1596
1597 if ( textEditMode ) {
1598 if ( attr.contains("style" ) ) {
1599 QString a = attr["style"];
1600 for ( int s = 0; s < a.contains(';')+1; s++ ) {
1601 QString style = QTextDocument::section( a, ";", s, s );
1602 if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) {
1603 scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) /
1604 style.mid( 10, style.length() - 12 ).toInt();
1605 }
1606 }
1607 }
1608 nstyle = 0; // ignore body in textEditMode
1609 }
1610 // end qt- and body-tag handling
1611 } else if ( tagname == "meta" ) {
1612 if ( attr["name"] == "qrichtext" && attr["content"] == "1" )
1613 textEditMode = TRUE;
1614 } else if ( tagname == "title" ) {
1615 QString title;
1616 while ( pos < length ) {
1617 if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) &&
1618 parseCloseTag( doc, length, pos ) == "title" )
1619 break;
1620 title += doc[ pos ];
1621 ++pos;
1622 }
1623 attribs.replace( "title", title );
1760 } 1624 }
1761 } else { 1625 } // end of well-known tag handling
1626
1627 if ( !custom ) // try generic custom item
1762 custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); 1628 custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
1763 }
1764 1629
@@ -1768,6 +1633,4 @@ void QTextDocument::setRichTextInternal( const QString &text )
1768 if ( custom ) { 1633 if ( custom ) {
1769 int index = curpar->length() - 1; 1634 int index = QMAX( curpar->length(),1) - 1;
1770 if ( index < 0 ) 1635 QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
1771 index = 0;
1772 QTextFormat format = curtag.format.makeTextFormat( nstyle, attr );
1773 curpar->append( QChar('*') ); 1636 curpar->append( QChar('*') );
@@ -1784,10 +1647,5 @@ void QTextDocument::setRichTextInternal( const QString &text )
1784 } else if ( !emptyTag ) { 1647 } else if ( !emptyTag ) {
1785 // ignore whitespace for inline elements if there was already one 1648 /* if we do nesting, push curtag on the stack,
1786 if ( nstyle->whiteSpaceMode() == QStyleSheetItem::WhiteSpaceNormal 1649 otherwise reinint curag. */
1787 && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) ) 1650 if ( curtag.style->name() != tagname || nstyle->selfNesting() ) {
1788 eatSpace( doc, length, pos );
1789
1790 // if we do nesting, push curtag on the stack,
1791 // otherwise reinint curag.
1792 if ( nstyle != curtag.style || nstyle->selfNesting() ) {
1793 tags.push( curtag ); 1651 tags.push( curtag );
@@ -1800,4 +1658,2 @@ void QTextDocument::setRichTextInternal( const QString &text )
1800 1658
1801 const QStyleSheetItem* ostyle = curtag.style;
1802
1803 curtag.name = tagname; 1659 curtag.name = tagname;
@@ -1806,6 +1662,12 @@ void QTextDocument::setRichTextInternal( const QString &text )
1806 curtag.style = nstyle; 1662 curtag.style = nstyle;
1807 if ( nstyle->whiteSpaceMode() != QStyleSheetItem::WhiteSpaceNormal ) 1663 if ( int(nstyle->whiteSpaceMode()) != QStyleSheetItem::Undefined )
1808 curtag.wsm = nstyle->whiteSpaceMode(); 1664 curtag.wsm = nstyle->whiteSpaceMode();
1809 curtag.liststyle = chooseListStyle( nstyle, attr, curtag.liststyle ); 1665
1810 curtag.format = curtag.format.makeTextFormat( nstyle, attr ); 1666 /* ignore whitespace for inline elements if there
1667 was already one*/
1668 if ( !textEditMode && curtag.wsm == QStyleSheetItem::WhiteSpaceNormal
1669 && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) )
1670 eatSpace( doc, length, pos );
1671
1672 curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
1811 if ( nstyle->isAnchor() ) { 1673 if ( nstyle->isAnchor() ) {
@@ -1821,46 +1683,84 @@ void QTextDocument::setRichTextInternal( const QString &text )
1821 1683
1822 if ( ostyle->displayMode() == QStyleSheetItem::DisplayListItem && 1684 if ( (int) nstyle->listStyle() != QStyleSheetItem::Undefined )
1823 curpar->length() <= 1 1685 curtag.liststyle = nstyle->listStyle();
1824 && nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { 1686
1825 // do not do anything, we reuse the paragraph we have 1687 if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock
1826 } else if ( nstyle->displayMode() != QStyleSheetItem::DisplayInline && nstyle->displayMode() != QStyleSheetItem::DisplayNone ) { 1688 || nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) {
1689
1690 if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") {
1691 QString type = attr["type"];
1692 if ( !type.isEmpty() ) {
1693 if ( type == "1" ) {
1694 curtag.liststyle = QStyleSheetItem::ListDecimal;
1695 } else if ( type == "a" ) {
1696 curtag.liststyle = QStyleSheetItem::ListLowerAlpha;
1697 } else if ( type == "A" ) {
1698 curtag.liststyle = QStyleSheetItem::ListUpperAlpha;
1699 } else {
1700 type = type.lower();
1701 if ( type == "square" )
1702 curtag.liststyle = QStyleSheetItem::ListSquare;
1703 else if ( type == "disc" )
1704 curtag.liststyle = QStyleSheetItem::ListDisc;
1705 else if ( type == "circle" )
1706 curtag.liststyle = QStyleSheetItem::ListCircle;
1707 }
1708 }
1709 }
1710
1711
1712 /* Internally we treat ordered and bullet
1713 lists the same for margin calculations. In
1714 order to have fast pointer compares in the
1715 xMargin() functions we restrict ourselves to
1716 <ol>. Once we calculate the margins in the
1717 parser rathern than later, the unelegance of
1718 this approach goes awy
1719 */
1720 if ( nstyle->name() == "ul" )
1721 curtag.style = sheet_->item( "ol" );
1722
1723 if ( attr.contains( "align" ) ) {
1724 QString align = attr["align"];
1725 if ( align == "center" )
1726 curtag.alignment = Qt::AlignCenter;
1727 else if ( align == "right" )
1728 curtag.alignment = Qt::AlignRight;
1729 else if ( align == "justify" )
1730 curtag.alignment = Qt3::AlignJustify;
1731 }
1732 if ( attr.contains( "dir" ) ) {
1733 QString dir = attr["dir"];
1734 if ( dir == "rtl" )
1735 curtag.direction = QChar::DirR;
1736 else if ( dir == "ltr" )
1737 curtag.direction = QChar::DirL;
1738 }
1739
1827 NEWPAR; 1740 NEWPAR;
1828 }
1829 1741
1830 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { 1742 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1831 curpar->setListStyle( curtag.liststyle ); 1743 if ( attr.contains( "value " ) )
1832 if ( attr.find( "value" ) != attr.end() ) 1744 curpar->setListValue( attr["value"].toInt() );
1833 curpar->setListValue( (*attr.find( "value" )).toInt() ); 1745 }
1834 }
1835 1746
1836 if ( nstyle->displayMode() != QStyleSheetItem::DisplayInline ) 1747 if ( attr.contains( "style" ) ) {
1837 curpar->setFormat( &curtag.format ); 1748 QString a = attr["style"];
1838 1749 bool ok = TRUE;
1839 if ( attr.contains( "align" ) && 1750 for ( int s = 0; ok && s < a.contains(';')+1; s++ ) {
1840 ( curtag.name == "p" || 1751 QString style = QTextDocument::section( a, ";", s, s );
1841 curtag.name == "div" || 1752 if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") )
1842 curtag.name == "li" || 1753 curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
1843 curtag.name[ 0 ] == 'h' ) ) { 1754 else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") )
1844 QString align = attr["align"]; 1755 curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
1845 if ( align == "center" ) 1756 else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") )
1846 curtag.alignment = Qt::AlignCenter; 1757 curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
1847 else if ( align == "right" ) 1758 else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") )
1848 curtag.alignment = Qt::AlignRight; 1759 curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
1849 else if ( align == "justify" ) 1760 else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") )
1850 curtag.alignment = Qt3::AlignJustify; 1761 curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
1851 } 1762 }
1852 if ( attr.contains( "dir" ) && 1763 if ( !ok ) // be pressmistic
1853 ( curtag.name == "p" || 1764 curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
1854 curtag.name == "div" || 1765 }
1855 curtag.name == "li" ||
1856 curtag.name[ 0 ] == 'h' ) ) {
1857 QString dir = attr["dir"];
1858 if ( dir == "rtl" )
1859 curtag.direction = QChar::DirR;
1860 else if ( dir == "ltr" )
1861 curtag.direction = QChar::DirL;
1862 }
1863 if ( nstyle->displayMode() != QStyleSheetItem::DisplayInline ) {
1864 curpar->setAlignment( curtag.alignment );
1865 curpar->setDirection( (QChar::Direction)curtag.direction );
1866 } 1766 }
@@ -1869,3 +1769,2 @@ void QTextDocument::setRichTextInternal( const QString &text )
1869 QString tagname = parseCloseTag( doc, length, pos ); 1769 QString tagname = parseCloseTag( doc, length, pos );
1870 lastClose = tagname;
1871 if ( tagname.isEmpty() ) 1770 if ( tagname.isEmpty() )
@@ -1875,10 +1774,6 @@ void QTextDocument::setRichTextInternal( const QString &text )
1875 1774
1876
1877 // we close a block item. Since the text may continue, we need to have a new paragraph 1775 // we close a block item. Since the text may continue, we need to have a new paragraph
1878 bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock; 1776 bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock
1777 || curtag.style->displayMode() == QStyleSheetItem::DisplayListItem;
1879 1778
1880 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
1881 needNewPar = TRUE;
1882 hasNewPar = FALSE; // we want empty paragraphs in this case
1883 }
1884 1779
@@ -1903,7 +1798,4 @@ void QTextDocument::setRichTextInternal( const QString &text )
1903 if ( needNewPar ) { 1798 if ( needNewPar ) {
1904 if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { 1799 if ( textEditMode && tagname == "p" ) // preserve empty paragraphs
1905 tags.push( curtag ); 1800 hasNewPar = FALSE;
1906 curtag.name = "p";
1907 curtag.style = sheet_->item( curtag.name ); // a list item continues, use p for that
1908 }
1909 NEWPAR; 1801 NEWPAR;
@@ -1916,13 +1808,38 @@ void QTextDocument::setRichTextInternal( const QString &text )
1916 while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){ 1808 while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){
1917 QStyleSheetItem::WhiteSpaceMode wsm = curtag.wsm; 1809 if ( textEditMode ) {
1918 if ( s.length() > 4096 ) 1810 // text edit mode: we handle all white space but ignore newlines
1919 wsm = (QStyleSheetItem::WhiteSpaceMode)QStyleSheetItem_WhiteSpaceNormalWithNewlines; 1811 c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre );
1920 1812 if ( c == QChar_linesep )
1921 c = parseChar( doc, length, pos, wsm ); 1813 break;
1814 } else {
1815 int l = pos;
1816 c = parseChar( doc, length, pos, curtag.wsm );
1817
1818 // in white space pre mode: treat any space as non breakable
1819 if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre )
1820 c = QChar::nbsp;
1821
1822 if ( c == ' ' || c == QChar_linesep ) {
1823 /* avoid overlong paragraphs by forcing a new
1824 paragraph after 4096 characters. This case can
1825 occur when loading undiscovered plain text
1826 documents in rich text mode. Instead of hanging
1827 forever, we do the trick.
1828 */
1829 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do {
1830 if ( doc[l] == '\n' ) {
1831 hasNewPar = FALSE; // for a new paragraph ...
1832 NEWPAR;
1833 hasNewPar = FALSE; // ... and make it non-reusable
1834 c = '\n'; // make sure we break below
1835 break;
1836 }
1837 } while ( ++l < pos );
1838 }
1839 }
1922 1840
1923 if ( c == '\n' ) // happens only in whitespacepre-mode or with WhiteSpaceNormalWithNewlines. 1841 if ( c == '\n' )
1924 break; // we want a new line in this case 1842 break; // break on newlines, pre delievers a QChar_linesep
1925 1843
1926 bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && 1844 bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode;
1927 curtag.wsm != QStyleSheetItem_WhiteSpaceNoCompression;
1928 1845
@@ -1937,5 +1854,3 @@ void QTextDocument::setRichTextInternal( const QString &text )
1937 hasNewPar = FALSE; 1854 hasNewPar = FALSE;
1938 int index = curpar->length() - 1; 1855 int index = QMAX( curpar->length(),1) - 1;
1939 if ( index < 0 )
1940 index = 0;
1941 curpar->append( s ); 1856 curpar->append( s );
@@ -1953,12 +1868,5 @@ void QTextDocument::setRichTextInternal( const QString &text )
1953 } 1868 }
1954 if ( c == '\n' ) { // happens in WhiteSpacePre mode
1955 hasNewPar = FALSE;
1956 tags.push( curtag );
1957 NEWPAR;
1958 curtag = tags.pop();
1959 }
1960 } 1869 }
1961 } 1870 }
1962 1871 if ( hasNewPar && curpar != fParag && !cursor ) {
1963 if ( hasNewPar && curpar != fParag ) {
1964 // cleanup unused last paragraphs 1872 // cleanup unused last paragraphs
@@ -1967,3 +1875,2 @@ void QTextDocument::setRichTextInternal( const QString &text )
1967 } 1875 }
1968
1969 if ( !anchorName.isEmpty() ) { 1876 if ( !anchorName.isEmpty() ) {
@@ -1972,2 +1879,164 @@ void QTextDocument::setRichTextInternal( const QString &text )
1972 } 1879 }
1880
1881
1882 setRichTextMarginsInternal( styles, stylesPar );
1883
1884 if ( cursor ) {
1885 cursor->gotoPreviousLetter();
1886 cursor->remove();
1887 }
1888
1889}
1890
1891void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar )
1892{
1893 // margin and line spacing calculation
1894 QPtrVector<QStyleSheetItem>* prevStyle = 0;
1895 QPtrVector<QStyleSheetItem>* curStyle = styles.first();
1896 QPtrVector<QStyleSheetItem>* nextStyle = styles.next();
1897 while ( stylesPar ) {
1898 if ( !curStyle ) {
1899 stylesPar = stylesPar->next();
1900 prevStyle = curStyle;
1901 curStyle = nextStyle;
1902 nextStyle = styles.next();
1903 continue;
1904 }
1905
1906 int i, mar;
1907 QStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
1908 if ( mainStyle && mainStyle->displayMode() == QStyleSheetItem::DisplayListItem )
1909 stylesPar->setListItem( TRUE );
1910 int numLists = 0;
1911 for ( i = 0; i < (int)curStyle->size(); ++i ) {
1912 if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
1913 && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
1914 numLists++;
1915 }
1916 stylesPar->ldepth = numLists;
1917 if ( stylesPar->next() && nextStyle ) {
1918 // also set the depth of the next paragraph, required for the margin calculation
1919 numLists = 0;
1920 for ( i = 0; i < (int)nextStyle->size(); ++i ) {
1921 if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
1922 && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
1923 numLists++;
1924 }
1925 stylesPar->next()->ldepth = numLists;
1926 }
1927
1928 // do the top margin
1929 QStyleSheetItem* item = mainStyle;
1930 int m;
1931 if (stylesPar->utm > 0 ) {
1932 m = stylesPar->utm-1;
1933 stylesPar->utm = 0;
1934 } else {
1935 m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) );
1936 if ( item->displayMode() == QStyleSheetItem::DisplayListItem
1937 && stylesPar->ldepth )
1938 m /= stylesPar->ldepth;
1939 }
1940 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1941 item = (*curStyle)[ i ];
1942 if ( prevStyle && i < (int) prevStyle->size() &&
1943 ( item->displayMode() == QStyleSheetItem::DisplayBlock &&
1944 (*prevStyle)[ i ] == item ) )
1945 break;
1946 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
1947 if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
1948 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
1949 continue;
1950 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) );
1951 m = QMAX( m, mar );
1952 }
1953 stylesPar->utm = m - stylesPar->topMargin();
1954
1955 // do the bottom margin
1956 item = mainStyle;
1957 if (stylesPar->ubm > 0 ) {
1958 m = stylesPar->ubm-1;
1959 stylesPar->ubm = 0;
1960 } else {
1961 m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
1962 if ( item->displayMode() == QStyleSheetItem::DisplayListItem
1963 && stylesPar->ldepth )
1964 m /= stylesPar->ldepth;
1965 }
1966 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1967 item = (*curStyle)[ i ];
1968 if ( nextStyle && i < (int) nextStyle->size() &&
1969 ( item->displayMode() == QStyleSheetItem::DisplayBlock &&
1970 (*nextStyle)[ i ] == item ) )
1971 break;
1972 // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
1973 if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
1974 ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
1975 continue;
1976 mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
1977 m = QMAX( m, mar );
1978 }
1979 stylesPar->ubm = m - stylesPar->bottomMargin();
1980
1981 // do the left margin, simplyfied
1982 item = mainStyle;
1983 if (stylesPar->ulm > 0 ) {
1984 m = stylesPar->ulm-1;
1985 stylesPar->ulm = 0;
1986 } else {
1987 m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1988 }
1989 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1990 item = (*curStyle)[ i ];
1991 m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1992 }
1993 stylesPar->ulm = m - stylesPar->leftMargin();
1994
1995 // do the right margin, simplyfied
1996 item = mainStyle;
1997 if (stylesPar->urm > 0 ) {
1998 m = stylesPar->urm-1;
1999 stylesPar->urm = 0;
2000 } else {
2001 m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
2002 }
2003 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
2004 item = (*curStyle)[ i ];
2005 m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
2006 }
2007 stylesPar->urm = m - stylesPar->rightMargin();
2008
2009 // do the first line margin, which really should be called text-indent
2010 item = mainStyle;
2011 if (stylesPar->uflm > 0 ) {
2012 m = stylesPar->uflm-1;
2013 stylesPar->uflm = 0;
2014 } else {
2015 m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
2016 }
2017 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
2018 item = (*curStyle)[ i ];
2019 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
2020 m = QMAX( m, mar );
2021 }
2022 stylesPar->uflm =m - stylesPar->firstLineMargin();
2023
2024 // do the bogus line "spacing", which really is just an extra margin
2025 item = mainStyle;
2026 for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) {
2027 item = (*curStyle)[ i ];
2028 if ( item->lineSpacing() != QStyleSheetItem::Undefined ) {
2029 stylesPar->ulinespacing = item->lineSpacing();
2030 if ( formatCollection() &&
2031 stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() )
2032 stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
2033 break;
2034 }
2035 }
2036
2037 stylesPar = stylesPar->next();
2038 prevStyle = curStyle;
2039 curStyle = nextStyle;
2040 nextStyle = styles.next();
2041 }
1973} 2042}
@@ -1985,128 +2054,189 @@ void QTextDocument::setText( const QString &text, const QString &context )
1985 2054
1986QString QTextDocument::plainText( QTextParag *p ) const 2055QString QTextDocument::plainText() const
1987{ 2056{
1988 if ( !p ) { 2057 QString buffer;
1989 QString buffer; 2058 QString s;
1990 QString s; 2059 QTextParagraph *p = fParag;
1991 QTextParag *p = fParag; 2060 while ( p ) {
1992 while ( p ) { 2061 if ( !p->mightHaveCustomItems ) {
1993 if ( !p->mightHaveCustomItems ) { 2062 s = p->string()->toString();
1994 s = p->string()->toString(); 2063 } else {
1995 } else { 2064 for ( int i = 0; i < p->length() - 1; ++i ) {
1996 for ( int i = 0; i < p->length() - 1; ++i ) { 2065 if ( p->at( i )->isCustom() ) {
1997 if ( p->at( i )->isCustom() ) { 2066 if ( p->at( i )->customItem()->isNested() ) {
1998 if ( p->at( i )->customItem()->isNested() ) { 2067 s += "\n";
1999 s += "\n"; 2068 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2000 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 2069 QPtrList<QTextTableCell> cells = t->tableCells();
2001 QPtrList<QTextTableCell> cells = t->tableCells(); 2070 for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
2002 for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) 2071 s += c->richText()->plainText() + "\n";
2003 s += c->richText()->plainText() + "\n"; 2072 s += "\n";
2004 s += "\n";
2005 }
2006 } else {
2007 s += p->at( i )->c;
2008 } 2073 }
2074 } else {
2075 s += p->at( i )->c;
2009 } 2076 }
2010 } 2077 }
2011 s.remove( s.length() - 1, 1 );
2012 if ( p->next() )
2013 s += "\n";
2014 buffer += s;
2015 p = p->next();
2016 } 2078 }
2017 return buffer; 2079 s.remove( s.length() - 1, 1 );
2018 } else { 2080 if ( p->next() )
2019 return p->string()->toString(); 2081 s += "\n";
2082 buffer += s;
2083 p = p->next();
2020 } 2084 }
2085 return buffer;
2021} 2086}
2022 2087
2023static QString align_to_string( const QString &tag, int a ) 2088static QString align_to_string( int a )
2024{ 2089{
2025 if ( tag == "p" || tag == "li" || ( tag[0] == 'h' && tag[1].isDigit() ) ) { 2090 if ( a & Qt::AlignRight )
2026 if ( a & Qt::AlignRight ) 2091 return " align=\"right\"";
2027 return " align=\"right\""; 2092 if ( a & Qt::AlignHCenter )
2028 if ( a & Qt::AlignCenter ) 2093 return " align=\"center\"";
2029 return " align=\"center\""; 2094 if ( a & Qt3::AlignJustify )
2030 if ( a & Qt3::AlignJustify ) 2095 return " align=\"justify\"";
2031 return " align=\"justify\""; 2096 return QString::null;
2032 }
2033 return "";
2034} 2097}
2035 2098
2036static QString direction_to_string( const QString &tag, int d ) 2099static QString direction_to_string( int d )
2037{ 2100{
2038 if ( d != QChar::DirON && 2101 if ( d != QChar::DirON )
2039 ( tag == "p" || tag == "div" || tag == "li" || ( tag[0] == 'h' && tag[1].isDigit() ) ) )
2040 return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); 2102 return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" );
2041 return ""; 2103 return QString::null;
2042} 2104}
2043 2105
2044QString QTextDocument::richText( QTextParag *p ) const 2106static QString list_value_to_string( int v )
2045{ 2107{
2046 QString s,n; 2108 if ( v != -1 )
2047 if ( !p ) { 2109 return " listvalue=\"" + QString::number( v ) + "\"";
2048 p = fParag; 2110 return QString::null;
2049 QPtrVector<QStyleSheetItem> lastItems, items; 2111}
2050 while ( p ) { 2112
2051 items = p->styleSheetItems(); 2113static QString list_style_to_string( int v )
2052 if ( items.size() ) { 2114{
2053 QStyleSheetItem *item = items[ items.size() - 1 ]; 2115 switch( v ) {
2054 items.resize( items.size() - 1 ); 2116 case QStyleSheetItem::ListDecimal: return "\"1\"";
2055 if ( items.size() > lastItems.size() ) { 2117 case QStyleSheetItem::ListLowerAlpha: return "\"a\"";
2056 for ( int i = lastItems.size(); i < (int)items.size(); ++i ) { 2118 case QStyleSheetItem::ListUpperAlpha: return "\"A\"";
2057 n = items[i]->name(); 2119 case QStyleSheetItem::ListDisc: return "\"disc\"";
2058 if ( n.isEmpty() || n == "li" ) 2120 case QStyleSheetItem::ListSquare: return "\"square\"";
2059 continue; 2121 case QStyleSheetItem::ListCircle: return "\"circle\"";
2060 s += "<" + n + align_to_string( n, p->alignment() ) + ">"; 2122 default:
2061 } 2123 return QString::null;
2062 } else { 2124 }
2063 QString end; 2125}
2064 for ( int i = items.size(); i < (int)lastItems.size(); ++i ) { 2126
2065 n = lastItems[i]->name(); 2127static inline bool list_is_ordered( int v )
2066 if ( n.isEmpty() || n == "li" || n == "br" ) 2128{
2067 continue; 2129 return v == QStyleSheetItem::ListDecimal ||
2068 end.prepend( "</" + lastItems[ i ]->name() + ">" ); 2130 v == QStyleSheetItem::ListLowerAlpha ||
2069 } 2131 v == QStyleSheetItem::ListUpperAlpha;
2070 s += end; 2132}
2071 } 2133
2072 lastItems = items; 2134
2073 n = item->name(); 2135static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl )
2074 if ( n == "li" && p->listValue() != -1 ) { 2136{
2075 s += "<li value=\"" + QString::number( p->listValue() ) + "\">"; 2137 QString s;
2076 } else { 2138 if ( l > 0 )
2077 QString ps = p->richText(); 2139 s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px";
2078 if ( ps.isEmpty() ) 2140 if ( r > 0 )
2079 s += "<br>"; // empty paragraph 2141 s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px";
2080 else if ( !n.isEmpty() ) { 2142 if ( t > 0 )
2081 s += "<" + n + align_to_string( n, p->alignment() ) 2143 s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px";
2082 + direction_to_string( n, p->direction() ) + ">" + ps; 2144 if ( b > 0 )
2083 if ( n != "li" && n != "br") 2145 s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px";
2084 s += "</" + n + ">"; 2146 if ( fl > 0 )
2085 } else 2147 s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px";
2086 s += ps; 2148 if ( !!s )
2087 } 2149 return " style=\"" + s + "\"";
2088 } else { 2150 return QString::null;
2089 QString end; 2151}
2090 for ( int i = 0; i < (int)lastItems.size(); ++i ) { 2152
2091 QString n = lastItems[i]->name(); 2153QString QTextDocument::richText() const
2092 if ( n.isEmpty() || n == "li" || n == "br" ) 2154{
2093 continue; 2155 QString s = "";
2094 end.prepend( "</" + n + ">" ); 2156 if ( !par ) {
2095 } 2157 s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ;
2096 s += end; 2158 s += QString::number( formatCollection()->defaultFormat()->font().pointSize() );
2097 QString ps = p->richText(); 2159 s += "pt;font-family:";
2098 if ( ps.isEmpty() ) 2160 s += formatCollection()->defaultFormat()->font().family();
2099 s += "<br>"; // empty paragraph 2161 s +="\">";
2100 else 2162 }
2101 s += "<p" + align_to_string( "p", p->alignment() ) + direction_to_string( "p", p->direction() ) 2163 QTextParagraph* p = fParag;
2102 + ">" + ps + "</p>"; 2164
2103 lastItems = items; 2165 QStyleSheetItem* item_p = styleSheet()->item("p");
2166 QStyleSheetItem* item_ul = styleSheet()->item("ul");
2167 QStyleSheetItem* item_ol = styleSheet()->item("ol");
2168 QStyleSheetItem* item_li = styleSheet()->item("li");
2169 if ( !item_p || !item_ul || !item_ol || !item_li ) {
2170 qWarning( "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" );
2171 return QString::null;
2172 }
2173 int pastListDepth = 0;
2174 int listDepth = 0;
2175 int futureListDepth = 0;
2176 QMemArray<int> listStyles(10);
2177
2178 while ( p ) {
2179 listDepth = p->listDepth();
2180 if ( listDepth < pastListDepth ) {
2181 for ( int i = listDepth+1; i <= pastListDepth; i++ )
2182 s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>";
2183 s += '\n';
2184 } else if ( listDepth > pastListDepth ) {
2185 s += '\n';
2186 listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) );
2187 QString list_type;
2188 listStyles[listDepth] = p->listStyle();
2189 if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() )
2190 list_type = " type=" + list_style_to_string( p->listStyle() );
2191 for ( int i = pastListDepth; i < listDepth; i++ ) {
2192 s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ;
2193 s += list_type + ">";
2104 } 2194 }
2105 if ( ( p = p->next() ) ) 2195 } else {
2106 s += '\n'; 2196 s += '\n';
2107 } 2197 }
2108 } else { 2198
2109 s = p->richText(); 2199 QString ps = p->richText();
2200
2201 // for the bottom margin we need to know whether we are at the end of a list
2202 futureListDepth = 0;
2203 if ( listDepth > 0 && p->next() )
2204 futureListDepth = p->next()->listDepth();
2205
2206 if ( richTextExportStart && richTextExportStart->paragraph() ==p &&
2207 richTextExportStart->index() == 0 )
2208 s += "<selstart/>";
2209
2210 if ( p->isListItem() ) {
2211 s += "<li";
2212 if ( p->listStyle() != listStyles[listDepth] )
2213 s += " type=" + list_style_to_string( p->listStyle() );
2214 s +=align_to_string( p->alignment() );
2215 s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
2216 s += list_value_to_string( p->listValue() );
2217 s += direction_to_string( p->direction() );
2218 s +=">";
2219 s += ps;
2220 s += "</li>";
2221 } else {
2222 // normal paragraph item
2223 s += "<p";
2224 s += align_to_string( p->alignment() );
2225 s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
2226 s +=direction_to_string( p->direction() );
2227 s += ">";
2228 s += ps;
2229 s += "</p>";
2230 }
2231 pastListDepth = listDepth;
2232 p = p->next();
2233 }
2234 while ( listDepth > 0 ) {
2235 s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>";
2236 listDepth--;
2110 } 2237 }
2111 2238
2239 if ( !par )
2240 s += "\n</body></html>\n";
2241
2112 return s; 2242 return s;
@@ -2116,7 +2246,5 @@ QString QTextDocument::text() const
2116{ 2246{
2117 if ( plainText().simplifyWhiteSpace().isEmpty() )
2118 return QString("");
2119 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) 2247 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText )
2120 return richText(); 2248 return richText();
2121 return plainText( 0 ); 2249 return plainText();
2122} 2250}
@@ -2125,3 +2253,3 @@ QString QTextDocument::text( int parag ) const
2125{ 2253{
2126 QTextParag *p = paragAt( parag ); 2254 QTextParagraph *p = paragAt( parag );
2127 if ( !p ) 2255 if ( !p )
@@ -2130,5 +2258,5 @@ QString QTextDocument::text( int parag ) const
2130 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) 2258 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText )
2131 return richText( p ); 2259 return p->richText();
2132 else 2260 else
2133 return plainText( p ); 2261 return p->string()->toString();
2134} 2262}
@@ -2137,3 +2265,3 @@ void QTextDocument::invalidate()
2137{ 2265{
2138 QTextParag *s = fParag; 2266 QTextParagraph *s = fParag;
2139 while ( s ) { 2267 while ( s ) {
@@ -2150,3 +2278,3 @@ void QTextDocument::selectionStart( int id, int &paragId, int &index )
2150 QTextDocumentSelection &sel = *it; 2278 QTextDocumentSelection &sel = *it;
2151 paragId = !sel.swapped ? sel.startCursor.parag()->paragId() : sel.endCursor.parag()->paragId(); 2279 paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
2152 index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); 2280 index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
@@ -2182,3 +2310,3 @@ void QTextDocument::selectionEnd( int id, int &paragId, int &index )
2182 QTextDocumentSelection &sel = *it; 2310 QTextDocumentSelection &sel = *it;
2183 paragId = sel.swapped ? sel.startCursor.parag()->paragId() : sel.endCursor.parag()->paragId(); 2311 paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
2184 index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); 2312 index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
@@ -2186,24 +2314,2 @@ void QTextDocument::selectionEnd( int id, int &paragId, int &index )
2186 2314
2187QTextParag *QTextDocument::selectionStart( int id )
2188{
2189 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2190 if ( it == selections.end() )
2191 return 0;
2192 QTextDocumentSelection &sel = *it;
2193 if ( sel.startCursor.parag()->paragId() < sel.endCursor.parag()->paragId() )
2194 return sel.startCursor.parag();
2195 return sel.endCursor.parag();
2196}
2197
2198QTextParag *QTextDocument::selectionEnd( int id )
2199{
2200 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2201 if ( it == selections.end() )
2202 return 0;
2203 QTextDocumentSelection &sel = *it;
2204 if ( sel.startCursor.parag()->paragId() > sel.endCursor.parag()->paragId() )
2205 return sel.startCursor.parag();
2206 return sel.endCursor.parag();
2207}
2208
2209void QTextDocument::addSelection( int id ) 2315void QTextDocument::addSelection( int id )
@@ -2222,9 +2328,9 @@ static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCur
2222 2328
2223 c1.parag()->removeSelection( id ); 2329 c1.paragraph()->removeSelection( id );
2224 c2.parag()->removeSelection( id ); 2330 c2.paragraph()->removeSelection( id );
2225 if ( c1.parag() != c2.parag() ) { 2331 if ( c1.paragraph() != c2.paragraph() ) {
2226 c1.parag()->setSelection( id, c1.index(), c1.parag()->length() - 1 ); 2332 c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 );
2227 c2.parag()->setSelection( id, 0, c2.index() ); 2333 c2.paragraph()->setSelection( id, 0, c2.index() );
2228 } else { 2334 } else {
2229 c1.parag()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); 2335 c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) );
2230 } 2336 }
@@ -2233,3 +2339,3 @@ static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCur
2233 sel.endCursor = end; 2339 sel.endCursor = end;
2234 if ( sel.startCursor.parag() == sel.endCursor.parag() ) 2340 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
2235 sel.swapped = sel.startCursor.index() > sel.endCursor.index(); 2341 sel.swapped = sel.startCursor.index() > sel.endCursor.index();
@@ -2237,3 +2343,3 @@ static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCur
2237 2343
2238bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor ) 2344bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor )
2239{ 2345{
@@ -2245,3 +2351,3 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2245 QTextCursor start = sel.startCursor; 2351 QTextCursor start = sel.startCursor;
2246 QTextCursor end = *cursor; 2352 QTextCursor end = cursor;
2247 2353
@@ -2253,3 +2359,3 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2253 2359
2254 if ( sel.endCursor.parag() == end.parag() ) { 2360 if ( sel.endCursor.paragraph() == end.paragraph() ) {
2255 setSelectionEndHelper( id, sel, start, end ); 2361 setSelectionEndHelper( id, sel, start, end );
@@ -2264,6 +2370,5 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2264 tmp.restoreState(); 2370 tmp.restoreState();
2265 QTextCursor tmp2 = *cursor; 2371 QTextCursor tmp2 = cursor;
2266 tmp2.restoreState(); 2372 tmp2.restoreState();
2267 c.setParag( tmp.parag()->paragId() < tmp2.parag()->paragId() ? tmp.parag() : tmp2.parag() ); 2373 c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() );
2268 QTextCursor old;
2269 bool hadStart = FALSE; 2374 bool hadStart = FALSE;
@@ -2281,5 +2386,5 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2281 hadEnd = TRUE; 2386 hadEnd = TRUE;
2282 if ( c.parag() == start.parag() ) 2387 if ( c.paragraph() == start.paragraph() )
2283 hadStartParag = TRUE; 2388 hadStartParag = TRUE;
2284 if ( c.parag() == end.parag() ) 2389 if ( c.paragraph() == end.paragraph() )
2285 hadEndParag = TRUE; 2390 hadEndParag = TRUE;
@@ -2292,3 +2397,3 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2292 ( hadEnd && !hadStart || 2397 ( hadEnd && !hadStart ||
2293 hadEnd && hadStart && start.parag() == end.parag() && start.index() > end.index() ) ) 2398 hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) )
2294 sel.swapped = TRUE; 2399 sel.swapped = TRUE;
@@ -2299,6 +2404,6 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2299 tmp.restoreState(); 2404 tmp.restoreState();
2300 if ( tmp.parag() != c.parag() ) { 2405 if ( tmp.paragraph() != c.paragraph() ) {
2301 int sstart = tmp.parag()->selectionStart( id ); 2406 int sstart = tmp.paragraph()->selectionStart( id );
2302 tmp.parag()->removeSelection( id ); 2407 tmp.paragraph()->removeSelection( id );
2303 tmp.parag()->setSelection( id, sstart, tmp.index() ); 2408 tmp.paragraph()->setSelection( id, sstart, tmp.index() );
2304 } 2409 }
@@ -2312,17 +2417,17 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2312 2417
2313 bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.parag()->hasSelection( id ) && c.atParagEnd(); 2418 bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd();
2314 c.parag()->removeSelection( id ); 2419 c.paragraph()->removeSelection( id );
2315 if ( inSelection ) { 2420 if ( inSelection ) {
2316 if ( c.parag() == start.parag() && start.parag() == end.parag() ) { 2421 if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) {
2317 c.parag()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); 2422 c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) );
2318 } else if ( c.parag() == start.parag() && !hadEndParag ) { 2423 } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) {
2319 c.parag()->setSelection( id, start.index(), c.parag()->length() - 1 ); 2424 c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 );
2320 } else if ( c.parag() == end.parag() && !hadStartParag ) { 2425 } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) {
2321 c.parag()->setSelection( id, end.index(), c.parag()->length() - 1 ); 2426 c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 );
2322 } else if ( c.parag() == end.parag() && hadEndParag ) { 2427 } else if ( c.paragraph() == end.paragraph() && hadEndParag ) {
2323 c.parag()->setSelection( id, 0, end.index() ); 2428 c.paragraph()->setSelection( id, 0, end.index() );
2324 } else if ( c.parag() == start.parag() && hadStartParag ) { 2429 } else if ( c.paragraph() == start.paragraph() && hadStartParag ) {
2325 c.parag()->setSelection( id, 0, start.index() ); 2430 c.paragraph()->setSelection( id, 0, start.index() );
2326 } else { 2431 } else {
2327 c.parag()->setSelection( id, 0, c.parag()->length() - 1 ); 2432 c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 );
2328 } 2433 }
@@ -2333,6 +2438,18 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2333 2438
2334 old = c; 2439 if ( noSelectionAnymore )
2335 c.gotoNextLetter();
2336 if ( old == c || noSelectionAnymore )
2337 break; 2440 break;
2441 // *ugle*hack optimization
2442 QTextParagraph *p = c.paragraph();
2443 if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) {
2444 c.gotoNextLetter();
2445 if ( p == lastParagraph() && c.atParagEnd() )
2446 break;
2447 } else {
2448 if ( p->document()->parent() )
2449 do {
2450 c.gotoNextLetter();
2451 } while ( c.paragraph() == p );
2452 else
2453 c.setParagraph( p->next() );
2454 }
2338 } 2455 }
@@ -2340,3 +2457,3 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2340 if ( !sel.swapped ) 2457 if ( !sel.swapped )
2341 sel.startCursor.parag()->setSelection( id, sel.startCursor.index(), sel.startCursor.parag()->length() - 1 ); 2458 sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 );
2342 2459
@@ -2344,3 +2461,3 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2344 sel.endCursor = end; 2461 sel.endCursor = end;
2345 if ( sel.startCursor.parag() == sel.endCursor.parag() ) 2462 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
2346 sel.swapped = sel.startCursor.index() > sel.endCursor.index(); 2463 sel.swapped = sel.startCursor.index() > sel.endCursor.index();
@@ -2360,3 +2477,3 @@ void QTextDocument::selectAll( int id )
2360 2477
2361 c.setParag( fParag ); 2478 c.setParagraph( fParag );
2362 c.setIndex( 0 ); 2479 c.setIndex( 0 );
@@ -2364,3 +2481,3 @@ void QTextDocument::selectAll( int id )
2364 2481
2365 c.setParag( lParag ); 2482 c.setParagraph( lParag );
2366 c.setIndex( lParag->length() - 1 ); 2483 c.setIndex( lParag->length() - 1 );
@@ -2368,13 +2485,7 @@ void QTextDocument::selectAll( int id )
2368 2485
2369 QTextParag *p = fParag; 2486 selections.insert( id, sel );
2487
2488 QTextParagraph *p = fParag;
2370 while ( p ) { 2489 while ( p ) {
2371 p->setSelection( id, 0, p->length() - 1 ); 2490 p->setSelection( id, 0, p->length() - 1 );
2372 for ( int i = 0; i < (int)p->length(); ++i ) {
2373 if ( p->at( i )->isCustom() && p->at( i )->customItem()->isNested() ) {
2374 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2375 QPtrList<QTextTableCell> tableCells = t->tableCells();
2376 for ( QTextTableCell *c = tableCells.first(); c; c = tableCells.next() )
2377 c->richText()->selectAll( id );
2378 }
2379 }
2380 p = p->next(); 2491 p = p->next();
@@ -2382,3 +2493,4 @@ void QTextDocument::selectAll( int id )
2382 2493
2383 selections.insert( id, sel ); 2494 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
2495 d->selectAll( id );
2384} 2496}
@@ -2387,68 +2499,17 @@ bool QTextDocument::removeSelection( int id )
2387{ 2499{
2388 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2500 if ( !selections.contains( id ) )
2389 if ( it == selections.end() )
2390 return FALSE; 2501 return FALSE;
2391 2502
2392 QTextDocumentSelection &sel = *it; 2503 QTextDocumentSelection &sel = selections[ id ];
2393
2394 if ( sel.startCursor == sel.endCursor ) {
2395 selections.remove( id );
2396 return TRUE;
2397 }
2398
2399 if ( !mightHaveCustomItems ) {
2400 QTextCursor start = sel.startCursor;
2401 QTextCursor end = sel.endCursor;
2402 if ( sel.swapped ) {
2403 start = sel.endCursor;
2404 end = sel.startCursor;
2405 }
2406 2504
2407 for ( QTextParag *p = start.parag(); p; p = p->next() ) { 2505 QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
2506 QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
2507 QTextParagraph* p = 0;
2508 while ( start != end ) {
2509 if ( p != start.paragraph() ) {
2510 p = start.paragraph();
2408 p->removeSelection( id ); 2511 p->removeSelection( id );
2409 if ( p == end.parag() )
2410 break;
2411 } 2512 }
2412 2513 start.gotoNextLetter();
2413 selections.remove( id );
2414 return TRUE;
2415 }
2416
2417 QTextCursor c( this );
2418 QTextCursor tmp = sel.startCursor;
2419 if ( sel.swapped )
2420 tmp = sel.endCursor;
2421 tmp.restoreState();
2422 c.setParag( tmp.parag() );
2423 QTextCursor old;
2424 bool hadStart = FALSE;
2425 bool hadEnd = FALSE;
2426 QTextParag *lastParag = 0;
2427 bool leftSelection = FALSE;
2428 bool inSelection = FALSE;
2429 sel.swapped = FALSE;
2430 for ( ;; ) {
2431 if ( c.parag() == sel.startCursor.parag() )
2432 hadStart = TRUE;
2433 if ( c.parag() == sel.endCursor.parag() )
2434 hadEnd = TRUE;
2435
2436 if ( inSelection &&
2437 ( c == sel.endCursor && hadStart || c == sel.startCursor && hadEnd ) )
2438 leftSelection = TRUE;
2439 else if ( !leftSelection && !inSelection && ( c.parag() == sel.startCursor.parag() || c.parag() == sel.endCursor.parag() ) )
2440 inSelection = TRUE;
2441
2442 bool noSelectionAnymore = leftSelection && !inSelection && !c.parag()->hasSelection( id ) && c.atParagEnd();
2443
2444 if ( lastParag != c.parag() )
2445 c.parag()->removeSelection( id );
2446
2447 old = c;
2448 lastParag = c.parag();
2449 c.gotoNextLetter();
2450 if ( old == c || noSelectionAnymore )
2451 break;
2452 } 2514 }
2453
2454 selections.remove( id ); 2515 selections.remove( id );
@@ -2457,5 +2518,4 @@ bool QTextDocument::removeSelection( int id )
2457 2518
2458QString QTextDocument::selectedText( int id, bool withCustom ) const 2519QString QTextDocument::selectedText( int id, bool asRichText ) const
2459{ 2520{
2460 // ######## TODO: look at textFormat() and return rich text or plain text (like the text() method!)
2461 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); 2521 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id );
@@ -2483,3 +2543,3 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2483 2543
2484 ### Fix this properly for 3.0.4. 2544 ### Fix this properly when refactoring
2485 */ 2545 */
@@ -2490,3 +2550,3 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2490 while ( c1.nestedDepth() && c2.nestedDepth() && 2550 while ( c1.nestedDepth() && c2.nestedDepth() &&
2491 c1.parag()->document() != c2.parag()->document() ) { 2551 c1.paragraph()->document() != c2.paragraph()->document() ) {
2492 c1.oneUp(); 2552 c1.oneUp();
@@ -2494,5 +2554,5 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2494 } 2554 }
2495 // do not trust sel_swapped with tables. Fix this properly for 3.0.4 as well 2555 // do not trust sel_swapped with tables. Fix this properly when refactoring as well
2496 if ( c1.parag()->paragId() > c2.parag()->paragId() || 2556 if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
2497 (c1.parag() == c2.parag() && c1.index() > c2.index() ) ) { 2557 (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) {
2498 QTextCursor tmp = c1; 2558 QTextCursor tmp = c1;
@@ -2504,6 +2564,18 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2504 2564
2565 if ( asRichText && !parent() ) {
2566 richTextExportStart = &c1;
2567 richTextExportEnd = &c2;
2505 2568
2506 if ( c1.parag() == c2.parag() ) { 2569 QString sel = richText();
2507 QString s; 2570 int from = sel.find( "<selstart/>" );
2508 QTextParag *p = c1.parag(); 2571 int to = sel.findRev( "<selend/>" );
2572 if ( from >= 0 && from <= to )
2573 sel = sel.mid( from, to - from );
2574 richTextExportStart = richTextExportEnd = 0;
2575 return sel;
2576 }
2577
2578 QString s;
2579 if ( c1.paragraph() == c2.paragraph() ) {
2580 QTextParagraph *p = c1.paragraph();
2509 int end = c2.index(); 2581 int end = c2.index();
@@ -2511,3 +2583,3 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2511 ++end; 2583 ++end;
2512 if ( !withCustom || !p->mightHaveCustomItems ) { 2584 if ( !p->mightHaveCustomItems ) {
2513 s += p->string()->toString().mid( c1.index(), end - c1.index() ); 2585 s += p->string()->toString().mid( c1.index(), end - c1.index() );
@@ -2529,37 +2601,43 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2529 } 2601 }
2530 return s; 2602 } else {
2531 } 2603 QTextParagraph *p = c1.paragraph();
2532 2604 int start = c1.index();
2533 QString s; 2605 while ( p ) {
2534 QTextParag *p = c1.parag(); 2606 int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
2535 int start = c1.index(); 2607 if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() )
2536 while ( p ) { 2608 ++end;
2537 int end = p == c2.parag() ? c2.index() : p->length() - 1; 2609 if ( !p->mightHaveCustomItems ) {
2538 if ( p == c2.parag() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) 2610 s += p->string()->toString().mid( start, end - start );
2539 ++end; 2611 if ( p != c2.paragraph() )
2540 if ( !withCustom || !p->mightHaveCustomItems ) { 2612 s += "\n";
2541 s += p->string()->toString().mid( start, end - start ); 2613 } else {
2542 if ( p != c2.parag() ) 2614 for ( int i = start; i < end; ++i ) {
2543 s += "\n"; 2615 if ( p->at( i )->isCustom() ) {
2544 } else { 2616 if ( p->at( i )->customItem()->isNested() ) {
2545 for ( int i = start; i < end; ++i ) { 2617 s += "\n";
2546 if ( p->at( i )->isCustom() ) { 2618 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2547 if ( p->at( i )->customItem()->isNested() ) { 2619 QPtrList<QTextTableCell> cells = t->tableCells();
2548 s += "\n"; 2620 for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
2549 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 2621 s += c->richText()->plainText() + "\n";
2550 QPtrList<QTextTableCell> cells = t->tableCells(); 2622 s += "\n";
2551 for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) 2623 }
2552 s += c->richText()->plainText() + "\n"; 2624 } else {
2553 s += "\n"; 2625 s += p->at( i )->c;
2554 } 2626 }
2555 } else {
2556 s += p->at( i )->c;
2557 } 2627 }
2558 } 2628 }
2629 start = 0;
2630 if ( p == c2.paragraph() )
2631 break;
2632 p = p->next();
2559 } 2633 }
2560 start = 0;
2561 if ( p == c2.parag() )
2562 break;
2563 p = p->next();
2564 } 2634 }
2635 // ### workaround for plain text export until we get proper
2636 // mime types: turn unicode line seperators into the more
2637 // widely understood \n. Makes copy and pasting code snipplets
2638 // from within Assistent possible
2639 QChar* uc = (QChar*) s.unicode();
2640 for ( uint ii = 0; ii < s.length(); ii++ )
2641 if ( uc[(int)ii] == QChar_linesep )
2642 uc[(int)ii] = QChar('\n');
2565 return s; 2643 return s;
@@ -2585,4 +2663,4 @@ void QTextDocument::setFormat( int id, QTextFormat *f, int flags )
2585 2663
2586 if ( c1.parag() == c2.parag() ) { 2664 if ( c1.paragraph() == c2.paragraph() ) {
2587 c1.parag()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); 2665 c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags );
2588 return; 2666 return;
@@ -2590,5 +2668,5 @@ void QTextDocument::setFormat( int id, QTextFormat *f, int flags )
2590 2668
2591 c1.parag()->setFormat( c1.index(), c1.parag()->length() - c1.index(), f, TRUE, flags ); 2669 c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags );
2592 QTextParag *p = c1.parag()->next(); 2670 QTextParagraph *p = c1.paragraph()->next();
2593 while ( p && p != c2.parag() ) { 2671 while ( p && p != c2.paragraph() ) {
2594 p->setFormat( 0, p->length(), f, TRUE, flags ); 2672 p->setFormat( 0, p->length(), f, TRUE, flags );
@@ -2596,13 +2674,3 @@ void QTextDocument::setFormat( int id, QTextFormat *f, int flags )
2596 } 2674 }
2597 c2.parag()->setFormat( 0, c2.index(), f, TRUE, flags ); 2675 c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags );
2598}
2599
2600void QTextDocument::copySelectedText( int id )
2601{
2602#ifndef QT_NO_CLIPBOARD
2603 if ( !hasSelection( id ) )
2604 return;
2605
2606 QApplication::clipboard()->setText( selectedText( id ) );
2607#endif
2608} 2676}
@@ -2634,4 +2702,4 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2634 2702
2635 if ( c1.parag() == c2.parag() ) { 2703 if ( c1.paragraph() == c2.paragraph() ) {
2636 c1.parag()->remove( c1.index(), c2.index() - c1.index() ); 2704 c1.paragraph()->remove( c1.index(), c2.index() - c1.index() );
2637 return; 2705 return;
@@ -2639,4 +2707,4 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2639 2707
2640 if ( c1.parag() == fParag && c1.index() == 0 && 2708 if ( c1.paragraph() == fParag && c1.index() == 0 &&
2641 c2.parag() == lParag && c2.index() == lParag->length() - 1 ) 2709 c2.paragraph() == lParag && c2.index() == lParag->length() - 1 )
2642 cursor->setValid( FALSE ); 2710 cursor->setValid( FALSE );
@@ -2644,3 +2712,3 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2644 bool didGoLeft = FALSE; 2712 bool didGoLeft = FALSE;
2645 if ( c1.index() == 0 && c1.parag() != fParag ) { 2713 if ( c1.index() == 0 && c1.paragraph() != fParag ) {
2646 cursor->gotoPreviousLetter(); 2714 cursor->gotoPreviousLetter();
@@ -2650,7 +2718,7 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2650 2718
2651 c1.parag()->remove( c1.index(), c1.parag()->length() - 1 - c1.index() ); 2719 c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() );
2652 QTextParag *p = c1.parag()->next(); 2720 QTextParagraph *p = c1.paragraph()->next();
2653 int dy = 0; 2721 int dy = 0;
2654 QTextParag *tmp; 2722 QTextParagraph *tmp;
2655 while ( p && p != c2.parag() ) { 2723 while ( p && p != c2.paragraph() ) {
2656 tmp = p->next(); 2724 tmp = p->next();
@@ -2660,3 +2728,3 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2660 } 2728 }
2661 c2.parag()->remove( 0, c2.index() ); 2729 c2.paragraph()->remove( 0, c2.index() );
2662 while ( p ) { 2730 while ( p ) {
@@ -2668,3 +2736,3 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2668 2736
2669 c1.parag()->join( c2.parag() ); 2737 c1.paragraph()->join( c2.paragraph() );
2670 2738
@@ -2681,10 +2749,10 @@ void QTextDocument::indentSelection( int id )
2681 QTextDocumentSelection sel = *it; 2749 QTextDocumentSelection sel = *it;
2682 QTextParag *startParag = sel.startCursor.parag(); 2750 QTextParagraph *startParag = sel.startCursor.paragraph();
2683 QTextParag *endParag = sel.endCursor.parag(); 2751 QTextParagraph *endParag = sel.endCursor.paragraph();
2684 if ( sel.endCursor.parag()->paragId() < sel.startCursor.parag()->paragId() ) { 2752 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
2685 endParag = sel.startCursor.parag(); 2753 endParag = sel.startCursor.paragraph();
2686 startParag = sel.endCursor.parag(); 2754 startParag = sel.endCursor.paragraph();
2687 } 2755 }
2688 2756
2689 QTextParag *p = startParag; 2757 QTextParagraph *p = startParag;
2690 while ( p && p != endParag ) { 2758 while ( p && p != endParag ) {
@@ -2710,67 +2778,57 @@ QTextCursor *QTextDocument::redo( QTextCursor *c )
2710 2778
2711bool QTextDocument::find( const QString &expr, bool cs, bool wo, bool forward, 2779bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward )
2712 int *parag, int *index, QTextCursor *cursor )
2713{ 2780{
2714 QTextParag *p = forward ? fParag : lParag; 2781 removeSelection( Standard );
2715 if ( parag ) 2782 QTextParagraph *p = 0;
2716 p = paragAt( *parag ); 2783 QString expr = e;
2717 else if ( cursor ) 2784 // if we search for 'word only' than we have to be sure that
2718 p = cursor->parag(); 2785 // the expression contains no space or punct character at the
2719 bool first = TRUE; 2786 // beginning or in the end. Otherwise we would run into a
2720 2787 // endlessloop.
2721 while ( p ) { 2788 if ( wo ) {
2722 QString s = p->string()->toString(); 2789 for ( ;; ) {
2723 s.remove( s.length() - 1, 1 ); // get rid of trailing space 2790 if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() )
2724 int start = forward ? 0 : s.length() - 1; 2791 expr = expr.right( expr.length() - 1 );
2725 if ( first && index ) 2792 else
2726 start = *index; 2793 break;
2727 else if ( first )
2728 start = cursor->index();
2729 if ( !forward && first ) {
2730 start -= expr.length() + 1;
2731 if ( start < 0 ) {
2732 first = FALSE;
2733 p = p->prev();
2734 continue;
2735 }
2736 } 2794 }
2737 first = FALSE;
2738
2739 for ( ;; ) { 2795 for ( ;; ) {
2740 int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); 2796 if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() )
2741 if ( res == -1 ) 2797 expr = expr.left( expr.length() - 1 );
2798 else
2742 break; 2799 break;
2743 2800 }
2744 bool ok = TRUE; 2801 }
2745 if ( wo ) { 2802 for (;;) {
2803 if ( p != cursor.paragraph() ) {
2804 p = cursor.paragraph();
2805 QString s = cursor.paragraph()->string()->toString();
2806 int start = cursor.index();
2807 for ( ;; ) {
2808 int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs );
2746 int end = res + expr.length(); 2809 int end = res + expr.length();
2747 if ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && 2810 if ( res == -1 || ( !forward && start < end ) )
2748 ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) )
2749 ok = TRUE;
2750 else
2751 ok = FALSE;
2752 }
2753 if ( ok ) {
2754 cursor->setParag( p );
2755 cursor->setIndex( res );
2756 setSelectionStart( Standard, cursor );
2757 cursor->setIndex( res + expr.length() );
2758 setSelectionEnd( Standard, cursor );
2759 if ( parag )
2760 *parag = p->paragId();
2761 if ( index )
2762 *index = res;
2763 return TRUE;
2764 }
2765 if ( forward ) {
2766 start = res + 1;
2767 } else {
2768 if ( res == 0 )
2769 break; 2811 break;
2770 start = res - 1; 2812 if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) &&
2813 ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) {
2814 removeSelection( Standard );
2815 cursor.setIndex( forward ? end : res );
2816 setSelectionStart( Standard, cursor );
2817 cursor.setIndex( forward ? res : end );
2818 setSelectionEnd( Standard, cursor );
2819 return TRUE;
2820 }
2821 start = res + (forward ? 1 : -1);
2771 } 2822 }
2772 } 2823 }
2773 p = forward ? p->next() : p->prev(); 2824 if ( forward ) {
2825 if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () )
2826 break;
2827 cursor.gotoNextLetter();
2828 } else {
2829 if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() )
2830 break;
2831 cursor.gotoPreviousLetter();
2832 }
2774 } 2833 }
2775
2776 return FALSE; 2834 return FALSE;
@@ -2781,9 +2839,4 @@ void QTextDocument::setTextFormat( Qt::TextFormat f )
2781 txtFormat = f; 2839 txtFormat = f;
2782 if ( txtFormat == Qt::RichText && fParag && fParag == lParag && fParag->length() <= 1 ) { 2840 if ( fParag == lParag && fParag->length() <= 1 )
2783 QPtrVector<QStyleSheetItem> v = fParag->styleSheetItems(); 2841 fParag->rtext = ( f == Qt::RichText );
2784 v.resize( v.size() + 1 );
2785 v.insert( v.size() - 1, styleSheet()->item( "p" ) );
2786 fParag->setStyleSheetItems( v );
2787 }
2788
2789} 2842}
@@ -2802,13 +2855,13 @@ bool QTextDocument::inSelection( int selId, const QPoint &pos ) const
2802 QTextDocumentSelection sel = *it; 2855 QTextDocumentSelection sel = *it;
2803 QTextParag *startParag = sel.startCursor.parag(); 2856 QTextParagraph *startParag = sel.startCursor.paragraph();
2804 QTextParag *endParag = sel.endCursor.parag(); 2857 QTextParagraph *endParag = sel.endCursor.paragraph();
2805 if ( sel.startCursor.parag() == sel.endCursor.parag() && 2858 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
2806 sel.startCursor.parag()->selectionStart( selId ) == sel.endCursor.parag()->selectionEnd( selId ) ) 2859 sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) )
2807 return FALSE; 2860 return FALSE;
2808 if ( sel.endCursor.parag()->paragId() < sel.startCursor.parag()->paragId() ) { 2861 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
2809 endParag = sel.startCursor.parag(); 2862 endParag = sel.startCursor.paragraph();
2810 startParag = sel.endCursor.parag(); 2863 startParag = sel.endCursor.paragraph();
2811 } 2864 }
2812 2865
2813 QTextParag *p = startParag; 2866 QTextParagraph *p = startParag;
2814 while ( p ) { 2867 while ( p ) {
@@ -2857,3 +2910,3 @@ void QTextDocument::doLayout( QPainter *p, int w )
2857 vw = w; 2910 vw = w;
2858 QTextParag *parag = fParag; 2911 QTextParagraph *parag = fParag;
2859 while ( parag ) { 2912 while ( parag ) {
@@ -2870,14 +2923,6 @@ QPixmap *QTextDocument::bufferPixmap( const QSize &s )
2870{ 2923{
2871 if ( !buf_pixmap ) { 2924 if ( !buf_pixmap )
2872 int w = QABS( s.width() ); 2925 buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) );
2873 int h = QABS( s.height() ); 2926 else if ( buf_pixmap->size() != s )
2874 buf_pixmap = new QPixmap( w, h ); 2927 buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) );
2875 } else {
2876 if ( buf_pixmap->width() < s.width() ||
2877 buf_pixmap->height() < s.height() ) {
2878 buf_pixmap->resize( QMAX( s.width(), buf_pixmap->width() ),
2879 QMAX( s.height(), buf_pixmap->height() ) );
2880 }
2881 }
2882
2883 return buf_pixmap; 2928 return buf_pixmap;
@@ -2887,3 +2932,3 @@ void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg,
2887{ 2932{
2888 if ( !firstParag() ) 2933 if ( !firstParagraph() )
2889 return; 2934 return;
@@ -2896,17 +2941,6 @@ void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg,
2896 2941
2897 if ( formatCollection()->defaultFormat()->color() != cg.text() ) { 2942 if ( formatCollection()->defaultFormat()->color() != cg.text() )
2898 QDict<QTextFormat> formats = formatCollection()->dict(); 2943 setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
2899 QDictIterator<QTextFormat> it( formats );
2900 while ( it.current() ) {
2901 if ( it.current() == formatCollection()->defaultFormat() ) {
2902 ++it;
2903 continue;
2904 }
2905 it.current()->setColor( cg.text() );
2906 ++it;
2907 }
2908 formatCollection()->defaultFormat()->setColor( cg.text() );
2909 }
2910 2944
2911 QTextParag *parag = firstParag(); 2945 QTextParagraph *parag = firstParagraph();
2912 while ( parag ) { 2946 while ( parag ) {
@@ -2934,3 +2968,3 @@ void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg,
2934 2968
2935void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, int cw, int ch, 2969void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch,
2936 QPixmap *&doubleBuffer, const QColorGroup &cg, 2970 QPixmap *&doubleBuffer, const QColorGroup &cg,
@@ -2967,19 +3001,7 @@ void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, i
2967 3001
2968 if ( useDoubleBuffer || is_printer( painter ) ) { 3002 if ( useDoubleBuffer || is_printer( painter ) )
2969 if ( !parag->backgroundColor() ) 3003 painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) );
2970 painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), 3004 else if ( cursor && cursor->paragraph() == parag )
2971 cg.brush( QColorGroup::Base ) ); 3005 painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
2972 else 3006 parag->backgroundBrush( cg ) );
2973 painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ),
2974 *parag->backgroundColor() );
2975 } else {
2976 if ( cursor && cursor->parag() == parag ) {
2977 if ( !parag->backgroundColor() )
2978 painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
2979 cg.brush( QColorGroup::Base ) );
2980 else
2981 painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
2982 *parag->backgroundColor() );
2983 }
2984 }
2985 3007
@@ -2997,7 +3019,9 @@ void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, i
2997 3019
2998 if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { 3020 if ( useDoubleBuffer ) {
2999 p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(), 3021 if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) {
3000 ( parag->document()->x() + parag->document()->width() ) - 3022 p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(),
3001 ( parag->rect().x() + parag->rect().width() ), 3023 ( parag->document()->x() + parag->document()->width() ) -
3002 parag->rect().height(), cg.brush( QColorGroup::Base ) ); 3024 ( parag->rect().x() + parag->rect().width() ),
3025 parag->rect().height(), cg.brush( QColorGroup::Base ) );
3026 }
3003 } 3027 }
@@ -3007,3 +3031,3 @@ void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, i
3007 3031
3008QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, 3032QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg,
3009 bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) 3033 bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged )
@@ -3018,7 +3042,5 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3018 3042
3019 if ( !firstParag() ) 3043 if ( !firstParagraph() )
3020 return 0; 3044 return 0;
3021 3045
3022 if ( drawCursor && cursor )
3023 tmpCursor = cursor;
3024 if ( cx < 0 && cy < 0 ) { 3046 if ( cx < 0 && cy < 0 ) {
@@ -3030,4 +3052,4 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3030 3052
3031 QTextParag *lastFormatted = 0; 3053 QTextParagraph *lastFormatted = 0;
3032 QTextParag *parag = firstParag(); 3054 QTextParagraph *parag = firstParagraph();
3033 3055
@@ -3036,2 +3058,3 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3036 3058
3059 bool fullWidthSelection = FALSE;
3037 while ( parag ) { 3060 while ( parag ) {
@@ -3041,16 +3064,8 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3041 3064
3042 if ( !parag->rect().intersects( QRect( cx, cy, cw, ch ) ) ) { 3065 QRect pr = parag->rect();
3043 QRect pr( parag->rect() ); 3066 if ( fullWidthSelection )
3044 pr.setWidth( parag->document()->width() ); 3067 pr.setWidth( parag->document()->width() );
3045 if ( pr.intersects( QRect( cx, cy, cw, ch ) ) ) 3068 if ( pr.y() > cy + ch )
3046 p->fillRect( pr.intersect( QRect( cx, cy, cw, ch ) ), cg.brush( QColorGroup::Base ) ); 3069 goto floating;
3047 if ( parag->rect().y() > cy + ch ) { 3070 if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) {
3048 tmpCursor = 0;
3049 goto floating;
3050 }
3051 parag = parag->next();
3052 continue;
3053 }
3054
3055 if ( !parag->hasChanged() && onlyChanged ) {
3056 parag = parag->next(); 3071 parag = parag->next();
@@ -3059,3 +3074,3 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3059 3074
3060 drawParag( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); 3075 drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged );
3061 parag = parag->next(); 3076 parag = parag->next();
@@ -3063,3 +3078,3 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3063 3078
3064 parag = lastParag(); 3079 parag = lastParagraph();
3065 3080
@@ -3067,3 +3082,3 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3067 if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { 3082 if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) {
3068 if ( !parag->document()->parent() ) { // !useDoubleBuffer 3083 if ( !parag->document()->parent() ) {
3069 p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), 3084 p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
@@ -3074,4 +3089,2 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3074 QRect cr( cx, cy, cw, ch ); 3089 QRect cr( cx, cy, cw, ch );
3075 // cr = cr.intersect( QRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
3076 // parag->document()->height() - ( parag->rect().y() + parag->rect().height() ) ) );
3077 flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); 3090 flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE );
@@ -3085,3 +3098,2 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3085 3098
3086 tmpCursor = 0;
3087 return lastFormatted; 3099 return lastFormatted;
@@ -3089,14 +3101,28 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3089 3101
3090void QTextDocument::setDefaultFont( const QFont &f ) 3102/*
3103 #### this function only sets the default font size in the format collection
3104 */
3105void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color )
3091{ 3106{
3092 int s = f.pointSize(); 3107 bool reformat = font != fCollection->defaultFormat()->font();
3093 bool usePixels = FALSE; 3108 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
3094 if ( s == -1 ) { 3109 d->setDefaultFormat( font, color );
3095 s = f.pixelSize(); 3110 fCollection->updateDefaultFormat( font, color, sheet_ );
3096 usePixels = TRUE; 3111
3112 if ( !reformat )
3113 return;
3114 tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
3115
3116 // invalidate paragraphs and custom items
3117 QTextParagraph *p = fParag;
3118 while ( p ) {
3119 p->invalidate( 0 );
3120 for ( int i = 0; i < p->length() - 1; ++i )
3121 if ( p->at( i )->isCustom() )
3122 p->at( i )->customItem()->invalidate();
3123 p = p->next();
3097 } 3124 }
3098 updateFontSizes( s, usePixels );
3099} 3125}
3100 3126
3101void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParag *p ) 3127void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p )
3102{ 3128{
@@ -3110,3 +3136,3 @@ void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParag *p )
3110 3136
3111void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParag *p ) 3137void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p )
3112{ 3138{
@@ -3145,3 +3171,3 @@ bool QTextDocument::focusNextPrevChild( bool next )
3145 if ( next ) { 3171 if ( next ) {
3146 QTextParag *p = focusIndicator.parag; 3172 QTextParagraph *p = focusIndicator.parag;
3147 int index = focusIndicator.start + focusIndicator.len; 3173 int index = focusIndicator.start + focusIndicator.len;
@@ -3204,3 +3230,3 @@ bool QTextDocument::focusNextPrevChild( bool next )
3204 } else { 3230 } else {
3205 QTextParag *p = focusIndicator.parag; 3231 QTextParagraph *p = focusIndicator.parag;
3206 int index = focusIndicator.start - 1; 3232 int index = focusIndicator.start - 1;
@@ -3284,3 +3310,3 @@ int QTextDocument::length() const
3284 int l = 0; 3310 int l = 0;
3285 QTextParag *p = fParag; 3311 QTextParagraph *p = fParag;
3286 while ( p ) { 3312 while ( p ) {
@@ -3387,9 +3413,14 @@ void QTextString::insert( int index, const QString &s, QTextFormat *f )
3387{ 3413{
3414 insert( index, s.unicode(), s.length(), f );
3415}
3416
3417void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f )
3418{
3388 int os = data.size(); 3419 int os = data.size();
3389 data.resize( data.size() + s.length() ); 3420 data.resize( data.size() + len );
3390 if ( index < os ) { 3421 if ( index < os ) {
3391 memmove( data.data() + index + s.length(), data.data() + index, 3422 memmove( data.data() + index + len, data.data() + index,
3392 sizeof( QTextStringChar ) * ( os - index ) ); 3423 sizeof( QTextStringChar ) * ( os - index ) );
3393 } 3424 }
3394 for ( int i = 0; i < (int)s.length(); ++i ) { 3425 for ( int i = 0; i < len; ++i ) {
3395 data[ (int)index + i ].x = 0; 3426 data[ (int)index + i ].x = 0;
@@ -3400,3 +3431,3 @@ void QTextString::insert( int index, const QString &s, QTextFormat *f )
3400 data[ (int)index + i ].startOfRun = 0; 3431 data[ (int)index + i ].startOfRun = 0;
3401 data[ (int)index + i ].c = s[ i ]; 3432 data[ (int)index + i ].c = unicode[i];
3402 data[ (int)index + i ].setFormat( f ); 3433 data[ (int)index + i ].setFormat( f );
@@ -3411,3 +3442,3 @@ QTextString::~QTextString()
3411 3442
3412void QTextString::insert( int index, QTextStringChar *c ) 3443void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat )
3413{ 3444{
@@ -3425,2 +3456,4 @@ void QTextString::insert( int index, QTextStringChar *c )
3425 data[ (int)index ].type = QTextStringChar::Regular; 3456 data[ (int)index ].type = QTextStringChar::Regular;
3457 if ( doAddRefFormat && c->format() )
3458 c->format()->addRef();
3426 data[ (int)index ].setFormat( c->format() ); 3459 data[ (int)index ].setFormat( c->format() );
@@ -3547,30 +3580,25 @@ void QTextDocument::setStyleSheet( QStyleSheet *s )
3547 sheet_ = s; 3580 sheet_ = s;
3548 fCollection->setStyleSheet( s ); 3581 list_tm = list_bm = par_tm = par_bm = 12;
3549 updateStyles(); 3582 list_lm = 40;
3550} 3583 li_tm = li_bm = 0;
3551 3584 QStyleSheetItem* item = s->item( "ol" );
3552void QTextDocument::updateStyles() 3585 if ( item ) {
3553{ 3586 list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3554 invalidate(); 3587 list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3555 if ( par ) 3588 list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft ));
3556 underlLinks = par->underlLinks; 3589 }
3557 fCollection->updateStyles(); 3590 if ( (item = s->item( "li" ) ) ) {
3558 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 3591 li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3559 d->updateStyles(); 3592 li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3560} 3593 }
3561 3594 if ( (item = s->item( "p" ) ) ) {
3562void QTextDocument::updateFontSizes( int base, bool usePixels ) 3595 par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3563{ 3596 par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3564 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 3597 }
3565 d->updateFontSizes( base, usePixels );
3566 invalidate();
3567 fCollection->updateFontSizes( base, usePixels );
3568} 3598}
3569 3599
3570void QTextDocument::updateFontAttributes( const QFont &f, const QFont &old ) 3600void QTextDocument::setUnderlineLinks( bool b ) {
3571{ 3601 underlLinks = b;
3572 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 3602 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
3573 d->updateFontAttributes( f, old ); 3603 d->setUnderlineLinks( b );
3574 invalidate();
3575 fCollection->updateFontAttributes( f, old );
3576} 3604}
@@ -3580,9 +3608,9 @@ void QTextStringChar::setFormat( QTextFormat *f )
3580 if ( type == Regular ) { 3608 if ( type == Regular ) {
3581 d.format = f; 3609 d.format = f;
3582 } else { 3610 } else {
3583 if ( !d.custom ) { 3611 if ( !d.custom ) {
3584 d.custom = new CustomData; 3612 d.custom = new CustomData;
3585 d.custom->custom = 0; 3613 d.custom->custom = 0;
3586 } 3614 }
3587 d.custom->format = f; 3615 d.custom->format = f;
3588 } 3616 }
@@ -3653,3 +3681,3 @@ int QTextString::width( int idx ) const
3653 QTextStringChar *c = &at( idx ); 3681 QTextStringChar *c = &at( idx );
3654 if ( c->c.unicode() == 0xad ) 3682 if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 )
3655 return 0; 3683 return 0;
@@ -3701,38 +3729,20 @@ QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const
3701 3729
3702QTextStringChar *QTextStringChar::clone() const
3703{
3704 QTextStringChar *chr = new QTextStringChar;
3705 chr->c = c;
3706 chr->x = 0;
3707 chr->lineStart = 0;
3708 chr->rightToLeft = 0;
3709 chr->d.format = 0;
3710 chr->type = QTextStringChar::Regular;
3711 chr->setFormat( format() );
3712 if ( chr->format() )
3713 chr->format()->addRef();
3714 return chr;
3715}
3716
3717// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3730// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3718 3731
3719QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool updateIds ) 3732QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds )
3720 : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), align( 0 ),mSelections( 0 ), 3733 : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ),
3721 mStyleSheetItemsVec( 0 ), mFloatingItems( 0 ), listS( QStyleSheetItem::ListDisc ), 3734 changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE),
3722 numSubParag( -1 ), tm( -1 ), bm( -1 ), lm( -1 ), rm( -1 ), flm( -1 ), 3735 lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE),
3723 tArray(0), tabStopWidth(0), eData( 0 ) 3736 mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE),
3724{ 3737 align( 0 ),mSelections( 0 ),
3725 listS = QStyleSheetItem::ListDisc; 3738 mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ),
3726 if ( ! (hasdoc = docOrPseudo != 0 ) ) 3739 utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ),
3727 docOrPseudo = new QTextParagPseudoDocument; 3740 tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 )
3741{
3742 lstyle = QStyleSheetItem::ListDisc;
3743 if ( !hasdoc )
3744 docOrPseudo = new QTextParagraphPseudoDocument;
3728 bgcol = 0; 3745 bgcol = 0;
3729 breakable = TRUE;
3730 isBr = FALSE;
3731 movedDown = FALSE;
3732 mightHaveCustomItems = FALSE;
3733 visible = TRUE;
3734 list_val = -1; 3746 list_val = -1;
3735 newLinesAllowed = FALSE; 3747 QTextFormat* defFormat = formatCollection()->defaultFormat();
3736 lastInFrame = FALSE;
3737 defFormat = formatCollection()->defaultFormat();
3738 if ( !hasdoc ) { 3748 if ( !hasdoc ) {
@@ -3741,6 +3751,2 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3741 } 3751 }
3742#if defined(PARSER_DEBUG)
3743 qDebug( debug_indent + "new QTextParag" );
3744#endif
3745 fullWidth = TRUE;
3746 3752
@@ -3753,10 +3759,7 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3753 if ( !p && hasdoc ) 3759 if ( !p && hasdoc )
3754 document()->setFirstParag( this ); 3760 document()->setFirstParagraph( this );
3755 if ( !n && hasdoc ) 3761 if ( !n && hasdoc )
3756 document()->setLastParag( this ); 3762 document()->setLastParagraph( this );
3757 3763
3758 changed = FALSE;
3759 firstFormat = TRUE;
3760 state = -1; 3764 state = -1;
3761 needPreProcess = FALSE;
3762 3765
@@ -3767,7 +3770,6 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3767 if ( n && updateIds ) { 3770 if ( n && updateIds ) {
3768 QTextParag *s = n; 3771 QTextParagraph *s = n;
3769 while ( s ) { 3772 while ( s ) {
3770 s->id = s->p->id + 1; 3773 s->id = s->p->id + 1;
3771 s->numSubParag = -1; 3774 s->invalidateStyleCache();
3772 s->lm = s->rm = s->tm = s->bm = -1, s->flm = -1;
3773 s = s->n; 3775 s = s->n;
@@ -3775,3 +3777,2 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3775 } 3777 }
3776 firstPProcess = TRUE;
3777 3778
@@ -3781,3 +3782,3 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3781 3782
3782QTextParag::~QTextParag() 3783QTextParagraph::~QTextParagraph()
3783{ 3784{
@@ -3798,3 +3799,3 @@ QTextParag::~QTextParag()
3798 delete eData; 3799 delete eData;
3799 QMap<int, QTextParagLineStart*>::Iterator it = lineStarts.begin(); 3800 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
3800 for ( ; it != lineStarts.end(); ++it ) 3801 for ( ; it != lineStarts.end(); ++it )
@@ -3805,4 +3806,2 @@ QTextParag::~QTextParag()
3805 delete mFloatingItems; 3806 delete mFloatingItems;
3806 if ( mStyleSheetItemsVec )
3807 delete mStyleSheetItemsVec;
3808 if ( p ) 3807 if ( p )
@@ -3813,3 +3812,3 @@ QTextParag::~QTextParag()
3813 3812
3814void QTextParag::setNext( QTextParag *s ) 3813void QTextParagraph::setNext( QTextParagraph *s )
3815{ 3814{
@@ -3817,6 +3816,6 @@ void QTextParag::setNext( QTextParag *s )
3817 if ( !n && hasdoc ) 3816 if ( !n && hasdoc )
3818 document()->setLastParag( this ); 3817 document()->setLastParagraph( this );
3819} 3818}
3820 3819
3821void QTextParag::setPrev( QTextParag *s ) 3820void QTextParagraph::setPrev( QTextParagraph *s )
3822{ 3821{
@@ -3824,6 +3823,6 @@ void QTextParag::setPrev( QTextParag *s )
3824 if ( !p && hasdoc ) 3823 if ( !p && hasdoc )
3825 document()->setFirstParag( this ); 3824 document()->setFirstParagraph( this );
3826} 3825}
3827 3826
3828void QTextParag::invalidate( int chr ) 3827void QTextParagraph::invalidate( int chr )
3829{ 3828{
@@ -3837,12 +3836,24 @@ void QTextParag::invalidate( int chr )
3837 } 3836 }
3838 lm = rm = bm = tm = flm = -1; 3837 invalidateStyleCache();
3839} 3838}
3840 3839
3841void QTextParag::insert( int index, const QString &s ) 3840void QTextParagraph::invalidateStyleCache()
3841{
3842 if ( list_val < 0 )
3843 list_val = -1;
3844}
3845
3846
3847void QTextParagraph::insert( int index, const QString &s )
3848{
3849 insert( index, s.unicode(), s.length() );
3850}
3851
3852void QTextParagraph::insert( int index, const QChar *unicode, int len )
3842{ 3853{
3843 if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) 3854 if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() )
3844 str->insert( index, s, 3855 str->insert( index, unicode, len,
3845 document()->preProcessor()->format( QTextPreProcessor::Standard ) ); 3856 document()->preProcessor()->format( QTextPreProcessor::Standard ) );
3846 else 3857 else
3847 str->insert( index, s, formatCollection()->defaultFormat() ); 3858 str->insert( index, unicode, len, formatCollection()->defaultFormat() );
3848 invalidate( index ); 3859 invalidate( index );
@@ -3851,3 +3862,3 @@ void QTextParag::insert( int index, const QString &s )
3851 3862
3852void QTextParag::truncate( int index ) 3863void QTextParagraph::truncate( int index )
3853{ 3864{
@@ -3858,3 +3869,3 @@ void QTextParag::truncate( int index )
3858 3869
3859void QTextParag::remove( int index, int len ) 3870void QTextParagraph::remove( int index, int len )
3860{ 3871{
@@ -3873,3 +3884,3 @@ void QTextParag::remove( int index, int len )
3873 3884
3874void QTextParag::join( QTextParag *s ) 3885void QTextParagraph::join( QTextParagraph *s )
3875{ 3886{
@@ -3880,3 +3891,3 @@ void QTextParag::join( QTextParag *s )
3880 else if ( hasdoc ) 3891 else if ( hasdoc )
3881 document()->setLastParag( this ); 3892 document()->setLastParagraph( this );
3882 3893
@@ -3898,2 +3909,6 @@ void QTextParag::join( QTextParag *s )
3898 s->str->at( i ).loseCustomItem(); 3909 s->str->at( i ).loseCustomItem();
3910 if ( hasdoc ) {
3911 document()->unregisterCustomItem( item, s );
3912 document()->registerCustomItem( item, this );
3913 }
3899 } 3914 }
@@ -3916,3 +3931,4 @@ void QTextParag::join( QTextParag *s )
3916 if ( n ) { 3931 if ( n ) {
3917 QTextParag *s = n; 3932 QTextParagraph *s = n;
3933 s->invalidate( 0 );
3918 while ( s ) { 3934 while ( s ) {
@@ -3922,2 +3938,3 @@ void QTextParag::join( QTextParag *s )
3922 s->changed = TRUE; 3938 s->changed = TRUE;
3939 s->invalidateStyleCache();
3923 s = s->n; 3940 s = s->n;
@@ -3929,3 +3946,3 @@ void QTextParag::join( QTextParag *s )
3929 3946
3930void QTextParag::move( int &dy ) 3947void QTextParagraph::move( int &dy )
3931{ 3948{
@@ -3953,3 +3970,3 @@ void QTextParag::move( int &dy )
3953 3970
3954void QTextParag::format( int start, bool doMove ) 3971void QTextParagraph::format( int start, bool doMove )
3955{ 3972{
@@ -3968,3 +3985,2 @@ void QTextParag::format( int start, bool doMove )
3968 r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); 3985 r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) );
3969 r.setWidth( documentWidth() );
3970 if ( p ) 3986 if ( p )
@@ -3977,2 +3993,3 @@ void QTextParag::format( int start, bool doMove )
3977 3993
3994 r.setWidth( documentWidth() );
3978 if ( hasdoc && mFloatingItems ) { 3995 if ( hasdoc && mFloatingItems ) {
@@ -3985,3 +4002,3 @@ void QTextParag::format( int start, bool doMove )
3985 } 4002 }
3986 QMap<int, QTextParagLineStart*> oldLineStarts = lineStarts; 4003 QMap<int, QTextLineStart*> oldLineStarts = lineStarts;
3987 lineStarts.clear(); 4004 lineStarts.clear();
@@ -3993,3 +4010,3 @@ void QTextParag::format( int start, bool doMove )
3993 4010
3994 QMap<int, QTextParagLineStart*>::Iterator it = oldLineStarts.begin(); 4011 QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin();
3995 4012
@@ -3999,8 +4016,8 @@ void QTextParag::format( int start, bool doMove )
3999 QTextStringChar *c = 0; 4016 QTextStringChar *c = 0;
4000 // do not do this on mac, as the paragraph 4017 // do not do this on mac, as the paragraph
4001 // with has to be the full document width on mac as the selections 4018 // with has to be the full document width on mac as the selections
4002 // always extend completely to the right. This is a bit unefficient, 4019 // always extend completely to the right. This is a bit unefficient,
4003 // as this results in a bigger double buffer than needed but ok for 4020 // as this results in a bigger double buffer than needed but ok for
4004 // now. 4021 // now.
4005 if ( lineStarts.count() == 1 ) { //&& ( !doc || document()->flow()->isEmpty() ) ) { 4022 if ( lineStarts.count() == 1 ) {
4006 if ( !string()->isBidi() ) { 4023 if ( !string()->isBidi() ) {
@@ -4013,3 +4030,3 @@ void QTextParag::format( int start, bool doMove )
4013 4030
4014 if ( newLinesAllowed ) { 4031 if ( !hasdoc ) { // qt_format_text bounding rect handling
4015 it = lineStarts.begin(); 4032 it = lineStarts.begin();
@@ -4056,3 +4073,3 @@ void QTextParag::format( int start, bool doMove )
4056 int dy = ( r.y() + r.height() ) - n->r.y(); 4073 int dy = ( r.y() + r.height() ) - n->r.y();
4057 QTextParag *s = n; 4074 QTextParagraph *s = n;
4058 bool makeInvalid = p && p->lastInFrame; 4075 bool makeInvalid = p && p->lastInFrame;
@@ -4076,8 +4093,8 @@ void QTextParag::format( int start, bool doMove )
4076 4093
4077int QTextParag::lineHeightOfChar( int i, int *bl, int *y ) const 4094int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const
4078{ 4095{
4079 if ( !isValid() ) 4096 if ( !isValid() )
4080 ( (QTextParag*)this )->format(); 4097 ( (QTextParagraph*)this )->format();
4081 4098
4082 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.end(); 4099 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
4083 --it; 4100 --it;
@@ -4096,3 +4113,3 @@ int QTextParag::lineHeightOfChar( int i, int *bl, int *y ) const
4096 4113
4097 qWarning( "QTextParag::lineHeightOfChar: couldn't find lh for %d", i ); 4114 qWarning( "QTextParagraph::lineHeightOfChar: couldn't find lh for %d", i );
4098 return 15; 4115 return 15;
@@ -4100,9 +4117,9 @@ int QTextParag::lineHeightOfChar( int i, int *bl, int *y ) const
4100 4117
4101QTextStringChar *QTextParag::lineStartOfChar( int i, int *index, int *line ) const 4118QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const
4102{ 4119{
4103 if ( !isValid() ) 4120 if ( !isValid() )
4104 ( (QTextParag*)this )->format(); 4121 ( (QTextParagraph*)this )->format();
4105 4122
4106 int l = (int)lineStarts.count() - 1; 4123 int l = (int)lineStarts.count() - 1;
4107 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.end(); 4124 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
4108 --it; 4125 --it;
@@ -4122,3 +4139,3 @@ QTextStringChar *QTextParag::lineStartOfChar( int i, int *index, int *line ) con
4122 4139
4123 qWarning( "QTextParag::lineStartOfChar: couldn't find %d", i ); 4140 qWarning( "QTextParagraph::lineStartOfChar: couldn't find %d", i );
4124 return 0; 4141 return 0;
@@ -4126,6 +4143,6 @@ QTextStringChar *QTextParag::lineStartOfChar( int i, int *index, int *line ) con
4126 4143
4127int QTextParag::lines() const 4144int QTextParagraph::lines() const
4128{ 4145{
4129 if ( !isValid() ) 4146 if ( !isValid() )
4130 ( (QTextParag*)this )->format(); 4147 ( (QTextParagraph*)this )->format();
4131 4148
@@ -4134,9 +4151,9 @@ int QTextParag::lines() const
4134 4151
4135QTextStringChar *QTextParag::lineStartOfLine( int line, int *index ) const 4152QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const
4136{ 4153{
4137 if ( !isValid() ) 4154 if ( !isValid() )
4138 ( (QTextParag*)this )->format(); 4155 ( (QTextParagraph*)this )->format();
4139 4156
4140 if ( line >= 0 && line < (int)lineStarts.count() ) { 4157 if ( line >= 0 && line < (int)lineStarts.count() ) {
4141 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 4158 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
4142 while ( line-- > 0 ) 4159 while ( line-- > 0 )
@@ -4149,3 +4166,3 @@ QTextStringChar *QTextParag::lineStartOfLine( int line, int *index ) const
4149 4166
4150 qWarning( "QTextParag::lineStartOfLine: couldn't find %d", line ); 4167 qWarning( "QTextParagraph::lineStartOfLine: couldn't find %d", line );
4151 return 0; 4168 return 0;
@@ -4153,6 +4170,6 @@ QTextStringChar *QTextParag::lineStartOfLine( int line, int *index ) const
4153 4170
4154int QTextParag::leftGap() const 4171int QTextParagraph::leftGap() const
4155{ 4172{
4156 if ( !isValid() ) 4173 if ( !isValid() )
4157 ( (QTextParag*)this )->format(); 4174 ( (QTextParagraph*)this )->format();
4158 4175
@@ -4161,3 +4178,3 @@ int QTextParag::leftGap() const
4161 if ( str->isBidi() ) { 4178 if ( str->isBidi() ) {
4162 for ( int i = 1; i < str->length(); ++i ) 4179 for ( int i = 1; i < str->length()-1; ++i )
4163 x = QMIN(x, str->at(i).x); 4180 x = QMIN(x, str->at(i).x);
@@ -4166,3 +4183,3 @@ int QTextParag::leftGap() const
4166 4183
4167 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 4184 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
4168 while (line < (int)lineStarts.count()) { 4185 while (line < (int)lineStarts.count()) {
@@ -4176,3 +4193,3 @@ int QTextParag::leftGap() const
4176 4193
4177void QTextParag::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) 4194void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags )
4178{ 4195{
@@ -4214,5 +4231,5 @@ void QTextParag::setFormat( int index, int len, QTextFormat *f, bool useCollecti
4214 4231
4215void QTextParag::indent( int *oldIndent, int *newIndent ) 4232void QTextParagraph::indent( int *oldIndent, int *newIndent )
4216{ 4233{
4217 if ( !hasdoc || !document()->indent() || style() && style()->displayMode() != QStyleSheetItem::DisplayBlock ) { 4234 if ( !hasdoc || !document()->indent() || isListItem() ) {
4218 if ( oldIndent ) 4235 if ( oldIndent )
@@ -4228,3 +4245,3 @@ void QTextParag::indent( int *oldIndent, int *newIndent )
4228 4245
4229void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, 4246void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections,
4230 int clipx, int clipy, int clipw, int cliph ) 4247 int clipx, int clipy, int clipw, int cliph )
@@ -4233,72 +4250,64 @@ void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *c
4233 return; 4250 return;
4234 QTextStringChar *chr = at( 0 ); 4251 QTextStringChar *chr = 0;
4235 int i = 0; 4252 int i, y, h, baseLine, xstart, xend;
4236 int h = 0; 4253 i = y =h = baseLine = 0;
4237 int baseLine = 0, lastBaseLine = 0; 4254 QRect cursorRect;
4238 QTextStringChar *formatChar = 0; 4255 drawSelections &= ( mSelections != 0 );
4239 int lastY = -1; 4256 // macintosh full-width selection style
4240 int startX = 0; 4257 bool fullWidthStyle = FALSE;
4241 int bw = 0; 4258 int fullSelectionWidth = 0;
4242 int cy = 0; 4259 if ( drawSelections && fullWidthStyle )
4243 int curx = -1, cury = 0, curh = 0; 4260 fullSelectionWidth = (hasdoc ? document()->width() : r.width());
4244 bool lastDirection = chr->rightToLeft; 4261
4245 const int full_sel_width = (hasdoc ? document()->width() : r.width());
4246#if 0 // seems we don't need that anymore
4247 int tw = 0;
4248#endif
4249
4250 QString qstr = str->toString(); 4262 QString qstr = str->toString();
4251 // ### workaround so that \n are not drawn, actually this should be 4263 // ### workaround so that \n are not drawn, actually this should
4252 // fixed in QFont somewhere (under Windows you get ugly boxes 4264 // be fixed in QFont somewhere (under Windows you get ugly boxes
4253 // otherwise) 4265 // otherwise)
4254 QChar* uc = (QChar*) qstr.unicode(); 4266 QChar* uc = (QChar*) qstr.unicode();
4255 for ( uint ii = 0; ii < qstr.length(); ii++ ) { 4267 for ( uint ii = 0; ii < qstr.length(); ii++ )
4256 if ( uc[(int)ii]== '\n' ) 4268 if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' )
4257 uc[(int)ii] = 0x20; 4269 uc[(int)ii] = 0x20;
4258 }
4259
4260
4261 const int nSels = hasdoc ? document()->numSelections() : 1;
4262 QMemArray<int> selectionStarts( nSels );
4263 QMemArray<int> selectionEnds( nSels );
4264 if ( drawSelections ) {
4265 bool hasASelection = FALSE;
4266 for ( i = 0; i < nSels; ++i ) {
4267 if ( !hasSelection( i ) ) {
4268 selectionStarts[ i ] = -1;
4269 selectionEnds[ i ] = -1;
4270 } else {
4271 hasASelection = TRUE;
4272 selectionStarts[ i ] = selectionStart( i );
4273 int end = selectionEnd( i );
4274 if ( end == length() - 1 && n && n->hasSelection( i ) )
4275 end++;
4276 selectionEnds[ i ] = end;
4277 }
4278 }
4279 if ( !hasASelection )
4280 drawSelections = FALSE;
4281 }
4282 4270
4283 int line = -1; 4271 int line = -1;
4284 int cw;
4285 bool didListLabel = FALSE;
4286 int paintStart = 0; 4272 int paintStart = 0;
4287 int paintEnd = -1; 4273 int selection = -1;
4288 int lasth = 0;
4289 for ( i = 0; i < length(); i++ ) { 4274 for ( i = 0; i < length(); i++ ) {
4290 chr = at( i ); 4275 chr = at( i );
4291#if 0 // seems we don't need that anymore 4276
4292 if ( !str->isBidi() && is_printer( &painter ) ) { // ### fix our broken ps-printer 4277 // we flush at end of document
4293 if ( !chr->lineStart ) 4278 bool flush = i== length()-1;
4294 chr->x = QMAX( chr->x, tw ); 4279 bool selectionStateChanged = FALSE;
4295 else 4280 if ( !flush ) {
4296 tw = 0; 4281 QTextStringChar *nextchr = at( i+1 );
4282 // we flush at end of line
4283 flush |= nextchr->lineStart;
4284 // we flush on format changes
4285 flush |= ( nextchr->format() != chr->format() );
4286 // we flush on anchor changes
4287 flush |= ( nextchr->isAnchor() != chr->isAnchor() );
4288 // we flush on start of run
4289 flush |= nextchr->startOfRun;
4290 // we flush on bidi changes
4291 flush |= ( nextchr->rightToLeft != chr->rightToLeft );
4292 // we flush on tab
4293 flush |= ( chr->c == '\t' );
4294 // we flush on soft hypens
4295 flush |= ( chr->c.unicode() == 0xad );
4296 // we flush on custom items
4297 flush |= chr->isCustom();
4298 // we flush before custom items
4299 flush |= nextchr->isCustom();
4300 // when painting justified, we flush on spaces
4301 if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify )
4302 flush |= QTextFormatter::isBreakable( str, i );
4303 // we flush when the string is getting too long
4304 flush |= ( i - paintStart >= 256 );
4305 // we flush when the selection state changes
4306 if ( drawSelections ) {
4307 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin();
4308 it != mSelections->end(); ++it )
4309 selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 );
4310 flush |= selectionStateChanged;
4311 }
4297 } 4312 }
4298#endif
4299 cw = string()->width( i );
4300 if ( chr->c == '\t' && i < length() - 1 )
4301 cw = at( i + 1 )->x - chr->x + 1;
4302 if ( chr->c.unicode() == 0xad && i < length() - 1 )
4303 cw = 0;
4304 4313
@@ -4306,18 +4315,17 @@ void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *c
4306 if ( chr->lineStart ) { 4315 if ( chr->lineStart ) {
4307#if 0 // seems we don't need that anymore 4316 if (fullWidthStyle && drawSelections && selection >= 0)
4308 tw = 0; 4317 painter.fillRect( xend, y, fullSelectionWidth - xend, h,
4309#endif 4318 (selection == QTextDocument::Standard || !hasdoc) ?
4319 cg.color( QColorGroup::Highlight ) :
4320 document()->selectionColor( selection ) );
4310 ++line; 4321 ++line;
4311 lineInfo( line, cy, h, baseLine ); 4322 paintStart = i;
4312 lasth = h; 4323 lineInfo( line, y, h, baseLine );
4313 if ( clipy != -1 && cy > clipy - r.y() + cliph ) // outside clip area, leave 4324 if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave
4314 break; 4325 break;
4315 if ( lastBaseLine == 0 ) 4326 }
4316 lastBaseLine = baseLine;
4317 }
4318 4327
4319 // draw bullet list items 4328 // if this is the first line and we are a list item, draw the the bullet label
4320 if ( !didListLabel && line == 0 && style() && style()->displayMode() == QStyleSheetItem::DisplayListItem ) { 4329 if ( line == 0 && isListItem() )
4321 didListLabel = TRUE; 4330 drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg );
4322 drawLabel( &painter, chr->x, cy, 0, 0, baseLine, cg );
4323 } 4331 }
@@ -4325,140 +4333,75 @@ void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *c
4325 // check for cursor mark 4333 // check for cursor mark
4326 if ( cursor && this == cursor->parag() && i == cursor->index() ) { 4334 if ( cursor && this == cursor->paragraph() && i == cursor->index() ) {
4327 curx = cursor->x(); 4335 QTextStringChar *c = i == 0 ? chr : chr - 1;
4328 QTextStringChar *c = chr; 4336 cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(),
4329 if ( i > 0 ) 4337 1, c->format()->height() );
4330 --c;
4331 curh = c->format()->height();
4332 cury = cy + baseLine - c->format()->ascent();
4333 }
4334
4335 // first time - start again...
4336 if ( !formatChar || lastY == -1 ) {
4337 formatChar = chr;
4338 lastY = cy;
4339 startX = chr->x;
4340 if ( !chr->isCustom() && chr->c != '\n' )
4341 paintEnd = i;
4342 bw = cw;
4343 if ( !chr->isCustom() )
4344 continue;
4345 } 4338 }
4346 4339
4347 // check if selection state changed 4340 // check if we are in a selection and store which one it is
4348 bool selectionChange = FALSE; 4341 selection = -1;
4349 if ( drawSelections ) { 4342 if ( drawSelections ) {
4350 for ( int j = 0; j < nSels; ++j ) { 4343 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin();
4351 selectionChange = selectionStarts[ j ] == i || selectionEnds[ j ] == i; 4344 it != mSelections->end(); ++it )
4352 if ( selectionChange ) 4345 if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0
4346 // exclude the standard selection from printing
4347 && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) {
4348 selection = it.key();
4353 break; 4349 break;
4354 } 4350 }
4355 } 4351 }
4356 4352
4357 //if something (format, etc.) changed, draw what we have so far 4353 if ( flush ) { // something changed, draw what we have so far
4358 if ( ( ( ( alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify && at(paintEnd)->c.isSpace() ) || 4354 if ( chr->rightToLeft ) {
4359 lastDirection != (bool)chr->rightToLeft || 4355 xstart = chr->x;
4360 chr->startOfRun || 4356 xend = at( paintStart )->x + str->width( paintStart );
4361 lastY != cy || chr->format() != formatChar->format() || chr->isAnchor() != formatChar->isAnchor() ||
4362 ( paintEnd != -1 && at( paintEnd )->c =='\t' ) || chr->c == '\t' ||
4363 ( paintEnd != -1 && at( paintEnd )->c.unicode() == 0xad ) || chr->c.unicode() == 0xad ||
4364 selectionChange || chr->isCustom() ) ) {
4365 if ( paintStart <= paintEnd ) {
4366 // ### temporary hack until I get the new placement/shaping stuff working
4367 int x = startX;
4368 if ( ( alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify && paintEnd != -1 &&
4369 paintEnd > 1 && at( paintEnd )->c.isSpace() ) {
4370 int add = str->at(paintEnd).x - str->at(paintEnd-1).x - str->width(paintEnd-1);
4371 bw += ( lastDirection ? 0 : add );
4372 }
4373 drawParagString( painter, qstr, paintStart, paintEnd - paintStart + 1, x, lastY,
4374 lastBaseLine, bw, lasth, drawSelections,
4375 formatChar, i, selectionStarts, selectionEnds, cg, lastDirection );
4376 }
4377#if 0 // seems we don't need that anymore
4378 if ( !str->isBidi() && is_printer( &painter ) ) { // ### fix our broken ps-printer
4379 if ( !chr->lineStart ) {
4380 // ### the next line doesn't look 100% correct for arabic
4381 tw = startX + painter.fontMetrics().width( qstr.mid(paintStart, paintEnd - paintStart +1) );
4382 chr->x = QMAX( chr->x, tw );
4383 } else {
4384 tw = 0;
4385 }
4386 }
4387#endif
4388 if ( !chr->isCustom() ) {
4389 if ( chr->c != '\n' ) {
4390 paintStart = i;
4391 paintEnd = i;
4392 } else {
4393 paintStart = i+1;
4394 paintEnd = -1;
4395 }
4396 formatChar = chr;
4397 lastY = cy;
4398 startX = chr->x;
4399 bw = cw;
4400 } else { 4357 } else {
4401 if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) { 4358 xstart = at( paintStart )->x;
4402 chr->customItem()->draw( &painter, chr->x, cy, clipx - r.x(), clipy - r.y(), clipw, cliph, cg, 4359 if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart )
4403 nSels && selectionStarts[ 0 ] <= i && selectionEnds[ 0 ] >= i ); 4360 xend = str->at( i + 1 ).x;
4404 paintStart = i+1; 4361 else
4405 paintEnd = -1; 4362 xend = chr->x + str->width( i );
4406 formatChar = chr;
4407 lastY = cy;
4408 startX = chr->x + string()->width( i );
4409 bw = 0;
4410 } else {
4411 chr->customItem()->resize( chr->customItem()->width );
4412 paintStart = i+1;
4413 paintEnd = -1;
4414 formatChar = chr;
4415 lastY = cy;
4416 startX = chr->x + string()->width( i );
4417 bw = 0;
4418 }
4419 } 4363 }
4420 } else { 4364
4421 if ( chr->c != '\n' ) { 4365 if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) {
4422 if( chr->rightToLeft ) { 4366 if ( !chr->isCustom() )
4423 startX = chr->x; 4367 drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y,
4424 } 4368 baseLine, xend-xstart, h, selection,
4425 paintEnd = i; 4369 chr, cg, chr->rightToLeft );
4370 else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline )
4371 chr->customItem()->draw( &painter, chr->x, y,
4372 clipx == -1 ? clipx : (clipx - r.x()),
4373 clipy == -1 ? clipy : (clipy - r.y()),
4374 clipw, cliph, cg, selection >= 0 );
4426 } 4375 }
4427 bw += cw; 4376 paintStart = i+1;
4428 } 4377 }
4429 lastBaseLine = baseLine; 4378
4430 lasth = h;
4431 lastDirection = chr->rightToLeft;
4432 } 4379 }
4433 4380
4434 // if we are through the parag, but still have some stuff left to draw, draw it now 4381 if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections)
4435 if ( paintStart <= paintEnd ) { 4382 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin();
4436 bool selectionChange = FALSE; 4383 it != next()->mSelections->end(); ++it )
4437 if ( drawSelections ) { 4384 if (((*it).start) == 0) {
4438 for ( int j = 0; j < nSels; ++j ) { 4385 painter.fillRect( xend, y, fullSelectionWidth - xend, h,
4439 selectionChange = selectionStarts[ j ] == i || selectionEnds[ j ] == i; 4386 (selection == QTextDocument::Standard || !hasdoc) ?
4440 if ( selectionChange ) 4387 cg.color( QColorGroup::Highlight ) :
4441 break; 4388 document()->selectionColor( selection ) );
4389 break;
4442 } 4390 }
4443 }
4444 int x = startX;
4445 drawParagString( painter, qstr, paintStart, paintEnd-paintStart+1, x, lastY,
4446 lastBaseLine, bw, h, drawSelections,
4447 formatChar, i, selectionStarts, selectionEnds, cg, lastDirection );
4448 }
4449 4391
4450 // if we should draw a cursor, draw it now 4392 // time to draw the cursor
4451 if ( curx != -1 && cursor ) { 4393 const int cursor_extent = 4;
4452 painter.fillRect( QRect( curx, cury, 1, curh - lineSpacing() ), cg.color( QColorGroup::Text ) ); 4394 if ( !cursorRect.isNull() && cursor &&
4395 ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) {
4396 painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) );
4453 painter.save(); 4397 painter.save();
4454 if ( string()->isBidi() ) { 4398 if ( string()->isBidi() ) {
4455 const int d = 4;
4456 if ( at( cursor->index() )->rightToLeft ) { 4399 if ( at( cursor->index() )->rightToLeft ) {
4457 painter.setPen( Qt::black ); 4400 painter.setPen( Qt::black );
4458 painter.drawLine( curx, cury, curx - d / 2, cury + d / 2 ); 4401 painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4459 painter.drawLine( curx, cury + d, curx - d / 2, cury + d / 2 ); 4402 painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4460 } else { 4403 } else {
4461 painter.setPen( Qt::black ); 4404 painter.setPen( Qt::black );
4462 painter.drawLine( curx, cury, curx + d / 2, cury + d / 2 ); 4405 painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4463 painter.drawLine( curx, cury + d, curx + d / 2, cury + d / 2 ); 4406 painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4464 } 4407 }
@@ -4471,7 +4414,8 @@ void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *c
4471 4414
4472void QTextParag::drawParagString( QPainter &painter, const QString &s, int start, int len, int startX, 4415void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart,
4473 int lastY, int baseLine, int bw, int h, bool drawSelections, 4416 int y, int baseLine, int w, int h, int selection,
4474 QTextStringChar *formatChar, int i, const QMemArray<int> &selectionStarts, 4417 QTextStringChar *formatChar, const QColorGroup& cg,
4475 const QMemArray<int> &selectionEnds, const QColorGroup &cg, bool rightToLeft ) 4418 bool rightToLeft )
4476{ 4419{
4420 int i = start + len - 1;
4477 bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; 4421 bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE;
@@ -4501,15 +4445,8 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4501 4445
4502 if ( drawSelections ) { 4446 if ( selection >= 0 ) {
4503 const int nSels = hasdoc ? document()->numSelections() : 1; 4447 if ( !hasdoc || document()->invertSelectionText( selection ) )
4504 const int startSel = is_printer( 0 ) ? 1 : 0; 4448 painter.setPen( cg.color( QColorGroup::HighlightedText ) );
4505 for ( int j = startSel; j < nSels; ++j ) { 4449 painter.fillRect( xstart, y, w, h,
4506 if ( i > selectionStarts[ j ] && i <= selectionEnds[ j ] ) { 4450 (selection == QTextDocument::Standard || !hasdoc) ?
4507 if ( !hasdoc || document()->invertSelectionText( j ) ) 4451 cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) );
4508 painter.setPen( QPen( cg.color( QColorGroup::HighlightedText ) ) );
4509 if ( j == QTextDocument::Standard )
4510 painter.fillRect( startX, lastY, bw, h, cg.color( QColorGroup::Highlight ) );
4511 else
4512 painter.fillRect( startX, lastY, bw, h, hasdoc ? document()->selectionColor( j ) : cg.color( QColorGroup::Highlight ) );
4513 }
4514 }
4515 } 4452 }
@@ -4518,3 +4455,3 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4518 if ( format->vAlign() == QTextFormat::AlignNormal ) { 4455 if ( format->vAlign() == QTextFormat::AlignNormal ) {
4519 painter.drawText( startX, lastY + baseLine, str.mid( start ), len ); 4456 painter.drawText( xstart, y + baseLine, str.mid( start ), len );
4520#ifdef BIDI_DEBUG 4457#ifdef BIDI_DEBUG
@@ -4522,4 +4459,4 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4522 painter.setPen ( Qt::red ); 4459 painter.setPen ( Qt::red );
4523 painter.drawLine( startX, lastY, startX, lastY + baseLine ); 4460 painter.drawLine( xstart, y, xstart, y + baseLine );
4524 painter.drawLine( startX, lastY + baseLine/2, startX + 10, lastY + baseLine/2 ); 4461 painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 );
4525 int w = 0; 4462 int w = 0;
@@ -4529,4 +4466,4 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4529 painter.setPen ( Qt::blue ); 4466 painter.setPen ( Qt::blue );
4530 painter.drawLine( startX + w - 1, lastY, startX + w - 1, lastY + baseLine ); 4467 painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine );
4531 painter.drawLine( startX + w - 1, lastY + baseLine/2, startX + w - 1 - 10, lastY + baseLine/2 ); 4468 painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 );
4532 painter.restore(); 4469 painter.restore();
@@ -4540,4 +4477,4 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4540 painter.setFont( f ); 4477 painter.setFont( f );
4541 painter.drawText( startX, lastY + baseLine - ( painter.fontMetrics().height() / 2 ), 4478 painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ),
4542 str.mid( start ), len ); 4479 str.mid( start ), len );
4543 } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { 4480 } else if ( format->vAlign() == QTextFormat::AlignSubScript ) {
@@ -4549,3 +4486,3 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4549 painter.setFont( f ); 4486 painter.setFont( f );
4550 painter.drawText( startX, lastY + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); 4487 painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len );
4551 } 4488 }
@@ -4553,3 +4490,3 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4553 if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { 4490 if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) {
4554 painter.drawText( startX + bw, lastY + baseLine, "\xad" ); 4491 painter.drawText( xstart + w, y + baseLine, "\xad" );
4555 } 4492 }
@@ -4558,3 +4495,3 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4558 painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); 4495 painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) );
4559 painter.drawLine( startX, lastY + baseLine + 1, startX + bw, lastY + baseLine + 1 ); 4496 painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 );
4560 painter.restore(); 4497 painter.restore();
@@ -4570,3 +4507,3 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4570 document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { 4507 document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) {
4571 painter.drawWinFocusRect( QRect( startX, lastY, bw, h ) ); 4508 painter.drawWinFocusRect( QRect( xstart, y, w, h ) );
4572 } 4509 }
@@ -4575,6 +4512,4 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4575 4512
4576void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) 4513void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg )
4577{ 4514{
4578 if ( !style() )
4579 return;
4580 QRect r ( x, y, w, h ); 4515 QRect r ( x, y, w, h );
@@ -4583,15 +4518,7 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4583 p->save(); 4518 p->save();
4584 p->setPen( defFormat->color() ); 4519 QTextFormat *format = at( 0 )->format();
4585 4520 if ( format ) {
4586 QFont font2( defFormat->font() ); 4521 p->setPen( format->color() );
4587 if ( length() > 0 ) { 4522 p->setFont( format->font() );
4588 QTextFormat *format = at( 0 )->format();
4589 if ( format ) {
4590 if ( format->fontSizesInPixels() )
4591 font2.setPixelSize( at( 0 )->format()->font().pixelSize() );
4592 else
4593 font2.setPointSize( at( 0 )->format()->font().pointSize() );
4594 }
4595 } 4523 }
4596 p->setFont( font2 );
4597 QFontMetrics fm( p->fontMetrics() ); 4524 QFontMetrics fm( p->fontMetrics() );
@@ -4604,3 +4531,18 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4604 { 4531 {
4605 int n = numberOfSubParagraph(); 4532 if ( list_val == -1 ) { // uninitialised list value, calcluate the right one
4533 int depth = listDepth();
4534 list_val--;
4535 // ### evil, square and expensive. This needs to be done when formatting, not when painting
4536 QTextParagraph* s = prev();
4537 int depth_s;
4538 while ( s && (depth_s = s->listDepth()) >= depth ) {
4539 if ( depth_s == depth && s->isListItem() )
4540 list_val--;
4541 s = s->prev();
4542 }
4543 }
4544
4545 int n = list_val;
4546 if ( n < -1 )
4547 n = -n - 1;
4606 QString l; 4548 QString l;
@@ -4629,3 +4571,3 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4629 QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); 4571 QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size );
4630 p->fillRect( er , cg.brush( QColorGroup::Foreground ) ); 4572 p->fillRect( er , cg.brush( QColorGroup::Text ) );
4631 } 4573 }
@@ -4641,3 +4583,3 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4641 { 4583 {
4642 p->setBrush( cg.brush( QColorGroup::Foreground )); 4584 p->setBrush( cg.brush( QColorGroup::Text ));
4643 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); 4585 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size);
@@ -4652,61 +4594,14 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4652 4594
4653void QTextParag::setStyleSheetItems( const QPtrVector<QStyleSheetItem> &vec ) 4595void QTextParagraph::readStyleInformation( QDataStream& stream )
4654{
4655 styleSheetItemsVec() = vec;
4656 invalidate( 0 );
4657 lm = rm = tm = bm = flm = -1;
4658 numSubParag = -1;
4659}
4660
4661void QTextParag::setList( bool b, int listStyle )
4662{ 4596{
4663 if ( !hasdoc ) 4597 int int_align, int_lstyle;
4664 return; 4598 uchar uchar_litem, uchar_rtext, uchar_dir;
4665 4599 stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
4666 if ( !style() ) { 4600 >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
4667 styleSheetItemsVec().resize( 2 ); 4601 align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle;
4668 mStyleSheetItemsVec->insert( 0, document()->styleSheet()->item( "html" ) ); 4602 litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir );
4669 mStyleSheetItemsVec->insert( 1, document()->styleSheet()->item( "p" ) ); 4603 QTextParagraph* s = prev() ? prev() : this;
4670 } 4604 while ( s ) {
4671 4605 s->invalidate( 0 );
4672 if ( b ) { 4606 s = s->next();
4673 if ( style()->displayMode() != QStyleSheetItem::DisplayListItem || this->listStyle() != listStyle ) {
4674 styleSheetItemsVec().remove( styleSheetItemsVec().size() - 1 );
4675 QStyleSheetItem *item = (*mStyleSheetItemsVec)[ mStyleSheetItemsVec->size() - 1 ];
4676 if ( item )
4677 mStyleSheetItemsVec->remove( mStyleSheetItemsVec->size() - 1 );
4678 mStyleSheetItemsVec->insert( mStyleSheetItemsVec->size() - 1,
4679 listStyle == QStyleSheetItem::ListDisc || listStyle == QStyleSheetItem::ListCircle
4680 || listStyle == QStyleSheetItem::ListSquare ?
4681 document()->styleSheet()->item( "ul" ) : document()->styleSheet()->item( "ol" ) );
4682 mStyleSheetItemsVec->insert( mStyleSheetItemsVec->size() - 1, document()->styleSheet()->item( "li" ) );
4683 setListStyle( (QStyleSheetItem::ListStyle)listStyle );
4684 } else {
4685 return;
4686 }
4687 } else {
4688 if ( style()->displayMode() != QStyleSheetItem::DisplayBlock ) {
4689 styleSheetItemsVec().remove( styleSheetItemsVec().size() - 1 );
4690 if ( mStyleSheetItemsVec->size() >= 2 ) {
4691 mStyleSheetItemsVec->remove( mStyleSheetItemsVec->size() - 2 );
4692 mStyleSheetItemsVec->resize( mStyleSheetItemsVec->size() - 2 );
4693 } else {
4694 mStyleSheetItemsVec->resize( mStyleSheetItemsVec->size() - 1 );
4695 }
4696 } else {
4697 return;
4698 }
4699 }
4700 invalidate( 0 );
4701 lm = rm = tm = bm = flm = -1;
4702 numSubParag = -1;
4703 if ( next() ) {
4704 QTextParag *s = next();
4705 while ( s ) {
4706 s->numSubParag = -1;
4707 s->lm = s->rm = s->tm = s->bm = flm = -1;
4708 s->numSubParag = -1;
4709 s->invalidate( 0 );
4710 s = s->next();
4711 }
4712 } 4607 }
@@ -4714,68 +4609,21 @@ void QTextParag::setList( bool b, int listStyle )
4714 4609
4715void QTextParag::incDepth() 4610void QTextParagraph::writeStyleInformation( QDataStream& stream ) const
4716{ 4611{
4717 if ( !style() || !hasdoc ) 4612 stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
4718 return;
4719 if ( style()->displayMode() != QStyleSheetItem::DisplayListItem )
4720 return;
4721 styleSheetItemsVec().resize( styleSheetItemsVec().size() + 1 );
4722 mStyleSheetItemsVec->insert( mStyleSheetItemsVec->size() - 1, (*mStyleSheetItemsVec)[ mStyleSheetItemsVec->size() - 2 ] );
4723 mStyleSheetItemsVec->insert( mStyleSheetItemsVec->size() - 2,
4724 listStyle() == QStyleSheetItem::ListDisc || listStyle() == QStyleSheetItem::ListCircle ||
4725 listStyle() == QStyleSheetItem::ListSquare ?
4726 document()->styleSheet()->item( "ul" ) : document()->styleSheet()->item( "ol" ) );
4727 invalidate( 0 );
4728 lm = -1;
4729 flm = -1;
4730} 4613}
4731 4614
4732void QTextParag::decDepth()
4733{
4734 if ( !style() || !hasdoc )
4735 return;
4736 if ( style()->displayMode() != QStyleSheetItem::DisplayListItem )
4737 return;
4738 int numLists = 0;
4739 QStyleSheetItem *lastList = 0;
4740 int lastIndex = 0;
4741 int i;
4742 if ( mStyleSheetItemsVec ) {
4743 for ( i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) {
4744 QStyleSheetItem *item = (*mStyleSheetItemsVec)[ i ];
4745 if ( item->name() == "ol" || item->name() == "ul" ) {
4746 lastList = item;
4747 lastIndex = i;
4748 numLists++;
4749 }
4750 }
4751 }
4752 4615
4753 if ( !lastList )
4754 return;
4755 styleSheetItemsVec().remove( lastIndex );
4756 for ( i = lastIndex; i < (int)mStyleSheetItemsVec->size() - 1; ++i )
4757 mStyleSheetItemsVec->insert( i, (*mStyleSheetItemsVec)[ i + 1 ] );
4758 mStyleSheetItemsVec->resize( mStyleSheetItemsVec->size() - 1 );
4759 if ( numLists == 1 )
4760 setList( FALSE, -1 );
4761 invalidate( 0 );
4762 lm = -1;
4763 flm = -1;
4764}
4765 4616
4766int QTextParag::listDepth() const 4617void QTextParagraph::setListDepth( int depth ) {
4767{ 4618 if ( !hasdoc || depth == ldepth )
4768 int numLists = 0; 4619 return;
4769 int i; 4620 ldepth = depth;
4770 if ( mStyleSheetItemsVec ) { 4621 QTextParagraph* s = prev() ? prev() : this;
4771 for ( i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) { 4622 while ( s ) {
4772 QStyleSheetItem *item = (*mStyleSheetItemsVec)[ i ]; 4623 s->invalidate( 0 );
4773 if ( item->name() == "ol" || item->name() == "ul" ) 4624 s = s->next();
4774 numLists++;
4775 }
4776 } 4625 }
4777 return numLists - 1;
4778} 4626}
4779 4627
4780int *QTextParag::tabArray() const 4628int *QTextParagraph::tabArray() const
4781{ 4629{
@@ -4787,3 +4635,3 @@ int *QTextParag::tabArray() const
4787 4635
4788int QTextParag::nextTab( int, int x ) 4636int QTextParagraph::nextTab( int, int x )
4789{ 4637{
@@ -4813,3 +4661,3 @@ int QTextParag::nextTab( int, int x )
4813 4661
4814void QTextParag::adjustToPainter( QPainter *p ) 4662void QTextParagraph::adjustToPainter( QPainter *p )
4815{ 4663{
@@ -4821,3 +4669,3 @@ void QTextParag::adjustToPainter( QPainter *p )
4821 4669
4822QTextFormatCollection *QTextParag::formatCollection() const 4670QTextFormatCollection *QTextParagraph::formatCollection() const
4823{ 4671{
@@ -4833,3 +4681,3 @@ QTextFormatCollection *QTextParag::formatCollection() const
4833 4681
4834QString QTextParag::richText() const 4682QString QTextParagraph::richText() const
4835{ 4683{
@@ -4838,5 +4686,10 @@ QString QTextParag::richText() const
4838 QString spaces; 4686 QString spaces;
4839 bool lastCharWasSpace = FALSE; 4687 bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
4840 int firstcol = 0; 4688 bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
4841 for ( int i = 0; i < length()-1; ++i ) { 4689 int i;
4690 for ( i = 0; i < length()-1; ++i ) {
4691 if ( doStart && i && richTextExportStart->index() == i )
4692 s += "<selstart/>";
4693 if ( doEnd && richTextExportEnd->index() == i )
4694 s += "<selend/>";
4842 QTextStringChar *c = &str->at( i ); 4695 QTextStringChar *c = &str->at( i );
@@ -4852,59 +4705,26 @@ QString QTextParag::richText() const
4852 if ( !formatChar ) { 4705 if ( !formatChar ) {
4853 s += c->format()->makeFormatChangeTags( 0, QString::null, c->anchorHref() ); 4706 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
4707 0, QString::null, c->anchorHref() );
4854 formatChar = c; 4708 formatChar = c;
4855 } else if ( ( formatChar->format()->key() != c->format()->key() ) || 4709 } else if ( ( formatChar->format()->key() != c->format()->key() ) ||
4856 (formatChar->isAnchor() != c->isAnchor() && 4710 (c->anchorHref() != formatChar->anchorHref() ) ) {
4857 (!c->anchorHref().isEmpty() || !formatChar->anchorHref().isEmpty() ) ) ) {// lisp was here 4711 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
4858 4712 formatChar->format() , formatChar->anchorHref(), c->anchorHref() );
4859 if ( !spaces.isEmpty() ) {
4860 if ( spaces[0] == '\t' || lastCharWasSpace )
4861 s += "<wsp>" + spaces + "</wsp>";
4862 else if ( spaces.length() > 1 )
4863 s += "<wsp>" + spaces.mid(1) + "</wsp> ";
4864 else
4865 s += spaces;
4866 lastCharWasSpace = TRUE;
4867 spaces = QString::null;
4868 }
4869 s += c->format()->makeFormatChangeTags( formatChar->format() , formatChar->anchorHref(), c->anchorHref() );
4870 formatChar = c; 4713 formatChar = c;
4871 } 4714 }
4872 4715 if ( c->c == '<' )
4873 if ( c->c == ' ' || c->c == '\t' ) {
4874 spaces += c->c;
4875 continue;
4876 } else if ( !spaces.isEmpty() ) {
4877 if ( spaces[0] == '\t' || lastCharWasSpace )
4878 s += "<wsp>" + spaces + "</wsp>";
4879 else if ( spaces.length() > 1 )
4880 s += "<wsp>" + spaces.mid(1) + "</wsp> ";
4881 else
4882 s += spaces;
4883 spaces = QString::null;
4884 if ( s.length() - firstcol > 60 ) {
4885 s += '\n';
4886 firstcol = s.length();
4887 }
4888 }
4889
4890 lastCharWasSpace = FALSE;
4891 if ( c->c == '<' ) {
4892 s += "&lt;"; 4716 s += "&lt;";
4893 } else if ( c->c == '>' ) { 4717 else if ( c->c == '>' )
4894 s += "&gt;"; 4718 s += "&gt;";
4895 } else if ( c->isCustom() ) { 4719 else if ( c->isCustom() )
4896 s += c->customItem()->richText(); 4720 s += c->customItem()->richText();
4897 } else { 4721 else if ( c->c == '\n' || c->c == QChar_linesep )
4898 s += c->c; 4722 s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co.
4899 }
4900 }
4901 if ( !spaces.isEmpty() ) {
4902 if ( spaces.length() > 1 || spaces[0] == '\t' || lastCharWasSpace )
4903 s += "<wsp>" + spaces + "</wsp>";
4904 else 4723 else
4905 s += spaces; 4724 s += c->c;
4906 } 4725 }
4907 4726 if ( doEnd && richTextExportEnd->index() == i )
4727 s += "<selend/>";
4908 if ( formatChar ) 4728 if ( formatChar )
4909 s += formatChar->format()->makeFormatEndTags( formatChar->anchorHref() ); 4729 s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() );
4910 return s; 4730 return s;
@@ -4912,3 +4732,3 @@ QString QTextParag::richText() const
4912 4732
4913void QTextParag::addCommand( QTextCommand *cmd ) 4733void QTextParagraph::addCommand( QTextCommand *cmd )
4914{ 4734{
@@ -4920,3 +4740,3 @@ void QTextParag::addCommand( QTextCommand *cmd )
4920 4740
4921QTextCursor *QTextParag::undo( QTextCursor *c ) 4741QTextCursor *QTextParagraph::undo( QTextCursor *c )
4922{ 4742{
@@ -4927,3 +4747,3 @@ QTextCursor *QTextParag::undo( QTextCursor *c )
4927 4747
4928QTextCursor *QTextParag::redo( QTextCursor *c ) 4748QTextCursor *QTextParagraph::redo( QTextCursor *c )
4929{ 4749{
@@ -4934,167 +4754,66 @@ QTextCursor *QTextParag::redo( QTextCursor *c )
4934 4754
4935int QTextParag::topMargin() const 4755int QTextParagraph::topMargin() const
4936{ 4756{
4937 if ( !p && ( !hasdoc || !document()->addMargins() ) )
4938 return 0;
4939 if ( tm != -1 )
4940 return tm;
4941 QStyleSheetItem *item = style();
4942 if ( !item ) {
4943 ( (QTextParag*)this )->tm = 0;
4944 return 0;
4945 }
4946
4947 int m = 0; 4757 int m = 0;
4948 if ( item->margin( QStyleSheetItem::MarginTop ) != QStyleSheetItem::Undefined ) 4758 if ( rtext ) {
4949 m = item->margin( QStyleSheetItem::MarginTop ); 4759 m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm;
4950 if ( mStyleSheetItemsVec ) { 4760 if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) )
4951 QStyleSheetItem *it = 0; 4761 m = QMAX( m, document()->list_tm );
4952 QStyleSheetItem *p = prev() ? prev()->style() : 0;
4953 for ( int i = (int)mStyleSheetItemsVec->size() - 2 ; i >= 0; --i ) {
4954 it = (*mStyleSheetItemsVec)[ i ];
4955 if ( it != p )
4956 break;
4957 int mar = it->margin( QStyleSheetItem::MarginTop );
4958 m += (mar != QStyleSheetItem::Undefined) ? mar : 0;
4959 if ( it->displayMode() != QStyleSheetItem::DisplayInline )
4960 break;
4961 }
4962 } 4762 }
4963 m = scale( m, QTextFormat::painter() ); 4763 m += utm;
4964 4764 return scale( m, QTextFormat::painter() );
4965 ( (QTextParag*)this )->tm = m;
4966 return tm;
4967} 4765}
4968 4766
4969int QTextParag::bottomMargin() const 4767int QTextParagraph::bottomMargin() const
4970{ 4768{
4971 if ( bm != -1 )
4972 return bm;
4973 QStyleSheetItem *item = style();
4974 if ( !item || !next() ) {
4975 ( (QTextParag*)this )->bm = 0;
4976 return 0;
4977 }
4978
4979 int m = 0; 4769 int m = 0;
4980 if ( item->margin( QStyleSheetItem::MarginBottom ) != QStyleSheetItem::Undefined ) 4770 if ( rtext ) {
4981 m = item->margin( QStyleSheetItem::MarginBottom ); 4771 m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm;
4982 if ( mStyleSheetItemsVec ) { 4772 if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) )
4983 QStyleSheetItem *it = 0; 4773 m = QMAX( m, document()->list_bm );
4984 QStyleSheetItem *n = next() ? next()->style() : 0;
4985 for ( int i =(int)mStyleSheetItemsVec->size() - 2 ; i >= 0; --i ) {
4986 it = (*mStyleSheetItemsVec)[ i ];
4987 if ( it != n )
4988 break;
4989 int mar = it->margin( QStyleSheetItem::MarginBottom );
4990 m += mar != QStyleSheetItem::Undefined ? mar : 0;
4991 if ( it->displayMode() != QStyleSheetItem::DisplayInline )
4992 break;
4993 }
4994 } 4774 }
4995 m = scale ( m, QTextFormat::painter() ); 4775 m += ubm;
4996 4776 return scale( m, QTextFormat::painter() );
4997 ( (QTextParag*)this )->bm = m;
4998 return bm;
4999} 4777}
5000 4778
5001int QTextParag::leftMargin() const 4779int QTextParagraph::leftMargin() const
5002{ 4780{
5003 if ( lm != -1 ) 4781 int m = ulm;
5004 return lm; 4782 if ( listDepth() )
5005 QStyleSheetItem *item = style(); 4783 m += listDepth() * document()->list_lm;
5006 if ( !item ) { 4784 return scale( m, QTextFormat::painter() );
5007 ( (QTextParag*)this )->lm = 0;
5008 return 0;
5009 }
5010 int m = 0;
5011 if ( mStyleSheetItemsVec ) {
5012 for ( int i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) {
5013 item = (*mStyleSheetItemsVec)[ i ];
5014 int mar = item->margin( QStyleSheetItem::MarginLeft );
5015 m += mar != QStyleSheetItem::Undefined ? mar : 0;
5016 if ( item->name() == "ol" || item->name() == "ul" ) {
5017 QPainter* oldPainter = QTextFormat::painter();
5018 QTextFormat::setPainter( 0 );
5019 m += defFormat->width( '1' ) +
5020 defFormat->width( '2' ) +
5021 defFormat->width( '3' ) +
5022 defFormat->width( '.' );
5023 QTextFormat::setPainter( oldPainter );
5024 }
5025 }
5026 }
5027
5028 m = scale ( m, QTextFormat::painter() );
5029
5030 ( (QTextParag*)this )->lm = m;
5031 return lm;
5032} 4785}
5033 4786
5034int QTextParag::firstLineMargin() const 4787int QTextParagraph::firstLineMargin() const
5035{ 4788{
5036 if ( flm != -1 ) 4789 int m = uflm;
5037 return lm; 4790 return scale( m, QTextFormat::painter() );
5038 QStyleSheetItem *item = style();
5039 if ( !item ) {
5040 ( (QTextParag*)this )->flm = 0;
5041 return 0;
5042 }
5043 int m = 0;
5044 if ( mStyleSheetItemsVec ) {
5045 for ( int i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) {
5046 item = (*mStyleSheetItemsVec)[ i ];
5047 int mar = item->margin( QStyleSheetItem::MarginFirstLine );
5048 m += mar != QStyleSheetItem::Undefined ? mar : 0;
5049 }
5050 }
5051
5052 m = scale( m, QTextFormat::painter() );
5053
5054 ( (QTextParag*)this )->flm = m;
5055 return flm;
5056} 4791}
5057 4792
5058int QTextParag::rightMargin() const 4793int QTextParagraph::rightMargin() const
5059{ 4794{
5060 if ( rm != -1 ) 4795 int m = urm;
5061 return rm; 4796 return scale( m, QTextFormat::painter() );
5062 QStyleSheetItem *item = style();
5063 if ( !item ) {
5064 ( (QTextParag*)this )->rm = 0;
5065 return 0;
5066 }
5067 int m = 0;
5068 if ( mStyleSheetItemsVec ) {
5069 for ( int i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) {
5070 item = (*mStyleSheetItemsVec)[ i ];
5071 int mar = item->margin( QStyleSheetItem::MarginRight );
5072 m += mar != QStyleSheetItem::Undefined ? mar : 0;
5073 }
5074 }
5075 m = scale( m, QTextFormat::painter() );
5076
5077 ( (QTextParag*)this )->rm = m;
5078 return rm;
5079} 4797}
5080 4798
5081int QTextParag::lineSpacing() const 4799int QTextParagraph::lineSpacing() const
5082{ 4800{
5083 QStyleSheetItem *item = style(); 4801 int l = ulinespacing;
5084 if ( !item ) 4802 l = scale( l, QTextFormat::painter() );
5085 return 0; 4803 return l;
5086
5087 int ls = item->lineSpacing();
5088 if ( ls == QStyleSheetItem::Undefined )
5089 return 0;
5090 ls = scale( ls, QTextFormat::painter() );
5091
5092 return ls;
5093} 4804}
5094 4805
5095void QTextParag::copyParagData( QTextParag *parag ) 4806void QTextParagraph::copyParagData( QTextParagraph *parag )
5096{ 4807{
5097 setStyleSheetItems( parag->styleSheetItems() ); 4808 rtext = parag->rtext;
5098 setListStyle( parag->listStyle() ); 4809 lstyle = parag->lstyle;
5099 setAlignment( parag->alignment() ); 4810 ldepth = parag->ldepth;
4811 litem = parag->litem;
4812 align = parag->align;
4813 utm = parag->utm;
4814 ubm = parag->ubm;
4815 urm = parag->urm;
4816 ulm = parag->ulm;
4817 uflm = parag->uflm;
4818 ulinespacing = parag->ulinespacing;
5100 QColor *c = parag->backgroundColor(); 4819 QColor *c = parag->backgroundColor();
@@ -5102,5 +4821,6 @@ void QTextParag::copyParagData( QTextParag *parag )
5102 setBackgroundColor( *c ); 4821 setBackgroundColor( *c );
4822 str->setDirection( parag->str->direction() );
5103} 4823}
5104 4824
5105void QTextParag::show() 4825void QTextParagraph::show()
5106{ 4826{
@@ -5111,3 +4831,3 @@ void QTextParag::show()
5111 4831
5112void QTextParag::hide() 4832void QTextParagraph::hide()
5113{ 4833{
@@ -5118,3 +4838,3 @@ void QTextParag::hide()
5118 4838
5119void QTextParag::setDirection( QChar::Direction d ) 4839void QTextParagraph::setDirection( QChar::Direction d )
5120{ 4840{
@@ -5126,3 +4846,3 @@ void QTextParag::setDirection( QChar::Direction d )
5126 4846
5127QChar::Direction QTextParag::direction() const 4847QChar::Direction QTextParagraph::direction() const
5128{ 4848{
@@ -5131,3 +4851,3 @@ QChar::Direction QTextParag::direction() const
5131 4851
5132void QTextParag::setChanged( bool b, bool recursive ) 4852void QTextParagraph::setChanged( bool b, bool recursive )
5133{ 4853{
@@ -5135,4 +4855,4 @@ void QTextParag::setChanged( bool b, bool recursive )
5135 if ( recursive ) { 4855 if ( recursive ) {
5136 if ( document() && document()->parentParag() ) 4856 if ( document() && document()->parentParagraph() )
5137 document()->parentParag()->setChanged( b, recursive ); 4857 document()->parentParagraph()->setChanged( b, recursive );
5138 } 4858 }
@@ -5154,5 +4874,3 @@ QTextFormatter::QTextFormatter()
5154 4874
5155/* only used for bidi or complex text reordering 4875QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line,
5156 */
5157QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString *string, QTextParagLineStart *line,
5158 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) 4876 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space )
@@ -5163,3 +4881,2 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5163#endif 4881#endif
5164 space = QMAX( space, 0 ); // #### with nested tables this gets negative because of a bug I didn't find yet, so workaround for now. This also means non-left aligned nested tables do not work at the moment
5165 int start = (startChar - &string->at(0)); 4882 int start = (startChar - &string->at(0));
@@ -5174,3 +4891,9 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5174 int numSpaces = 0; 4891 int numSpaces = 0;
5175 for ( int j = start; j < last; ++j ) { 4892 // End at "last-1", the last space ends up with a width of 0
4893 for ( int j = last-1; j >= start; --j ) {
4894 // Start at last tab, if any.
4895 if ( string->at( j ).c == '\t' ) {
4896 start = j+1;
4897 break;
4898 }
5176 if( isBreakable( string, j ) ) { 4899 if( isBreakable( string, j ) ) {
@@ -5196,3 +4919,3 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5196 4919
5197 return new QTextParagLineStart(); 4920 return new QTextLineStart();
5198} 4921}
@@ -5206,3 +4929,3 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5206// collects one line of the paragraph and transforms it to visual order 4929// collects one line of the paragraph and transforms it to visual order
5207QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QTextString *text, QTextParagLineStart *line, 4930QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line,
5208 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) 4931 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space )
@@ -5211,3 +4934,2 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5211 int last = (lastChar - &text->at(0) ); 4934 int last = (lastChar - &text->at(0) );
5212 //qDebug("doing BiDi reordering from %d to %d!", start, last);
5213 4935
@@ -5245,3 +4967,9 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5245 else if ( align & Qt3::AlignJustify ) { 4967 else if ( align & Qt3::AlignJustify ) {
5246 for ( int j = start; j < last; ++j ) { 4968 // End at "last-1", the last space ends up with a width of 0
4969 for ( int j = last-1; j >= start; --j ) {
4970 // Start at last tab, if any.
4971 if ( text->at( j ).c == '\t' ) {
4972 start = j+1;
4973 break;
4974 }
5247 if( isBreakable( text, j ) ) { 4975 if( isBreakable( text, j ) ) {
@@ -5307,3 +5035,2 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5307 } 5035 }
5308 //qDebug("setting char %d at pos %d", pos, x);
5309 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; 5036 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww;
@@ -5318,3 +5045,3 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5318 line->w = xmax + 10; 5045 line->w = xmax + 10;
5319 QTextParagLineStart *ls = new QTextParagLineStart( control->context, control->status ); 5046 QTextLineStart *ls = new QTextLineStart( control->context, control->status );
5320 delete control; 5047 delete control;
@@ -5325,3 +5052,3 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5325 5052
5326bool QTextFormatter::isBreakable( QTextString *string, int pos ) const 5053bool QTextFormatter::isBreakable( QTextString *string, int pos )
5327{ 5054{
@@ -5329,2 +5056,4 @@ bool QTextFormatter::isBreakable( QTextString *string, int pos ) const
5329 char ch = c.latin1(); 5056 char ch = c.latin1();
5057 if ( c == QChar_linesep )
5058 return TRUE;
5330 if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) 5059 if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U )
@@ -5376,3 +5105,3 @@ bool QTextFormatter::isBreakable( QTextString *string, int pos ) const
5376 5105
5377void QTextFormatter::insertLineStart( QTextParag *parag, int index, QTextParagLineStart *ls ) 5106void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls )
5378{ 5107{
@@ -5382,3 +5111,3 @@ void QTextFormatter::insertLineStart( QTextParag *parag, int index, QTextParagLi
5382 } 5111 }
5383 QMap<int, QTextParagLineStart*>::Iterator it; 5112 QMap<int, QTextLineStart*>::Iterator it;
5384 if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { 5113 if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) {
@@ -5396,10 +5125,10 @@ void QTextFormatter::insertLineStart( QTextParag *parag, int index, QTextParagLi
5396 */ 5125 */
5397int QTextFormatter::formatVertically( QTextDocument* doc, QTextParag* parag ) 5126int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag )
5398{ 5127{
5399 int oldHeight = parag->rect().height(); 5128 int oldHeight = parag->rect().height();
5400 QMap<int, QTextParagLineStart*>& lineStarts = parag->lineStartList(); 5129 QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList();
5401 QMap<int, QTextParagLineStart*>::Iterator it = lineStarts.begin(); 5130 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
5402 int h = doc->addMargins() ? parag->topMargin() : 0; 5131 int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0;
5403 for ( ; it != lineStarts.end() ; ++it ) { 5132 for ( ; it != lineStarts.end() ; ++it ) {
5404 QTextParagLineStart * ls = it.data(); 5133 QTextLineStart * ls = it.data();
5405 ls->y = h; 5134 ls->y = h;
@@ -5422,6 +5151,6 @@ int QTextFormatter::formatVertically( QTextDocument* doc, QTextParag* parag )
5422 int m = parag->bottomMargin(); 5151 int m = parag->bottomMargin();
5423 if ( parag->next() && doc && !doc->addMargins() ) 5152 if ( !parag->next() )
5424 m = QMAX( m, parag->next()->topMargin() );
5425 if ( parag->next() && parag->next()->isLineBreak() )
5426 m = 0; 5153 m = 0;
5154 else
5155 m = QMAX(m, parag->next()->topMargin() ) / 2;
5427 h += m; 5156 h += m;
@@ -5437,4 +5166,6 @@ QTextFormatterBreakInWords::QTextFormatterBreakInWords()
5437 5166
5438int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag, 5167#define SPACE(s) doc?(s>0?s:0):s
5439 int start, const QMap<int, QTextParagLineStart*> & ) 5168
5169int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag,
5170 int start, const QMap<int, QTextLineStart*> & )
5440{ 5171{
@@ -5442,6 +5173,6 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5442 QTextStringChar *firstChar = 0; 5173 QTextStringChar *firstChar = 0;
5443 int left = doc ? parag->leftMargin() + doc->leftMargin() : 4; 5174 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
5444 int x = left + ( doc ? parag->firstLineMargin() : 0 ); 5175 int x = left + ( doc ? parag->firstLineMargin() : 0 );
5445 int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); 5176 int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 );
5446 int y = doc && doc->addMargins() ? parag->topMargin() : 0; 5177 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
5447 int h = y; 5178 int h = y;
@@ -5462,3 +5193,3 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5462 int i = start; 5193 int i = start;
5463 QTextParagLineStart *lineStart = new QTextParagLineStart( y, y, 0 ); 5194 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
5464 insertLineStart( parag, 0, lineStart ); 5195 insertLineStart( parag, 0, lineStart );
@@ -5503,3 +5234,3 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5503 h = c->height(); 5234 h = c->height();
5504 lineStart = new QTextParagLineStart( y, h, h ); 5235 lineStart = new QTextLineStart( y, h, h );
5505 insertLineStart( parag, i, lineStart ); 5236 insertLineStart( parag, i, lineStart );
@@ -5513,4 +5244,3 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5513 ( wrapAtColumn() == -1 && x + ww > w || 5244 ( wrapAtColumn() == -1 && x + ww > w ||
5514 wrapAtColumn() != -1 && col >= wrapAtColumn() ) || 5245 wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) {
5515 parag->isNewLinesAllowed() && lastChr == '\n' ) {
5516 x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5246 x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
@@ -5519,3 +5249,3 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5519 h = c->height(); 5249 h = c->height();
5520 lineStart = formatLine( parag, parag->string(), lineStart, firstChar, c-1 ); 5250 lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) );
5521 lineStart->y = y; 5251 lineStart->y = y;
@@ -5541,8 +5271,10 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5541 int m = parag->bottomMargin(); 5271 int m = parag->bottomMargin();
5542 if ( parag->next() && doc && !doc->addMargins() ) 5272 if ( !parag->next() )
5543 m = QMAX( m, parag->next()->topMargin() );
5544 parag->setFullWidth( fullWidth );
5545 if ( parag->next() && parag->next()->isLineBreak() )
5546 m = 0; 5273 m = 0;
5274 else
5275 m = QMAX(m, parag->next()->topMargin() ) / 2;
5276 parag->setFullWidth( fullWidth );
5547 y += h + m; 5277 y += h + m;
5278 if ( doc )
5279 minw += doc->rightMargin();
5548 if ( !wrapEnabled ) 5280 if ( !wrapEnabled )
@@ -5568,4 +5300,4 @@ QTextFormatterBreakWords::QTextFormatterBreakWords()
5568 5300
5569int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag, 5301int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag,
5570 int start, const QMap<int, QTextParagLineStart*> & ) 5302 int start, const QMap<int, QTextLineStart*> & )
5571{ 5303{
@@ -5576,3 +5308,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5576 int x = left + ( doc ? parag->firstLineMargin() : 0 ); 5308 int x = left + ( doc ? parag->firstLineMargin() : 0 );
5577 int y = doc && doc->addMargins() ? parag->topMargin() : 0; 5309 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
5578 int h = y; 5310 int h = y;
@@ -5592,3 +5324,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5592 int tminw = marg; 5324 int tminw = marg;
5593 int linespace = doc ? parag->lineSpacing() : 0; 5325 int linespacing = doc ? parag->lineSpacing() : 0;
5594 bool wrapEnabled = isWrapEnabled( parag ); 5326 bool wrapEnabled = isWrapEnabled( parag );
@@ -5600,3 +5332,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5600 int i = start; 5332 int i = start;
5601 QTextParagLineStart *lineStart = new QTextParagLineStart( y, y, 0 ); 5333 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
5602 insertLineStart( parag, 0, lineStart ); 5334 insertLineStart( parag, 0, lineStart );
@@ -5656,3 +5388,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5656 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); 5388 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5657 QTextParagLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, w - x ); 5389 QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
5658 ci->resize( w - x); 5390 ci->resize( w - x);
@@ -5668,4 +5400,4 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5668 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { 5400 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) {
5669 y += QMAX( h, tmph ); 5401 y += QMAX( h, QMAX( tmph, linespacing ) );
5670 tmph = c->height() + linespace; 5402 tmph = c->height();
5671 h = tmph; 5403 h = tmph;
@@ -5677,3 +5409,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5677 } else { 5409 } else {
5678 tmph = c->height() + linespace; 5410 tmph = c->height();
5679 h = tmph; 5411 h = tmph;
@@ -5688,3 +5420,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5688 5420
5689 int tw = ci->minimumWidth(); 5421 int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
5690 if ( tw < QWIDGETSIZE_MAX ) 5422 if ( tw < QWIDGETSIZE_MAX )
@@ -5701,11 +5433,26 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5701 5433
5702 if ( wrapEnabled && ( !c->c.isSpace() || lastBreak == -2 ) 5434 bool lastWasOwnLineCustomItem = lastBreak == -2;
5703 && ( lastBreak != -1 || allowBreakInWords() ) && 5435 bool hadBreakableChar = lastBreak != -1;
5704 ( wrapAtColumn() == -1 && x + ww > w && lastBreak != -1 || 5436 bool lastWasHardBreak = lastChr == QChar_linesep;
5705 wrapAtColumn() == -1 && x + ww > w - 4 && lastBreak == -1 && allowBreakInWords() || 5437
5706 wrapAtColumn() != -1 && col >= wrapAtColumn() ) || 5438 // we break if
5707 parag->isNewLinesAllowed() && lastChr == '\n' && firstChar < c ) { 5439 // 1. the last character was a hard break (QChar_linesep) or
5440 // 2. the last charater was a own-line custom item (eg. table or ruler) or
5441 // 3. wrapping was enabled, it was not a space and following
5442 // condition is true: We either had a breakable character
5443 // previously or we ar allowed to break in words and - either
5444 // we break at w pixels and the current char would exceed that
5445 // or - we break at a column and the current character would
5446 // exceed that.
5447 if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
5448 ( wrapEnabled &&
5449 ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
5450 ( (wrapAtColumn() == -1 && x + ww > w) ||
5451 (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) )
5452 )
5453 ) {
5708 if ( wrapAtColumn() != -1 ) 5454 if ( wrapAtColumn() != -1 )
5709 minw = QMAX( minw, x + ww ); 5455 minw = QMAX( minw, x + ww );
5710 if ( lastBreak < 0 ) { 5456 // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
5457 if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) {
5711 if ( lineStart ) { 5458 if ( lineStart ) {
@@ -5716,6 +5463,6 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5716 } 5463 }
5717 lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, w - x ); 5464 lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
5718 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5465 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
5719 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); 5466 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5720 if ( parag->isNewLinesAllowed() && c->c == '\t' ) { 5467 if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
5721 int nx = parag->nextTab( i, x - left ) + left; 5468 int nx = parag->nextTab( i, x - left ) + left;
@@ -5727,4 +5474,4 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5727 curLeft = x; 5474 curLeft = x;
5728 y += h; 5475 y += QMAX( h, linespacing );
5729 tmph = c->height() + linespace; 5476 tmph = c->height();
5730 h = 0; 5477 h = 0;
@@ -5739,9 +5486,9 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5739 col = 0; 5486 col = 0;
5740 } else { 5487 } else { // ... otherwise if we had a breakable char, break there
5741 DO_FLOW( lineStart ); 5488 DO_FLOW( lineStart );
5742 i = lastBreak; 5489 i = lastBreak;
5743 lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ), align, w - string->at( i ).x ); 5490 lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) );
5744 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5491 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
5745 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); 5492 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5746 if ( parag->isNewLinesAllowed() && c->c == '\t' ) { 5493 if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
5747 int nx = parag->nextTab( i, x - left ) + left; 5494 int nx = parag->nextTab( i, x - left ) + left;
@@ -5753,4 +5500,4 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5753 curLeft = x; 5500 curLeft = x;
5754 y += h; 5501 y += QMAX( h, linespacing );
5755 tmph = c->height() + linespace; 5502 tmph = c->height();
5756 h = tmph; 5503 h = tmph;
@@ -5768,6 +5515,6 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5768 } 5515 }
5769 } else if ( lineStart && ( isBreakable( string, i ) || parag->isNewLinesAllowed() && c->c == '\n' ) ) { 5516 } else if ( lineStart && isBreakable( string, i ) ) {
5770 if ( len <= 2 || i < len - 1 ) { 5517 if ( len <= 2 || i < len - 1 ) {
5771 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); 5518 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
5772 tmph = QMAX( tmph, c->height() + linespace ); 5519 tmph = QMAX( tmph, c->height() );
5773 } 5520 }
@@ -5782,3 +5529,3 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5782 tminw += ww; 5529 tminw += ww;
5783 int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height() + linespace - c->ascent() ); 5530 int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() );
5784 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); 5531 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
@@ -5792,4 +5539,6 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5792 5539
5793 // ### hack. The last char in the paragraph is always invisible, and somehow sometimes has a wrong format. It changes between 5540 // ### hack. The last char in the paragraph is always invisible,
5794 // layouting and printing. This corrects some layouting errors in BiDi mode due to this. 5541 // ### and somehow sometimes has a wrong format. It changes
5542 // ### between // layouting and printing. This corrects some
5543 // ### layouting errors in BiDi mode due to this.
5795 if ( len > 1 && !c->isAnchor() ) { 5544 if ( len > 1 && !c->isAnchor() ) {
@@ -5805,6 +5554,6 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5805 // last line in a paragraph is not justified 5554 // last line in a paragraph is not justified
5806 if ( align == Qt3::AlignJustify ) 5555 if ( align == Qt3::AlignJustify || lastChr == QChar_linesep )
5807 align = Qt3::AlignAuto; 5556 align = Qt3::AlignAuto;
5808 DO_FLOW( lineStart ); 5557 DO_FLOW( lineStart );
5809 lineStart = formatLine( parag, string, lineStart, firstChar, c, align, w - x ); 5558 lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) );
5810 delete lineStart; 5559 delete lineStart;
@@ -5813,10 +5562,12 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5813 minw = QMAX( minw, tminw ); 5562 minw = QMAX( minw, tminw );
5563 if ( doc )
5564 minw += doc->rightMargin();
5814 5565
5815 int m = parag->bottomMargin(); 5566 int m = parag->bottomMargin();
5816 if ( parag->next() && doc && !doc->addMargins() ) 5567 if ( !parag->next() )
5817 m = QMAX( m, parag->next()->topMargin() );
5818 parag->setFullWidth( fullWidth );
5819 if ( parag->next() && parag->next()->isLineBreak() )
5820 m = 0; 5568 m = 0;
5821 y += h + m; 5569 else
5570 m = QMAX(m, parag->next()->topMargin() ) / 2;
5571 parag->setFullWidth( fullWidth );
5572 y += QMAX( h, linespacing ) + m;
5822 5573
@@ -5825,2 +5576,10 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5825 minw = QMAX(minw, wused); 5576 minw = QMAX(minw, wused);
5577
5578 // This is the case where we are breaking wherever we darn well please
5579 // in cases like that, the minw should not be the length of the entire
5580 // word, because we necessarily want to show the word on the whole line.
5581 // example: word wrap in iconview
5582 if ( allowBreakInWords() && minw > wused )
5583 minw = wused;
5584
5826 thisminw = minw; 5585 thisminw = minw;
@@ -5839,3 +5598,3 @@ QTextIndent::QTextIndent()
5839QTextFormatCollection::QTextFormatCollection() 5598QTextFormatCollection::QTextFormatCollection()
5840 : cKey( 307 ), sheet( 0 ) 5599 : cKey( 307 )
5841{ 5600{
@@ -5857,5 +5616,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5857 if ( f->parent() == this || f == defFormat ) { 5616 if ( f->parent() == this || f == defFormat ) {
5858#ifdef DEBUG_COLLECTION
5859 qDebug( "need '%s', best case!", f->key().latin1() );
5860#endif
5861 lastFormat = f; 5617 lastFormat = f;
@@ -5866,5 +5622,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5866 if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { 5622 if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) {
5867#ifdef DEBUG_COLLECTION
5868 qDebug( "need '%s', good case!", f->key().latin1() );
5869#endif
5870 lastFormat->addRef(); 5623 lastFormat->addRef();
@@ -5875,5 +5628,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5875 if ( fm ) { 5628 if ( fm ) {
5876#ifdef DEBUG_COLLECTION
5877 qDebug( "need '%s', normal case!", f->key().latin1() );
5878#endif
5879 lastFormat = fm; 5629 lastFormat = fm;
@@ -5886,5 +5636,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5886 5636
5887#ifdef DEBUG_COLLECTION
5888 qDebug( "need '%s', worst case!", f->key().latin1() );
5889#endif
5890 lastFormat = createFormat( *f ); 5637 lastFormat = createFormat( *f );
@@ -5898,5 +5645,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5898 if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { 5645 if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) {
5899#ifdef DEBUG_COLLECTION
5900 qDebug( "mix of '%s' and '%s, best case!", of->key().latin1(), nf->key().latin1() );
5901#endif
5902 cres->addRef(); 5646 cres->addRef();
@@ -5915,2 +5659,4 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5915 cres->fn.setUnderline( nf->fn.underline() ); 5659 cres->fn.setUnderline( nf->fn.underline() );
5660 if ( flags & QTextFormat::StrikeOut )
5661 cres->fn.setStrikeOut( nf->fn.strikeOut() );
5916 if ( flags & QTextFormat::Family ) 5662 if ( flags & QTextFormat::Family )
@@ -5933,5 +5679,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5933 if ( !fm ) { 5679 if ( !fm ) {
5934#ifdef DEBUG_COLLECTION
5935 qDebug( "mix of '%s' and '%s, worst case!", of->key().latin1(), nf->key().latin1() );
5936#endif
5937 cres->collection = this; 5680 cres->collection = this;
@@ -5939,5 +5682,2 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5939 } else { 5682 } else {
5940#ifdef DEBUG_COLLECTION
5941 qDebug( "mix of '%s' and '%s, good case!", of->key().latin1(), nf->key().latin1() );
5942#endif
5943 delete cres; 5683 delete cres;
@@ -5953,5 +5693,2 @@ QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5953 if ( cachedFormat && cfont == f && ccol == c ) { 5693 if ( cachedFormat && cfont == f && ccol == c ) {
5954#ifdef DEBUG_COLLECTION
5955 qDebug( "format of font and col '%s' - best case", cachedFormat->key().latin1() );
5956#endif
5957 cachedFormat->addRef(); 5694 cachedFormat->addRef();
@@ -5966,5 +5703,2 @@ QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5966 if ( cachedFormat ) { 5703 if ( cachedFormat ) {
5967#ifdef DEBUG_COLLECTION
5968 qDebug( "format of font and col '%s' - good case", cachedFormat->key().latin1() );
5969#endif
5970 cachedFormat->addRef(); 5704 cachedFormat->addRef();
@@ -5981,5 +5715,2 @@ QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5981 qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1() ); 5715 qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1() );
5982#ifdef DEBUG_COLLECTION
5983 qDebug( "format of font and col '%s' - worst case", cachedFormat->key().latin1() );
5984#endif
5985 return cachedFormat; 5716 return cachedFormat;
@@ -5998,54 +5729,7 @@ void QTextFormatCollection::remove( QTextFormat *f )
5998 5729
5999void QTextFormatCollection::debug() 5730#define UPDATE( up, lo, rest ) \
6000{ 5731 if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \
6001#ifdef DEBUG_COLLECTION 5732 fm->fn.set##up##rest( font.lo##rest() )
6002 qDebug( "------------ QTextFormatCollection: debug --------------- BEGIN" );
6003 QDictIterator<QTextFormat> it( cKey );
6004 for ( ; it.current(); ++it ) {
6005 qDebug( "format '%s' (%p): refcount: %d", it.current()->key().latin1(),
6006 it.current(), it.current()->ref );
6007 }
6008 qDebug( "------------ QTextFormatCollection: debug --------------- END" );
6009#endif
6010}
6011
6012void QTextFormatCollection::updateStyles()
6013{
6014 QDictIterator<QTextFormat> it( cKey );
6015 QTextFormat *f;
6016 while ( ( f = it.current() ) ) {
6017 ++it;
6018 f->updateStyle();
6019 }
6020 updateKeys();
6021}
6022
6023void QTextFormatCollection::updateFontSizes( int base, bool usePixels )
6024{
6025 QDictIterator<QTextFormat> it( cKey );
6026 QTextFormat *f;
6027 while ( ( f = it.current() ) ) {
6028 ++it;
6029 f->stdSize = base;
6030 f->usePixelSizes = usePixels;
6031 if ( usePixels )
6032 f->fn.setPixelSize( f->stdSize );
6033 else
6034 f->fn.setPointSize( f->stdSize );
6035 styleSheet()->scaleFont( f->fn, f->logicalFontSize );
6036 f->update();
6037 }
6038 f = defFormat;
6039 f->stdSize = base;
6040 f->usePixelSizes = usePixels;
6041 if ( usePixels )
6042 f->fn.setPixelSize( f->stdSize );
6043 else
6044 f->fn.setPointSize( f->stdSize );
6045 styleSheet()->scaleFont( f->fn, f->logicalFontSize );
6046 f->update();
6047 updateKeys();
6048}
6049 5733
6050void QTextFormatCollection::updateFontAttributes( const QFont &f, const QFont &old ) 5734void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet )
6051{ 5735{
@@ -6053,26 +5737,33 @@ void QTextFormatCollection::updateFontAttributes( const QFont &f, const QFont &o
6053 QTextFormat *fm; 5737 QTextFormat *fm;
5738 bool usePixels = font.pointSize() == -1;
5739 bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
5740 font.pointSize() != defFormat->fn.pointSize();
5741 int base = usePixels ? font.pixelSize() : font.pointSize();
6054 while ( ( fm = it.current() ) ) { 5742 while ( ( fm = it.current() ) ) {
6055 ++it; 5743 ++it;
6056 if ( fm->fn.family() == old.family() && 5744 UPDATE( F, f, amily );
6057 fm->fn.weight() == old.weight() && 5745 UPDATE( W, w, eight );
6058 fm->fn.italic() == old.italic() && 5746 UPDATE( B, b, old );
6059 fm->fn.underline() == old.underline() ) { 5747 UPDATE( I, i, talic );
6060 fm->fn.setFamily( f.family() ); 5748 UPDATE( U, u, nderline );
6061 fm->fn.setWeight( f.weight() ); 5749 if ( changeSize ) {
6062 fm->fn.setItalic( f.italic() ); 5750 fm->stdSize = base;
6063 fm->fn.setUnderline( f.underline() ); 5751 fm->usePixelSizes = usePixels;
6064 fm->update(); 5752 if ( usePixels )
6065 } 5753 fm->fn.setPixelSize( fm->stdSize );
6066 } 5754 else
6067 fm = defFormat; 5755 fm->fn.setPointSize( fm->stdSize );
6068 if ( fm->fn.family() == old.family() && 5756 sheet->scaleFont( fm->fn, fm->logicalFontSize );
6069 fm->fn.weight() == old.weight() && 5757 }
6070 fm->fn.italic() == old.italic() && 5758 if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col )
6071 fm->fn.underline() == old.underline() ) { 5759 fm->col = color;
6072 fm->fn.setFamily( f.family() );
6073 fm->fn.setWeight( f.weight() );
6074 fm->fn.setItalic( f.italic() );
6075 fm->fn.setUnderline( f.underline() );
6076 fm->update(); 5760 fm->update();
6077 } 5761 }
5762
5763 defFormat->fn = font;
5764 defFormat->col = color;
5765 defFormat->update();
5766 defFormat->stdSize = base;
5767 defFormat->usePixelSizes = usePixels;
5768
6078 updateKeys(); 5769 updateKeys();
@@ -6080,3 +5771,2 @@ void QTextFormatCollection::updateFontAttributes( const QFont &f, const QFont &o
6080 5771
6081
6082// the keys in cKey have changed, rebuild the hashtable 5772// the keys in cKey have changed, rebuild the hashtable
@@ -6087,3 +5777,3 @@ void QTextFormatCollection::updateKeys()
6087 cKey.setAutoDelete( FALSE ); 5777 cKey.setAutoDelete( FALSE );
6088 QTextFormat** formats = new QTextFormat*[ cKey.count() + 1]; 5778 QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ];
6089 QTextFormat **f = formats; 5779 QTextFormat **f = formats;
@@ -6098,2 +5788,3 @@ void QTextFormatCollection::updateKeys()
6098 cKey.setAutoDelete( TRUE ); 5788 cKey.setAutoDelete( TRUE );
5789 delete [] formats;
6099} 5790}
@@ -6144,2 +5835,10 @@ void QTextFormat::setUnderline( bool b )
6144 5835
5836void QTextFormat::setStrikeOut( bool b )
5837{
5838 if ( b == fn.strikeOut() )
5839 return;
5840 fn.setStrikeOut( b );
5841 update();
5842}
5843
6145void QTextFormat::setFamily( const QString &f ) 5844void QTextFormat::setFamily( const QString &f )
@@ -6177,45 +5876,8 @@ void QTextFormat::setColor( const QColor &c )
6177 5876
6178static int makeLogicFontSize( int s ) 5877QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f,
6179{ 5878 const QString& oldAnchorHref, const QString& anchorHref ) const
6180 int defSize = QApplication::font().pointSize();
6181 if ( s < defSize - 4 )
6182 return 1;
6183 if ( s < defSize )
6184 return 2;
6185 if ( s < defSize + 4 )
6186 return 3;
6187 if ( s < defSize + 8 )
6188 return 4;
6189 if ( s < defSize + 12 )
6190 return 5;
6191 if (s < defSize + 16 )
6192 return 6;
6193 return 7;
6194}
6195
6196static QTextFormat *defaultFormat = 0;
6197
6198QString QTextFormat::makeFormatChangeTags( QTextFormat *f, const QString& oldAnchorHref, const QString& anchorHref ) const
6199{ 5879{
6200 if ( !defaultFormat ) // #### wrong, use the document's default format instead
6201 defaultFormat = new QTextFormat( QApplication::font(),
6202 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) );
6203
6204 QString tag; 5880 QString tag;
6205 if ( f ) { 5881 if ( f )
6206 if ( f->font() != defaultFormat->font() ) { 5882 tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref );
6207 if ( f->font().family() != defaultFormat->font().family()
6208 || f->font().pointSize() != defaultFormat->font().pointSize()
6209 || f->color().rgb() != defaultFormat->color().rgb() )
6210 tag += "</font>";
6211 if ( f->font().underline() && f->font().underline() != defaultFormat->font().underline() )
6212 tag += "</u>";
6213 if ( f->font().italic() && f->font().italic() != defaultFormat->font().italic() )
6214 tag += "</i>";
6215 if ( f->font().bold() && f->font().bold() != defaultFormat->font().bold() )
6216 tag += "</b>";
6217 }
6218 if ( !oldAnchorHref.isEmpty() )
6219 tag += "</a>";
6220 }
6221 5883
@@ -6224,23 +5886,29 @@ QString QTextFormat::makeFormatChangeTags( QTextFormat *f, const QString& oldAnc
6224 5886
6225 if ( font() != defaultFormat->font() ) {
6226 if ( font().bold() && font().bold() != defaultFormat->font().bold() )
6227 tag += "<b>";
6228 if ( font().italic() && font().italic() != defaultFormat->font().italic() )
6229 tag += "<i>";
6230 if ( font().underline() && font().underline() != defaultFormat->font().underline() )
6231 tag += "<u>";
6232 }
6233 if ( font() != defaultFormat->font() 5887 if ( font() != defaultFormat->font()
5888 || vAlign() != defaultFormat->vAlign()
6234 || color().rgb() != defaultFormat->color().rgb() ) { 5889 || color().rgb() != defaultFormat->color().rgb() ) {
6235 QString f; 5890 QString s;
6236 if ( font().family() != defaultFormat->font().family() ) 5891 if ( font().family() != defaultFormat->font().family() )
6237 f +=" face=\"" + fn.family() + "\""; 5892 s += QString(!!s?";":"") + "font-family:" + fn.family();
6238 if ( font().pointSize() != defaultFormat->font().pointSize() ) { 5893 if ( font().italic() && font().italic() != defaultFormat->font().italic() )
6239 f +=" size=\"" + QString::number( makeLogicFontSize( fn.pointSize() ) ) + "\""; 5894 s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal");
6240 f +=" style=\"font-size:" + QString::number( fn.pointSize() ) + "pt\""; 5895 if ( font().pointSize() != defaultFormat->font().pointSize() )
5896 s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt";
5897 if ( font().weight() != defaultFormat->font().weight() )
5898 s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 );
5899 if ( font().underline() != defaultFormat->font().underline() )
5900 s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none");
5901 if ( vAlign() != defaultFormat->vAlign() ) {
5902 s += QString(!!s?";":"") + "vertical-align:";
5903 if ( vAlign() == QTextFormat::AlignSuperScript )
5904 s += "super";
5905 else if ( vAlign() == QTextFormat::AlignSubScript )
5906 s += "sub";
5907 else
5908 s += "normal";
6241 } 5909 }
6242 if ( color().rgb() != defaultFormat->color().rgb() ) 5910 if ( color().rgb() != defaultFormat->color().rgb() )
6243 f +=" color=\"" + col.name() + "\""; 5911 s += QString(!!s?";":"") + "color:" + col.name();
6244 if ( !f.isEmpty() ) 5912 if ( !s.isEmpty() )
6245 tag += "<font" + f + ">"; 5913 tag += "<span style=\"" + s + "\">";
6246 } 5914 }
@@ -6250,21 +5918,14 @@ QString QTextFormat::makeFormatChangeTags( QTextFormat *f, const QString& oldAnc
6250 5918
6251QString QTextFormat::makeFormatEndTags( const QString& anchorHref ) const 5919QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const
6252{ 5920{
6253 if ( !defaultFormat )
6254 defaultFormat = new QTextFormat( QApplication::font(),
6255 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) );
6256
6257 QString tag; 5921 QString tag;
6258 if ( font() != defaultFormat->font() ) { 5922 if ( font().family() != defaultFormat->font().family()
6259 if ( font().family() != defaultFormat->font().family() 5923 || font().pointSize() != defaultFormat->font().pointSize()
6260 || font().pointSize() != defaultFormat->font().pointSize() 5924 || font().weight() != defaultFormat->font().weight()
6261 || color().rgb() != defaultFormat->color().rgb() ) 5925 || font().italic() != defaultFormat->font().italic()
6262 tag += "</font>"; 5926 || font().underline() != defaultFormat->font().underline()
6263 if ( font().underline() && font().underline() != defaultFormat->font().underline() ) 5927 || font().strikeOut() != defaultFormat->font().strikeOut()
6264 tag += "</u>"; 5928 || vAlign() != defaultFormat->vAlign()
6265 if ( font().italic() && font().italic() != defaultFormat->font().italic() ) 5929 || color().rgb() != defaultFormat->color().rgb() )
6266 tag += "</i>"; 5930 tag += "</span>";
6267 if ( font().bold() && font().bold() != defaultFormat->font().bold() )
6268 tag += "</b>";
6269 }
6270 if ( !anchorHref.isEmpty() ) 5931 if ( !anchorHref.isEmpty() )
@@ -6274,91 +5935,120 @@ QString QTextFormat::makeFormatEndTags( const QString& anchorHref ) const
6274 5935
6275QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr ) const 5936QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const
6276{ 5937{
6277 QTextFormat format(*this); 5938 QTextFormat format(*this);
6278 if ( style ) { 5939 if (!style )
6279 format.style = style->name(); 5940 return format;
6280 if ( style->name() == "font") { 5941
6281 if ( attr.contains("color") ) { 5942 if ( !style->isAnchor() && style->color().isValid() ) {
6282 QString s = attr["color"]; 5943 // the style is not an anchor and defines a color.
6283 if ( !s.isEmpty() ) { 5944 // It might be used inside an anchor and it should
6284 format.col.setNamedColor( s ); 5945 // override the link color.
6285 format.linkColor = FALSE; 5946 format.linkColor = FALSE;
6286 } 5947 }
6287 } 5948 switch ( style->verticalAlignment() ) {
6288 if ( attr.contains("size") ) { 5949 case QStyleSheetItem::VAlignBaseline:
6289 QString a = attr["size"]; 5950 format.setVAlign( QTextFormat::AlignNormal );
6290 int n = a.toInt(); 5951 break;
6291 if ( a[0] == '+' || a[0] == '-' ) 5952 case QStyleSheetItem::VAlignSuper:
6292 n += format.logicalFontSize; 5953 format.setVAlign( QTextFormat::AlignSuperScript );
6293 format.logicalFontSize = n; 5954 break;
6294 if ( format.usePixelSizes ) 5955 case QStyleSheetItem::VAlignSub:
6295 format.fn.setPixelSize( format.stdSize ); 5956 format.setVAlign( QTextFormat::AlignSubScript );
6296 else 5957 break;
6297 format.fn.setPointSize( format.stdSize ); 5958 }
6298 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 5959
6299 } 5960 if ( style->fontWeight() != QStyleSheetItem::Undefined )
6300 if ( attr.contains("style" ) ) { 5961 format.fn.setWeight( style->fontWeight() );
6301 QString a = attr["style"]; 5962 if ( style->fontSize() != QStyleSheetItem::Undefined ) {
6302 if ( a.startsWith( "font-size:" ) ) { 5963 format.fn.setPointSize( style->fontSize() );
6303 QString s = a.mid( a.find( ':' ) + 1 ); 5964 } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) {
6304 int n = s.left( s.length() - 2 ).toInt(); 5965 format.logicalFontSize = style->logicalFontSize();
6305 format.logicalFontSize = 0; 5966 if ( format.usePixelSizes )
6306 if ( format.usePixelSizes ) 5967 format.fn.setPixelSize( format.stdSize );
6307 format.fn.setPixelSize( n ); 5968 else
6308 else 5969 format.fn.setPointSize( format.stdSize );
6309 format.fn.setPointSize( n ); 5970 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
6310 } 5971 } else if ( style->logicalFontSizeStep() ) {
6311 } 5972 format.logicalFontSize += style->logicalFontSizeStep();
6312 if ( attr.contains("face") ) { 5973 if ( format.usePixelSizes )
6313 QString a = attr["face"]; 5974 format.fn.setPixelSize( format.stdSize );
6314 if ( a.contains(',') ) 5975 else
6315 a = a.left( a.find(',') ); 5976 format.fn.setPointSize( format.stdSize );
6316 format.fn.setFamily( a ); 5977 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
6317 } 5978 }
6318 } else { 5979 if ( !style->fontFamily().isEmpty() )
6319 if ( !style->isAnchor() && style->color().isValid() ) { 5980 format.fn.setFamily( style->fontFamily() );
6320 // the style is not an anchor and defines a color. 5981 if ( style->color().isValid() )
6321 // It might be used inside an anchor and it should 5982 format.col = style->color();
6322 // override the link color. 5983 if ( style->definesFontItalic() )
5984 format.fn.setItalic( style->fontItalic() );
5985 if ( style->definesFontUnderline() )
5986 format.fn.setUnderline( style->fontUnderline() );
5987 if ( style->definesFontStrikeOut() )
5988 format.fn.setStrikeOut( style->fontStrikeOut() );
5989
5990
5991 if ( style->name() == "font") {
5992 if ( attr.contains("color") ) {
5993 QString s = attr["color"];
5994 if ( !s.isEmpty() ) {
5995 format.col.setNamedColor( s );
6323 format.linkColor = FALSE; 5996 format.linkColor = FALSE;
6324 } 5997 }
6325 switch ( style->verticalAlignment() ) { 5998 }
6326 case QStyleSheetItem::VAlignBaseline: 5999 if ( attr.contains("face") ) {
6327 format.setVAlign( QTextFormat::AlignNormal ); 6000 QString a = attr["face"];
6328 break; 6001 QString family = QTextDocument::section( a, ",", 0, 0 );
6329 case QStyleSheetItem::VAlignSuper: 6002 if ( !!family )
6330 format.setVAlign( QTextFormat::AlignSuperScript ); 6003 format.fn.setFamily( family );
6331 break; 6004 }
6332 case QStyleSheetItem::VAlignSub: 6005 if ( attr.contains("size") ) {
6333 format.setVAlign( QTextFormat::AlignSubScript ); 6006 QString a = attr["size"];
6334 break; 6007 int n = a.toInt();
6335 } 6008 if ( a[0] == '+' || a[0] == '-' )
6336 6009 n += format.logicalFontSize;
6337 if ( style->fontWeight() != QStyleSheetItem::Undefined ) 6010 format.logicalFontSize = n;
6338 format.fn.setWeight( style->fontWeight() ); 6011 if ( format.usePixelSizes )
6339 if ( style->fontSize() != QStyleSheetItem::Undefined ) { 6012 format.fn.setPixelSize( format.stdSize );
6340 format.fn.setPointSize( style->fontSize() ); 6013 else
6341 } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { 6014 format.fn.setPointSize( format.stdSize );
6342 format.logicalFontSize = style->logicalFontSize(); 6015 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
6343 if ( format.usePixelSizes ) 6016 }
6344 format.fn.setPixelSize( format.stdSize ); 6017 }
6345 else 6018 if ( attr.contains("style" ) ) {
6346 format.fn.setPointSize( format.stdSize ); 6019 QString a = attr["style"];
6347 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 6020 for ( int s = 0; s < a.contains(';')+1; s++ ) {
6348 } else if ( style->logicalFontSizeStep() ) { 6021 QString style = QTextDocument::section( a, ";", s, s );
6349 format.logicalFontSize += style->logicalFontSizeStep(); 6022 if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) {
6350 if ( format.usePixelSizes ) 6023 format.logicalFontSize = 0;
6351 format.fn.setPixelSize( format.stdSize ); 6024 format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) );
6025 } if ( style.startsWith("font-style:" ) ) {
6026 QString s = style.mid( 11 ).stripWhiteSpace();
6027 if ( s == "normal" )
6028 format.fn.setItalic( FALSE );
6029 else if ( s == "italic" || s == "oblique" )
6030 format.fn.setItalic( TRUE );
6031 } else if ( style.startsWith("font-weight:" ) ) {
6032 QString s = style.mid( 12 );
6033 bool ok = TRUE;
6034 int n = s.toInt( &ok );
6035 if ( ok )
6036 format.fn.setWeight( n/8 );
6037 } else if ( style.startsWith("font-family:" ) ) {
6038 format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() );
6039 } else if ( style.startsWith("text-decoration:" ) ) {
6040 QString s = style.mid( 16 ).stripWhiteSpace();
6041 format.fn.setUnderline( s == "underline" );
6042 } else if ( style.startsWith("vertical-align:" ) ) {
6043 QString s = style.mid( 15 ).stripWhiteSpace();
6044 if ( s == "sub" )
6045 format.setVAlign( QTextFormat::AlignSubScript );
6046 else if ( s == "super" )
6047 format.setVAlign( QTextFormat::AlignSuperScript );
6352 else 6048 else
6353 format.fn.setPointSize( format.stdSize ); 6049 format.setVAlign( QTextFormat::AlignNormal );
6354 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 6050 } else if ( style.startsWith("color:" ) ) {
6051 format.col.setNamedColor( style.mid(6) );
6052 format.linkColor = FALSE;
6355 } 6053 }
6356 if ( !style->fontFamily().isEmpty() )
6357 format.fn.setFamily( style->fontFamily() );
6358 if ( style->color().isValid() )
6359 format.col = style->color();
6360 if ( style->definesFontItalic() )
6361 format.fn.setItalic( style->fontItalic() );
6362 if ( style->definesFontUnderline() )
6363 format.fn.setUnderline( style->fontUnderline() );
6364 } 6054 }
@@ -6383,6 +6073,2 @@ QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, co
6383{ 6073{
6384#if defined(PARSER_DEBUG)
6385 qDebug( debug_indent + "new QTextImage (pappi: %p)", p );
6386#endif
6387
6388 width = height = 0; 6074 width = height = 0;
@@ -6399,6 +6085,2 @@ QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, co
6399 6085
6400#if defined(PARSER_DEBUG)
6401 qDebug( debug_indent + " .." + imageName );
6402#endif
6403
6404 if ( !imageName.isEmpty() ) { 6086 if ( !imageName.isEmpty() ) {
@@ -6489,2 +6171,3 @@ QTextImage::~QTextImage()
6489 } 6171 }
6172 delete reg;
6490} 6173}
@@ -6647,3 +6330,3 @@ static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col
6647QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, 6330QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt,
6648 const QChar* doc, int length, int& pos, QTextParag *curpar ) 6331 const QChar* doc, int length, int& pos, QTextParagraph *curpar )
6649{ 6332{
@@ -6667,5 +6350,2 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6667 if ( tagname == "table" ) { 6350 if ( tagname == "table" ) {
6668#if defined(PARSER_DEBUG)
6669 debug_indent.remove( debug_indent.length() - 3, 2 );
6670#endif
6671 return table; 6351 return table;
@@ -6726,6 +6406,6 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6726 QTextTableCell* cell = new QTextTableCell( table, row, col, 6406 QTextTableCell* cell = new QTextTableCell( table, row, col,
6727 attr2, s, fmt.makeTextFormat( s, attr2 ), 6407 attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ),
6728 contxt, *factory_, sheet_, 6408 contxt, *factory_, sheet_,
6729 QString( doc, length).mid( pos, end - pos ) ); 6409 QString( doc, length).mid( pos, end - pos ) );
6730 cell->richText()->parParag = curpar; 6410 cell->richText()->parentPar = curpar;
6731 if ( cell->colspan() > 1 || cell->rowspan() > 1 ) 6411 if ( cell->colspan() > 1 || cell->rowspan() > 1 )
@@ -6742,5 +6422,2 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6742 } 6422 }
6743#if defined(PARSER_DEBUG)
6744 debug_indent.remove( debug_indent.length() - 3, 2 );
6745#endif
6746 return table; 6423 return table;
@@ -7133,15 +6810,6 @@ QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleShe
7133 if ( wsm == QStyleSheetItem::WhiteSpacePre ) { 6810 if ( wsm == QStyleSheetItem::WhiteSpacePre ) {
7134 if ( c == ' ' )
7135 return QChar::nbsp;
7136 else
7137 return c;
7138 } else if ( wsm == QStyleSheetItem_WhiteSpaceNoCompression ) {
7139 return c;
7140 } else if ( wsm == QStyleSheetItem_WhiteSpaceNormalWithNewlines ) {
7141 if ( c == '\n' ) 6811 if ( c == '\n' )
6812 return QChar_linesep;
6813 else
7142 return c; 6814 return c;
7143 while ( pos< length &&
7144 doc[pos].isSpace() && doc[pos] != QChar::nbsp && doc[pos] != '\n' )
7145 pos++;
7146 return ' ';
7147 } else { // non-pre mode: collapse whitespace except nbsp 6815 } else { // non-pre mode: collapse whitespace except nbsp
@@ -7357,7 +7025,2 @@ QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr )
7357 cells.setAutoDelete( FALSE ); 7025 cells.setAutoDelete( FALSE );
7358#if defined(PARSER_DEBUG)
7359 debug_indent += "\t";
7360 qDebug( debug_indent + "new QTextTable (%p)", this );
7361 debug_indent += "\t";
7362#endif
7363 cellspacing = 2; 7026 cellspacing = 2;
@@ -7442,6 +7105,6 @@ QString QTextTable::richText() const
7442 } 7105 }
7443 s += "<td "; 7106 s += "<td";
7444 it = cell->attributes.begin(); 7107 it = cell->attributes.begin();
7445 for ( ; it != cell->attributes.end(); ++it ) 7108 for ( ; it != cell->attributes.end(); ++it )
7446 s += it.key() + "=" + *it + " "; 7109 s += " " + it.key() + "=" + *it;
7447 s += ">"; 7110 s += ">";
@@ -7578,8 +7241,2 @@ void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch,
7578 7241
7579#if defined(DEBUG_TABLE_RENDERING)
7580 p->save();
7581 p->setPen( Qt::red );
7582 p->drawRect( x, y, width, height );
7583 p->restore();
7584#endif
7585} 7242}
@@ -7645,3 +7302,3 @@ void QTextTable::addCell( QTextTableCell* cell )
7645 7302
7646bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, bool atEnd ) 7303bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd )
7647{ 7304{
@@ -7654,3 +7311,3 @@ bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7654 7311
7655bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, const QPoint &pos ) 7312bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos )
7656{ 7313{
@@ -7694,3 +7351,3 @@ bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParag *&para
7694 doc = cell->richText(); 7351 doc = cell->richText();
7695 parag = doc->firstParag(); 7352 parag = doc->firstParagraph();
7696 idx = 0; 7353 idx = 0;
@@ -7701,3 +7358,3 @@ bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParag *&para
7701 7358
7702bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 7359bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7703{ 7360{
@@ -7727,3 +7384,3 @@ bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7727 doc = cell->richText(); 7384 doc = cell->richText();
7728 parag = doc->firstParag(); 7385 parag = doc->firstParagraph();
7729 idx = 0; 7386 idx = 0;
@@ -7734,3 +7391,3 @@ bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7734 7391
7735bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 7392bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7736{ 7393{
@@ -7760,3 +7417,3 @@ bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7760 doc = cell->richText(); 7417 doc = cell->richText();
7761 parag = doc->firstParag(); 7418 parag = doc->lastParagraph();
7762 idx = parag->length() - 1; 7419 idx = parag->length() - 1;
@@ -7767,3 +7424,3 @@ bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7767 7424
7768bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 7425bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7769{ 7426{
@@ -7798,3 +7455,3 @@ bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7798 return FALSE; 7455 return FALSE;
7799 parag = doc->firstParag(); 7456 parag = doc->firstParagraph();
7800 idx = 0; 7457 idx = 0;
@@ -7805,3 +7462,3 @@ bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7805 7462
7806bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 7463bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7807{ 7464{
@@ -7836,3 +7493,3 @@ bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, in
7836 return FALSE; 7493 return FALSE;
7837 parag = doc->lastParag(); 7494 parag = doc->lastParagraph();
7838 idx = parag->length() - 1; 7495 idx = parag->length() - 1;
@@ -7851,6 +7508,2 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7851{ 7508{
7852#if defined(PARSER_DEBUG)
7853 qDebug( debug_indent + "new QTextTableCell1 (pappi: %p)", table );
7854 qDebug( debug_indent + doc );
7855#endif
7856 cached_width = -1; 7509 cached_width = -1;
@@ -7890,3 +7543,4 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7890 richtext->setStyleSheet( sheet ); 7543 richtext->setStyleSheet( sheet );
7891 richtext->setDefaultFont( table->parent->formatCollection()->defaultFormat()->font() ); 7544 richtext->setDefaultFormat( table->parent->formatCollection()->defaultFormat()->font(),
7545 table->parent->formatCollection()->defaultFormat()->color() );
7892 richtext->setRichText( doc, context ); 7546 richtext->setRichText( doc, context );
@@ -7926,30 +7580,2 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7926 7580
7927QTextTableCell::QTextTableCell( QTextTable* table, int row, int column )
7928{
7929#if defined(PARSER_DEBUG)
7930 qDebug( debug_indent + "new QTextTableCell2( pappi: %p", table );
7931#endif
7932 maxw = QWIDGETSIZE_MAX;
7933 minw = 0;
7934 cached_width = -1;
7935 cached_sizehint = -1;
7936
7937 parent = table;
7938 row_ = row;
7939 col_ = column;
7940 stretch_ = 0;
7941 richtext = new QTextDocument( table->parent );
7942 richtext->setTableCell( this );
7943 richtext->setFormatter( table->parent->formatter() );
7944 richtext->setUseFormatCollection( table->parent->useFormatCollection() );
7945 richtext->setDefaultFont( table->parent->formatCollection()->defaultFormat()->font() );
7946 richtext->setRichText( "<html></html>", QString::null );
7947 rowspan_ = 1;
7948 colspan_ = 1;
7949 background = 0;
7950 hasFixedWidth = FALSE;
7951 parent->addCell( this );
7952}
7953
7954
7955QTextTableCell::~QTextTableCell() 7581QTextTableCell::~QTextTableCell()
@@ -8029,3 +7655,3 @@ void QTextTableCell::adjustToPainter( QPainter* p )
8029{ 7655{
8030 QTextParag *parag = richtext->firstParag(); 7656 QTextParagraph *parag = richtext->firstParagraph();
8031 while ( parag ) { 7657 while ( parag ) {
@@ -8073,5 +7699,2 @@ void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, in
8073 QRegion r; 7699 QRegion r;
8074 QTextCursor *c = 0;
8075 if ( richtext->parent()->tmpCursor )
8076 c = richtext->parent()->tmpCursor;
8077 if ( cx >= 0 && cy >= 0 ) 7700 if ( cx >= 0 && cy >= 0 )
@@ -8079,5 +7702,5 @@ void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, in
8079 cy - ( y + geom.y() + verticalAlignmentOffset() ), 7702 cy - ( y + geom.y() + verticalAlignmentOffset() ),
8080 cw, ch, g, FALSE, (c != 0), c ); 7703 cw, ch, g, FALSE, FALSE, 0 );
8081 else 7704 else
8082 richtext->draw( p, -1, -1, -1, -1, g, FALSE, (c != 0), c ); 7705 richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 );
8083 7706
@@ -8085 +7708,137 @@ void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, in
8085} 7708}
7709
7710QString QTextDocument::section( QString str, const QString &sep, int start, int end )
7711{
7712 const QChar *uc = str.unicode();
7713 if ( !uc )
7714 return QString();
7715 QString _sep = sep;
7716 const QChar *uc_sep = _sep.unicode();
7717 if(!uc_sep)
7718 return QString();
7719 bool match = FALSE, last_match = TRUE;
7720
7721 //find start
7722 int n = str.length(), sep_len = _sep.length();
7723 const QChar *begin = start < 0 ? uc + n : uc;
7724 while(start) {
7725 match = FALSE;
7726 int c = 0;
7727 for(const QChar *tmp = start < 0 ? begin - sep_len : begin;
7728 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7729 if( *tmp != *(uc_sep + c) )
7730 break;
7731 if(c == sep_len - 1) {
7732 match = TRUE;
7733 break;
7734 }
7735 }
7736 last_match = match;
7737
7738 if(start < 0) {
7739 if(match) {
7740 begin -= sep_len;
7741 if(!++start)
7742 break;
7743 } else {
7744 if(start == -1 && begin == uc)
7745 break;
7746 begin--;
7747 }
7748 } else {
7749 if(match) {
7750 if(!--start)
7751 break;
7752 begin += sep_len;
7753 } else {
7754 if(start == 1 && begin == uc + n)
7755 break;
7756 begin++;
7757 }
7758 }
7759 if(begin > uc + n || begin < uc)
7760 return QString();
7761 }
7762 if(match)
7763 begin+=sep_len;
7764 if(begin > uc + n || begin < uc)
7765 return QString();
7766
7767 //now find last
7768 match = FALSE;
7769 const QChar *last = end < 0 ? uc + n : uc;
7770 if(end == -1) {
7771 int c = 0;
7772 for(const QChar *tmp = end < 0 ? last - sep_len : last;
7773 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7774 if( *tmp != *(uc_sep + c) )
7775 break;
7776 if(c == sep_len - 1) {
7777 match = TRUE;
7778 break;
7779 }
7780 }
7781 } else {
7782 end++;
7783 last_match = TRUE;
7784 while(end) {
7785 match = FALSE;
7786 int c = 0;
7787 for(const QChar *tmp = end < 0 ? last - sep_len : last;
7788 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7789 if( *tmp != *(uc_sep + c) )
7790 break;
7791 if(c == sep_len - 1) {
7792 match = TRUE;
7793 break;
7794 }
7795 }
7796 last_match = match;
7797
7798 if(end < 0) {
7799 if(match) {
7800 if(!++end)
7801 break;
7802 last -= sep_len;
7803 } else {
7804 last--;
7805 }
7806 } else {
7807 if(match) {
7808 last += sep_len;
7809 if(!--end)
7810 break;
7811 } else {
7812 last++;
7813 }
7814 }
7815 if(last >= uc + n) {
7816 last = uc + n;
7817 break;
7818 } else if(last < uc) {
7819 return QString();
7820 }
7821 }
7822 }
7823 if(match)
7824 last -= sep_len;
7825 if(last < uc || last > uc + n || begin >= last)
7826 return QString();
7827
7828 //done
7829 return QString(begin, last - begin);
7830}
7831
7832bool QTextDocument::endsWith( QString str, const QString &s)
7833{
7834 if ( str.isNull() )
7835 return s.isNull();
7836 int pos = str.length() - s.length();
7837 if ( pos < 0 )
7838 return FALSE;
7839 for ( uint i = 0; i < s.length(); i++ ) {
7840 if ( str.unicode()[pos+i] != s[(int)i] )
7841 return FALSE;
7842 }
7843 return TRUE;
7844}