summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-write
authorleseb <leseb>2002-07-15 23:22:50 (UTC)
committer leseb <leseb>2002-07-15 23:22:50 (UTC)
commit72eb74051ed8f1b7696041e241ab99df3af5b08d (patch) (unidiff)
treebf9beee9469bc4384cb8178fbd6565cf161b4708 /noncore/apps/opie-write
parentdcea0e50a00ed9efb988ded5abf5d39de1bea393 (diff)
downloadopie-72eb74051ed8f1b7696041e241ab99df3af5b08d.zip
opie-72eb74051ed8f1b7696041e241ab99df3af5b08d.tar.gz
opie-72eb74051ed8f1b7696041e241ab99df3af5b08d.tar.bz2
Sync with Qt 3.0.5
Diffstat (limited to 'noncore/apps/opie-write') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-write/qcleanuphandler.h12
-rw-r--r--noncore/apps/opie-write/qcomplextext.cpp3
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp4311
-rw-r--r--noncore/apps/opie-write/qrichtext_p.cpp303
-rw-r--r--noncore/apps/opie-write/qrichtext_p.h576
-rw-r--r--noncore/apps/opie-write/qstylesheet.cpp1230
-rw-r--r--noncore/apps/opie-write/qstylesheet.h16
-rw-r--r--noncore/apps/opie-write/qt3namespace.h1
-rw-r--r--noncore/apps/opie-write/qtextedit.cpp1495
-rw-r--r--noncore/apps/opie-write/qtextedit.h30
10 files changed, 3833 insertions, 4144 deletions
diff --git a/noncore/apps/opie-write/qcleanuphandler.h b/noncore/apps/opie-write/qcleanuphandler.h
index 5c5bf16..2d6eb7c 100644
--- a/noncore/apps/opie-write/qcleanuphandler.h
+++ b/noncore/apps/opie-write/qcleanuphandler.h
@@ -41,11 +41,7 @@
41#endif // QT_H 41#endif // QT_H
42 42
43template<class Type> 43template<class Type>
44#ifdef Q_NO_TEMPLATE_EXPORT
45class QCleanupHandler 44class QCleanupHandler
46#else
47class Q_EXPORT QCleanupHandler
48#endif
49{ 45{
50public: 46public:
51 QCleanupHandler() : cleanupObjects( 0 ) {} 47 QCleanupHandler() : cleanupObjects( 0 ) {}
@@ -88,11 +84,7 @@ private:
88}; 84};
89 85
90template<class Type> 86template<class Type>
91#ifdef Q_NO_TEMPLATE_EXPORT
92class QSingleCleanupHandler 87class QSingleCleanupHandler
93#else
94class Q_EXPORT QSingleCleanupHandler
95#endif
96{ 88{
97public: 89public:
98 QSingleCleanupHandler() : object( 0 ) {} 90 QSingleCleanupHandler() : object( 0 ) {}
@@ -112,11 +104,7 @@ private:
112}; 104};
113 105
114template<class Type> 106template<class Type>
115#ifdef Q_NO_TEMPLATE_EXPORT
116class QSharedCleanupHandler 107class QSharedCleanupHandler
117#else
118class Q_EXPORT QSharedCleanupHandler
119#endif
120{ 108{
121public: 109public:
122 QSharedCleanupHandler() : object( 0 ) {} 110 QSharedCleanupHandler() : object( 0 ) {}
diff --git a/noncore/apps/opie-write/qcomplextext.cpp b/noncore/apps/opie-write/qcomplextext.cpp
index 0fa6c2e..e8b94da 100644
--- a/noncore/apps/opie-write/qcomplextext.cpp
+++ b/noncore/apps/opie-write/qcomplextext.cpp
@@ -66,9 +66,6 @@ QBidiContext::~QBidiContext()
66 delete parent; 66 delete parent;
67} 67}
68 68
69static QChar *shapeBuffer = 0;
70static int shapeBufSize = 0;
71
72/* 69/*
73 Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on 70 Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
74 arabic). 71 arabic).
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
@@ -41,14 +41,11 @@
41#include "qfont.h" 41#include "qfont.h"
42#include "qtextstream.h" 42#include "qtextstream.h"
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"
48#include "qfileinfo.h" 46#include "qfileinfo.h"
49#include "qstylesheet.h" 47#include "qstylesheet.h"
50#include "qmime.h" 48#include "qmime.h"
51#include "qregexp.h"
52#include "qimage.h" 49#include "qimage.h"
53#include "qdragobject.h" 50#include "qdragobject.h"
54#include "qpaintdevicemetrics.h" 51#include "qpaintdevicemetrics.h"
@@ -64,25 +61,19 @@
64 61
65using namespace Qt3; 62using 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
71static QTextFormatCollection *qFormatCollection = 0; 67static 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
83#include "qt_windows.h" 72#include "qt_windows.h"
84#endif 73#endif
85 74
75#define QChar_linesep QChar(0x2028U)
76
86static inline bool is_printer( QPainter *p ) 77static inline bool is_printer( QPainter *p )
87{ 78{
88 if ( !p || !p->device() ) 79 if ( !p || !p->device() )
@@ -177,10 +168,8 @@ bool QTextCommandHistory::isRedoAvailable()
177// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 168// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
178 169
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{
185 for ( int j = 0; j < (int)text.size(); ++j ) { 174 for ( int j = 0; j < (int)text.size(); ++j ) {
186 if ( text[ j ].format() ) 175 if ( text[ j ].format() )
@@ -188,7 +177,7 @@ QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const
188 } 177 }
189} 178}
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 )
193{ 182{
194 for ( int i = 0; i < (int)text.size(); ++i ) { 183 for ( int i = 0; i < (int)text.size(); ++i ) {
@@ -208,22 +197,22 @@ QTextDeleteCommand::~QTextDeleteCommand()
208 197
209QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) 198QTextCursor *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;
215 } 204 }
216 205
217 cursor.setParag( s ); 206 cursor.setParagraph( s );
218 cursor.setIndex( index ); 207 cursor.setIndex( index );
219 int len = text.size(); 208 int len = text.size();
220 if ( c ) 209 if ( c )
221 *c = cursor; 210 *c = cursor;
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 );
228 if ( c ) 217 if ( c )
229 *c = cursor; 218 *c = cursor;
@@ -236,56 +225,40 @@ QTextCursor *QTextDeleteCommand::execute( QTextCursor *c )
236 225
237QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) 226QTextCursor *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;
243 } 232 }
244 233
245 cursor.setParag( s ); 234 cursor.setParagraph( s );
246 cursor.setIndex( index ); 235 cursor.setIndex( index );
247 QString str = QTextString::toString( text ); 236 QString str = QTextString::toString( text );
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 );
254 for ( int i = 0; i < (int)text.size(); ++i ) 243 for ( int i = 0; i < (int)text.size(); ++i )
255 c->gotoNextLetter(); 244 c->gotoNextLetter();
256 } 245 }
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 ) {
286 s->format(); 259 s->format();
287 s->setChanged( TRUE ); 260 s->setChanged( TRUE );
288 if ( s == c->parag() ) 261 if ( s == c->paragraph() )
289 break; 262 break;
290 s = s->next(); 263 s = s->next();
291 } 264 }
@@ -315,20 +288,20 @@ QTextFormatCommand::~QTextFormatCommand()
315 288
316QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) 289QTextCursor *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 )
321 return c; 294 return c;
322 295
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 );
333 doc->removeSelection( QTextDocument::Temp ); 306 doc->removeSelection( QTextDocument::Temp );
334 if ( endIndex == ep->length() ) 307 if ( endIndex == ep->length() )
@@ -339,8 +312,8 @@ QTextCursor *QTextFormatCommand::execute( QTextCursor *c )
339 312
340QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) 313QTextCursor *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 )
345 return 0; 318 return 0;
346 319
@@ -373,7 +346,7 @@ QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
373 } 346 }
374 347
375 QTextCursor end( doc ); 348 QTextCursor end( doc );
376 end.setParag( ep ); 349 end.setParagraph( ep );
377 end.setIndex( endIndex ); 350 end.setIndex( endIndex );
378 if ( endIndex == ep->length() ) 351 if ( endIndex == ep->length() )
379 end.gotoLeft(); 352 end.gotoLeft();
@@ -381,111 +354,73 @@ QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
381 return c; 354 return c;
382} 355}
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;
439} 398}
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;
460} 404}
461 405
462// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 406// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
463 407
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}
477 414
478QTextCursor::QTextCursor( const QTextCursor &c ) 415QTextCursor::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;
490 yOffsets = c.yOffsets; 425 yOffsets = c.yOffsets;
491 valid = c.valid; 426 valid = c.valid;
@@ -493,15 +428,13 @@ QTextCursor::QTextCursor( const QTextCursor &c )
493 428
494QTextCursor &QTextCursor::operator=( const QTextCursor &c ) 429QTextCursor &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;
506 yOffsets = c.yOffsets; 439 yOffsets = c.yOffsets;
507 valid = c.valid; 440 valid = c.valid;
@@ -511,59 +444,52 @@ QTextCursor &QTextCursor::operator=( const QTextCursor &c )
511 444
512bool QTextCursor::operator==( const QTextCursor &c ) const 445bool 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}
516 449
517int QTextCursor::totalOffsetX() const 450int 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;
525 return xoff; 455 return xoff;
526} 456}
527 457
528int QTextCursor::totalOffsetY() const 458int 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;
536 return yoff; 463 return yoff;
537} 464}
538 465
539void QTextCursor::gotoIntoNested( const QPoint &globalPos ) 466void QTextCursor::gotoIntoNested( const QPoint &globalPos )
540{ 467{
541 if ( !doc ) 468 if ( !para )
542 return; 469 return;
543 push(); 470 push();
544 ox = 0; 471 ox = 0;
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}
554 482
555void QTextCursor::invalidateNested() 483void 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 }
568} 494}
569 495
@@ -573,65 +499,63 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
573 bool justInsert = TRUE; 499 bool justInsert = TRUE;
574 QString s( str ); 500 QString s( str );
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
579 if ( checkNewLine ) 508 if ( checkNewLine )
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 ) {
584 for ( int i = 0; i < (int)s.length(); ++i ) { 513 for ( int i = 0; i < (int)s.length(); ++i ) {
585 if ( formatting->at( i ).format() ) { 514 if ( formatting->at( i ).format() ) {
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 }
589 } 518 }
590 } 519 }
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 ) {
618 if ( formatting->at( i + lastIndex ).format() ) { 537 if ( formatting->at( i + lastIndex ).format() ) {
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();
636 while ( p ) { 560 while ( p ) {
637 p->setParagId( p->prev()->paragId() + 1 ); 561 p->setParagId( p->prev()->paragId() + 1 );
@@ -642,17 +566,17 @@ void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QText
642 } 566 }
643 } 567 }
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}
652 576
653void QTextCursor::gotoLeft() 577void QTextCursor::gotoLeft()
654{ 578{
655 if ( string->string()->isRightToLeft() ) 579 if ( para->string()->isRightToLeft() )
656 gotoNextLetter(); 580 gotoNextLetter();
657 else 581 else
658 gotoPreviousLetter(); 582 gotoPreviousLetter();
@@ -664,56 +588,45 @@ void QTextCursor::gotoPreviousLetter()
664 588
665 if ( idx > 0 ) { 589 if ( idx > 0 ) {
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 }
688 } 610 }
689 } 611 }
690
691 const QTextStringChar *tsc = string->at( idx );
692 if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) {
693 processNesting( EnterEnd );
694 }
695} 612}
696 613
697void QTextCursor::push() 614void QTextCursor::push()
698{ 615{
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}
705 621
706void QTextCursor::pop() 622void 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}
718 631
719void QTextCursor::restoreState() 632void QTextCursor::restoreState()
@@ -722,16 +635,16 @@ void QTextCursor::restoreState()
722 pop(); 635 pop();
723} 636}
724 637
725bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link ) 638bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link )
726{ 639{
727 QPoint pos( p ); 640 QPoint pos( p );
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() )
731 pos.setY( s->rect().y() ); 644 pos.setY( s->rect().y() );
732 while ( s ) { 645 while ( s ) {
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() )
736 str = s; 649 str = s;
737 if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() ) 650 if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() )
@@ -744,7 +657,7 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
744 657
745 s = str; 658 s = str;
746 659
747 setParag( s, FALSE ); 660 setParagraph( s );
748 int y = s->rect().y(); 661 int y = s->rect().y();
749 int lines = s->lines(); 662 int lines = s->lines();
750 QTextStringChar *chr = 0; 663 QTextStringChar *chr = 0;
@@ -758,7 +671,7 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
758 ch = s->lineHeight( i ); 671 ch = s->lineHeight( i );
759 if ( !chr ) 672 if ( !chr )
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;
763 } 676 }
764 int nextLine; 677 int nextLine;
@@ -798,15 +711,15 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
798 } 711 }
799 i++; 712 i++;
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();
811 } 724 }
812 return TRUE; 725 return TRUE;
@@ -814,34 +727,34 @@ bool QTextCursor::place( const QPoint &p, QTextParag *s, bool link )
814 727
815void QTextCursor::processNesting( Operation op ) 728void 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;
826 739
827 switch ( op ) { 740 switch ( 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;
846 } 759 }
847 if ( !ok ) 760 if ( !ok )
@@ -850,7 +763,7 @@ void QTextCursor::processNesting( Operation op )
850 763
851void QTextCursor::gotoRight() 764void QTextCursor::gotoRight()
852{ 765{
853 if ( string->string()->isRightToLeft() ) 766 if ( para->string()->isRightToLeft() )
854 gotoPreviousLetter(); 767 gotoPreviousLetter();
855 else 768 else
856 gotoNextLetter(); 769 gotoNextLetter();
@@ -860,34 +773,29 @@ void QTextCursor::gotoNextLetter()
860{ 773{
861 tmpIndex = -1; 774 tmpIndex = -1;
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() ) {
865 processNesting( EnterBegin ); 778 processNesting( EnterBegin );
866 return; 779 return;
867 } 780 }
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 }
892 } 800 }
893 } 801 }
@@ -897,20 +805,20 @@ void QTextCursor::gotoUp()
897{ 805{
898 int indexOfLineStart; 806 int indexOfLineStart;
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 )
902 return; 810 return;
903 811
904 tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); 812 tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart );
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;
909 pop(); 817 pop();
910 processNesting( Up ); 818 processNesting( Up );
911 if ( idx == -1 ) { 819 if ( idx == -1 ) {
912 pop(); 820 pop();
913 if ( !string->prev() ) 821 if ( !para->prev() )
914 return; 822 return;
915 idx = tmpIndex = 0; 823 idx = tmpIndex = 0;
916 } else { 824 } else {
@@ -918,22 +826,22 @@ void QTextCursor::gotoUp()
918 return; 826 return;
919 } 827 }
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 {
934 --line; 842 --line;
935 int oldIndexOfLineStart = indexOfLineStart; 843 int oldIndexOfLineStart = indexOfLineStart;
936 if ( !string->lineStartOfLine( line, &indexOfLineStart ) ) 844 if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
937 return; 845 return;
938 if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart ) 846 if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart )
939 idx = indexOfLineStart + tmpIndex; 847 idx = indexOfLineStart + tmpIndex;
@@ -946,20 +854,20 @@ void QTextCursor::gotoDown()
946{ 854{
947 int indexOfLineStart; 855 int indexOfLineStart;
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 )
951 return; 859 return;
952 860
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;
958 pop(); 866 pop();
959 processNesting( Down ); 867 processNesting( Down );
960 if ( idx == -1 ) { 868 if ( idx == -1 ) {
961 pop(); 869 pop();
962 if ( !string->next() ) 870 if ( !para->next() )
963 return; 871 return;
964 idx = tmpIndex = 0; 872 idx = tmpIndex = 0;
965 } else { 873 } else {
@@ -967,18 +875,18 @@ void QTextCursor::gotoDown()
967 return; 875 return;
968 } 876 }
969 } 877 }
970 QTextParag *s = string->next(); 878 QTextParagraph *s = para->next();
971 while ( s && !s->isVisible() ) 879 while ( s && !s->isVisible() )
972 s = s->next(); 880 s = s->next();
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 )
983 idx = indexOfLineStart + tmpIndex; 891 idx = indexOfLineStart + tmpIndex;
984 else 892 else
@@ -986,11 +894,11 @@ void QTextCursor::gotoDown()
986 } else { 894 } else {
987 ++line; 895 ++line;
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;
995 if ( indexOfLineStart + tmpIndex < end ) 903 if ( indexOfLineStart + tmpIndex < end )
996 idx = indexOfLineStart + tmpIndex; 904 idx = indexOfLineStart + tmpIndex;
@@ -1004,14 +912,14 @@ void QTextCursor::gotoLineEnd()
1004 tmpIndex = -1; 912 tmpIndex = -1;
1005 int indexOfLineStart; 913 int indexOfLineStart;
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 )
1009 return; 917 return;
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--;
1016 idx = indexOfLineStart; 924 idx = indexOfLineStart;
1017 } 925 }
@@ -1022,7 +930,7 @@ void QTextCursor::gotoLineStart()
1022 tmpIndex = -1; 930 tmpIndex = -1;
1023 int indexOfLineStart; 931 int indexOfLineStart;
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 )
1027 return; 935 return;
1028 936
@@ -1031,71 +939,44 @@ void QTextCursor::gotoLineStart()
1031 939
1032void QTextCursor::gotoHome() 940void 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}
1039 947
1040void QTextCursor::gotoEnd() 948void 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}
1050 956
1051void QTextCursor::gotoPageUp( int visibleHeight ) 957void 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}
1069 966
1070void QTextCursor::gotoPageDown( int visibleHeight ) 967void 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}
1095 976
1096void QTextCursor::gotoWordRight() 977void QTextCursor::gotoWordRight()
1097{ 978{
1098 if ( string->string()->isRightToLeft() ) 979 if ( para->string()->isRightToLeft() )
1099 gotoPreviousWord(); 980 gotoPreviousWord();
1100 else 981 else
1101 gotoNextWord(); 982 gotoNextWord();
@@ -1103,7 +984,7 @@ void QTextCursor::gotoWordRight()
1103 984
1104void QTextCursor::gotoWordLeft() 985void QTextCursor::gotoWordLeft()
1105{ 986{
1106 if ( string->string()->isRightToLeft() ) 987 if ( para->string()->isRightToLeft() )
1107 gotoNextWord(); 988 gotoNextWord();
1108 else 989 else
1109 gotoPreviousWord(); 990 gotoPreviousWord();
@@ -1113,7 +994,7 @@ void QTextCursor::gotoPreviousWord()
1113{ 994{
1114 gotoPreviousLetter(); 995 gotoPreviousLetter();
1115 tmpIndex = -1; 996 tmpIndex = -1;
1116 QTextString *s = string->string(); 997 QTextString *s = para->string();
1117 bool allowSame = FALSE; 998 bool allowSame = FALSE;
1118 if ( idx == ((int)s->length()-1) ) 999 if ( idx == ((int)s->length()-1) )
1119 return; 1000 return;
@@ -1135,7 +1016,7 @@ void QTextCursor::gotoPreviousWord()
1135void QTextCursor::gotoNextWord() 1016void QTextCursor::gotoNextWord()
1136{ 1017{
1137 tmpIndex = -1; 1018 tmpIndex = -1;
1138 QTextString *s = string->string(); 1019 QTextString *s = para->string();
1139 bool allowSame = FALSE; 1020 bool allowSame = FALSE;
1140 for ( int i = idx; i < (int)s->length(); ++i ) { 1021 for ( int i = idx; i < (int)s->length(); ++i ) {
1141 if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || 1022 if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' ||
@@ -1153,12 +1034,12 @@ void QTextCursor::gotoNextWord()
1153 1034
1154 if ( idx < ((int)s->length()-1) ) { 1035 if ( idx < ((int)s->length()-1) ) {
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;
1163 } 1044 }
1164 } else { 1045 } else {
@@ -1173,75 +1054,79 @@ bool QTextCursor::atParagStart()
1173 1054
1174bool QTextCursor::atParagEnd() 1055bool 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;
1183 tmpIndex = -1; 1064 tmpIndex = -1;
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 }
1193 } 1074 }
1194 1075
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 ) {
1202 int oi, ni; 1083 int oi, ni;
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;
1209 } 1090 }
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 ) {
1217 s->indent(); 1098 s->indent();
1218 s->format(); 1099 s->format();
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 );
1228 s->append( str, TRUE ); 1109 s->append( str, TRUE );
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 ) {
1239 int oi, ni; 1124 int oi, ni;
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;
1246 } 1131 }
1247 } 1132 }
@@ -1253,58 +1138,26 @@ bool QTextCursor::remove()
1253{ 1138{
1254 tmpIndex = -1; 1139 tmpIndex = -1;
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();
1286 return TRUE; 1152 return TRUE;
1287 } 1153 }
1288 return FALSE; 1154 return FALSE;
1289} 1155}
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()
1305{ 1158{
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 )
1309 return; 1162 return;
1310 1163
@@ -1314,27 +1167,17 @@ void QTextCursor::indent()
1314 idx = ni; 1167 idx = ni;
1315} 1168}
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// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1328 1171
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{
1332 fCollection = new QTextFormatCollection; 1175 fCollection = new QTextFormatCollection;
1333 init(); 1176 init();
1334} 1177}
1335 1178
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{
1339 fCollection = f; 1182 fCollection = f;
1340 init(); 1183 init();
@@ -1342,9 +1185,6 @@ QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f )
1342 1185
1343void QTextDocument::init() 1186void 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;
1349 mightHaveCustomItems = FALSE; 1189 mightHaveCustomItems = FALSE;
1350 if ( par ) 1190 if ( par )
@@ -1363,12 +1203,10 @@ void QTextDocument::init()
1363 minwParag = curParag = 0; 1203 minwParag = curParag = 0;
1364 align = AlignAuto; 1204 align = AlignAuto;
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
1373 underlLinks = par ? par->underlLinks : TRUE; 1211 underlLinks = par ? par->underlLinks : TRUE;
1374 backBrush = 0; 1212 backBrush = 0;
@@ -1380,8 +1218,7 @@ void QTextDocument::init()
1380 else 1218 else
1381 withoutDoubleBuffer = FALSE; 1219 withoutDoubleBuffer = FALSE;
1382 1220
1383 lParag = fParag = createParag( this, 0, 0 ); 1221 lParag = fParag = createParagraph( this, 0, 0 );
1384 tmpCursor = 0;
1385 1222
1386 cx = 0; 1223 cx = 0;
1387 cy = 2; 1224 cy = 2;
@@ -1393,6 +1230,8 @@ void QTextDocument::init()
1393 flow_->setWidth( cw ); 1230 flow_->setWidth( cw );
1394 1231
1395 leftmargin = rightmargin = 4; 1232 leftmargin = rightmargin = 4;
1233 scaleFontsFactor = 1;
1234
1396 1235
1397 selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight ); 1236 selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight );
1398 selectionText[ Standard ] = TRUE; 1237 selectionText[ Standard ] = TRUE;
@@ -1423,14 +1262,16 @@ void QTextDocument::clear( bool createEmptyParag )
1423 if ( flow_ ) 1262 if ( flow_ )
1424 flow_->clear(); 1263 flow_->clear();
1425 while ( fParag ) { 1264 while ( fParag ) {
1426 QTextParag *p = fParag->next(); 1265 QTextParagraph *p = fParag->next();
1427 delete fParag; 1266 delete fParag;
1428 fParag = p; 1267 fParag = p;
1429 } 1268 }
1430 fParag = lParag = 0; 1269 fParag = lParag = 0;
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}
1435 1276
1436int QTextDocument::widthUsed() const 1277int QTextDocument::widthUsed() const
@@ -1449,12 +1290,12 @@ int QTextDocument::height() const
1449 1290
1450 1291
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{
1459 if ( needed == -1 ) { 1300 if ( needed == -1 ) {
1460 minw = 0; 1301 minw = 0;
@@ -1485,7 +1326,7 @@ void QTextDocument::setPlainText( const QString &text )
1485 int lastNl = 0; 1326 int lastNl = 0;
1486 int nl = text.find( '\n' ); 1327 int nl = text.find( '\n' );
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 )
1490 fParag = lParag; 1331 fParag = lParag;
1491 QString s = text; 1332 QString s = text;
@@ -1496,7 +1337,7 @@ void QTextDocument::setPlainText( const QString &text )
1496 } 1337 }
1497 } else { 1338 } else {
1498 for (;;) { 1339 for (;;) {
1499 lParag = createParag( this, lParag, 0 ); 1340 lParag = createParagraph( this, lParag, 0 );
1500 if ( !fParag ) 1341 if ( !fParag )
1501 fParag = lParag; 1342 fParag = lParag;
1502 QString s = text.mid( lastNl, nl - lastNl ); 1343 QString s = text.mid( lastNl, nl - lastNl );
@@ -1514,7 +1355,7 @@ void QTextDocument::setPlainText( const QString &text )
1514 } 1355 }
1515 } 1356 }
1516 if ( !lParag ) 1357 if ( !lParag )
1517 lParag = fParag = createParag( this, 0, 0 ); 1358 lParag = fParag = createParagraph( this, 0, 0 );
1518} 1359}
1519 1360
1520struct Q_EXPORT QTextDocumentTag { 1361struct Q_EXPORT QTextDocumentTag {
@@ -1559,75 +1400,77 @@ struct Q_EXPORT QTextDocumentTag {
1559#endif 1400#endif
1560}; 1401};
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
1575 1422
1576void QTextDocument::setRichText( const QString &text, const QString &context ) 1423void QTextDocument::setRichText( const QString &text, const QString &context )
1577{ 1424{
1578 setTextFormat( Qt::RichText );
1579 if ( !context.isEmpty() ) 1425 if ( !context.isEmpty() )
1580 setContext( context ); 1426 setContext( 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;
1621 QValueStack<QTextDocumentTag> tags; 1439 QValueStack<QTextDocumentTag> tags;
1622 QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); 1440 QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() );
1623 QTextDocumentTag curtag = initag; 1441 QTextDocumentTag curtag = initag;
1624 bool space = TRUE; 1442 bool space = TRUE;
1443 bool canMergeLi = FALSE;
1444
1445 bool textEditMode = FALSE;
1625 1446
1626 const QChar* doc = text.unicode(); 1447 const QChar* doc = text.unicode();
1627 int length = text.length(); 1448 int length = text.length();
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 ) {
1632 if ( hasPrefix(doc, length, pos, '<' ) ){ 1475 if ( hasPrefix(doc, length, pos, '<' ) ){
1633 if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { 1476 if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) {
@@ -1638,33 +1481,8 @@ void QTextDocument::setRichTextInternal( const QString &text )
1638 if ( tagname.isEmpty() ) 1481 if ( tagname.isEmpty() )
1639 continue; // nothing we could do with this, probably parse error 1482 continue; // nothing we could do with this, probably parse error
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 ) {
1669 // we might have to close some 'forgotten' tags 1487 // we might have to close some 'forgotten' tags
1670 while ( !nstyle->allowedInContext( curtag.style ) ) { 1488 while ( !nstyle->allowedInContext( curtag.style ) ) {
@@ -1677,57 +1495,74 @@ void QTextDocument::setRichTextInternal( const QString &text )
1677 curtag = tags.pop(); 1495 curtag = tags.pop();
1678 } 1496 }
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" ) {
1683 if ( tags.isEmpty() ) 1506 if ( tags.isEmpty() )
1684 break; 1507 break;
1685 curtag = tags.pop(); 1508 curtag = tags.pop();
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 }
1690 1532
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 }
1732 } 1567 }
1733 if ( !img.isNull() ) { 1568 if ( !img.isNull() ) {
@@ -1736,8 +1571,9 @@ void QTextDocument::setRichTextInternal( const QString &text )
1736 QBrush *b = new QBrush( QColor(), pm ); 1571 QBrush *b = new QBrush( QColor(), pm );
1737 setPaper( b ); 1572 setPaper( b );
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 ) {
1742 QDict<QTextFormat> formats = formatCollection()->dict(); 1578 QDict<QTextFormat> formats = formatCollection()->dict();
1743 QDictIterator<QTextFormat> it( formats ); 1579 QDictIterator<QTextFormat> it( formats );
@@ -1752,24 +1588,51 @@ void QTextDocument::setRichTextInternal( const QString &text )
1752 formatCollection()->defaultFormat()->setColor( c ); 1588 formatCollection()->defaultFormat()->setColor( c );
1753 curtag.format.setColor( c ); 1589 curtag.format.setColor( c );
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
1765 if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it 1630 if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it
1766 continue; 1631 continue;
1767 1632
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('*') );
1774 curpar->setFormat( index, 1, &format ); 1637 curpar->setFormat( index, 1, &format );
1775 curpar->at( index )->setCustomItem( custom ); 1638 curpar->at( index )->setCustomItem( custom );
@@ -1782,14 +1645,9 @@ void QTextDocument::setRichTextInternal( const QString &text )
1782 registerCustomItem( custom, curpar ); 1645 registerCustomItem( custom, curpar );
1783 hasNewPar = FALSE; 1646 hasNewPar = FALSE;
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 );
1794 } else { 1652 } else {
1795 if ( !tags.isEmpty() ) 1653 if ( !tags.isEmpty() )
@@ -1798,16 +1656,20 @@ void QTextDocument::setRichTextInternal( const QString &text )
1798 curtag = initag; 1656 curtag = initag;
1799 } 1657 }
1800 1658
1801 const QStyleSheetItem* ostyle = curtag.style;
1802
1803 curtag.name = tagname; 1659 curtag.name = tagname;
1804 curtag.style = nstyle; 1660 curtag.style = nstyle;
1805 curtag.name = tagname; 1661 curtag.name = tagname;
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() ) {
1812 if ( !anchorName.isEmpty() ) 1674 if ( !anchorName.isEmpty() )
1813 anchorName += "#" + attr["name"]; 1675 anchorName += "#" + attr["name"];
@@ -1819,68 +1681,101 @@ void QTextDocument::setRichTextInternal( const QString &text )
1819 if ( nstyle->alignment() != QStyleSheetItem::Undefined ) 1681 if ( nstyle->alignment() != QStyleSheetItem::Undefined )
1820 curtag.alignment = nstyle->alignment(); 1682 curtag.alignment = nstyle->alignment();
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 }
1867 } 1767 }
1868 } else { 1768 } else {
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() )
1872 continue; // nothing we could do with this, probably parse error 1771 continue; // nothing we could do with this, probably parse error
1873 if ( !sheet_->item( tagname ) ) // ignore unknown tags 1772 if ( !sheet_->item( tagname ) ) // ignore unknown tags
1874 continue; 1773 continue;
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
1885 // html slopiness: handle unbalanched tag closing 1780 // html slopiness: handle unbalanched tag closing
1886 while ( curtag.name != tagname ) { 1781 while ( curtag.name != tagname ) {
@@ -1901,11 +1796,8 @@ void QTextDocument::setRichTextInternal( const QString &text )
1901 curtag = initag; 1796 curtag = initag;
1902 1797
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;
1910 } 1802 }
1911 } 1803 }
@@ -1914,17 +1806,42 @@ void QTextDocument::setRichTextInternal( const QString &text )
1914 QString s; 1806 QString s;
1915 QChar c; 1807 QChar c;
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
1929 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) 1846 if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space )
1930 continue; 1847 continue;
@@ -1935,9 +1852,7 @@ void QTextDocument::setRichTextInternal( const QString &text )
1935 } 1852 }
1936 if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { 1853 if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) {
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 );
1942 QTextFormat* f = formatCollection()->format( &curtag.format ); 1857 QTextFormat* f = formatCollection()->format( &curtag.format );
1943 curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already 1858 curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already
@@ -1951,25 +1866,179 @@ void QTextDocument::setRichTextInternal( const QString &text )
1951 anchorName = QString::null; 1866 anchorName = QString::null;
1952 } 1867 }
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
1965 curpar = curpar->p; 1873 curpar = curpar->p;
1966 delete curpar->n; 1874 delete curpar->n;
1967 } 1875 }
1968
1969 if ( !anchorName.isEmpty() ) { 1876 if ( !anchorName.isEmpty() ) {
1970 curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); 1877 curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() );
1971 anchorName = QString::null; 1878 anchorName = QString::null;
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}
1974 2043
1975void QTextDocument::setText( const QString &text, const QString &context ) 2044void QTextDocument::setText( const QString &text, const QString &context )
@@ -1983,159 +2052,218 @@ void QTextDocument::setText( const QString &text, const QString &context )
1983 setPlainText( text ); 2052 setPlainText( text );
1984} 2053}
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;
2113} 2243}
2114 2244
2115QString QTextDocument::text() const 2245QString 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}
2123 2251
2124QString QTextDocument::text( int parag ) const 2252QString QTextDocument::text( int parag ) const
2125{ 2253{
2126 QTextParag *p = paragAt( parag ); 2254 QTextParagraph *p = paragAt( parag );
2127 if ( !p ) 2255 if ( !p )
2128 return QString::null; 2256 return QString::null;
2129 2257
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}
2135 2263
2136void QTextDocument::invalidate() 2264void QTextDocument::invalidate()
2137{ 2265{
2138 QTextParag *s = fParag; 2266 QTextParagraph *s = fParag;
2139 while ( s ) { 2267 while ( s ) {
2140 s->invalidate( 0 ); 2268 s->invalidate( 0 );
2141 s = s->next(); 2269 s = s->next();
@@ -2148,7 +2276,7 @@ void QTextDocument::selectionStart( int id, int &paragId, int &index )
2148 if ( it == selections.end() ) 2276 if ( it == selections.end() )
2149 return; 2277 return;
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();
2153} 2281}
2154 2282
@@ -2180,32 +2308,10 @@ void QTextDocument::selectionEnd( int id, int &paragId, int &index )
2180 if ( it == selections.end() ) 2308 if ( it == selections.end() )
2181 return; 2309 return;
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();
2185} 2313}
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 )
2210{ 2316{
2211 nSelections = QMAX( nSelections, id + 1 ); 2317 nSelections = QMAX( nSelections, id + 1 );
@@ -2220,22 +2326,22 @@ static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCur
2220 c2 = start; 2326 c2 = start;
2221 } 2327 }
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 }
2231 2337
2232 sel.startCursor = start; 2338 sel.startCursor = start;
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();
2236} 2342}
2237 2343
2238bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor ) 2344bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor )
2239{ 2345{
2240 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2346 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2241 if ( it == selections.end() ) 2347 if ( it == selections.end() )
@@ -2243,7 +2349,7 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2243 QTextDocumentSelection &sel = *it; 2349 QTextDocumentSelection &sel = *it;
2244 2350
2245 QTextCursor start = sel.startCursor; 2351 QTextCursor start = sel.startCursor;
2246 QTextCursor end = *cursor; 2352 QTextCursor end = cursor;
2247 2353
2248 if ( start == end ) { 2354 if ( start == end ) {
2249 removeSelection( id ); 2355 removeSelection( id );
@@ -2251,7 +2357,7 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2251 return TRUE; 2357 return TRUE;
2252 } 2358 }
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 );
2256 return TRUE; 2362 return TRUE;
2257 } 2363 }
@@ -2262,10 +2368,9 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2262 if ( sel.swapped ) 2368 if ( sel.swapped )
2263 tmp = sel.endCursor; 2369 tmp = sel.endCursor;
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;
2270 bool hadEnd = FALSE; 2375 bool hadEnd = FALSE;
2271 bool hadStartParag = FALSE; 2376 bool hadStartParag = FALSE;
@@ -2279,9 +2384,9 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2279 hadStart = TRUE; 2384 hadStart = TRUE;
2280 if ( c == end ) 2385 if ( c == end )
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;
2286 if ( c == sel.startCursor ) 2391 if ( c == sel.startCursor )
2287 hadOldStart = TRUE; 2392 hadOldStart = TRUE;
@@ -2290,17 +2395,17 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2290 2395
2291 if ( !sel.swapped && 2396 if ( !sel.swapped &&
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;
2295 2400
2296 if ( c == end && hadStartParag || 2401 if ( c == end && hadStartParag ||
2297 c == start && hadEndParag ) { 2402 c == start && hadEndParag ) {
2298 QTextCursor tmp = c; 2403 QTextCursor tmp = c;
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 }
2305 } 2410 }
2306 2411
@@ -2310,39 +2415,51 @@ bool QTextDocument::setSelectionEnd( int id, QTextCursor *cursor )
2310 else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) 2415 else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) )
2311 inSelection = TRUE; 2416 inSelection = TRUE;
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 }
2329 } 2434 }
2330 2435
2331 if ( leftSelection ) 2436 if ( leftSelection )
2332 inSelection = FALSE; 2437 inSelection = FALSE;
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 }
2339 2456
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
2343 sel.startCursor = start; 2460 sel.startCursor = start;
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();
2347 2464
2348 setSelectionEndHelper( id, sel, start, end ); 2465 setSelectionEndHelper( id, sel, start, end );
@@ -2358,106 +2475,49 @@ void QTextDocument::selectAll( int id )
2358 sel.swapped = FALSE; 2475 sel.swapped = FALSE;
2359 QTextCursor c( this ); 2476 QTextCursor c( this );
2360 2477
2361 c.setParag( fParag ); 2478 c.setParagraph( fParag );
2362 c.setIndex( 0 ); 2479 c.setIndex( 0 );
2363 sel.startCursor = c; 2480 sel.startCursor = c;
2364 2481
2365 c.setParag( lParag ); 2482 c.setParagraph( lParag );
2366 c.setIndex( lParag->length() - 1 ); 2483 c.setIndex( lParag->length() - 1 );
2367 sel.endCursor = c; 2484 sel.endCursor = c;
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();
2381 } 2492 }
2382 2493
2383 selections.insert( id, sel ); 2494 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
2495 d->selectAll( id );
2384} 2496}
2385 2497
2386bool QTextDocument::removeSelection( int id ) 2498bool 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 );
2455 return TRUE; 2516 return TRUE;
2456} 2517}
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 );
2462 if ( it == selections.end() ) 2522 if ( it == selections.end() )
2463 return QString::null; 2523 return QString::null;
@@ -2481,20 +2541,20 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2481 entire table. This is still far better than the 3.0.2, where 2541 entire table. This is still far better than the 3.0.2, where
2482 you always got the entire table. 2542 you always got the entire table.
2483 2543
2484 ### Fix this properly for 3.0.4. 2544 ### Fix this properly when refactoring
2485 */ 2545 */
2486 while ( c2.nestedDepth() > c1.nestedDepth() ) 2546 while ( c2.nestedDepth() > c1.nestedDepth() )
2487 c2.oneUp(); 2547 c2.oneUp();
2488 while ( c1.nestedDepth() > c2.nestedDepth() ) 2548 while ( c1.nestedDepth() > c2.nestedDepth() )
2489 c1.oneUp(); 2549 c1.oneUp();
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();
2493 c2.oneUp(); 2553 c2.oneUp();
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;
2499 c2 = c1; 2559 c2 = c1;
2500 c1 = tmp; 2560 c1 = tmp;
@@ -2502,14 +2562,26 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2502 2562
2503 // end selection 3.0.3 improvement 2563 // end selection 3.0.3 improvement
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();
2510 if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) 2582 if ( p->at( QMAX( 0, end - 1 ) )->isCustom() )
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() );
2514 } else { 2586 } else {
2515 for ( int i = c1.index(); i < end; ++i ) { 2587 for ( int i = c1.index(); i < end; ++i ) {
@@ -2527,41 +2599,47 @@ QString QTextDocument::selectedText( int id, bool withCustom ) const
2527 } 2599 }
2528 } 2600 }
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;
2566} 2644}
2567 2645
@@ -2583,28 +2661,18 @@ void QTextDocument::setFormat( int id, QTextFormat *f, int flags )
2583 c2.restoreState(); 2661 c2.restoreState();
2584 c1.restoreState(); 2662 c1.restoreState();
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;
2589 } 2667 }
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 );
2595 p = p->next(); 2673 p = p->next();
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}
2609 2677
2610void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) 2678void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
@@ -2632,33 +2700,33 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2632 *cursor = c1; 2700 *cursor = c1;
2633 removeSelection( id ); 2701 removeSelection( id );
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;
2638 } 2706 }
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 );
2643 2711
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();
2647 if ( cursor->isValid() ) 2715 if ( cursor->isValid() )
2648 didGoLeft = TRUE; 2716 didGoLeft = TRUE;
2649 } 2717 }
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();
2657 dy -= p->rect().height(); 2725 dy -= p->rect().height();
2658 delete p; 2726 delete p;
2659 p = tmp; 2727 p = tmp;
2660 } 2728 }
2661 c2.parag()->remove( 0, c2.index() ); 2729 c2.paragraph()->remove( 0, c2.index() );
2662 while ( p ) { 2730 while ( p ) {
2663 p->move( dy ); 2731 p->move( dy );
2664 p->invalidate( 0 ); 2732 p->invalidate( 0 );
@@ -2666,7 +2734,7 @@ void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2666 p = p->next(); 2734 p = p->next();
2667 } 2735 }
2668 2736
2669 c1.parag()->join( c2.parag() ); 2737 c1.paragraph()->join( c2.paragraph() );
2670 2738
2671 if ( didGoLeft ) 2739 if ( didGoLeft )
2672 cursor->gotoNextLetter(); 2740 cursor->gotoNextLetter();
@@ -2679,14 +2747,14 @@ void QTextDocument::indentSelection( int id )
2679 return; 2747 return;
2680 2748
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 ) {
2691 p->indent(); 2759 p->indent();
2692 p = p->next(); 2760 p = p->next();
@@ -2708,84 +2776,69 @@ QTextCursor *QTextDocument::redo( QTextCursor *c )
2708 return commandHistory->redo( c ); 2776 return commandHistory->redo( c );
2709} 2777}
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;
2777} 2835}
2778 2836
2779void QTextDocument::setTextFormat( Qt::TextFormat f ) 2837void QTextDocument::setTextFormat( Qt::TextFormat f )
2780{ 2838{
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}
2790 2843
2791Qt::TextFormat QTextDocument::textFormat() const 2844Qt::TextFormat QTextDocument::textFormat() const
@@ -2800,17 +2853,17 @@ bool QTextDocument::inSelection( int selId, const QPoint &pos ) const
2800 return FALSE; 2853 return FALSE;
2801 2854
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 ) {
2815 if ( p->rect().contains( pos ) ) { 2868 if ( p->rect().contains( pos ) ) {
2816 bool inSel = FALSE; 2869 bool inSel = FALSE;
@@ -2855,7 +2908,7 @@ void QTextDocument::doLayout( QPainter *p, int w )
2855 flow_->setWidth( w ); 2908 flow_->setWidth( w );
2856 cw = w; 2909 cw = w;
2857 vw = w; 2910 vw = w;
2858 QTextParag *parag = fParag; 2911 QTextParagraph *parag = fParag;
2859 while ( parag ) { 2912 while ( parag ) {
2860 parag->invalidate( 0 ); 2913 parag->invalidate( 0 );
2861 if ( p ) 2914 if ( p )
@@ -2868,24 +2921,16 @@ void QTextDocument::doLayout( QPainter *p, int w )
2868 2921
2869QPixmap *QTextDocument::bufferPixmap( const QSize &s ) 2922QPixmap *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;
2884} 2929}
2885 2930
2886void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) 2931void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper )
2887{ 2932{
2888 if ( !firstParag() ) 2933 if ( !firstParagraph() )
2889 return; 2934 return;
2890 2935
2891 if ( paper ) { 2936 if ( paper ) {
@@ -2894,21 +2939,10 @@ void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg,
2894 p->fillRect( rect, *paper ); 2939 p->fillRect( rect, *paper );
2895 } 2940 }
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 ) {
2913 if ( !parag->isValid() ) 2947 if ( !parag->isValid() )
2914 parag->format(); 2948 parag->format();
@@ -2932,7 +2966,7 @@ void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg,
2932 } 2966 }
2933} 2967}
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,
2937 bool drawCursor, QTextCursor *cursor, bool resetChanged ) 2971 bool drawCursor, QTextCursor *cursor, bool resetChanged )
2938{ 2972{
@@ -2965,23 +2999,11 @@ void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, i
2965 2999
2966 painter->setBrushOrigin( -ir.x(), -ir.y() ); 3000 painter->setBrushOrigin( -ir.x(), -ir.y() );
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
2986 painter->translate( -( ir.x() - parag->rect().x() ), 3008 painter->translate( -( ir.x() - parag->rect().x() ),
2987 -( ir.y() - parag->rect().y() ) ); 3009 -( ir.y() - parag->rect().y() ) );
@@ -2995,17 +3017,19 @@ void QTextDocument::drawParag( QPainter *p, QTextParag *parag, int cx, int cy, i
2995 painter->translate( -ir.x(), -ir.y() ); 3017 painter->translate( -ir.x(), -ir.y() );
2996 } 3018 }
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 }
3004 3028
3005 parag->document()->nextDoubleBuffered = FALSE; 3029 parag->document()->nextDoubleBuffered = FALSE;
3006} 3030}
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 )
3010{ 3034{
3011 if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { 3035 if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) {
@@ -3016,11 +3040,9 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3016 } 3040 }
3017 withoutDoubleBuffer = FALSE; 3041 withoutDoubleBuffer = FALSE;
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 ) {
3025 cx = 0; 3047 cx = 0;
3026 cy = 0; 3048 cy = 0;
@@ -3028,52 +3050,43 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3028 ch = height(); 3050 ch = height();
3029 } 3051 }
3030 3052
3031 QTextParag *lastFormatted = 0; 3053 QTextParagraph *lastFormatted = 0;
3032 QTextParag *parag = firstParag(); 3054 QTextParagraph *parag = firstParagraph();
3033 3055
3034 QPixmap *doubleBuffer = 0; 3056 QPixmap *doubleBuffer = 0;
3035 QPainter painter; 3057 QPainter painter;
3036 3058
3059 bool fullWidthSelection = FALSE;
3037 while ( parag ) { 3060 while ( parag ) {
3038 lastFormatted = parag; 3061 lastFormatted = parag;
3039 if ( !parag->isValid() ) 3062 if ( !parag->isValid() )
3040 parag->format(); 3063 parag->format();
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();
3057 continue; 3072 continue;
3058 } 3073 }
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();
3062 } 3077 }
3063 3078
3064 parag = lastParag(); 3079 parag = lastParagraph();
3065 3080
3066 floating: 3081 floating:
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(),
3070 parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), 3085 parag->document()->height() - ( parag->rect().y() + parag->rect().height() ),
3071 cg.brush( QColorGroup::Base ) ); 3086 cg.brush( QColorGroup::Base ) );
3072 } 3087 }
3073 if ( !flow()->isEmpty() ) { 3088 if ( !flow()->isEmpty() ) {
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 );
3078 } 3091 }
3079 } 3092 }
@@ -3083,22 +3096,35 @@ QTextParag *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, co
3083 buf_pixmap = 0; 3096 buf_pixmap = 0;
3084 } 3097 }
3085 3098
3086 tmpCursor = 0;
3087 return lastFormatted; 3099 return lastFormatted;
3088} 3100}
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{
3103 if ( i && i->placement() != QTextCustomItem::PlaceInline ) { 3129 if ( i && i->placement() != QTextCustomItem::PlaceInline ) {
3104 flow_->registerFloatingItem( i ); 3130 flow_->registerFloatingItem( i );
@@ -3108,7 +3134,7 @@ void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParag *p )
3108 p->mightHaveCustomItems = mightHaveCustomItems = TRUE; 3134 p->mightHaveCustomItems = mightHaveCustomItems = TRUE;
3109} 3135}
3110 3136
3111void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParag *p ) 3137void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p )
3112{ 3138{
3113 flow_->unregisterFloatingItem( i ); 3139 flow_->unregisterFloatingItem( i );
3114 p->unregisterFloatingItem( i ); 3140 p->unregisterFloatingItem( i );
@@ -3143,7 +3169,7 @@ bool QTextDocument::focusNextPrevChild( bool next )
3143 focusIndicator.href = QString::null; 3169 focusIndicator.href = QString::null;
3144 3170
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;
3148 while ( p ) { 3174 while ( p ) {
3149 for ( int i = index; i < p->length(); ++i ) { 3175 for ( int i = index; i < p->length(); ++i ) {
@@ -3202,7 +3228,7 @@ bool QTextDocument::focusNextPrevChild( bool next )
3202 p = p->next(); 3228 p = p->next();
3203 } 3229 }
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;
3207 if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) 3233 if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 )
3208 index++; 3234 index++;
@@ -3282,7 +3308,7 @@ bool QTextDocument::focusNextPrevChild( bool next )
3282int QTextDocument::length() const 3308int QTextDocument::length() const
3283{ 3309{
3284 int l = 0; 3310 int l = 0;
3285 QTextParag *p = fParag; 3311 QTextParagraph *p = fParag;
3286 while ( p ) { 3312 while ( p ) {
3287 l += p->length() - 1; // don't count trailing space 3313 l += p->length() - 1; // don't count trailing space
3288 p = p->next(); 3314 p = p->next();
@@ -3385,20 +3411,25 @@ QTextString::QTextString( const QTextString &s )
3385 3411
3386void QTextString::insert( int index, const QString &s, QTextFormat *f ) 3412void 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;
3396 data[ (int)index + i ].lineStart = 0; 3427 data[ (int)index + i ].lineStart = 0;
3397 data[ (int)index + i ].d.format = 0; 3428 data[ (int)index + i ].d.format = 0;
3398 data[ (int)index + i ].type = QTextStringChar::Regular; 3429 data[ (int)index + i ].type = QTextStringChar::Regular;
3399 data[ (int)index + i ].rightToLeft = 0; 3430 data[ (int)index + i ].rightToLeft = 0;
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 );
3403 } 3434 }
3404 bidiDirty = TRUE; 3435 bidiDirty = TRUE;
@@ -3409,7 +3440,7 @@ QTextString::~QTextString()
3409 clear(); 3440 clear();
3410} 3441}
3411 3442
3412void QTextString::insert( int index, QTextStringChar *c ) 3443void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat )
3413{ 3444{
3414 int os = data.size(); 3445 int os = data.size();
3415 data.resize( data.size() + 1 ); 3446 data.resize( data.size() + 1 );
@@ -3423,6 +3454,8 @@ void QTextString::insert( int index, QTextStringChar *c )
3423 data[ (int)index ].rightToLeft = 0; 3454 data[ (int)index ].rightToLeft = 0;
3424 data[ (int)index ].d.format = 0; 3455 data[ (int)index ].d.format = 0;
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() );
3427 bidiDirty = TRUE; 3460 bidiDirty = TRUE;
3428} 3461}
@@ -3545,46 +3578,41 @@ void QTextDocument::setStyleSheet( QStyleSheet *s )
3545 if ( !s ) 3578 if ( !s )
3546 return; 3579 return;
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}
3577 3605
3578void QTextStringChar::setFormat( QTextFormat *f ) 3606void QTextStringChar::setFormat( QTextFormat *f )
3579{ 3607{
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 }
3589} 3617}
3590 3618
@@ -3651,7 +3679,7 @@ int QTextString::width( int idx ) const
3651{ 3679{
3652 int w = 0; 3680 int w = 0;
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;
3656 if( c->isCustom() ) { 3684 if( c->isCustom() ) {
3657 if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) 3685 if( c->customItem()->placement() == QTextCustomItem::PlaceInline )
@@ -3699,50 +3727,28 @@ QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const
3699 return a; 3727 return a;
3700} 3728}
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 ) {
3739 tabStopWidth = defFormat->width( 'x' ) * 8; 3749 tabStopWidth = defFormat->width( 'x' ) * 8;
3740 pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); 3750 pseudoDocument()->commandHistory = new QTextCommandHistory( 100 );
3741 } 3751 }
3742#if defined(PARSER_DEBUG)
3743 qDebug( debug_indent + "new QTextParag" );
3744#endif
3745 fullWidth = TRUE;
3746 3752
3747 if ( p ) 3753 if ( p )
3748 p->n = this; 3754 p->n = this;
@@ -3751,35 +3757,30 @@ QTextParag::QTextParag( QTextDocument *d, QTextParag *pr, QTextParag *nx, bool u
3751 3757
3752 3758
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
3763 if ( p ) 3766 if ( p )
3764 id = p->id + 1; 3767 id = p->id + 1;
3765 else 3768 else
3766 id = 0; 3769 id = 0;
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;
3774 } 3776 }
3775 } 3777 }
3776 firstPProcess = TRUE;
3777 3778
3778 str = new QTextString(); 3779 str = new QTextString();
3779 str->insert( 0, " ", formatCollection()->defaultFormat() ); 3780 str->insert( 0, " ", formatCollection()->defaultFormat() );
3780} 3781}
3781 3782
3782QTextParag::~QTextParag() 3783QTextParagraph::~QTextParagraph()
3783{ 3784{
3784 delete str; 3785 delete str;
3785 if ( hasdoc ) { 3786 if ( hasdoc ) {
@@ -3796,36 +3797,34 @@ QTextParag::~QTextParag()
3796 if ( tArray ) 3797 if ( tArray )
3797 delete [] tArray; 3798 delete [] tArray;
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 )
3801 delete *it; 3802 delete *it;
3802 if ( mSelections ) 3803 if ( mSelections )
3803 delete mSelections; 3804 delete mSelections;
3804 if ( mFloatingItems ) 3805 if ( mFloatingItems )
3805 delete mFloatingItems; 3806 delete mFloatingItems;
3806 if ( mStyleSheetItemsVec )
3807 delete mStyleSheetItemsVec;
3808 if ( p ) 3807 if ( p )
3809 p->setNext( n ); 3808 p->setNext( n );
3810 if ( n ) 3809 if ( n )
3811 n->setPrev( p ); 3810 n->setPrev( p );
3812} 3811}
3813 3812
3814void QTextParag::setNext( QTextParag *s ) 3813void QTextParagraph::setNext( QTextParagraph *s )
3815{ 3814{
3816 n = s; 3815 n = 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{
3823 p = s; 3822 p = 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{
3830 if ( invalid < 0 ) 3829 if ( invalid < 0 )
3831 invalid = chr; 3830 invalid = chr;
@@ -3835,28 +3834,40 @@ void QTextParag::invalidate( int chr )
3835 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) 3834 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
3836 i->ypos = -1; 3835 i->ypos = -1;
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 );
3849 needPreProcess = TRUE; 3860 needPreProcess = TRUE;
3850} 3861}
3851 3862
3852void QTextParag::truncate( int index ) 3863void QTextParagraph::truncate( int index )
3853{ 3864{
3854 str->truncate( index ); 3865 str->truncate( index );
3855 insert( length(), " " ); 3866 insert( length(), " " );
3856 needPreProcess = TRUE; 3867 needPreProcess = TRUE;
3857} 3868}
3858 3869
3859void QTextParag::remove( int index, int len ) 3870void QTextParagraph::remove( int index, int len )
3860{ 3871{
3861 if ( index + len - str->length() > 0 ) 3872 if ( index + len - str->length() > 0 )
3862 return; 3873 return;
@@ -3871,14 +3882,14 @@ void QTextParag::remove( int index, int len )
3871 needPreProcess = TRUE; 3882 needPreProcess = TRUE;
3872} 3883}
3873 3884
3874void QTextParag::join( QTextParag *s ) 3885void QTextParagraph::join( QTextParagraph *s )
3875{ 3886{
3876 int oh = r.height() + s->r.height(); 3887 int oh = r.height() + s->r.height();
3877 n = s->n; 3888 n = s->n;
3878 if ( n ) 3889 if ( n )
3879 n->p = this; 3890 n->p = this;
3880 else if ( hasdoc ) 3891 else if ( hasdoc )
3881 document()->setLastParag( this ); 3892 document()->setLastParagraph( this );
3882 3893
3883 int start = str->length(); 3894 int start = str->length();
3884 if ( length() > 0 && at( length() - 1 )->c == ' ' ) { 3895 if ( length() > 0 && at( length() - 1 )->c == ' ' ) {
@@ -3896,6 +3907,10 @@ void QTextParag::join( QTextParag *s )
3896 QTextCustomItem * item = s->str->at( i ).customItem(); 3907 QTextCustomItem * item = s->str->at( i ).customItem();
3897 str->at( i + start ).setCustomItem( item ); 3908 str->at( i + start ).setCustomItem( item );
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 }
3900 if ( s->str->at( i ).isAnchor() ) { 3915 if ( s->str->at( i ).isAnchor() ) {
3901 str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), 3916 str->at( i + start ).setAnchor( s->str->at( i ).anchorName(),
@@ -3914,12 +3929,14 @@ void QTextParag::join( QTextParag *s )
3914 r.setHeight( oh ); 3929 r.setHeight( oh );
3915 needPreProcess = TRUE; 3930 needPreProcess = TRUE;
3916 if ( n ) { 3931 if ( n ) {
3917 QTextParag *s = n; 3932 QTextParagraph *s = n;
3933 s->invalidate( 0 );
3918 while ( s ) { 3934 while ( s ) {
3919 s->id = s->p->id + 1; 3935 s->id = s->p->id + 1;
3920 s->state = -1; 3936 s->state = -1;
3921 s->needPreProcess = TRUE; 3937 s->needPreProcess = TRUE;
3922 s->changed = TRUE; 3938 s->changed = TRUE;
3939 s->invalidateStyleCache();
3923 s = s->n; 3940 s = s->n;
3924 } 3941 }
3925 } 3942 }
@@ -3927,7 +3944,7 @@ void QTextParag::join( QTextParag *s )
3927 state = -1; 3944 state = -1;
3928} 3945}
3929 3946
3930void QTextParag::move( int &dy ) 3947void QTextParagraph::move( int &dy )
3931{ 3948{
3932 if ( dy == 0 ) 3949 if ( dy == 0 )
3933 return; 3950 return;
@@ -3951,7 +3968,7 @@ void QTextParag::move( int &dy )
3951 } 3968 }
3952} 3969}
3953 3970
3954void QTextParag::format( int start, bool doMove ) 3971void QTextParagraph::format( int start, bool doMove )
3955{ 3972{
3956 if ( !str || str->length() == 0 || !formatter() ) 3973 if ( !str || str->length() == 0 || !formatter() )
3957 return; 3974 return;
@@ -3966,7 +3983,6 @@ void QTextParag::format( int start, bool doMove )
3966 return; 3983 return;
3967 3984
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 )
3971 p->lastInFrame = FALSE; 3987 p->lastInFrame = FALSE;
3972 3988
@@ -3975,6 +3991,7 @@ void QTextParag::format( int start, bool doMove )
3975 3991
3976 formatAgain: 3992 formatAgain:
3977 3993
3994 r.setWidth( documentWidth() );
3978 if ( hasdoc && mFloatingItems ) { 3995 if ( hasdoc && mFloatingItems ) {
3979 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { 3996 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) {
3980 i->ypos = r.y(); 3997 i->ypos = r.y();
@@ -3983,7 +4000,7 @@ void QTextParag::format( int start, bool doMove )
3983 } 4000 }
3984 } 4001 }
3985 } 4002 }
3986 QMap<int, QTextParagLineStart*> oldLineStarts = lineStarts; 4003 QMap<int, QTextLineStart*> oldLineStarts = lineStarts;
3987 lineStarts.clear(); 4004 lineStarts.clear();
3988 int y = formatter()->format( document(), this, start, oldLineStarts ); 4005 int y = formatter()->format( document(), this, start, oldLineStarts );
3989 4006
@@ -3991,18 +4008,18 @@ void QTextParag::format( int start, bool doMove )
3991 r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); 4008 r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) );
3992 4009
3993 4010
3994 QMap<int, QTextParagLineStart*>::Iterator it = oldLineStarts.begin(); 4011 QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin();
3995 4012
3996 for ( ; it != oldLineStarts.end(); ++it ) 4013 for ( ; it != oldLineStarts.end(); ++it )
3997 delete *it; 4014 delete *it;
3998 4015
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() ) {
4007 c = &str->at( str->length() - 1 ); 4024 c = &str->at( str->length() - 1 );
4008 r.setWidth( c->x + str->width( str->length() - 1 ) ); 4025 r.setWidth( c->x + str->width( str->length() - 1 ) );
@@ -4011,7 +4028,7 @@ void QTextParag::format( int start, bool doMove )
4011 } 4028 }
4012 } 4029 }
4013 4030
4014 if ( newLinesAllowed ) { 4031 if ( !hasdoc ) { // qt_format_text bounding rect handling
4015 it = lineStarts.begin(); 4032 it = lineStarts.begin();
4016 int usedw = 0; 4033 int usedw = 0;
4017 for ( ; it != lineStarts.end(); ++it ) 4034 for ( ; it != lineStarts.end(); ++it )
@@ -4054,7 +4071,7 @@ void QTextParag::format( int start, bool doMove )
4054 4071
4055 if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { 4072 if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) {
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;
4059 while ( s && dy ) { 4076 while ( s && dy ) {
4060 if ( !s->isFullWidth() ) 4077 if ( !s->isFullWidth() )
@@ -4074,12 +4091,12 @@ void QTextParag::format( int start, bool doMove )
4074 //##### string()->setTextChanged( FALSE ); 4091 //##### string()->setTextChanged( FALSE );
4075} 4092}
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;
4084 for ( ;; ) { 4101 for ( ;; ) {
4085 if ( i >= it.key() ) { 4102 if ( i >= it.key() ) {
@@ -4094,17 +4111,17 @@ int QTextParag::lineHeightOfChar( int i, int *bl, int *y ) const
4094 --it; 4111 --it;
4095 } 4112 }
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;
4099} 4116}
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;
4109 for ( ;; ) { 4126 for ( ;; ) {
4110 if ( i >= it.key() ) { 4127 if ( i >= it.key() ) {
@@ -4120,25 +4137,25 @@ QTextStringChar *QTextParag::lineStartOfChar( int i, int *index, int *line ) con
4120 --l; 4137 --l;
4121 } 4138 }
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;
4125} 4142}
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
4132 return (int)lineStarts.count(); 4149 return (int)lineStarts.count();
4133} 4150}
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 )
4143 ++it; 4160 ++it;
4144 int i = it.key(); 4161 int i = it.key();
@@ -4147,24 +4164,24 @@ QTextStringChar *QTextParag::lineStartOfLine( int line, int *index ) const
4147 return &str->at( i ); 4164 return &str->at( i );
4148 } 4165 }
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;
4152} 4169}
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
4159 int line = 0; 4176 int line = 0;
4160 int x = str->at(0).x; /* set x to x of first char */ 4177 int x = str->at(0).x; /* set x to x of first char */
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);
4164 return x; 4181 return x;
4165 } 4182 }
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()) {
4169 int i = it.key(); /* char index */ 4186 int i = it.key(); /* char index */
4170 x = QMIN(x, str->at(i).x); 4187 x = QMIN(x, str->at(i).x);
@@ -4174,7 +4191,7 @@ int QTextParag::leftGap() const
4174 return x; 4191 return x;
4175} 4192}
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{
4179 if ( !f ) 4196 if ( !f )
4180 return; 4197 return;
@@ -4212,9 +4229,9 @@ void QTextParag::setFormat( int index, int len, QTextFormat *f, bool useCollecti
4212 } 4229 }
4213} 4230}
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 )
4219 *oldIndent = 0; 4236 *oldIndent = 0;
4220 if ( newIndent ) 4237 if ( newIndent )
@@ -4226,241 +4243,167 @@ void QTextParag::indent( int *oldIndent, int *newIndent )
4226 document()->indent()->indent( document(), this, oldIndent, newIndent ); 4243 document()->indent()->indent( document(), this, oldIndent, newIndent );
4227} 4244}
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 )
4231{ 4248{
4232 if ( !visible ) 4249 if ( !visible )
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
4305 // init a new line 4314 // init a new line
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 }
4324 4332
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 }
4465 } 4408 }
4466 painter.restore(); 4409 painter.restore();
@@ -4469,11 +4412,12 @@ void QTextParag::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *c
4469 4412
4470//#define BIDI_DEBUG 4413//#define BIDI_DEBUG
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;
4478 QTextFormat* format = formatChar->format(); 4422 QTextFormat* format = formatChar->format();
4479 QString str( s ); 4423 QString str( s );
@@ -4499,36 +4443,29 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4499 } 4443 }
4500 } 4444 }
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 }
4516 4453
4517 if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { 4454 if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) {
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
4521 painter.save(); 4458 painter.save();
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;
4526 int i = 0; 4463 int i = 0;
4527 while( i < len ) 4464 while( i < len )
4528 w += painter.fontMetrics().charWidth( str, start + i++ ); 4465 w += painter.fontMetrics().charWidth( str, start + i++ );
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();
4533#endif 4470#endif
4534 } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { 4471 } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) {
@@ -4538,8 +4475,8 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4538 else 4475 else
4539 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 4476 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
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 ) {
4544 QFont f( painter.font() ); 4481 QFont f( painter.font() );
4545 if ( format->fontSizesInPixels() ) 4482 if ( format->fontSizesInPixels() )
@@ -4547,16 +4484,16 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4547 else 4484 else
4548 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 4485 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
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 }
4552 } 4489 }
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 }
4556 if ( format->isMisspelled() ) { 4493 if ( format->isMisspelled() ) {
4557 painter.save(); 4494 painter.save();
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();
4561 } 4498 }
4562 4499
@@ -4568,32 +4505,22 @@ void QTextParag::drawParagString( QPainter &painter, const QString &s, int start
4568 document()->focusIndicator.start + document()->focusIndicator.len <= i + len || 4505 document()->focusIndicator.start + document()->focusIndicator.len <= i + len ||
4569 document()->focusIndicator.start <= i && 4506 document()->focusIndicator.start <= i &&
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 }
4573 4510
4574} 4511}
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 );
4581 QStyleSheetItem::ListStyle s = listStyle(); 4516 QStyleSheetItem::ListStyle s = listStyle();
4582 4517
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() );
4598 int size = fm.lineSpacing() / 3; 4525 int size = fm.lineSpacing() / 3;
4599 4526
@@ -4602,7 +4529,22 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4602 case QStyleSheetItem::ListLowerAlpha: 4529 case QStyleSheetItem::ListLowerAlpha:
4603 case QStyleSheetItem::ListUpperAlpha: 4530 case QStyleSheetItem::ListUpperAlpha:
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;
4607 switch ( s ) { 4549 switch ( s ) {
4608 case QStyleSheetItem::ListLowerAlpha: 4550 case QStyleSheetItem::ListLowerAlpha:
@@ -4627,7 +4569,7 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4627 case QStyleSheetItem::ListSquare: 4569 case QStyleSheetItem::ListSquare:
4628 { 4570 {
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 }
4632 break; 4574 break;
4633 case QStyleSheetItem::ListCircle: 4575 case QStyleSheetItem::ListCircle:
@@ -4639,7 +4581,7 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4639 case QStyleSheetItem::ListDisc: 4581 case QStyleSheetItem::ListDisc:
4640 default: 4582 default:
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);
4644 p->drawEllipse( er ); 4586 p->drawEllipse( er );
4645 p->setBrush( Qt::NoBrush ); 4587 p->setBrush( Qt::NoBrush );
@@ -4650,134 +4592,40 @@ void QTextParag::drawLabel( QPainter* p, int x, int y, int w, int h, int base, c
4650 p->restore(); 4592 p->restore();
4651} 4593}
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 }
4713} 4608}
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{
4782 int *ta = tArray; 4630 int *ta = tArray;
4783 if ( !ta && hasdoc ) 4631 if ( !ta && hasdoc )
@@ -4785,7 +4633,7 @@ int *QTextParag::tabArray() const
4785 return ta; 4633 return ta;
4786} 4634}
4787 4635
4788int QTextParag::nextTab( int, int x ) 4636int QTextParagraph::nextTab( int, int x )
4789{ 4637{
4790 int *ta = tArray; 4638 int *ta = tArray;
4791 if ( hasdoc ) { 4639 if ( hasdoc ) {
@@ -4811,7 +4659,7 @@ int QTextParag::nextTab( int, int x )
4811 } 4659 }
4812} 4660}
4813 4661
4814void QTextParag::adjustToPainter( QPainter *p ) 4662void QTextParagraph::adjustToPainter( QPainter *p )
4815{ 4663{
4816 for ( int i = 0; i < length(); ++i ) { 4664 for ( int i = 0; i < length(); ++i ) {
4817 if ( at( i )->isCustom() ) 4665 if ( at( i )->isCustom() )
@@ -4819,7 +4667,7 @@ void QTextParag::adjustToPainter( QPainter *p )
4819 } 4667 }
4820} 4668}
4821 4669
4822QTextFormatCollection *QTextParag::formatCollection() const 4670QTextFormatCollection *QTextParagraph::formatCollection() const
4823{ 4671{
4824 if ( hasdoc ) 4672 if ( hasdoc )
4825 return document()->formatCollection(); 4673 return document()->formatCollection();
@@ -4831,14 +4679,19 @@ QTextFormatCollection *QTextParag::formatCollection() const
4831 return qFormatCollection; 4679 return qFormatCollection;
4832} 4680}
4833 4681
4834QString QTextParag::richText() const 4682QString QTextParagraph::richText() const
4835{ 4683{
4836 QString s; 4684 QString s;
4837 QTextStringChar *formatChar = 0; 4685 QTextStringChar *formatChar = 0;
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 );
4843 if ( c->isAnchor() && !c->anchorName().isEmpty() ) { 4696 if ( c->isAnchor() && !c->anchorName().isEmpty() ) {
4844 if ( c->anchorName().contains( '#' ) ) { 4697 if ( c->anchorName().contains( '#' ) ) {
@@ -4850,67 +4703,34 @@ QString QTextParag::richText() const
4850 } 4703 }
4851 } 4704 }
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;
4911} 4731}
4912 4732
4913void QTextParag::addCommand( QTextCommand *cmd ) 4733void QTextParagraph::addCommand( QTextCommand *cmd )
4914{ 4734{
4915 if ( !hasdoc ) 4735 if ( !hasdoc )
4916 pseudoDocument()->commandHistory->addCommand( cmd ); 4736 pseudoDocument()->commandHistory->addCommand( cmd );
@@ -4918,205 +4738,105 @@ void QTextParag::addCommand( QTextCommand *cmd )
4918 document()->commands()->addCommand( cmd ); 4738 document()->commands()->addCommand( cmd );
4919} 4739}
4920 4740
4921QTextCursor *QTextParag::undo( QTextCursor *c ) 4741QTextCursor *QTextParagraph::undo( QTextCursor *c )
4922{ 4742{
4923 if ( !hasdoc ) 4743 if ( !hasdoc )
4924 return pseudoDocument()->commandHistory->undo( c ); 4744 return pseudoDocument()->commandHistory->undo( c );
4925 return document()->commands()->undo( c ); 4745 return document()->commands()->undo( c );
4926} 4746}
4927 4747
4928QTextCursor *QTextParag::redo( QTextCursor *c ) 4748QTextCursor *QTextParagraph::redo( QTextCursor *c )
4929{ 4749{
4930 if ( !hasdoc ) 4750 if ( !hasdoc )
4931 return pseudoDocument()->commandHistory->redo( c ); 4751 return pseudoDocument()->commandHistory->redo( c );
4932 return document()->commands()->redo( c ); 4752 return document()->commands()->redo( c );
4933} 4753}
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();
5101 if ( c ) 4820 if ( c )
5102 setBackgroundColor( *c ); 4821 setBackgroundColor( *c );
4822 str->setDirection( parag->str->direction() );
5103} 4823}
5104 4824
5105void QTextParag::show() 4825void QTextParagraph::show()
5106{ 4826{
5107 if ( visible || !hasdoc ) 4827 if ( visible || !hasdoc )
5108 return; 4828 return;
5109 visible = TRUE; 4829 visible = TRUE;
5110} 4830}
5111 4831
5112void QTextParag::hide() 4832void QTextParagraph::hide()
5113{ 4833{
5114 if ( !visible || !hasdoc ) 4834 if ( !visible || !hasdoc )
5115 return; 4835 return;
5116 visible = FALSE; 4836 visible = FALSE;
5117} 4837}
5118 4838
5119void QTextParag::setDirection( QChar::Direction d ) 4839void QTextParagraph::setDirection( QChar::Direction d )
5120{ 4840{
5121 if ( str && str->direction() != d ) { 4841 if ( str && str->direction() != d ) {
5122 str->setDirection( d ); 4842 str->setDirection( d );
@@ -5124,17 +4844,17 @@ void QTextParag::setDirection( QChar::Direction d )
5124 } 4844 }
5125} 4845}
5126 4846
5127QChar::Direction QTextParag::direction() const 4847QChar::Direction QTextParagraph::direction() const
5128{ 4848{
5129 return (str ? str->direction() : QChar::DirON ); 4849 return (str ? str->direction() : QChar::DirON );
5130} 4850}
5131 4851
5132void QTextParag::setChanged( bool b, bool recursive ) 4852void QTextParagraph::setChanged( bool b, bool recursive )
5133{ 4853{
5134 changed = b; 4854 changed = b;
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 }
5139} 4859}
5140 4860
@@ -5152,16 +4872,13 @@ QTextFormatter::QTextFormatter()
5152{ 4872{
5153} 4873}
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 )
5159{ 4877{
5160#ifndef QT_NO_COMPLEXTEXT 4878#ifndef QT_NO_COMPLEXTEXT
5161 if( string->isBidi() ) 4879 if( string->isBidi() )
5162 return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); 4880 return bidiReorderLine( parag, string, line, startChar, lastChar, align, space );
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));
5166 int last = (lastChar - &string->at(0) ); 4883 int last = (lastChar - &string->at(0) );
5167 // do alignment Auto == Left in this case 4884 // do alignment Auto == Left in this case
@@ -5172,7 +4889,13 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5172 string->at( j ).x += space; 4889 string->at( j ).x += space;
5173 } else if ( align & Qt3::AlignJustify ) { 4890 } else if ( align & Qt3::AlignJustify ) {
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 ) ) {
5177 numSpaces++; 4900 numSpaces++;
5178 } 4901 }
@@ -5194,7 +4917,7 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5194 else 4917 else
5195 line->w = 0; 4918 line->w = 0;
5196 4919
5197 return new QTextParagLineStart(); 4920 return new QTextLineStart();
5198} 4921}
5199 4922
5200#ifndef QT_NO_COMPLEXTEXT 4923#ifndef QT_NO_COMPLEXTEXT
@@ -5204,12 +4927,11 @@ QTextParagLineStart *QTextFormatter::formatLine( QTextParag *parag, QTextString
5204#endif 4927#endif
5205 4928
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 )
5209{ 4932{
5210 int start = (startChar - &text->at(0)); 4933 int start = (startChar - &text->at(0));
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
5214 QBidiControl *control = new QBidiControl( line->context(), line->status ); 4936 QBidiControl *control = new QBidiControl( line->context(), line->status );
5215 QString str; 4937 QString str;
@@ -5243,7 +4965,13 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5243 else if ( align & Qt::AlignRight ) 4965 else if ( align & Qt::AlignRight )
5244 x += space; 4966 x += space;
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 ) ) {
5248 numSpaces++; 4976 numSpaces++;
5249 } 4977 }
@@ -5305,7 +5033,6 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5305 } else { 5033 } else {
5306 ww = c->format()->width( ' ' ); 5034 ww = c->format()->width( ' ' );
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;
5310 x += ww; 5037 x += ww;
5311 pos++; 5038 pos++;
@@ -5316,17 +5043,19 @@ QTextParagLineStart *QTextFormatter::bidiReorderLine( QTextParag * /*parag*/, QT
5316 } 5043 }
5317 5044
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;
5321 delete runs; 5048 delete runs;
5322 return ls; 5049 return ls;
5323} 5050}
5324#endif 5051#endif
5325 5052
5326bool QTextFormatter::isBreakable( QTextString *string, int pos ) const 5053bool QTextFormatter::isBreakable( QTextString *string, int pos )
5327{ 5054{
5328 const QChar &c = string->at( pos ).c; 5055 const QChar &c = string->at( pos ).c;
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 )
5331 return TRUE; 5060 return TRUE;
5332 if ( c.unicode() == 0xad ) // soft hyphen 5061 if ( c.unicode() == 0xad ) // soft hyphen
@@ -5374,13 +5103,13 @@ bool QTextFormatter::isBreakable( QTextString *string, int pos ) const
5374 return FALSE; 5103 return FALSE;
5375} 5104}
5376 5105
5377void QTextFormatter::insertLineStart( QTextParag *parag, int index, QTextParagLineStart *ls ) 5106void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls )
5378{ 5107{
5379 if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times 5108 if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times
5380 parag->lineStartList().insert( index, ls ); 5109 parag->lineStartList().insert( index, ls );
5381 return; 5110 return;
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() ) {
5385 parag->lineStartList().insert( index, ls ); 5114 parag->lineStartList().insert( index, ls );
5386 } else { 5115 } else {
@@ -5394,14 +5123,14 @@ void QTextFormatter::insertLineStart( QTextParag *parag, int index, QTextParagLi
5394/* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns 5123/* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns
5395 the shift of the paragraphs bottom line. 5124 the shift of the paragraphs bottom line.
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;
5406 QTextStringChar *c = &parag->string()->at(it.key()); 5135 QTextStringChar *c = &parag->string()->at(it.key());
5407 if ( c && c->customItem() && c->customItem()->ownLine() ) { 5136 if ( c && c->customItem() && c->customItem()->ownLine() ) {
@@ -5420,10 +5149,10 @@ int QTextFormatter::formatVertically( QTextDocument* doc, QTextParag* parag )
5420 h = ls->y + ls->h; 5149 h = ls->y + ls->h;
5421 } 5150 }
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;
5428 parag->setHeight( h ); 5157 parag->setHeight( h );
5429 return h - oldHeight; 5158 return h - oldHeight;
@@ -5435,15 +5164,17 @@ QTextFormatterBreakInWords::QTextFormatterBreakInWords()
5435{ 5164{
5436} 5165}
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{
5441 QTextStringChar *c = 0; 5172 QTextStringChar *c = 0;
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;
5448 int len = parag->length(); 5179 int len = parag->length();
5449 if ( doc ) 5180 if ( doc )
@@ -5460,7 +5191,7 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5460 c = &parag->string()->at( 0 ); 5191 c = &parag->string()->at( 0 );
5461 5192
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 );
5465 5196
5466 QPainter *painter = QTextFormat::painter(); 5197 QPainter *painter = QTextFormat::painter();
@@ -5501,7 +5232,7 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5501 w = dw; 5232 w = dw;
5502 y += h; 5233 y += h;
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 );
5506 c->lineStart = 1; 5237 c->lineStart = 1;
5507 firstChar = c; 5238 firstChar = c;
@@ -5511,13 +5242,12 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5511 5242
5512 if ( wrapEnabled && 5243 if ( wrapEnabled &&
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;
5517 w = dw; 5247 w = dw;
5518 y += h; 5248 y += h;
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;
5522 insertLineStart( parag, i, lineStart ); 5252 insertLineStart( parag, i, lineStart );
5523 lineStart->baseLine = c->ascent(); 5253 lineStart->baseLine = c->ascent();
@@ -5539,12 +5269,14 @@ int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParag *parag,
5539 } 5269 }
5540 5270
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 )
5549 minw = QMAX(minw, wused); 5281 minw = QMAX(minw, wused);
5550 5282
@@ -5566,15 +5298,15 @@ QTextFormatterBreakWords::QTextFormatterBreakWords()
5566 y += shift;\ 5298 y += shift;\
5567 }}while(FALSE) 5299 }}while(FALSE)
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{
5572 QTextStringChar *c = 0; 5304 QTextStringChar *c = 0;
5573 QTextStringChar *firstChar = 0; 5305 QTextStringChar *firstChar = 0;
5574 QTextString *string = parag->string(); 5306 QTextString *string = parag->string();
5575 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; 5307 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
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;
5579 int len = parag->length(); 5311 int len = parag->length();
5580 if ( doc ) 5312 if ( doc )
@@ -5590,7 +5322,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5590 int minw = 0; 5322 int minw = 0;
5591 int wused = 0; 5323 int wused = 0;
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 );
5595 5327
5596 start = 0; 5328 start = 0;
@@ -5598,7 +5330,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5598 c = &parag->string()->at( 0 ); 5330 c = &parag->string()->at( 0 );
5599 5331
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 );
5603 int lastBreak = -1; 5335 int lastBreak = -1;
5604 int tmpBaseLine = 0, tmph = 0; 5336 int tmpBaseLine = 0, tmph = 0;
@@ -5654,7 +5386,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5654 if ( c->isCustom() && ci->ownLine() ) { 5386 if ( c->isCustom() && ci->ownLine() ) {
5655 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5387 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
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);
5659 if ( ci->width < w - x ) { 5391 if ( ci->width < w - x ) {
5660 if ( align & Qt::AlignHCenter ) 5392 if ( align & Qt::AlignHCenter )
@@ -5666,8 +5398,8 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5666 c->x = x; 5398 c->x = x;
5667 curLeft = x; 5399 curLeft = x;
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;
5672 lineStart = lineStart2; 5404 lineStart = lineStart2;
5673 lineStart->y = y; 5405 lineStart->y = y;
@@ -5675,7 +5407,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5675 c->lineStart = 1; 5407 c->lineStart = 1;
5676 firstChar = c; 5408 firstChar = c;
5677 } else { 5409 } else {
5678 tmph = c->height() + linespace; 5410 tmph = c->height();
5679 h = tmph; 5411 h = tmph;
5680 delete lineStart2; 5412 delete lineStart2;
5681 } 5413 }
@@ -5686,7 +5418,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5686 x = 0xffffff; 5418 x = 0xffffff;
5687 minw = QMAX( minw, tminw ); 5419 minw = QMAX( minw, tminw );
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 )
5691 tminw = tw; 5423 tminw = tw;
5692 else 5424 else
@@ -5699,25 +5431,40 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5699 minw = QMAX( minw, tw ); 5431 minw = QMAX( minw, tw );
5700 } 5432 }
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 ) {
5712 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); 5459 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
5713 h = QMAX( h, tmph ); 5460 h = QMAX( h, tmph );
5714 lineStart->h = h; 5461 lineStart->h = h;
5715 DO_FLOW( lineStart ); 5462 DO_FLOW( lineStart );
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;
5722 if ( nx < x ) 5469 if ( nx < x )
5723 ww = w - x; 5470 ww = w - x;
@@ -5725,8 +5472,8 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5725 ww = nx - x; 5472 ww = nx - x;
5726 } 5473 }
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;
5731 lineStart->y = y; 5478 lineStart->y = y;
5732 insertLineStart( parag, i, lineStart ); 5479 insertLineStart( parag, i, lineStart );
@@ -5737,13 +5484,13 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5737 tmpBaseLine = lineStart->baseLine; 5484 tmpBaseLine = lineStart->baseLine;
5738 lastBreak = -1; 5485 lastBreak = -1;
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;
5748 if ( nx < x ) 5495 if ( nx < x )
5749 ww = w - x; 5496 ww = w - x;
@@ -5751,8 +5498,8 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5751 ww = nx - x; 5498 ww = nx - x;
5752 } 5499 }
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;
5757 lineStart->y = y; 5504 lineStart->y = y;
5758 insertLineStart( parag, i + 1, lineStart ); 5505 insertLineStart( parag, i + 1, lineStart );
@@ -5766,10 +5513,10 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5766 tminw = marg; 5513 tminw = marg;
5767 continue; 5514 continue;
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 }
5774 minw = QMAX( minw, tminw ); 5521 minw = QMAX( minw, tminw );
5775 tminw = marg + ww; 5522 tminw = marg + ww;
@@ -5780,7 +5527,7 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5780 lastBreak = i; 5527 lastBreak = i;
5781 } else { 5528 } else {
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() );
5785 tmph = tmpBaseLine + belowBaseLine; 5532 tmph = tmpBaseLine + belowBaseLine;
5786 } 5533 }
@@ -5790,8 +5537,10 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5790 wused = QMAX( wused, x ); 5537 wused = QMAX( wused, x );
5791 } 5538 }
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() ) {
5796 c->format()->removeRef(); 5545 c->format()->removeRef();
5797 c->setFormat( string->at( len - 2 ).format() ); 5546 c->setFormat( string->at( len - 2 ).format() );
@@ -5803,26 +5552,36 @@ int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParag *parag,
5803 h = QMAX( h, tmph ); 5552 h = QMAX( h, tmph );
5804 lineStart->h = h; 5553 lineStart->h = h;
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;
5811 } 5560 }
5812 5561
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
5823 wused += rm; 5574 wused += rm;
5824 if ( !wrapEnabled || wrapAtColumn() != -1 ) 5575 if ( !wrapEnabled || wrapAtColumn() != -1 )
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;
5827 thiswused = wused; 5586 thiswused = wused;
5828 return y; 5587 return y;
@@ -5837,7 +5596,7 @@ QTextIndent::QTextIndent()
5837// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5596// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5838 5597
5839QTextFormatCollection::QTextFormatCollection() 5598QTextFormatCollection::QTextFormatCollection()
5840 : cKey( 307 ), sheet( 0 ) 5599 : cKey( 307 )
5841{ 5600{
5842 defFormat = new QTextFormat( QApplication::font(), 5601 defFormat = new QTextFormat( QApplication::font(),
5843 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); 5602 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) );
@@ -5855,27 +5614,18 @@ QTextFormatCollection::~QTextFormatCollection()
5855QTextFormat *QTextFormatCollection::format( QTextFormat *f ) 5614QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5856{ 5615{
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;
5862 lastFormat->addRef(); 5618 lastFormat->addRef();
5863 return lastFormat; 5619 return lastFormat;
5864 } 5620 }
5865 5621
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();
5871 return lastFormat; 5624 return lastFormat;
5872 } 5625 }
5873 5626
5874 QTextFormat *fm = cKey.find( f->key() ); 5627 QTextFormat *fm = cKey.find( f->key() );
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;
5880 lastFormat->addRef(); 5630 lastFormat->addRef();
5881 return lastFormat; 5631 return lastFormat;
@@ -5884,9 +5634,6 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5884 if ( f->key() == defFormat->key() ) 5634 if ( f->key() == defFormat->key() )
5885 return defFormat; 5635 return defFormat;
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 );
5891 lastFormat->collection = this; 5638 lastFormat->collection = this;
5892 cKey.insert( lastFormat->key(), lastFormat ); 5639 cKey.insert( lastFormat->key(), lastFormat );
@@ -5896,9 +5643,6 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5896QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) 5643QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags )
5897{ 5644{
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();
5903 return cres; 5647 return cres;
5904 } 5648 }
@@ -5913,6 +5657,8 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5913 cres->fn.setItalic( nf->fn.italic() ); 5657 cres->fn.setItalic( nf->fn.italic() );
5914 if ( flags & QTextFormat::Underline ) 5658 if ( flags & QTextFormat::Underline )
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 )
5917 cres->fn.setFamily( nf->fn.family() ); 5663 cres->fn.setFamily( nf->fn.family() );
5918 if ( flags & QTextFormat::Size ) { 5664 if ( flags & QTextFormat::Size ) {
@@ -5931,15 +5677,9 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5931 5677
5932 QTextFormat *fm = cKey.find( cres->key() ); 5678 QTextFormat *fm = cKey.find( cres->key() );
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;
5938 cKey.insert( cres->key(), cres ); 5681 cKey.insert( cres->key(), cres );
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;
5944 cres = fm; 5684 cres = fm;
5945 cres->addRef(); 5685 cres->addRef();
@@ -5951,9 +5691,6 @@ QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, in
5951QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) 5691QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5952{ 5692{
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();
5958 return cachedFormat; 5695 return cachedFormat;
5959 } 5696 }
@@ -5964,9 +5701,6 @@ QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5964 ccol = c; 5701 ccol = c;
5965 5702
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();
5971 return cachedFormat; 5705 return cachedFormat;
5972 } 5706 }
@@ -5979,9 +5713,6 @@ QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5979 cKey.insert( cachedFormat->key(), cachedFormat ); 5713 cKey.insert( cachedFormat->key(), cachedFormat );
5980 if ( cachedFormat->key() != key ) 5714 if ( cachedFormat->key() != key )
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;
5986} 5717}
5987 5718
@@ -5996,96 +5727,55 @@ void QTextFormatCollection::remove( QTextFormat *f )
5996 cKey.remove( f->key() ); 5727 cKey.remove( f->key() );
5997} 5728}
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{
6052 QDictIterator<QTextFormat> it( cKey ); 5736 QDictIterator<QTextFormat> it( cKey );
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();
6079} 5770}
6080 5771
6081
6082// the keys in cKey have changed, rebuild the hashtable 5772// the keys in cKey have changed, rebuild the hashtable
6083void QTextFormatCollection::updateKeys() 5773void QTextFormatCollection::updateKeys()
6084{ 5774{
6085 if ( cKey.isEmpty() ) 5775 if ( cKey.isEmpty() )
6086 return; 5776 return;
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;
6090 QDictIterator<QTextFormat> it( cKey ); 5780 QDictIterator<QTextFormat> it( cKey );
6091 while ( ( *f = it.current() ) ) { 5781 while ( ( *f = it.current() ) ) {
@@ -6096,6 +5786,7 @@ void QTextFormatCollection::updateKeys()
6096 for ( f = formats; *f; f++ ) 5786 for ( f = formats; *f; f++ )
6097 cKey.insert( (*f)->key(), *f ); 5787 cKey.insert( (*f)->key(), *f );
6098 cKey.setAutoDelete( TRUE ); 5788 cKey.setAutoDelete( TRUE );
5789 delete [] formats;
6099} 5790}
6100 5791
6101 5792
@@ -6142,6 +5833,14 @@ void QTextFormat::setUnderline( bool b )
6142 update(); 5833 update();
6143} 5834}
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 )
6146{ 5845{
6147 if ( f == fn.family() ) 5846 if ( f == fn.family() )
@@ -6175,192 +5874,183 @@ void QTextFormat::setColor( const QColor &c )
6175 update(); 5874 update();
6176} 5875}
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
6222 if ( !anchorHref.isEmpty() ) 5884 if ( !anchorHref.isEmpty() )
6223 tag += "<a href=\"" + anchorHref + "\">"; 5885 tag += "<a href=\"" + anchorHref + "\">";
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 }
6247 5915
6248 return tag; 5916 return tag;
6249} 5917}
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() )
6271 tag += "</a>"; 5932 tag += "</a>";
6272 return tag; 5933 return tag;
6273} 5934}
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 }
6365 } 6055 }
6366 6056
@@ -6381,10 +6071,6 @@ QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, co
6381 QMimeSourceFactory &factory ) 6071 QMimeSourceFactory &factory )
6382 : QTextCustomItem( p ) 6072 : QTextCustomItem( p )
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;
6389 if ( attr.contains("width") ) 6075 if ( attr.contains("width") )
6390 width = attr["width"].toInt(); 6076 width = attr["width"].toInt();
@@ -6397,10 +6083,6 @@ QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, co
6397 if (!imageName) 6083 if (!imageName)
6398 imageName = attr["source"]; 6084 imageName = attr["source"];
6399 6085
6400#if defined(PARSER_DEBUG)
6401 qDebug( debug_indent + " .." + imageName );
6402#endif
6403
6404 if ( !imageName.isEmpty() ) { 6086 if ( !imageName.isEmpty() ) {
6405 imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); 6087 imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory );
6406 if ( !pixmap_map ) 6088 if ( !pixmap_map )
@@ -6487,6 +6169,7 @@ QTextImage::~QTextImage()
6487 } 6169 }
6488 } 6170 }
6489 } 6171 }
6172 delete reg;
6490} 6173}
6491 6174
6492QString QTextImage::richText() const 6175QString QTextImage::richText() const
@@ -6645,7 +6328,7 @@ static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col
6645} 6328}
6646 6329
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{
6650 6333
6651 QTextTable* table = new QTextTable( this, attr ); 6334 QTextTable* table = new QTextTable( this, attr );
@@ -6665,9 +6348,6 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6665 if (hasPrefix(doc, length, pos+1, QChar('/'))) { 6348 if (hasPrefix(doc, length, pos+1, QChar('/'))) {
6666 tagname = parseCloseTag( doc, length, pos ); 6349 tagname = parseCloseTag( doc, length, pos );
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;
6672 } 6352 }
6673 } else { 6353 } else {
@@ -6724,10 +6404,10 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6724 end++; 6404 end++;
6725 } 6405 }
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 )
6732 multicells.append( cell ); 6412 multicells.append( cell );
6733 col += cell->colspan()-1; 6413 col += cell->colspan()-1;
@@ -6740,9 +6420,6 @@ QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr,
6740 ++pos; 6420 ++pos;
6741 } 6421 }
6742 } 6422 }
6743#if defined(PARSER_DEBUG)
6744 debug_indent.remove( debug_indent.length() - 3, 2 );
6745#endif
6746 return table; 6423 return table;
6747} 6424}
6748 6425
@@ -7131,19 +6808,10 @@ QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleShe
7131 6808
7132 if ( c.isSpace() && c != QChar::nbsp ) { 6809 if ( c.isSpace() && c != QChar::nbsp ) {
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
7148 while ( pos< length && 6816 while ( pos< length &&
7149 doc[pos].isSpace() && doc[pos] != QChar::nbsp ) 6817 doc[pos].isSpace() && doc[pos] != QChar::nbsp )
@@ -7355,11 +7023,6 @@ QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr )
7355 : QTextCustomItem( p ) 7023 : QTextCustomItem( p )
7356{ 7024{
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;
7364 if ( attr.contains("cellspacing") ) 7027 if ( attr.contains("cellspacing") )
7365 cellspacing = attr["cellspacing"].toInt(); 7028 cellspacing = attr["cellspacing"].toInt();
@@ -7440,10 +7103,10 @@ QString QTextTable::richText() const
7440 lastRow = cell->row(); 7103 lastRow = cell->row();
7441 needEnd = TRUE; 7104 needEnd = TRUE;
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 += ">";
7448 s += cell->richText()->richText(); 7111 s += cell->richText()->richText();
7449 s += "</td>"; 7112 s += "</td>";
@@ -7576,12 +7239,6 @@ void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch,
7576 } 7239 }
7577 } 7240 }
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}
7586 7243
7587int QTextTable::minimumWidth() const 7244int QTextTable::minimumWidth() const
@@ -7643,7 +7300,7 @@ void QTextTable::addCell( QTextTableCell* cell )
7643 cell->column(), cell->column() + cell->colspan()-1 ); 7300 cell->column(), cell->column() + cell->colspan()-1 );
7644} 7301}
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{
7648 currCell.remove( c ); 7305 currCell.remove( c );
7649 if ( !atEnd ) 7306 if ( !atEnd )
@@ -7652,7 +7309,7 @@ bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7652 return prev( c, doc, parag, idx, ox, oy ); 7309 return prev( c, doc, parag, idx, ox, oy );
7653} 7310}
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{
7657 currCell.remove( c ); 7314 currCell.remove( c );
7658 int lastCell = -1; 7315 int lastCell = -1;
@@ -7692,14 +7349,14 @@ bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParag *&para
7692 if ( !cell ) 7349 if ( !cell )
7693 return FALSE; 7350 return FALSE;
7694 doc = cell->richText(); 7351 doc = cell->richText();
7695 parag = doc->firstParag(); 7352 parag = doc->firstParagraph();
7696 idx = 0; 7353 idx = 0;
7697 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7354 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7698 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7355 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7699 return TRUE; 7356 return TRUE;
7700} 7357}
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{
7704 int cc = -1; 7361 int cc = -1;
7705 if ( currCell.find( c ) != currCell.end() ) 7362 if ( currCell.find( c ) != currCell.end() )
@@ -7725,14 +7382,14 @@ bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7725 if ( !cell ) 7382 if ( !cell )
7726 return FALSE; 7383 return FALSE;
7727 doc = cell->richText(); 7384 doc = cell->richText();
7728 parag = doc->firstParag(); 7385 parag = doc->firstParagraph();
7729 idx = 0; 7386 idx = 0;
7730 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7387 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7731 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7388 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7732 return TRUE; 7389 return TRUE;
7733} 7390}
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{
7737 int cc = -1; 7394 int cc = -1;
7738 if ( currCell.find( c ) != currCell.end() ) 7395 if ( currCell.find( c ) != currCell.end() )
@@ -7758,14 +7415,14 @@ bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7758 if ( !cell ) 7415 if ( !cell )
7759 return FALSE; 7416 return FALSE;
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;
7763 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7420 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7764 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7421 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7765 return TRUE; 7422 return TRUE;
7766} 7423}
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{
7770 if ( currCell.find( c ) == currCell.end() ) 7427 if ( currCell.find( c ) == currCell.end() )
7771 return FALSE; 7428 return FALSE;
@@ -7796,14 +7453,14 @@ bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag,
7796 doc = cell->richText(); 7453 doc = cell->richText();
7797 if ( !cell ) 7454 if ( !cell )
7798 return FALSE; 7455 return FALSE;
7799 parag = doc->firstParag(); 7456 parag = doc->firstParagraph();
7800 idx = 0; 7457 idx = 0;
7801 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7458 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7802 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7459 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7803 return TRUE; 7460 return TRUE;
7804} 7461}
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{
7808 if ( currCell.find( c ) == currCell.end() ) 7465 if ( currCell.find( c ) == currCell.end() )
7809 return FALSE; 7466 return FALSE;
@@ -7834,7 +7491,7 @@ bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, in
7834 doc = cell->richText(); 7491 doc = cell->richText();
7835 if ( !cell ) 7492 if ( !cell )
7836 return FALSE; 7493 return FALSE;
7837 parag = doc->lastParag(); 7494 parag = doc->lastParagraph();
7838 idx = parag->length() - 1; 7495 idx = parag->length() - 1;
7839 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7496 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7840 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7497 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
@@ -7849,10 +7506,6 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7849 QMimeSourceFactory &factory, QStyleSheet *sheet, 7506 QMimeSourceFactory &factory, QStyleSheet *sheet,
7850 const QString& doc) 7507 const QString& doc)
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;
7857 cached_sizehint = -1; 7510 cached_sizehint = -1;
7858 7511
@@ -7888,7 +7541,8 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7888 richtext->setUseFormatCollection( table->parent->useFormatCollection() ); 7541 richtext->setUseFormatCollection( table->parent->useFormatCollection() );
7889 richtext->setMimeSourceFactory( &factory ); 7542 richtext->setMimeSourceFactory( &factory );
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 );
7893 rowspan_ = 1; 7547 rowspan_ = 1;
7894 colspan_ = 1; 7548 colspan_ = 1;
@@ -7924,34 +7578,6 @@ QTextTableCell::QTextTableCell( QTextTable* table,
7924 parent->addCell( this ); 7578 parent->addCell( this );
7925} 7579}
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()
7956{ 7582{
7957 delete background; 7583 delete background;
@@ -8027,7 +7653,7 @@ int QTextTableCell::heightForWidth( int w ) const
8027 7653
8028void QTextTableCell::adjustToPainter( QPainter* p ) 7654void QTextTableCell::adjustToPainter( QPainter* p )
8029{ 7655{
8030 QTextParag *parag = richtext->firstParag(); 7656 QTextParagraph *parag = richtext->firstParagraph();
8031 while ( parag ) { 7657 while ( parag ) {
8032 parag->adjustToPainter( p ); 7658 parag->adjustToPainter( p );
8033 parag = parag->next(); 7659 parag = parag->next();
@@ -8071,15 +7697,148 @@ void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, in
8071 p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() ); 7697 p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() );
8072 7698
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 )
8078 richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ), 7701 richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ),
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
8084 p->restore(); 7707 p->restore();
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}
diff --git a/noncore/apps/opie-write/qrichtext_p.cpp b/noncore/apps/opie-write/qrichtext_p.cpp
index fb20730..6783e0b 100644
--- a/noncore/apps/opie-write/qrichtext_p.cpp
+++ b/noncore/apps/opie-write/qrichtext_p.cpp
@@ -56,30 +56,29 @@ int QTextCustomItem::minimumWidth() const { return 0; }
56 56
57QString QTextCustomItem::richText() const { return QString::null; } 57QString QTextCustomItem::richText() const { return QString::null; }
58 58
59bool QTextCustomItem::enter( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, bool atEnd ) 59bool QTextCustomItem::enter( QTextCursor *, QTextDocument*&, QTextParagraph *&, int &, int &, int &, bool )
60{ 60{
61 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; Q_UNUSED( atEnd ) return TRUE; 61 return TRUE;
62
63} 62}
64bool QTextCustomItem::enterAt( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, const QPoint & ) 63bool QTextCustomItem::enterAt( QTextCursor *, QTextDocument *&, QTextParagraph *&, int &, int &, int &, const QPoint & )
65{ 64{
66 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; return TRUE; 65 return TRUE;
67} 66}
68bool QTextCustomItem::next( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 67bool QTextCustomItem::next( QTextCursor *, QTextDocument *&, QTextParagraph *&, int &, int &, int & )
69{ 68{
70 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; return TRUE; 69 return TRUE;
71} 70}
72bool QTextCustomItem::prev( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 71bool QTextCustomItem::prev( QTextCursor *, QTextDocument *&, QTextParagraph *&, int &, int &, int & )
73{ 72{
74 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; return TRUE; 73 return TRUE;
75} 74}
76bool QTextCustomItem::down( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 75bool QTextCustomItem::down( QTextCursor *, QTextDocument *&, QTextParagraph *&, int &, int &, int & )
77{ 76{
78 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; return TRUE; 77 return TRUE;
79} 78}
80bool QTextCustomItem::up( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ) 79bool QTextCustomItem::up( QTextCursor *, QTextDocument *&, QTextParagraph *&, int &, int &, int & )
81{ 80{
82 doc = doc; parag = parag; idx = idx; ox = ox; oy = oy; return TRUE; 81 return TRUE;
83} 82}
84 83
85void QTextFlow::setPageSize( int ps ) { pagesize = ps; } 84void QTextFlow::setPageSize( int ps ) { pagesize = ps; }
@@ -89,8 +88,8 @@ void QTextTableCell::invalidate() { cached_width = -1; cached_sizehint = -1; }
89 88
90void QTextTable::invalidate() { cachewidth = -1; } 89void QTextTable::invalidate() { cachewidth = -1; }
91 90
92QTextParagData::~QTextParagData() {} 91QTextParagraphData::~QTextParagraphData() {}
93void QTextParagData::join( QTextParagData * ) {} 92void QTextParagraphData::join( QTextParagraphData * ) {}
94 93
95QTextFormatter::~QTextFormatter() {} 94QTextFormatter::~QTextFormatter() {}
96void QTextFormatter::setWrapEnabled( bool b ) { wrapEnabled = b; } 95void QTextFormatter::setWrapEnabled( bool b ) { wrapEnabled = b; }
@@ -100,23 +99,51 @@ void QTextFormatter::setWrapAtColumn( int c ) { wrapColumn = c; }
100 99
101int QTextCursor::x() const 100int QTextCursor::x() const
102{ 101{
103 QTextStringChar *c = string->at( idx ); 102 QTextStringChar *c = para->at( idx );
104 int curx = c->x; 103 int curx = c->x;
105 if ( !c->rightToLeft && 104 if ( !c->rightToLeft &&
106 c->c.isSpace() && 105 c->c.isSpace() &&
107 idx > 0 && 106 idx > 0 &&
108 ( string->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify ) 107 !c->lineStart &&
109 curx = string->at( idx - 1 )->x + string->string()->width( idx - 1 ); 108 ( para->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify )
109 curx = para->at( idx - 1 )->x + para->string()->width( idx - 1 );
110 if ( c->rightToLeft ) 110 if ( c->rightToLeft )
111 curx += string->string()->width( idx ); 111 curx += para->string()->width( idx );
112 return curx; 112 return curx;
113} 113}
114 114
115int QTextCursor::y() const 115int QTextCursor::y() const
116{ 116{
117 int dummy, line; 117 int dummy, line;
118 string->lineStartOfChar( idx, &dummy, &line ); 118 para->lineStartOfChar( idx, &dummy, &line );
119 return string->lineY( line ); 119 return para->lineY( line );
120}
121
122int QTextCursor::globalX() const { return totalOffsetX() + para->rect().x() + x(); }
123int QTextCursor::globalY() const { return totalOffsetY() + para->rect().y() + y(); }
124
125QTextDocument *QTextCursor::document() const
126{
127 return para ? para->document() : 0;
128}
129
130void QTextCursor::gotoPosition( QTextParagraph* p, int index )
131{
132 if ( para && p != para ) {
133 while ( para->document() != p->document() && !indices.isEmpty() )
134 pop();
135 Q_ASSERT( indices.isEmpty() || para->document() == p->document() );
136 }
137 para = p;
138 if ( index < 0 || index >= para->length() ) {
139#if defined(QT_CHECK_RANGE)
140 qWarning( "QTextCursor::gotoParagraph Index: %d out of range", index );
141#endif
142 index = index < 0 ? 0 : para->length() - 1;
143 }
144
145 tmpIndex = -1;
146 idx = index;
120} 147}
121 148
122bool QTextDocument::hasSelection( int id, bool visible ) const 149bool QTextDocument::hasSelection( int id, bool visible ) const
@@ -127,18 +154,18 @@ bool QTextDocument::hasSelection( int id, bool visible ) const
127 ( (QTextDocument*)this )->selectionEndCursor( id ) ) ); 154 ( (QTextDocument*)this )->selectionEndCursor( id ) ) );
128} 155}
129 156
130void QTextDocument::setSelectionStart( int id, QTextCursor *cursor ) 157void QTextDocument::setSelectionStart( int id, const QTextCursor &cursor )
131{ 158{
132 QTextDocumentSelection sel; 159 QTextDocumentSelection sel;
133 sel.startCursor = *cursor; 160 sel.startCursor = cursor;
134 sel.endCursor = *cursor; 161 sel.endCursor = cursor;
135 sel.swapped = FALSE; 162 sel.swapped = FALSE;
136 selections[ id ] = sel; 163 selections[ id ] = sel;
137} 164}
138 165
139QTextParag *QTextDocument::paragAt( int i ) const 166QTextParagraph *QTextDocument::paragAt( int i ) const
140{ 167{
141 QTextParag* p = curParag; 168 QTextParagraph* p = curParag;
142 if ( !p || p->paragId() > i ) 169 if ( !p || p->paragId() > i )
143 p = fParag; 170 p = fParag;
144 while ( p && p->paragId() != i ) 171 while ( p && p->paragId() != i )
@@ -153,8 +180,7 @@ QTextFormat::~QTextFormat()
153} 180}
154 181
155QTextFormat::QTextFormat() 182QTextFormat::QTextFormat()
156 : fm( QFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( qApp->font().pointSize() ), 183 : fm( QFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( qApp->font().pointSize() )
157 different( NoFlags )
158{ 184{
159 ref = 0; 185 ref = 0;
160 186
@@ -163,15 +189,14 @@ QTextFormat::QTextFormat()
163 stdSize = qApp->font().pixelSize(); 189 stdSize = qApp->font().pixelSize();
164 usePixelSizes = TRUE; 190 usePixelSizes = TRUE;
165 } 191 }
166 192
167 missp = FALSE; 193 missp = FALSE;
168 ha = AlignNormal; 194 ha = AlignNormal;
169 collection = 0; 195 collection = 0;
170} 196}
171 197
172QTextFormat::QTextFormat( const QStyleSheetItem *style ) 198QTextFormat::QTextFormat( const QStyleSheetItem *style )
173 : fm( QFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( qApp->font().pointSize() ), 199 : fm( QFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( qApp->font().pointSize() )
174 different( NoFlags )
175{ 200{
176 ref = 0; 201 ref = 0;
177 202
@@ -181,7 +206,6 @@ QTextFormat::QTextFormat( const QStyleSheetItem *style )
181 usePixelSizes = TRUE; 206 usePixelSizes = TRUE;
182 } 207 }
183 208
184 this->style = style->name();
185 missp = FALSE; 209 missp = FALSE;
186 ha = AlignNormal; 210 ha = AlignNormal;
187 collection = 0; 211 collection = 0;
@@ -190,6 +214,7 @@ QTextFormat::QTextFormat( const QStyleSheetItem *style )
190 style->fontWeight(), 214 style->fontWeight(),
191 style->fontItalic() ); 215 style->fontItalic() );
192 fn.setUnderline( style->fontUnderline() ); 216 fn.setUnderline( style->fontUnderline() );
217 fn.setStrikeOut( style->fontStrikeOut() );
193 col = style->color(); 218 col = style->color();
194 fm = QFontMetrics( fn ); 219 fm = QFontMetrics( fn );
195 leftBearing = fm.minLeftBearing(); 220 leftBearing = fm.minLeftBearing();
@@ -202,12 +227,11 @@ QTextFormat::QTextFormat( const QStyleSheetItem *style )
202 memset( widths, 0, 256 ); 227 memset( widths, 0, 256 );
203 generateKey(); 228 generateKey();
204 addRef(); 229 addRef();
205 updateStyleFlags();
206} 230}
207 231
208QTextFormat::QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection *parent ) 232QTextFormat::QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection *parent )
209 : fn( f ), col( c ), fm( QFontMetrics( f ) ), linkColor( TRUE ), 233 : fn( f ), col( c ), fm( QFontMetrics( f ) ), linkColor( TRUE ),
210 logicalFontSize( 3 ), stdSize( f.pointSize() ), different( NoFlags ) 234 logicalFontSize( 3 ), stdSize( f.pointSize() )
211{ 235{
212 ref = 0; 236 ref = 0;
213 usePixelSizes = FALSE; 237 usePixelSizes = FALSE;
@@ -226,7 +250,6 @@ QTextFormat::QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection
226 memset( widths, 0, 256 ); 250 memset( widths, 0, 256 );
227 generateKey(); 251 generateKey();
228 addRef(); 252 addRef();
229 updateStyleFlags();
230} 253}
231 254
232QTextFormat::QTextFormat( const QTextFormat &f ) 255QTextFormat::QTextFormat( const QTextFormat &f )
@@ -249,8 +272,6 @@ QTextFormat::QTextFormat( const QTextFormat &f )
249 ha = f.ha; 272 ha = f.ha;
250 k = f.k; 273 k = f.k;
251 linkColor = f.linkColor; 274 linkColor = f.linkColor;
252 style = f.style;
253 different = f.different;
254 addRef(); 275 addRef();
255} 276}
256 277
@@ -274,8 +295,6 @@ QTextFormat& QTextFormat::operator=( const QTextFormat &f )
274 ha = f.ha; 295 ha = f.ha;
275 k = f.k; 296 k = f.k;
276 linkColor = f.linkColor; 297 linkColor = f.linkColor;
277 style = f.style;
278 different = f.different;
279 addRef(); 298 addRef();
280 return *this; 299 return *this;
281} 300}
@@ -290,7 +309,6 @@ void QTextFormat::update()
290 dsc = fm.descent(); 309 dsc = fm.descent();
291 memset( widths, 0, 256 ); 310 memset( widths, 0, 256 );
292 generateKey(); 311 generateKey();
293 updateStyleFlags();
294} 312}
295 313
296 314
@@ -372,52 +390,6 @@ QString QTextFormat::getKey( const QFont &fn, const QColor &col, bool misspelled
372 return k; 390 return k;
373} 391}
374 392
375void QTextFormat::updateStyle()
376{
377 if ( !collection || !collection->styleSheet() )
378 return;
379 QStyleSheetItem *item = collection->styleSheet()->item( style );
380 if ( !item )
381 return;
382 if ( !( different & Color ) && item->color().isValid() )
383 col = item->color();
384 if ( !( different & Size ) && item->fontSize() != -1 )
385 fn.setPointSize( item->fontSize() );
386 if ( !( different & Family ) && !item->fontFamily().isEmpty() )
387 fn.setFamily( item->fontFamily() );
388 if ( !( different & Bold ) && item->fontWeight() != -1 )
389 fn.setWeight( item->fontWeight() );
390 if ( !( different & Italic ) && item->definesFontItalic() )
391 fn.setItalic( item->fontItalic() );
392 if ( !( different & Underline ) && item->definesFontUnderline() )
393 fn.setUnderline( item->fontUnderline() );
394 generateKey();
395 update();
396
397}
398
399void QTextFormat::updateStyleFlags()
400{
401 different = NoFlags;
402 if ( !collection || !collection->styleSheet() )
403 return;
404 QStyleSheetItem *item = collection->styleSheet()->item( style );
405 if ( !item )
406 return;
407 if ( item->color() != col )
408 different |= Color;
409 if ( item->fontSize() != fn.pointSize() )
410 different |= Size;
411 if ( item->fontFamily() != fn.family() )
412 different |= Family;
413 if ( item->fontItalic() != fn.italic() )
414 different |= Italic;
415 if ( item->fontUnderline() != fn.underline() )
416 different |= Underline;
417 if ( item->fontWeight() != fn.weight() )
418 different |= Bold;
419}
420
421QString QTextString::toString( const QMemArray<QTextStringChar> &data ) 393QString QTextString::toString( const QMemArray<QTextStringChar> &data )
422{ 394{
423 QString s; 395 QString s;
@@ -443,22 +415,22 @@ QString QTextString::toString() const
443 return toString( data ); 415 return toString( data );
444} 416}
445 417
446void QTextParag::setSelection( int id, int start, int end ) 418void QTextParagraph::setSelection( int id, int start, int end )
447{ 419{
448 QMap<int, QTextParagSelection>::ConstIterator it = selections().find( id ); 420 QMap<int, QTextParagraphSelection>::ConstIterator it = selections().find( id );
449 if ( it != mSelections->end() ) { 421 if ( it != mSelections->end() ) {
450 if ( start == ( *it ).start && end == ( *it ).end ) 422 if ( start == ( *it ).start && end == ( *it ).end )
451 return; 423 return;
452 } 424 }
453 425
454 QTextParagSelection sel; 426 QTextParagraphSelection sel;
455 sel.start = start; 427 sel.start = start;
456 sel.end = end; 428 sel.end = end;
457 (*mSelections)[ id ] = sel; 429 (*mSelections)[ id ] = sel;
458 setChanged( TRUE, TRUE ); 430 setChanged( TRUE, TRUE );
459} 431}
460 432
461void QTextParag::removeSelection( int id ) 433void QTextParagraph::removeSelection( int id )
462{ 434{
463 if ( !hasSelection( id ) ) 435 if ( !hasSelection( id ) )
464 return; 436 return;
@@ -467,98 +439,93 @@ void QTextParag::removeSelection( int id )
467 setChanged( TRUE, TRUE ); 439 setChanged( TRUE, TRUE );
468} 440}
469 441
470int QTextParag::selectionStart( int id ) const 442int QTextParagraph::selectionStart( int id ) const
471{ 443{
472 if ( !mSelections ) 444 if ( !mSelections )
473 return -1; 445 return -1;
474 QMap<int, QTextParagSelection>::ConstIterator it = mSelections->find( id ); 446 QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->find( id );
475 if ( it == mSelections->end() ) 447 if ( it == mSelections->end() )
476 return -1; 448 return -1;
477 return ( *it ).start; 449 return ( *it ).start;
478} 450}
479 451
480int QTextParag::selectionEnd( int id ) const 452int QTextParagraph::selectionEnd( int id ) const
481{ 453{
482 if ( !mSelections ) 454 if ( !mSelections )
483 return -1; 455 return -1;
484 QMap<int, QTextParagSelection>::ConstIterator it = mSelections->find( id ); 456 QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->find( id );
485 if ( it == mSelections->end() ) 457 if ( it == mSelections->end() )
486 return -1; 458 return -1;
487 return ( *it ).end; 459 return ( *it ).end;
488} 460}
489 461
490bool QTextParag::hasSelection( int id ) const 462bool QTextParagraph::hasSelection( int id ) const
491{ 463{
492 if ( !mSelections ) 464 return mSelections ? mSelections->contains( id ) : FALSE;
493 return FALSE;
494 QMap<int, QTextParagSelection>::ConstIterator it = mSelections->find( id );
495 if ( it == mSelections->end() )
496 return FALSE;
497 return ( *it ).start != ( *it ).end || length() == 1;
498} 465}
499 466
500bool QTextParag::fullSelected( int id ) const 467bool QTextParagraph::fullSelected( int id ) const
501{ 468{
502 if ( !mSelections ) 469 if ( !mSelections )
503 return FALSE; 470 return FALSE;
504 QMap<int, QTextParagSelection>::ConstIterator it = mSelections->find( id ); 471 QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->find( id );
505 if ( it == mSelections->end() ) 472 if ( it == mSelections->end() )
506 return FALSE; 473 return FALSE;
507 return ( *it ).start == 0 && ( *it ).end == str->length() - 1; 474 return ( *it ).start == 0 && ( *it ).end == str->length() - 1;
508} 475}
509 476
510int QTextParag::lineY( int l ) const 477int QTextParagraph::lineY( int l ) const
511{ 478{
512 if ( l > (int)lineStarts.count() - 1 ) { 479 if ( l > (int)lineStarts.count() - 1 ) {
513 qWarning( "QTextParag::lineY: line %d out of range!", l ); 480 qWarning( "QTextParagraph::lineY: line %d out of range!", l );
514 return 0; 481 return 0;
515 } 482 }
516 483
517 if ( !isValid() ) 484 if ( !isValid() )
518 ( (QTextParag*)this )->format(); 485 ( (QTextParagraph*)this )->format();
519 486
520 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 487 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
521 while ( l-- > 0 ) 488 while ( l-- > 0 )
522 ++it; 489 ++it;
523 return ( *it )->y; 490 return ( *it )->y;
524} 491}
525 492
526int QTextParag::lineBaseLine( int l ) const 493int QTextParagraph::lineBaseLine( int l ) const
527{ 494{
528 if ( l > (int)lineStarts.count() - 1 ) { 495 if ( l > (int)lineStarts.count() - 1 ) {
529 qWarning( "QTextParag::lineBaseLine: line %d out of range!", l ); 496 qWarning( "QTextParagraph::lineBaseLine: line %d out of range!", l );
530 return 10; 497 return 10;
531 } 498 }
532 499
533 if ( !isValid() ) 500 if ( !isValid() )
534 ( (QTextParag*)this )->format(); 501 ( (QTextParagraph*)this )->format();
535 502
536 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 503 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
537 while ( l-- > 0 ) 504 while ( l-- > 0 )
538 ++it; 505 ++it;
539 return ( *it )->baseLine; 506 return ( *it )->baseLine;
540} 507}
541 508
542int QTextParag::lineHeight( int l ) const 509int QTextParagraph::lineHeight( int l ) const
543{ 510{
544 if ( l > (int)lineStarts.count() - 1 ) { 511 if ( l > (int)lineStarts.count() - 1 ) {
545 qWarning( "QTextParag::lineHeight: line %d out of range!", l ); 512 qWarning( "QTextParagraph::lineHeight: line %d out of range!", l );
546 return 15; 513 return 15;
547 } 514 }
548 515
549 if ( !isValid() ) 516 if ( !isValid() )
550 ( (QTextParag*)this )->format(); 517 ( (QTextParagraph*)this )->format();
551 518
552 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 519 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
553 while ( l-- > 0 ) 520 while ( l-- > 0 )
554 ++it; 521 ++it;
555 return ( *it )->h; 522 return ( *it )->h;
556} 523}
557 524
558void QTextParag::lineInfo( int l, int &y, int &h, int &bl ) const 525void QTextParagraph::lineInfo( int l, int &y, int &h, int &bl ) const
559{ 526{
560 if ( l > (int)lineStarts.count() - 1 ) { 527 if ( l > (int)lineStarts.count() - 1 ) {
561 qWarning( "QTextParag::lineInfo: line %d out of range!", l ); 528 qWarning( "QTextParagraph::lineInfo: line %d out of range!", l );
562 qDebug( "%d %d", (int)lineStarts.count() - 1, l ); 529 qDebug( "%d %d", (int)lineStarts.count() - 1, l );
563 y = 0; 530 y = 0;
564 h = 15; 531 h = 15;
@@ -567,9 +534,9 @@ void QTextParag::lineInfo( int l, int &y, int &h, int &bl ) const
567 } 534 }
568 535
569 if ( !isValid() ) 536 if ( !isValid() )
570 ( (QTextParag*)this )->format(); 537 ( (QTextParagraph*)this )->format();
571 538
572 QMap<int, QTextParagLineStart*>::ConstIterator it = lineStarts.begin(); 539 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
573 while ( l-- > 0 ) 540 while ( l-- > 0 )
574 ++it; 541 ++it;
575 y = ( *it )->y; 542 y = ( *it )->y;
@@ -577,95 +544,31 @@ void QTextParag::lineInfo( int l, int &y, int &h, int &bl ) const
577 bl = ( *it )->baseLine; 544 bl = ( *it )->baseLine;
578} 545}
579 546
580int QTextParag::alignment() const
581{
582 if ( align != -1 )
583 return align;
584 QStyleSheetItem *item = style();
585 if ( !item )
586 return Qt3::AlignAuto;
587 if ( mStyleSheetItemsVec ) {
588 for ( int i = 0; i < (int)mStyleSheetItemsVec->size(); ++i ) {
589 item = (*mStyleSheetItemsVec)[ i ];
590 if ( item->alignment() != QStyleSheetItem::Undefined )
591 return item->alignment();
592 }
593 }
594 return Qt3::AlignAuto;
595}
596 547
597QPtrVector<QStyleSheetItem> QTextParag::styleSheetItems() const 548void QTextParagraph::setAlignment( int a )
598{ 549{
599 QPtrVector<QStyleSheetItem> vec; 550 if ( a == (int)align )
600 if ( mStyleSheetItemsVec ) {
601 vec.resize( mStyleSheetItemsVec->size() );
602 for ( int i = 0; i < (int)vec.size(); ++i )
603 vec.insert( i, (*mStyleSheetItemsVec)[ i ] );
604 }
605 return vec;
606}
607
608QStyleSheetItem *QTextParag::style() const
609{
610 if ( !mStyleSheetItemsVec || mStyleSheetItemsVec->size() == 0 )
611 return 0;
612 return (*mStyleSheetItemsVec)[ mStyleSheetItemsVec->size() - 1 ];
613}
614
615int QTextParag::numberOfSubParagraph() const
616{
617 if ( list_val != -1 )
618 return list_val;
619 if ( numSubParag != -1 )
620 return numSubParag;
621 int n = 0;
622 QTextParag *p = (QTextParag*)this;
623 while ( p && ( styleSheetItemsVec().size() >= p->styleSheetItemsVec().size() &&
624 styleSheetItemsVec()[ (int)p->styleSheetItemsVec().size() - 1 ] == p->style() ||
625 p->styleSheetItemsVec().size() >= styleSheetItemsVec().size() &&
626 p->styleSheetItemsVec()[ (int)styleSheetItemsVec().size() - 1 ] == style() ) ) {
627 if ( p->style() == style() && listStyle() != p->listStyle()
628 && p->styleSheetItemsVec().size() == styleSheetItemsVec().size() )
629 break;
630 if ( p->style()->displayMode() == QStyleSheetItem::DisplayListItem
631 && p->style() != style() || styleSheetItemsVec().size() == p->styleSheetItemsVec().size() )
632 ++n;
633 p = p->prev();
634 }
635 ( (QTextParag*)this )->numSubParag = n;
636 return n;
637}
638
639void QTextParag::setFormat( QTextFormat *fm )
640{
641 bool doUpdate = FALSE;
642 if (defFormat && (defFormat != formatCollection()->defaultFormat()))
643 doUpdate = TRUE;
644 defFormat = formatCollection()->format( fm );
645 if ( !doUpdate )
646 return; 551 return;
647 for ( int i = 0; i < length(); ++i ) { 552 align = a;
648 if ( at( i )->format()->styleName() == defFormat->styleName() ) 553 invalidate( 0 );
649 at( i )->format()->updateStyle();
650 }
651} 554}
652 555
653QTextFormatter *QTextParag::formatter() const 556QTextFormatter *QTextParagraph::formatter() const
654{ 557{
655 if ( hasdoc ) 558 if ( hasdoc )
656 return document()->formatter(); 559 return document()->formatter();
657 if ( pseudoDocument()->pFormatter ) 560 if ( pseudoDocument()->pFormatter )
658 return pseudoDocument()->pFormatter; 561 return pseudoDocument()->pFormatter;
659 return ( ( (QTextParag*)this )->pseudoDocument()->pFormatter = new QTextFormatterBreakWords ); 562 return ( ( (QTextParagraph*)this )->pseudoDocument()->pFormatter = new QTextFormatterBreakWords );
660} 563}
661 564
662void QTextParag::setTabArray( int *a ) 565void QTextParagraph::setTabArray( int *a )
663{ 566{
664 delete [] tArray; 567 delete [] tArray;
665 tArray = a; 568 tArray = a;
666} 569}
667 570
668void QTextParag::setTabStops( int tw ) 571void QTextParagraph::setTabStops( int tw )
669{ 572{
670 if ( hasdoc ) 573 if ( hasdoc )
671 document()->setTabStops( tw ); 574 document()->setTabStops( tw );
@@ -673,24 +576,18 @@ void QTextParag::setTabStops( int tw )
673 tabStopWidth = tw; 576 tabStopWidth = tw;
674} 577}
675 578
676QMap<int, QTextParagSelection> &QTextParag::selections() const 579QMap<int, QTextParagraphSelection> &QTextParagraph::selections() const
677{ 580{
678 if ( !mSelections ) 581 if ( !mSelections )
679 ((QTextParag *)this)->mSelections = new QMap<int, QTextParagSelection>; 582 ((QTextParagraph *)this)->mSelections = new QMap<int, QTextParagraphSelection>;
680 return *mSelections; 583 return *mSelections;
681} 584}
682 585
683QPtrVector<QStyleSheetItem> &QTextParag::styleSheetItemsVec() const
684{
685 if ( !mStyleSheetItemsVec )
686 ((QTextParag *)this)->mStyleSheetItemsVec = new QPtrVector<QStyleSheetItem>;
687 return *mStyleSheetItemsVec;
688}
689 586
690QPtrList<QTextCustomItem> &QTextParag::floatingItems() const 587QPtrList<QTextCustomItem> &QTextParagraph::floatingItems() const
691{ 588{
692 if ( !mFloatingItems ) 589 if ( !mFloatingItems )
693 ((QTextParag *)this)->mFloatingItems = new QPtrList<QTextCustomItem>; 590 ((QTextParagraph *)this)->mFloatingItems = new QPtrList<QTextCustomItem>;
694 return *mFloatingItems; 591 return *mFloatingItems;
695} 592}
696 593
@@ -702,5 +599,5 @@ QTextStringChar::~QTextStringChar()
702 delete d.custom; 599 delete d.custom;
703} 600}
704 601
705QTextParagPseudoDocument::QTextParagPseudoDocument():pFormatter(0),commandHistory(0), minw(0),wused(0){} 602QTextParagraphPseudoDocument::QTextParagraphPseudoDocument():pFormatter(0),commandHistory(0), minw(0),wused(0){}
706QTextParagPseudoDocument::~QTextParagPseudoDocument(){ delete pFormatter; delete commandHistory; } 603QTextParagraphPseudoDocument::~QTextParagraphPseudoDocument(){ delete pFormatter; delete commandHistory; }
diff --git a/noncore/apps/opie-write/qrichtext_p.h b/noncore/apps/opie-write/qrichtext_p.h
index 94ce913..e368edb 100644
--- a/noncore/apps/opie-write/qrichtext_p.h
+++ b/noncore/apps/opie-write/qrichtext_p.h
@@ -51,7 +51,6 @@
51// 51//
52 52
53#ifndef QT_H 53#ifndef QT_H
54#include "qt3namespace.h"
55#include "qstring.h" 54#include "qstring.h"
56#include "qlist.h" 55#include "qlist.h"
57#include "qrect.h" 56#include "qrect.h"
@@ -78,8 +77,6 @@
78#include <limits.h> 77#include <limits.h>
79#endif // QT_H 78#endif // QT_H
80 79
81//#define DEBUG_COLLECTION
82
83namespace Qt3 { 80namespace Qt3 {
84 81
85class QTextDocument; 82class QTextDocument;
@@ -87,7 +84,7 @@ class QTextString;
87class QTextPreProcessor; 84class QTextPreProcessor;
88class QTextFormat; 85class QTextFormat;
89class QTextCursor; 86class QTextCursor;
90class QTextParag; 87class QTextParagraph;
91class QTextFormatter; 88class QTextFormatter;
92class QTextIndent; 89class QTextIndent;
93class QTextFormatCollection; 90class QTextFormatCollection;
@@ -125,7 +122,6 @@ public:
125 QTextCustomItem *customItem() const; 122 QTextCustomItem *customItem() const;
126 void setFormat( QTextFormat *f ); 123 void setFormat( QTextFormat *f );
127 void setCustomItem( QTextCustomItem *i ); 124 void setCustomItem( QTextCustomItem *i );
128 QTextStringChar *clone() const;
129 struct CustomData 125 struct CustomData
130 { 126 {
131 QTextFormat *format; 127 QTextFormat *format;
@@ -152,12 +148,12 @@ private:
152 return *this; 148 return *this;
153 } 149 }
154 friend class QComplexText; 150 friend class QComplexText;
155 friend class QTextParag; 151 friend class QTextParagraph;
156}; 152};
157 153
158#if defined(Q_TEMPLATEDLL) 154#if defined(Q_TEMPLATEDLL)
159// MOC_SKIP_BEGIN 155// MOC_SKIP_BEGIN
160template class Q_EXPORT QMemArray<QTextStringChar>; 156Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<QTextStringChar>;
161// MOC_SKIP_END 157// MOC_SKIP_END
162#endif 158#endif
163 159
@@ -178,7 +174,8 @@ public:
178 int width( int idx ) const; 174 int width( int idx ) const;
179 175
180 void insert( int index, const QString &s, QTextFormat *f ); 176 void insert( int index, const QString &s, QTextFormat *f );
181 void insert( int index, QTextStringChar *c ); 177 void insert( int index, const QChar *unicode, int len, QTextFormat *f );
178 void insert( int index, QTextStringChar *c, bool doAddRefFormat = FALSE );
182 void truncate( int index ); 179 void truncate( int index );
183 void remove( int index, int len ); 180 void remove( int index, int len );
184 void clear(); 181 void clear();
@@ -195,7 +192,7 @@ public:
195 QMemArray<QTextStringChar> rawData() const { return data; } 192 QMemArray<QTextStringChar> rawData() const { return data; }
196 193
197 void operator=( const QString &s ) { clear(); insert( 0, s, 0 ); } 194 void operator=( const QString &s ) { clear(); insert( 0, s, 0 ); }
198 void operator+=( const QString &s ); 195 void operator+=( const QString &s ) {insert( length(), s, 0 ); }
199 void prepend( const QString &s ) { insert( 0, s, 0 ); } 196 void prepend( const QString &s ) { insert( 0, s, 0 ); }
200 197
201private: 198private:
@@ -231,17 +228,16 @@ inline QChar::Direction QTextString::direction() const
231 228
232#if defined(Q_TEMPLATEDLL) 229#if defined(Q_TEMPLATEDLL)
233// MOC_SKIP_BEGIN 230// MOC_SKIP_BEGIN
234template class Q_EXPORT QValueStack<int>; 231Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<int>;
235template class Q_EXPORT QValueStack<QTextParag*>; 232Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<QTextParagraph*>;
236template class Q_EXPORT QValueStack<bool>; 233Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<bool>;
237// MOC_SKIP_END 234// MOC_SKIP_END
238#endif 235#endif
239 236
240class Q_EXPORT QTextCursor 237class Q_EXPORT QTextCursor
241{ 238{
242public: 239public:
243 QTextCursor( QTextDocument *d ); 240 QTextCursor( QTextDocument *d = 0 );
244 QTextCursor();
245 QTextCursor( const QTextCursor &c ); 241 QTextCursor( const QTextCursor &c );
246 QTextCursor &operator=( const QTextCursor &c ); 242 QTextCursor &operator=( const QTextCursor &c );
247 virtual ~QTextCursor() {} 243 virtual ~QTextCursor() {}
@@ -249,13 +245,13 @@ public:
249 bool operator==( const QTextCursor &c ) const; 245 bool operator==( const QTextCursor &c ) const;
250 bool operator!=( const QTextCursor &c ) const { return !(*this == c); } 246 bool operator!=( const QTextCursor &c ) const { return !(*this == c); }
251 247
252 QTextDocument *document() const { return doc; } 248 QTextParagraph *paragraph() const;
253 void setDocument( QTextDocument *d ); 249 void setParagraph( QTextParagraph*p ) { gotoPosition(p, 0 ); }
254 250 QTextDocument *document() const;
255 QTextParag *parag() const;
256 int index() const; 251 int index() const;
257 void setParag( QTextParag *s, bool restore = TRUE ); 252 void setIndex( int index ) { gotoPosition(paragraph(), index ); }
258 253
254 void gotoPosition( QTextParagraph* p, int index = 0);
259 void gotoLeft(); 255 void gotoLeft();
260 void gotoRight(); 256 void gotoRight();
261 void gotoNextLetter(); 257 void gotoNextLetter();
@@ -274,31 +270,29 @@ public:
274 void gotoWordRight(); 270 void gotoWordRight();
275 271
276 void insert( const QString &s, bool checkNewLine, QMemArray<QTextStringChar> *formatting = 0 ); 272 void insert( const QString &s, bool checkNewLine, QMemArray<QTextStringChar> *formatting = 0 );
277 void splitAndInsertEmptyParag( bool ind = TRUE, bool updateIds = TRUE ); 273 void splitAndInsertEmptyParagraph( bool ind = TRUE, bool updateIds = TRUE );
278 bool remove(); 274 bool remove();
279 void killLine();
280 void indent(); 275 void indent();
281 276
282 bool atParagStart(); 277 bool atParagStart();
283 bool atParagEnd(); 278 bool atParagEnd();
284 279
285 void setIndex( int i, bool restore = TRUE ); 280 int x() const; // x in current paragraph
286 281 int y() const; // y in current paragraph
287 void checkIndex();
288 282
289 int offsetX() const { return ox; } 283 int globalX() const;
290 int offsetY() const { return oy; } 284 int globalY() const;
291 285
292 QTextParag *topParag() const { return parags.isEmpty() ? string : parags.first(); } 286 QTextParagraph *topParagraph() const { return paras.isEmpty() ? para : paras.first(); }
293 int totalOffsetX() const; 287 int offsetX() const { return ox; } // inner document offset
294 int totalOffsetY() const; 288 int offsetY() const { return oy; } // inner document offset
289 int totalOffsetX() const; // total document offset
290 int totalOffsetY() const; // total document offset
295 291
296 bool place( const QPoint &pos, QTextParag *s ) { return place( pos, s, FALSE ); } 292 bool place( const QPoint &pos, QTextParagraph *s ) { return place( pos, s, FALSE ); }
297 bool place( const QPoint &pos, QTextParag *s, bool link ); 293 bool place( const QPoint &pos, QTextParagraph *s, bool link );
298 void restoreState(); 294 void restoreState();
299 295
300 int x() const;
301 int y() const;
302 296
303 int nestedDepth() const { return (int)indices.count(); } //### size_t/int cast 297 int nestedDepth() const { return (int)indices.count(); } //### size_t/int cast
304 void oneUp() { if ( !indices.isEmpty() ) pop(); } 298 void oneUp() { if ( !indices.isEmpty() ) pop(); }
@@ -314,16 +308,13 @@ private:
314 void invalidateNested(); 308 void invalidateNested();
315 void gotoIntoNested( const QPoint &globalPos ); 309 void gotoIntoNested( const QPoint &globalPos );
316 310
317 QTextParag *string; 311 QTextParagraph *para;
318 QTextDocument *doc;
319 int idx, tmpIndex; 312 int idx, tmpIndex;
320 int ox, oy; 313 int ox, oy;
321 QValueStack<int> indices; 314 QValueStack<int> indices;
322 QValueStack<QTextParag*> parags; 315 QValueStack<QTextParagraph*> paras;
323 QValueStack<int> xOffsets; 316 QValueStack<int> xOffsets;
324 QValueStack<int> yOffsets; 317 QValueStack<int> yOffsets;
325 QValueStack<bool> nestedStack;
326 uint nested : 1;
327 uint valid : 1; 318 uint valid : 1;
328 319
329}; 320};
@@ -333,7 +324,7 @@ private:
333class Q_EXPORT QTextCommand 324class Q_EXPORT QTextCommand
334{ 325{
335public: 326public:
336 enum Commands { Invalid, Insert, Delete, Format, Alignment, ParagType }; 327 enum Commands { Invalid, Insert, Delete, Format, Style };
337 328
338 QTextCommand( QTextDocument *d ) : doc( d ), cursor( d ) {} 329 QTextCommand( QTextDocument *d ) : doc( d ), cursor( d ) {}
339 virtual ~QTextCommand(); 330 virtual ~QTextCommand();
@@ -351,7 +342,7 @@ protected:
351 342
352#if defined(Q_TEMPLATEDLL) 343#if defined(Q_TEMPLATEDLL)
353// MOC_SKIP_BEGIN 344// MOC_SKIP_BEGIN
354template class Q_EXPORT QPtrList<QTextCommand>; 345Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextCommand>;
355// MOC_SKIP_END 346// MOC_SKIP_END
356#endif 347#endif
357 348
@@ -421,25 +412,25 @@ public:
421 412
422 QRect geometry() const { return QRect( xpos, ypos, width, height ); } 413 QRect geometry() const { return QRect( xpos, ypos, width, height ); }
423 414
424 virtual bool enter( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE ); 415 virtual bool enter( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
425 virtual bool enterAt( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, const QPoint & ); 416 virtual bool enterAt( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint & );
426 virtual bool next( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 417 virtual bool next( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
427 virtual bool prev( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 418 virtual bool prev( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
428 virtual bool down( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 419 virtual bool down( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
429 virtual bool up( QTextCursor *, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 420 virtual bool up( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
430 421
431 void setParagraph( QTextParag *p ) { parag = p; } 422 void setParagraph( QTextParagraph *p ) { parag = p; }
432 QTextParag *paragrapth() const { return parag; } 423 QTextParagraph *paragraph() const { return parag; }
433 424
434 QTextDocument *parent; 425 QTextDocument *parent;
435 QTextParag *parag; 426 QTextParagraph *parag;
436 427
437 virtual void pageBreak( int y, QTextFlow* flow ); 428 virtual void pageBreak( int y, QTextFlow* flow );
438}; 429};
439 430
440#if defined(Q_TEMPLATEDLL) 431#if defined(Q_TEMPLATEDLL)
441// MOC_SKIP_BEGIN 432// MOC_SKIP_BEGIN
442template class Q_EXPORT QMap<QString, QString>; 433Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<QString, QString>;
443// MOC_SKIP_END 434// MOC_SKIP_END
444#endif 435#endif
445 436
@@ -489,7 +480,7 @@ private:
489 480
490#if defined(Q_TEMPLATEDLL) 481#if defined(Q_TEMPLATEDLL)
491// MOC_SKIP_BEGIN 482// MOC_SKIP_BEGIN
492template class Q_EXPORT QPtrList<QTextCustomItem>; 483Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextCustomItem>;
493// MOC_SKIP_END 484// MOC_SKIP_END
494#endif 485#endif
495 486
@@ -546,7 +537,6 @@ public:
546 const QStyleSheetItem* style, 537 const QStyleSheetItem* style,
547 const QTextFormat& fmt, const QString& context, 538 const QTextFormat& fmt, const QString& context,
548 QMimeSourceFactory &factory, QStyleSheet *sheet, const QString& doc ); 539 QMimeSourceFactory &factory, QStyleSheet *sheet, const QString& doc );
549 QTextTableCell( QTextTable* table, int row, int column );
550 virtual ~QTextTableCell(); 540 virtual ~QTextTableCell();
551 541
552 QSize sizeHint() const ; 542 QSize sizeHint() const ;
@@ -600,8 +590,8 @@ private:
600 590
601#if defined(Q_TEMPLATEDLL) 591#if defined(Q_TEMPLATEDLL)
602// MOC_SKIP_BEGIN 592// MOC_SKIP_BEGIN
603template class Q_EXPORT QPtrList<QTextTableCell>; 593Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextTableCell>;
604template class Q_EXPORT QMap<QTextCursor*, int>; 594Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<QTextCursor*, int>;
605// MOC_SKIP_END 595// MOC_SKIP_END
606#endif 596#endif
607 597
@@ -625,12 +615,12 @@ public:
625 void resize( int nwidth ); 615 void resize( int nwidth );
626 virtual void invalidate(); 616 virtual void invalidate();
627 617
628 virtual bool enter( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE ); 618 virtual bool enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
629 virtual bool enterAt( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy, const QPoint &pos ); 619 virtual bool enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos );
630 virtual bool next( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 620 virtual bool next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
631 virtual bool prev( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 621 virtual bool prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
632 virtual bool down( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 622 virtual bool down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
633 virtual bool up( QTextCursor *c, QTextDocument *&doc, QTextParag *&parag, int &idx, int &ox, int &oy ); 623 virtual bool up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
634 624
635 QString richText() const; 625 QString richText() const;
636 626
@@ -666,7 +656,7 @@ private:
666// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 656// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
667 657
668class QTextTableCell; 658class QTextTableCell;
669class QTextParag; 659class QTextParagraph;
670 660
671struct Q_EXPORT QTextDocumentSelection 661struct Q_EXPORT QTextDocumentSelection
672{ 662{
@@ -676,10 +666,10 @@ struct Q_EXPORT QTextDocumentSelection
676 666
677#if defined(Q_TEMPLATEDLL) 667#if defined(Q_TEMPLATEDLL)
678// MOC_SKIP_BEGIN 668// MOC_SKIP_BEGIN
679template class Q_EXPORT QMap<int, QColor>; 669Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QColor>;
680template class Q_EXPORT QMap<int, bool>; 670Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, bool>;
681template class Q_EXPORT QMap<int, QTextDocumentSelection>; 671Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextDocumentSelection>;
682template class Q_EXPORT QPtrList<QTextDocument>; 672Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextDocument>;
683// MOC_SKIP_END 673// MOC_SKIP_END
684#endif 674#endif
685 675
@@ -690,7 +680,7 @@ class Q_EXPORT QTextDocument : public QObject
690 friend class QTextTableCell; 680 friend class QTextTableCell;
691 friend class QTextCursor; 681 friend class QTextCursor;
692 friend class QTextEdit; 682 friend class QTextEdit;
693 friend class QTextParag; 683 friend class QTextParagraph;
694 684
695public: 685public:
696 enum SelectionIds { 686 enum SelectionIds {
@@ -704,7 +694,7 @@ public:
704 virtual ~QTextDocument(); 694 virtual ~QTextDocument();
705 695
706 QTextDocument *parent() const { return par; } 696 QTextDocument *parent() const { return par; }
707 QTextParag *parentParag() const { return parParag; } 697 QTextParagraph *parentParagraph() const { return parentPar; }
708 698
709 void setText( const QString &text, const QString &context ); 699 void setText( const QString &text, const QString &context );
710 QMap<QString, QString> attributes() const { return attribs; } 700 QMap<QString, QString> attributes() const { return attribs; }
@@ -722,7 +712,7 @@ public:
722 int height() const; 712 int height() const;
723 void setWidth( int w ); 713 void setWidth( int w );
724 int minimumWidth() const; 714 int minimumWidth() const;
725 bool setMinimumWidth( int needed, int used = -1, QTextParag *parag = 0 ); 715 bool setMinimumWidth( int needed, int used = -1, QTextParagraph *parag = 0 );
726 716
727 void setY( int y ); 717 void setY( int y );
728 int leftMargin() const; 718 int leftMargin() const;
@@ -730,10 +720,10 @@ public:
730 int rightMargin() const; 720 int rightMargin() const;
731 void setRightMargin( int rm ); 721 void setRightMargin( int rm );
732 722
733 QTextParag *firstParag() const; 723 QTextParagraph *firstParagraph() const;
734 QTextParag *lastParag() const; 724 QTextParagraph *lastParagraph() const;
735 void setFirstParag( QTextParag *p ); 725 void setFirstParagraph( QTextParagraph *p );
736 void setLastParag( QTextParag *p ); 726 void setLastParagraph( QTextParagraph *p );
737 727
738 void invalidate(); 728 void invalidate();
739 729
@@ -751,8 +741,8 @@ public:
751 void setSelectionColor( int id, const QColor &c ); 741 void setSelectionColor( int id, const QColor &c );
752 void setInvertSelectionText( int id, bool b ); 742 void setInvertSelectionText( int id, bool b );
753 bool hasSelection( int id, bool visible = FALSE ) const; 743 bool hasSelection( int id, bool visible = FALSE ) const;
754 void setSelectionStart( int id, QTextCursor *cursor ); 744 void setSelectionStart( int id, const QTextCursor &cursor );
755 bool setSelectionEnd( int id, QTextCursor *cursor ); 745 bool setSelectionEnd( int id, const QTextCursor &cursor );
756 void selectAll( int id ); 746 void selectAll( int id );
757 bool removeSelection( int id ); 747 bool removeSelection( int id );
758 void selectionStart( int id, int &paragId, int &index ); 748 void selectionStart( int id, int &paragId, int &index );
@@ -760,17 +750,14 @@ public:
760 QTextCursor selectionEndCursor( int id ); 750 QTextCursor selectionEndCursor( int id );
761 void selectionEnd( int id, int &paragId, int &index ); 751 void selectionEnd( int id, int &paragId, int &index );
762 void setFormat( int id, QTextFormat *f, int flags ); 752 void setFormat( int id, QTextFormat *f, int flags );
763 QTextParag *selectionStart( int id );
764 QTextParag *selectionEnd( int id );
765 int numSelections() const { return nSelections; } 753 int numSelections() const { return nSelections; }
766 void addSelection( int id ); 754 void addSelection( int id );
767 755
768 QString selectedText( int id, bool withCustom = TRUE ) const; 756 QString selectedText( int id, bool asRichText = FALSE ) const;
769 void copySelectedText( int id );
770 void removeSelectedText( int id, QTextCursor *cursor ); 757 void removeSelectedText( int id, QTextCursor *cursor );
771 void indentSelection( int id ); 758 void indentSelection( int id );
772 759
773 QTextParag *paragAt( int i ) const; 760 QTextParagraph *paragAt( int i ) const;
774 761
775 void addCommand( QTextCommand *cmd ); 762 void addCommand( QTextCommand *cmd );
776 QTextCursor *undo( QTextCursor *c = 0 ); 763 QTextCursor *undo( QTextCursor *c = 0 );
@@ -779,7 +766,7 @@ public:
779 766
780 QTextFormatCollection *formatCollection() const; 767 QTextFormatCollection *formatCollection() const;
781 768
782 bool find( const QString &expr, bool cs, bool wo, bool forward, int *parag, int *index, QTextCursor *cursor ); 769 bool find( QTextCursor &cursor, const QString &expr, bool cs, bool wo, bool forward);
783 770
784 void setTextFormat( Qt::TextFormat f ); 771 void setTextFormat( Qt::TextFormat f );
785 Qt::TextFormat textFormat() const; 772 Qt::TextFormat textFormat() const;
@@ -791,13 +778,11 @@ public:
791 QString context() const { return contxt; } 778 QString context() const { return contxt; }
792 779
793 void setStyleSheet( QStyleSheet *s ); 780 void setStyleSheet( QStyleSheet *s );
794 void updateStyles(); 781 void setDefaultFormat( const QFont &font, const QColor &color );
795 void updateFontSizes( int base, bool usePixels );
796 void updateFontAttributes( const QFont &f, const QFont &old );
797 void setMimeSourceFactory( QMimeSourceFactory *f ) { if ( f ) factory_ = f; } 782 void setMimeSourceFactory( QMimeSourceFactory *f ) { if ( f ) factory_ = f; }
798 void setContext( const QString &c ) { if ( !c.isEmpty() ) contxt = c; } 783 void setContext( const QString &c ) { if ( !c.isEmpty() ) contxt = c; }
799 784
800 void setUnderlineLinks( bool b ) { underlLinks = b; } 785 void setUnderlineLinks( bool b );
801 bool underlineLinks() const { return underlLinks; } 786 bool underlineLinks() const { return underlLinks; }
802 787
803 void setPaper( QBrush *brush ) { if ( backBrush ) delete backBrush; backBrush = brush; } 788 void setPaper( QBrush *brush ) { if ( backBrush ) delete backBrush; backBrush = brush; }
@@ -805,17 +790,15 @@ public:
805 790
806 void doLayout( QPainter *p, int w ); 791 void doLayout( QPainter *p, int w );
807 void draw( QPainter *p, const QRect& rect, const QColorGroup &cg, const QBrush *paper = 0 ); 792 void draw( QPainter *p, const QRect& rect, const QColorGroup &cg, const QBrush *paper = 0 );
808 void drawParag( QPainter *p, QTextParag *parag, int cx, int cy, int cw, int ch, 793 void drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch,
809 QPixmap *&doubleBuffer, const QColorGroup &cg, 794 QPixmap *&doubleBuffer, const QColorGroup &cg,
810 bool drawCursor, QTextCursor *cursor, bool resetChanged = TRUE ); 795 bool drawCursor, QTextCursor *cursor, bool resetChanged = TRUE );
811 QTextParag *draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, 796 QTextParagraph *draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg,
812 bool onlyChanged = FALSE, bool drawCursor = FALSE, QTextCursor *cursor = 0, 797 bool onlyChanged = FALSE, bool drawCursor = FALSE, QTextCursor *cursor = 0,
813 bool resetChanged = TRUE ); 798 bool resetChanged = TRUE );
814 799
815 void setDefaultFont( const QFont &f ); 800 void registerCustomItem( QTextCustomItem *i, QTextParagraph *p );
816 801 void unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p );
817 void registerCustomItem( QTextCustomItem *i, QTextParag *p );
818 void unregisterCustomItem( QTextCustomItem *i, QTextParag *p );
819 802
820 void setFlow( QTextFlow *f ); 803 void setFlow( QTextFlow *f );
821 void takeFlow(); 804 void takeFlow();
@@ -831,8 +814,8 @@ public:
831 814
832 void setPlainText( const QString &text ); 815 void setPlainText( const QString &text );
833 void setRichText( const QString &text, const QString &context ); 816 void setRichText( const QString &text, const QString &context );
834 QString richText( QTextParag *p = 0 ) const; 817 QString richText() const;
835 QString plainText( QTextParag *p = 0 ) const; 818 QString plainText() const;
836 819
837 bool focusNextPrevChild( bool next ); 820 bool focusNextPrevChild( bool next );
838 821
@@ -850,21 +833,21 @@ public:
850 int length() const; 833 int length() const;
851 void clear( bool createEmptyParag = FALSE ); 834 void clear( bool createEmptyParag = FALSE );
852 835
853 virtual QTextParag *createParag( QTextDocument *d, QTextParag *pr = 0, QTextParag *nx = 0, bool updateIds = TRUE ); 836 virtual QTextParagraph *createParagraph( QTextDocument *d, QTextParagraph *pr = 0, QTextParagraph *nx = 0, bool updateIds = TRUE );
854 void insertChild( QObject *o ) { QObject::insertChild( o ); } 837 void insertChild( QObject *o ) { QObject::insertChild( o ); }
855 void removeChild( QObject *o ) { QObject::removeChild( o ); } 838 void removeChild( QObject *o ) { QObject::removeChild( o ); }
856 void insertChild( QTextDocument *d ) { childList.append( d ); } 839 void insertChild( QTextDocument *d ) { childList.append( d ); }
857 void removeChild( QTextDocument *d ) { childList.removeRef( d ); } 840 void removeChild( QTextDocument *d ) { childList.removeRef( d ); }
858 QPtrList<QTextDocument> children() const { return childList; } 841 QPtrList<QTextDocument> children() const { return childList; }
859 842
860 void setAddMargins( bool b ) { addMargs = b; }
861 int addMargins() const { return addMargs; }
862
863 bool hasFocusParagraph() const; 843 bool hasFocusParagraph() const;
864 QString focusHref() const; 844 QString focusHref() const;
865 845
866 void invalidateOriginalText() { oTextValid = FALSE; oText = ""; } 846 void invalidateOriginalText() { oTextValid = FALSE; oText = ""; }
867 847
848 static QString section( QString str, const QString &sep, int start, int end = 0xffffffff );
849 static bool endsWith( QString str, const QString &s);
850
868signals: 851signals:
869 void minimumWidthChanged( int ); 852 void minimumWidthChanged( int );
870 853
@@ -875,7 +858,7 @@ private:
875 bool hasPrefix(const QChar* doc, int length, int pos, QChar c); 858 bool hasPrefix(const QChar* doc, int length, int pos, QChar c);
876 bool hasPrefix(const QChar* doc, int length, int pos, const QString& s); 859 bool hasPrefix(const QChar* doc, int length, int pos, const QString& s);
877 QTextCustomItem* parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, 860 QTextCustomItem* parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt,
878 const QChar* doc, int length, int& pos, QTextParag *curpar ); 861 const QChar* doc, int length, int& pos, QTextParagraph *curpar );
879 bool eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp = FALSE ); 862 bool eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp = FALSE );
880 bool eat(const QChar* doc, int length, int& pos, QChar c); 863 bool eat(const QChar* doc, int length, int& pos, QChar c);
881 QString parseOpenTag(const QChar* doc, int length, int& pos, QMap<QString, QString> &attr, bool& emptyTag); 864 QString parseOpenTag(const QChar* doc, int length, int& pos, QMap<QString, QString> &attr, bool& emptyTag);
@@ -883,17 +866,18 @@ private:
883 QChar parseHTMLSpecialChar(const QChar* doc, int length, int& pos); 866 QChar parseHTMLSpecialChar(const QChar* doc, int length, int& pos);
884 QString parseWord(const QChar* doc, int length, int& pos, bool lower = TRUE); 867 QString parseWord(const QChar* doc, int length, int& pos, bool lower = TRUE);
885 QChar parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ); 868 QChar parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm );
886 void setRichTextInternal( const QString &text ); 869 void setRichTextInternal( const QString &text, QTextCursor* cursor = 0 );
870 void setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar );
887 871
888private: 872private:
889 struct Q_EXPORT Focus { 873 struct Q_EXPORT Focus {
890 QTextParag *parag; 874 QTextParagraph *parag;
891 int start, len; 875 int start, len;
892 QString href; 876 QString href;
893 }; 877 };
894 878
895 int cx, cy, cw, vw; 879 int cx, cy, cw, vw;
896 QTextParag *fParag, *lParag; 880 QTextParagraph *fParag, *lParag;
897 QTextPreProcessor *pProcessor; 881 QTextPreProcessor *pProcessor;
898 QMap<int, QColor> selectionColors; 882 QMap<int, QColor> selectionColors;
899 QMap<int, QTextDocumentSelection> selections; 883 QMap<int, QTextDocumentSelection> selections;
@@ -909,16 +893,14 @@ private:
909 uint withoutDoubleBuffer : 1; 893 uint withoutDoubleBuffer : 1;
910 uint underlLinks : 1; 894 uint underlLinks : 1;
911 uint nextDoubleBuffered : 1; 895 uint nextDoubleBuffered : 1;
912 uint addMargs : 1;
913 uint oTextValid : 1; 896 uint oTextValid : 1;
914 uint mightHaveCustomItems : 1; 897 uint mightHaveCustomItems : 1;
915 int align; 898 int align;
916 int nSelections; 899 int nSelections;
917 QTextFlow *flow_; 900 QTextFlow *flow_;
918 QTextDocument *par; 901 QTextDocument *par;
919 QTextParag *parParag; 902 QTextParagraph *parentPar;
920 QTextTableCell *tc; 903 QTextTableCell *tc;
921 QTextCursor *tmpCursor;
922 QBrush *backBrush; 904 QBrush *backBrush;
923 QPixmap *buf_pixmap; 905 QPixmap *buf_pixmap;
924 Focus focusIndicator; 906 Focus focusIndicator;
@@ -926,7 +908,7 @@ private:
926 int wused; 908 int wused;
927 int leftmargin; 909 int leftmargin;
928 int rightmargin; 910 int rightmargin;
929 QTextParag *minwParag, *curParag; 911 QTextParagraph *minwParag, *curParag;
930 QStyleSheet* sheet_; 912 QStyleSheet* sheet_;
931 QMimeSourceFactory* factory_; 913 QMimeSourceFactory* factory_;
932 QString contxt; 914 QString contxt;
@@ -937,7 +919,9 @@ private:
937 QString oText; 919 QString oText;
938 QPtrList<QTextDocument> childList; 920 QPtrList<QTextDocument> childList;
939 QColor linkColor; 921 QColor linkColor;
922 double scaleFontsFactor;
940 923
924 short list_tm,list_bm, list_lm, li_tm, li_bm, par_tm, par_bm;
941}; 925};
942 926
943// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 927// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -947,10 +931,8 @@ class Q_EXPORT QTextDeleteCommand : public QTextCommand
947{ 931{
948public: 932public:
949 QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, 933 QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
950 const QValueList< QPtrVector<QStyleSheetItem> > &os, 934 const QByteArray& oldStyle );
951 const QValueList<QStyleSheetItem::ListStyle> &ols, 935 QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str );
952 const QMemArray<int> &oas );
953 QTextDeleteCommand( QTextParag *p, int idx, const QMemArray<QTextStringChar> &str );
954 virtual ~QTextDeleteCommand(); 936 virtual ~QTextDeleteCommand();
955 937
956 Commands type() const { return Delete; } 938 Commands type() const { return Delete; }
@@ -959,11 +941,9 @@ public:
959 941
960protected: 942protected:
961 int id, index; 943 int id, index;
962 QTextParag *parag; 944 QTextParagraph *parag;
963 QMemArray<QTextStringChar> text; 945 QMemArray<QTextStringChar> text;
964 QValueList< QPtrVector<QStyleSheetItem> > oldStyles; 946 QByteArray styleInformation;
965 QValueList<QStyleSheetItem::ListStyle> oldListStyles;
966 QMemArray<int> oldAligns;
967 947
968}; 948};
969 949
@@ -971,11 +951,9 @@ class Q_EXPORT QTextInsertCommand : public QTextDeleteCommand
971{ 951{
972public: 952public:
973 QTextInsertCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, 953 QTextInsertCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
974 const QValueList< QPtrVector<QStyleSheetItem> > &os, 954 const QByteArray& oldStyleInfo )
975 const QValueList<QStyleSheetItem::ListStyle> &ols, 955 : QTextDeleteCommand( d, i, idx, str, oldStyleInfo ) {}
976 const QMemArray<int> &oas ) 956 QTextInsertCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str )
977 : QTextDeleteCommand( d, i, idx, str, os, ols, oas ) {}
978 QTextInsertCommand( QTextParag *p, int idx, const QMemArray<QTextStringChar> &str )
979 : QTextDeleteCommand( p, idx, str ) {} 957 : QTextDeleteCommand( p, idx, str ) {}
980 virtual ~QTextInsertCommand() {} 958 virtual ~QTextInsertCommand() {}
981 959
@@ -1003,70 +981,51 @@ protected:
1003 981
1004}; 982};
1005 983
1006class Q_EXPORT QTextAlignmentCommand : public QTextCommand 984class Q_EXPORT QTextStyleCommand : public QTextCommand
1007{ 985{
1008public: 986public:
1009 QTextAlignmentCommand( QTextDocument *d, int fParag, int lParag, int na, const QMemArray<int> &oa ); 987 QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange );
1010 virtual ~QTextAlignmentCommand() {} 988 virtual ~QTextStyleCommand() {}
1011 989
1012 Commands type() const { return Alignment; } 990 Commands type() const { return Style; }
1013 QTextCursor *execute( QTextCursor *c ); 991 QTextCursor *execute( QTextCursor *c );
1014 QTextCursor *unexecute( QTextCursor *c ); 992 QTextCursor *unexecute( QTextCursor *c );
1015 993
1016private: 994 static QByteArray readStyleInformation( QTextDocument* d, int fParag, int lParag );
1017 int firstParag, lastParag; 995 static void writeStyleInformation( QTextDocument* d, int fParag, const QByteArray& style );
1018 int newAlign;
1019 QMemArray<int> oldAligns;
1020
1021};
1022
1023class Q_EXPORT QTextParagTypeCommand : public QTextCommand
1024{
1025public:
1026 QTextParagTypeCommand( QTextDocument *d, int fParag, int lParag, bool l,
1027 QStyleSheetItem::ListStyle s, const QValueList< QPtrVector<QStyleSheetItem> > &os,
1028 const QValueList<QStyleSheetItem::ListStyle> &ols );
1029 virtual ~QTextParagTypeCommand() {}
1030
1031 Commands type() const { return ParagType; }
1032 QTextCursor *execute( QTextCursor *c );
1033 QTextCursor *unexecute( QTextCursor *c );
1034 996
1035private: 997private:
1036 int firstParag, lastParag; 998 int firstParag, lastParag;
1037 bool list; 999 QByteArray before;
1038 QStyleSheetItem::ListStyle listStyle; 1000 QByteArray after;
1039 QValueList< QPtrVector<QStyleSheetItem> > oldStyles;
1040 QValueList<QStyleSheetItem::ListStyle> oldListStyles;
1041
1042}; 1001};
1043 1002
1044// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1003// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1045 1004
1046struct Q_EXPORT QTextParagSelection 1005struct Q_EXPORT QTextParagraphSelection
1047{ 1006{
1048 int start, end; 1007 int start, end;
1049}; 1008};
1050 1009
1051struct Q_EXPORT QTextParagLineStart 1010struct Q_EXPORT QTextLineStart
1052{ 1011{
1053 QTextParagLineStart() : y( 0 ), baseLine( 0 ), h( 0 ) 1012 QTextLineStart() : y( 0 ), baseLine( 0 ), h( 0 )
1054#ifndef QT_NO_COMPLEXTEXT 1013#ifndef QT_NO_COMPLEXTEXT
1055 , bidicontext( 0 ) 1014 , bidicontext( 0 )
1056#endif 1015#endif
1057 { } 1016 { }
1058 QTextParagLineStart( ushort y_, ushort bl, ushort h_ ) : y( y_ ), baseLine( bl ), h( h_ ), 1017 QTextLineStart( ushort y_, ushort bl, ushort h_ ) : y( y_ ), baseLine( bl ), h( h_ ),
1059 w( 0 ) 1018 w( 0 )
1060#ifndef QT_NO_COMPLEXTEXT 1019#ifndef QT_NO_COMPLEXTEXT
1061 , bidicontext( 0 ) 1020 , bidicontext( 0 )
1062#endif 1021#endif
1063 { } 1022 { }
1064#ifndef QT_NO_COMPLEXTEXT 1023#ifndef QT_NO_COMPLEXTEXT
1065 QTextParagLineStart( QBidiContext *c, QBidiStatus s ) : y(0), baseLine(0), h(0), 1024 QTextLineStart( QBidiContext *c, QBidiStatus s ) : y(0), baseLine(0), h(0),
1066 status( s ), bidicontext( c ) { if ( bidicontext ) bidicontext->ref(); } 1025 status( s ), bidicontext( c ) { if ( bidicontext ) bidicontext->ref(); }
1067#endif 1026#endif
1068 1027
1069 virtual ~QTextParagLineStart() 1028 virtual ~QTextLineStart()
1070 { 1029 {
1071#ifndef QT_NO_COMPLEXTEXT 1030#ifndef QT_NO_COMPLEXTEXT
1072 if ( bidicontext && bidicontext->deref() ) 1031 if ( bidicontext && bidicontext->deref() )
@@ -1102,24 +1061,24 @@ private:
1102 1061
1103#if defined(Q_TEMPLATEDLL) 1062#if defined(Q_TEMPLATEDLL)
1104// MOC_SKIP_BEGIN 1063// MOC_SKIP_BEGIN
1105template class Q_EXPORT QMap<int, QTextParagSelection>; 1064Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextParagraphSelection>;
1106template class Q_EXPORT QMap<int, QTextParagLineStart*>; 1065Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextLineStart*>;
1107// MOC_SKIP_END 1066// MOC_SKIP_END
1108#endif 1067#endif
1109 1068
1110class Q_EXPORT QTextParagData 1069class Q_EXPORT QTextParagraphData
1111{ 1070{
1112public: 1071public:
1113 QTextParagData() {} 1072 QTextParagraphData() {}
1114 virtual ~QTextParagData(); 1073 virtual ~QTextParagraphData();
1115 virtual void join( QTextParagData * ); 1074 virtual void join( QTextParagraphData * );
1116}; 1075};
1117 1076
1118class Q_EXPORT QTextParagPseudoDocument 1077class Q_EXPORT QTextParagraphPseudoDocument
1119{ 1078{
1120public: 1079public:
1121 QTextParagPseudoDocument(); 1080 QTextParagraphPseudoDocument();
1122 ~QTextParagPseudoDocument(); 1081 ~QTextParagraphPseudoDocument();
1123 QRect docRect; 1082 QRect docRect;
1124 QTextFormatter *pFormatter; 1083 QTextFormatter *pFormatter;
1125 QTextCommandHistory *commandHistory; 1084 QTextCommandHistory *commandHistory;
@@ -1128,35 +1087,35 @@ public:
1128}; 1087};
1129 1088
1130//nase 1089//nase
1131class Q_EXPORT QTextParag 1090class Q_EXPORT QTextParagraph
1132{ 1091{
1133 friend class QTextDocument; 1092 friend class QTextDocument;
1134 friend class QTextCursor; 1093 friend class QTextCursor;
1135 1094
1136public: 1095public:
1137 QTextParag( QTextDocument *d, QTextParag *pr = 0, QTextParag *nx = 0, bool updateIds = TRUE ); 1096 QTextParagraph( QTextDocument *d, QTextParagraph *pr = 0, QTextParagraph *nx = 0, bool updateIds = TRUE );
1138 virtual ~QTextParag(); 1097 virtual ~QTextParagraph();
1139 1098
1140 QTextString *string() const; 1099 QTextString *string() const;
1141 QTextStringChar *at( int i ) const; // maybe remove later 1100 QTextStringChar *at( int i ) const; // maybe remove later
1142 int leftGap() const; 1101 int leftGap() const;
1143 int length() const; // maybe remove later 1102 int length() const; // maybe remove later
1144 1103
1145 void setListStyle( QStyleSheetItem::ListStyle ls ); 1104 void setListStyle( QStyleSheetItem::ListStyle ls ) { lstyle = ls; changed = TRUE; }
1146 QStyleSheetItem::ListStyle listStyle() const; 1105 QStyleSheetItem::ListStyle listStyle() const { return lstyle; }
1106 void setListItem( bool li ) { litem = li; changed = TRUE; }
1107 bool isListItem() const { return litem; }
1147 void setListValue( int v ) { list_val = v; } 1108 void setListValue( int v ) { list_val = v; }
1148 int listValue() const { return list_val; } 1109 int listValue() const { return list_val > 0 ? list_val : -1; }
1149 1110
1150 void setList( bool b, int listStyle ); 1111 void setListDepth( int depth );
1151 void incDepth(); 1112 int listDepth() const { return ldepth; }
1152 void decDepth();
1153 int listDepth() const;
1154 1113
1155 void setFormat( QTextFormat *fm ); 1114// void setFormat( QTextFormat *fm );
1156 QTextFormat *paragFormat() const; 1115// QTextFormat *paragFormat() const;
1157 1116
1158 QTextDocument *document() const; 1117 QTextDocument *document() const;
1159 QTextParagPseudoDocument *pseudoDocument() const; 1118 QTextParagraphPseudoDocument *pseudoDocument() const;
1160 1119
1161 QRect rect() const; 1120 QRect rect() const;
1162 void setHeight( int h ) { r.setHeight( h ); } 1121 void setHeight( int h ) { r.setHeight( h ); }
@@ -1164,16 +1123,17 @@ public:
1164 void hide(); 1123 void hide();
1165 bool isVisible() const { return visible; } 1124 bool isVisible() const { return visible; }
1166 1125
1167 QTextParag *prev() const; 1126 QTextParagraph *prev() const;
1168 QTextParag *next() const; 1127 QTextParagraph *next() const;
1169 void setPrev( QTextParag *s ); 1128 void setPrev( QTextParagraph *s );
1170 void setNext( QTextParag *s ); 1129 void setNext( QTextParagraph *s );
1171 1130
1172 void insert( int index, const QString &s ); 1131 void insert( int index, const QString &s );
1132 void insert( int index, const QChar *unicode, int len );
1173 void append( const QString &s, bool reallyAtEnd = FALSE ); 1133 void append( const QString &s, bool reallyAtEnd = FALSE );
1174 void truncate( int index ); 1134 void truncate( int index );
1175 void remove( int index, int len ); 1135 void remove( int index, int len );
1176 void join( QTextParag *s ); 1136 void join( QTextParagraph *s );
1177 1137
1178 void invalidate( int chr ); 1138 void invalidate( int chr );
1179 1139
@@ -1212,10 +1172,10 @@ public:
1212 1172
1213 void indent( int *oldIndent = 0, int *newIndent = 0 ); 1173 void indent( int *oldIndent = 0, int *newIndent = 0 );
1214 1174
1215 void setExtraData( QTextParagData *data ); 1175 void setExtraData( QTextParagraphData *data );
1216 QTextParagData *extraData() const; 1176 QTextParagraphData *extraData() const;
1217 1177
1218 QMap<int, QTextParagLineStart*> &lineStartList(); 1178 QMap<int, QTextLineStart*> &lineStartList();
1219 1179
1220 void setFormat( int index, int len, QTextFormat *f, bool useCollection = TRUE, int flags = -1 ); 1180 void setFormat( int index, int len, QTextFormat *f, bool useCollection = TRUE, int flags = -1 );
1221 1181
@@ -1225,10 +1185,6 @@ public:
1225 virtual void paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor = 0, bool drawSelections = FALSE, 1185 virtual void paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor = 0, bool drawSelections = FALSE,
1226 int clipx = -1, int clipy = -1, int clipw = -1, int cliph = -1 ); 1186 int clipx = -1, int clipy = -1, int clipw = -1, int cliph = -1 );
1227 1187
1228 void setStyleSheetItems( const QPtrVector<QStyleSheetItem> &vec );
1229 QPtrVector<QStyleSheetItem> styleSheetItems() const;
1230 QStyleSheetItem *style() const;
1231
1232 virtual int topMargin() const; 1188 virtual int topMargin() const;
1233 virtual int bottomMargin() const; 1189 virtual int bottomMargin() const;
1234 virtual int leftMargin() const; 1190 virtual int leftMargin() const;
@@ -1236,7 +1192,6 @@ public:
1236 virtual int rightMargin() const; 1192 virtual int rightMargin() const;
1237 virtual int lineSpacing() const; 1193 virtual int lineSpacing() const;
1238 1194
1239 int numberOfSubParagraph() const;
1240 void registerFloatingItem( QTextCustomItem *i ); 1195 void registerFloatingItem( QTextCustomItem *i );
1241 void unregisterFloatingItem( QTextCustomItem *i ); 1196 void unregisterFloatingItem( QTextCustomItem *i );
1242 1197
@@ -1270,7 +1225,7 @@ public:
1270 QTextCursor *undo( QTextCursor *c = 0 ); 1225 QTextCursor *undo( QTextCursor *c = 0 );
1271 QTextCursor *redo( QTextCursor *c = 0 ); 1226 QTextCursor *redo( QTextCursor *c = 0 );
1272 QTextCommandHistory *commands() const; 1227 QTextCommandHistory *commands() const;
1273 virtual void copyParagData( QTextParag *parag ); 1228 virtual void copyParagData( QTextParagraph *parag );
1274 1229
1275 void setBreakable( bool b ) { breakable = b; } 1230 void setBreakable( bool b ) { breakable = b; }
1276 bool isBreakable() const { return breakable; } 1231 bool isBreakable() const { return breakable; }
@@ -1279,59 +1234,59 @@ public:
1279 QColor *backgroundColor() const { return bgcol; } 1234 QColor *backgroundColor() const { return bgcol; }
1280 void clearBackgroundColor(); 1235 void clearBackgroundColor();
1281 1236
1282 bool isLineBreak() const { return isBr; }
1283
1284 void setMovedDown( bool b ) { movedDown = b; } 1237 void setMovedDown( bool b ) { movedDown = b; }
1285 bool wasMovedDown() const { return movedDown; } 1238 bool wasMovedDown() const { return movedDown; }
1286 1239
1287 void setDirection( QChar::Direction d ); 1240 void setDirection( QChar::Direction d );
1288 QChar::Direction direction() const; 1241 QChar::Direction direction() const;
1289 1242
1243 void readStyleInformation( QDataStream& stream );
1244 void writeStyleInformation( QDataStream& stream ) const;
1245
1290protected: 1246protected:
1291 virtual void drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ); 1247 virtual void drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg );
1292 virtual void drawParagString( QPainter &painter, const QString &str, int start, int len, int startX, 1248 virtual void drawString( QPainter &painter, const QString &str, int start, int len, int xstart,
1293 int lastY, int baseLine, int bw, int h, bool drawSelections, 1249 int y, int baseLine, int w, int h, int selection,
1294 QTextStringChar *formatChar, int i, const QMemArray<int> &selectionStarts, 1250 QTextStringChar *formatChar, const QColorGroup& cg,
1295 const QMemArray<int> &selectionEnds, const QColorGroup &cg, bool rightToLeft ); 1251 bool rightToLeft );
1296 1252
1297private: 1253private:
1298 QMap<int, QTextParagSelection> &selections() const; 1254 QMap<int, QTextParagraphSelection> &selections() const;
1299 QPtrVector<QStyleSheetItem> &styleSheetItemsVec() const;
1300 QPtrList<QTextCustomItem> &floatingItems() const; 1255 QPtrList<QTextCustomItem> &floatingItems() const;
1256 QBrush backgroundBrush( const QColorGroup&cg ) { if ( bgcol ) return *bgcol; return cg.brush( QColorGroup::Base ); }
1257 void invalidateStyleCache();
1301 1258
1302 QMap<int, QTextParagLineStart*> lineStarts; 1259 QMap<int, QTextLineStart*> lineStarts;
1303 int invalid; 1260 int invalid;
1304 QRect r; 1261 QRect r;
1305 QTextParag *p, *n; 1262 QTextParagraph *p, *n;
1306 void *docOrPseudo; 1263 void *docOrPseudo;
1307 uint changed : 1; 1264 uint changed : 1;
1308 uint firstFormat : 1; 1265 uint firstFormat : 1;
1309 uint firstPProcess : 1; 1266 uint firstPProcess : 1;
1310 uint needPreProcess : 1; 1267 uint needPreProcess : 1;
1311 uint fullWidth : 1; 1268 uint fullWidth : 1;
1312 uint newLinesAllowed : 1;
1313 uint lastInFrame : 1; 1269 uint lastInFrame : 1;
1314 uint visible : 1; 1270 uint visible : 1;
1315 uint breakable : 1; 1271 uint breakable : 1;
1316 uint isBr : 1;
1317 uint movedDown : 1; 1272 uint movedDown : 1;
1318 uint mightHaveCustomItems : 1; 1273 uint mightHaveCustomItems : 1;
1319 uint hasdoc : 1; 1274 uint hasdoc : 1;
1275 uint litem : 1; // whether the paragraph is a list item
1276 uint rtext : 1; // whether the paragraph needs rich text margin
1320 int align : 4; 1277 int align : 4;
1321 int state, id; 1278 int state, id;
1322 QTextString *str; 1279 QTextString *str;
1323 QMap<int, QTextParagSelection> *mSelections; 1280 QMap<int, QTextParagraphSelection> *mSelections;
1324 QPtrVector<QStyleSheetItem> *mStyleSheetItemsVec;
1325 QPtrList<QTextCustomItem> *mFloatingItems; 1281 QPtrList<QTextCustomItem> *mFloatingItems;
1326 QStyleSheetItem::ListStyle listS; 1282 QStyleSheetItem::ListStyle lstyle;
1327 int numSubParag; 1283 short utm, ubm, ulm, urm, uflm, ulinespacing;
1328 int tm, bm, lm, rm, flm;
1329 QTextFormat *defFormat;
1330 int *tArray; 1284 int *tArray;
1331 int tabStopWidth; 1285 short tabStopWidth;
1332 QTextParagData *eData; 1286 QTextParagraphData *eData;
1333 int list_val; 1287 short list_val;
1334 QColor *bgcol; 1288 QColor *bgcol;
1289 ushort ldepth;
1335 1290
1336}; 1291};
1337 1292
@@ -1343,10 +1298,10 @@ public:
1343 QTextFormatter(); 1298 QTextFormatter();
1344 virtual ~QTextFormatter(); 1299 virtual ~QTextFormatter();
1345 1300
1346 virtual int format( QTextDocument *doc, QTextParag *parag, int start, const QMap<int, QTextParagLineStart*> &oldLineStarts ) = 0; 1301 virtual int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts ) = 0;
1347 virtual int formatVertically( QTextDocument* doc, QTextParag* parag ); 1302 virtual int formatVertically( QTextDocument* doc, QTextParagraph* parag );
1348 1303
1349 bool isWrapEnabled( QTextParag *p ) const { if ( !wrapEnabled ) return FALSE; if ( p && !p->isBreakable() ) return FALSE; return TRUE;} 1304 bool isWrapEnabled( QTextParagraph *p ) const { if ( !wrapEnabled ) return FALSE; if ( p && !p->isBreakable() ) return FALSE; return TRUE;}
1350 int wrapAtColumn() const { return wrapColumn;} 1305 int wrapAtColumn() const { return wrapColumn;}
1351 virtual void setWrapEnabled( bool b ); 1306 virtual void setWrapEnabled( bool b );
1352 virtual void setWrapAtColumn( int c ); 1307 virtual void setWrapAtColumn( int c );
@@ -1356,15 +1311,16 @@ public:
1356 int minimumWidth() const { return thisminw; } 1311 int minimumWidth() const { return thisminw; }
1357 int widthUsed() const { return thiswused; } 1312 int widthUsed() const { return thiswused; }
1358 1313
1314 static bool isBreakable( QTextString *string, int pos );
1315
1359protected: 1316protected:
1360 virtual QTextParagLineStart *formatLine( QTextParag *parag, QTextString *string, QTextParagLineStart *line, QTextStringChar *start, 1317 virtual QTextLineStart *formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, QTextStringChar *start,
1361 QTextStringChar *last, int align = Qt3::AlignAuto, int space = 0 ); 1318 QTextStringChar *last, int align = Qt3::AlignAuto, int space = 0 );
1362#ifndef QT_NO_COMPLEXTEXT 1319#ifndef QT_NO_COMPLEXTEXT
1363 virtual QTextParagLineStart *bidiReorderLine( QTextParag *parag, QTextString *string, QTextParagLineStart *line, QTextStringChar *start, 1320 virtual QTextLineStart *bidiReorderLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, QTextStringChar *start,
1364 QTextStringChar *last, int align, int space ); 1321 QTextStringChar *last, int align, int space );
1365#endif 1322#endif
1366 virtual bool isBreakable( QTextString *string, int pos ) const; 1323 void insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls );
1367 void insertLineStart( QTextParag *parag, int index, QTextParagLineStart *ls );
1368 1324
1369 int thisminw; 1325 int thisminw;
1370 int thiswused; 1326 int thiswused;
@@ -1389,7 +1345,7 @@ public:
1389 QTextFormatterBreakInWords(); 1345 QTextFormatterBreakInWords();
1390 virtual ~QTextFormatterBreakInWords() {} 1346 virtual ~QTextFormatterBreakInWords() {}
1391 1347
1392 int format( QTextDocument *doc, QTextParag *parag, int start, const QMap<int, QTextParagLineStart*> &oldLineStarts ); 1348 int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts );
1393 1349
1394}; 1350};
1395 1351
@@ -1401,7 +1357,7 @@ public:
1401 QTextFormatterBreakWords(); 1357 QTextFormatterBreakWords();
1402 virtual ~QTextFormatterBreakWords() {} 1358 virtual ~QTextFormatterBreakWords() {}
1403 1359
1404 int format( QTextDocument *doc, QTextParag *parag, int start, const QMap<int, QTextParagLineStart*> &oldLineStarts ); 1360 int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts );
1405 1361
1406}; 1362};
1407 1363
@@ -1413,7 +1369,7 @@ public:
1413 QTextIndent(); 1369 QTextIndent();
1414 virtual ~QTextIndent() {} 1370 virtual ~QTextIndent() {}
1415 1371
1416 virtual void indent( QTextDocument *doc, QTextParag *parag, int *oldIndent = 0, int *newIndent = 0 ) = 0; 1372 virtual void indent( QTextDocument *doc, QTextParagraph *parag, int *oldIndent = 0, int *newIndent = 0 ) = 0;
1417 1373
1418}; 1374};
1419 1375
@@ -1429,7 +1385,7 @@ public:
1429 QTextPreProcessor(); 1385 QTextPreProcessor();
1430 virtual ~QTextPreProcessor() {} 1386 virtual ~QTextPreProcessor() {}
1431 1387
1432 virtual void process( QTextDocument *doc, QTextParag *, int, bool = TRUE ) = 0; 1388 virtual void process( QTextDocument *doc, QTextParagraph *, int, bool = TRUE ) = 0;
1433 virtual QTextFormat *format( int id ) = 0; 1389 virtual QTextFormat *format( int id ) = 0;
1434 1390
1435}; 1391};
@@ -1452,7 +1408,8 @@ public:
1452 Color = 32, 1408 Color = 32,
1453 Misspelled = 64, 1409 Misspelled = 64,
1454 VAlign = 128, 1410 VAlign = 128,
1455 Font = Bold | Italic | Underline | Family | Size, 1411 StrikeOut= 256,
1412 Font = Bold | Italic | Underline | Family | Size | StrikeOut,
1456 Format = Font | Color | Misspelled | VAlign 1413 Format = Font | Color | Misspelled | VAlign
1457 }; 1414 };
1458 1415
@@ -1464,7 +1421,7 @@ public:
1464 QTextFormat( const QStyleSheetItem *s ); 1421 QTextFormat( const QStyleSheetItem *s );
1465 QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection *parent = 0 ); 1422 QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection *parent = 0 );
1466 QTextFormat( const QTextFormat &fm ); 1423 QTextFormat( const QTextFormat &fm );
1467 QTextFormat makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr ) const; 1424 QTextFormat makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const;
1468 QTextFormat& operator=( const QTextFormat &fm ); 1425 QTextFormat& operator=( const QTextFormat &fm );
1469 QColor color() const; 1426 QColor color() const;
1470 QFont font() const; 1427 QFont font() const;
@@ -1483,6 +1440,7 @@ public:
1483 void setBold( bool b ); 1440 void setBold( bool b );
1484 void setItalic( bool b ); 1441 void setItalic( bool b );
1485 void setUnderline( bool b ); 1442 void setUnderline( bool b );
1443 void setStrikeOut( bool b );
1486 void setFamily( const QString &f ); 1444 void setFamily( const QString &f );
1487 void setPointSize( int s ); 1445 void setPointSize( int s );
1488 void setFont( const QFont &f ); 1446 void setFont( const QFont &f );
@@ -1499,17 +1457,12 @@ public:
1499 void addRef(); 1457 void addRef();
1500 void removeRef(); 1458 void removeRef();
1501 1459
1502 QString makeFormatChangeTags( QTextFormat *f, const QString& oldAnchorHref, const QString& anchorHref ) const; 1460 QString makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, const QString& oldAnchorHref, const QString& anchorHref ) const;
1503 QString makeFormatEndTags( const QString& anchorHref ) const; 1461 QString makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const;
1504 1462
1505 static void setPainter( QPainter *p ); 1463 static void setPainter( QPainter *p );
1506 static QPainter* painter(); 1464 static QPainter* painter();
1507 void updateStyle();
1508 void updateStyleFlags();
1509 void setStyle( const QString &s );
1510 QString styleName() const { return style; }
1511 1465
1512 int changed() const { return different; }
1513 bool fontSizesInPixels() { return usePixelSizes; } 1466 bool fontSizesInPixels() { return usePixelSizes; }
1514 1467
1515protected: 1468protected:
@@ -1535,8 +1488,6 @@ private:
1535 int logicalFontSize; 1488 int logicalFontSize;
1536 int stdSize; 1489 int stdSize;
1537 static QPainter *pntr; 1490 static QPainter *pntr;
1538 QString style;
1539 int different;
1540 1491
1541}; 1492};
1542 1493
@@ -1544,7 +1495,7 @@ private:
1544 1495
1545#if defined(Q_TEMPLATEDLL) 1496#if defined(Q_TEMPLATEDLL)
1546// MOC_SKIP_BEGIN 1497// MOC_SKIP_BEGIN
1547template class Q_EXPORT QDict<QTextFormat>; 1498Q_TEMPLATE_EXTERN template class Q_EXPORT QDict<QTextFormat>;
1548// MOC_SKIP_END 1499// MOC_SKIP_END
1549#endif 1500#endif
1550 1501
@@ -1565,13 +1516,8 @@ public:
1565 virtual void remove( QTextFormat *f ); 1516 virtual void remove( QTextFormat *f );
1566 virtual QTextFormat *createFormat( const QTextFormat &f ) { return new QTextFormat( f ); } 1517 virtual QTextFormat *createFormat( const QTextFormat &f ) { return new QTextFormat( f ); }
1567 virtual QTextFormat *createFormat( const QFont &f, const QColor &c ) { return new QTextFormat( f, c, this ); } 1518 virtual QTextFormat *createFormat( const QFont &f, const QColor &c ) { return new QTextFormat( f, c, this ); }
1568 void debug();
1569 1519
1570 QStyleSheet *styleSheet() const { return sheet; } 1520 void updateDefaultFormat( const QFont &font, const QColor &c, QStyleSheet *sheet );
1571 void setStyleSheet( QStyleSheet *s ) { sheet = s; }
1572 void updateStyles();
1573 void updateFontSizes( int base, bool usePixels );
1574 void updateFontAttributes( const QFont &f, const QFont &old );
1575 QDict<QTextFormat> dict() const { return cKey; } 1521 QDict<QTextFormat> dict() const { return cKey; }
1576 1522
1577private: 1523private:
@@ -1585,8 +1531,6 @@ private:
1585 QColor ccol; 1531 QColor ccol;
1586 QString kof, knf; 1532 QString kof, knf;
1587 int cflags; 1533 int cflags;
1588 QStyleSheet *sheet;
1589
1590}; 1534};
1591 1535
1592// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1536// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1596,24 +1540,19 @@ inline int QTextString::length() const
1596 return data.size(); 1540 return data.size();
1597} 1541}
1598 1542
1599inline void QTextString::operator+=( const QString &s ) 1543inline int QTextParagraph::length() const
1600{
1601 insert( length(), s, 0 );
1602}
1603
1604inline int QTextParag::length() const
1605{ 1544{
1606 return str->length(); 1545 return str->length();
1607} 1546}
1608 1547
1609inline QRect QTextParag::rect() const 1548inline QRect QTextParagraph::rect() const
1610{ 1549{
1611 return r; 1550 return r;
1612} 1551}
1613 1552
1614inline QTextParag *QTextCursor::parag() const 1553inline QTextParagraph *QTextCursor::paragraph() const
1615{ 1554{
1616 return string; 1555 return para;
1617} 1556}
1618 1557
1619inline int QTextCursor::index() const 1558inline int QTextCursor::index() const
@@ -1621,35 +1560,6 @@ inline int QTextCursor::index() const
1621 return idx; 1560 return idx;
1622} 1561}
1623 1562
1624inline void QTextCursor::setIndex( int i, bool restore )
1625{
1626 if ( restore )
1627 restoreState();
1628 if ( i < 0 || i >= string->length() ) {
1629#if defined(QT_CHECK_RANGE)
1630 qWarning( "QTextCursor::setIndex: %d out of range", i );
1631#endif
1632 i = i < 0 ? 0 : string->length() - 1;
1633 }
1634
1635 tmpIndex = -1;
1636 idx = i;
1637}
1638
1639inline void QTextCursor::setParag( QTextParag *s, bool restore )
1640{
1641 if ( restore )
1642 restoreState();
1643 idx = 0;
1644 string = s;
1645 tmpIndex = -1;
1646}
1647
1648inline void QTextCursor::checkIndex()
1649{
1650 if ( idx >= string->length() )
1651 idx = string->length() - 1;
1652}
1653 1563
1654// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1564// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1655 1565
@@ -1673,22 +1583,22 @@ inline int QTextDocument::visibleWidth() const
1673 return vw; 1583 return vw;
1674} 1584}
1675 1585
1676inline QTextParag *QTextDocument::firstParag() const 1586inline QTextParagraph *QTextDocument::firstParagraph() const
1677{ 1587{
1678 return fParag; 1588 return fParag;
1679} 1589}
1680 1590
1681inline QTextParag *QTextDocument::lastParag() const 1591inline QTextParagraph *QTextDocument::lastParagraph() const
1682{ 1592{
1683 return lParag; 1593 return lParag;
1684} 1594}
1685 1595
1686inline void QTextDocument::setFirstParag( QTextParag *p ) 1596inline void QTextDocument::setFirstParagraph( QTextParagraph *p )
1687{ 1597{
1688 fParag = p; 1598 fParag = p;
1689} 1599}
1690 1600
1691inline void QTextDocument::setLastParag( QTextParag *p ) 1601inline void QTextDocument::setLastParagraph( QTextParagraph *p )
1692{ 1602{
1693 lParag = p; 1603 lParag = p;
1694} 1604}
@@ -1870,9 +1780,6 @@ inline QTextFormatCollection *QTextFormat::parent() const
1870inline void QTextFormat::addRef() 1780inline void QTextFormat::addRef()
1871{ 1781{
1872 ref++; 1782 ref++;
1873#ifdef DEBUG_COLLECTION
1874 qDebug( "add ref of '%s' to %d (%p)", k.latin1(), ref, this );
1875#endif
1876} 1783}
1877 1784
1878inline void QTextFormat::removeRef() 1785inline void QTextFormat::removeRef()
@@ -1882,9 +1789,6 @@ inline void QTextFormat::removeRef()
1882 return; 1789 return;
1883 if ( this == collection->defFormat ) 1790 if ( this == collection->defFormat )
1884 return; 1791 return;
1885#ifdef DEBUG_COLLECTION
1886 qDebug( "remove ref of '%s' to %d (%p)", k.latin1(), ref, this );
1887#endif
1888 if ( ref == 0 ) 1792 if ( ref == 0 )
1889 collection->remove( this ); 1793 collection->remove( this );
1890} 1794}
@@ -1899,11 +1803,6 @@ inline bool QTextFormat::useLinkColor() const
1899 return linkColor; 1803 return linkColor;
1900} 1804}
1901 1805
1902inline void QTextFormat::setStyle( const QString &s )
1903{
1904 style = s;
1905 updateStyleFlags();
1906}
1907 1806
1908// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1807// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1909 1808
@@ -1914,34 +1813,34 @@ inline QTextStringChar &QTextString::at( int i ) const
1914 1813
1915// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1814// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1916 1815
1917inline QTextStringChar *QTextParag::at( int i ) const 1816inline QTextStringChar *QTextParagraph::at( int i ) const
1918{ 1817{
1919 return &str->at( i ); 1818 return &str->at( i );
1920} 1819}
1921 1820
1922inline bool QTextParag::isValid() const 1821inline bool QTextParagraph::isValid() const
1923{ 1822{
1924 return invalid == -1; 1823 return invalid == -1;
1925} 1824}
1926 1825
1927inline bool QTextParag::hasChanged() const 1826inline bool QTextParagraph::hasChanged() const
1928{ 1827{
1929 return changed; 1828 return changed;
1930} 1829}
1931 1830
1932inline void QTextParag::setBackgroundColor( const QColor & c ) 1831inline void QTextParagraph::setBackgroundColor( const QColor & c )
1933{ 1832{
1934 delete bgcol; 1833 delete bgcol;
1935 bgcol = new QColor( c ); 1834 bgcol = new QColor( c );
1936 setChanged( TRUE ); 1835 setChanged( TRUE );
1937} 1836}
1938 1837
1939inline void QTextParag::clearBackgroundColor() 1838inline void QTextParagraph::clearBackgroundColor()
1940{ 1839{
1941 delete bgcol; bgcol = 0; setChanged( TRUE ); 1840 delete bgcol; bgcol = 0; setChanged( TRUE );
1942} 1841}
1943 1842
1944inline void QTextParag::append( const QString &s, bool reallyAtEnd ) 1843inline void QTextParagraph::append( const QString &s, bool reallyAtEnd )
1945{ 1844{
1946 if ( reallyAtEnd ) 1845 if ( reallyAtEnd )
1947 insert( str->length(), s ); 1846 insert( str->length(), s );
@@ -1949,170 +1848,141 @@ inline void QTextParag::append( const QString &s, bool reallyAtEnd )
1949 insert( QMAX( str->length() - 1, 0 ), s ); 1848 insert( QMAX( str->length() - 1, 0 ), s );
1950} 1849}
1951 1850
1952inline QTextParag *QTextParag::prev() const 1851inline QTextParagraph *QTextParagraph::prev() const
1953{ 1852{
1954 return p; 1853 return p;
1955} 1854}
1956 1855
1957inline QTextParag *QTextParag::next() const 1856inline QTextParagraph *QTextParagraph::next() const
1958{ 1857{
1959 return n; 1858 return n;
1960} 1859}
1961 1860
1962inline bool QTextParag::hasAnySelection() const 1861inline bool QTextParagraph::hasAnySelection() const
1963{ 1862{
1964 return mSelections ? !selections().isEmpty() : FALSE; 1863 return mSelections ? !selections().isEmpty() : FALSE;
1965} 1864}
1966 1865
1967inline void QTextParag::setEndState( int s ) 1866inline void QTextParagraph::setEndState( int s )
1968{ 1867{
1969 if ( s == state ) 1868 if ( s == state )
1970 return; 1869 return;
1971 state = s; 1870 state = s;
1972} 1871}
1973 1872
1974inline int QTextParag::endState() const 1873inline int QTextParagraph::endState() const
1975{ 1874{
1976 return state; 1875 return state;
1977} 1876}
1978 1877
1979inline void QTextParag::setParagId( int i ) 1878inline void QTextParagraph::setParagId( int i )
1980{ 1879{
1981 id = i; 1880 id = i;
1982} 1881}
1983 1882
1984inline int QTextParag::paragId() const 1883inline int QTextParagraph::paragId() const
1985{ 1884{
1986 if ( id == -1 ) 1885 if ( id == -1 )
1987 qWarning( "invalid parag id!!!!!!!! (%p)", (void*)this ); 1886 qWarning( "invalid parag id!!!!!!!! (%p)", (void*)this );
1988 return id; 1887 return id;
1989} 1888}
1990 1889
1991inline bool QTextParag::firstPreProcess() const 1890inline bool QTextParagraph::firstPreProcess() const
1992{ 1891{
1993 return firstPProcess; 1892 return firstPProcess;
1994} 1893}
1995 1894
1996inline void QTextParag::setFirstPreProcess( bool b ) 1895inline void QTextParagraph::setFirstPreProcess( bool b )
1997{ 1896{
1998 firstPProcess = b; 1897 firstPProcess = b;
1999} 1898}
2000 1899
2001inline QMap<int, QTextParagLineStart*> &QTextParag::lineStartList() 1900inline QMap<int, QTextLineStart*> &QTextParagraph::lineStartList()
2002{ 1901{
2003 return lineStarts; 1902 return lineStarts;
2004} 1903}
2005 1904
2006inline QTextString *QTextParag::string() const 1905inline QTextString *QTextParagraph::string() const
2007{ 1906{
2008 return str; 1907 return str;
2009} 1908}
2010 1909
2011inline QTextDocument *QTextParag::document() const 1910inline QTextDocument *QTextParagraph::document() const
2012{ 1911{
2013 if ( hasdoc ) 1912 if ( hasdoc )
2014 return (QTextDocument*) docOrPseudo; 1913 return (QTextDocument*) docOrPseudo;
2015 return 0; 1914 return 0;
2016} 1915}
2017 1916
2018inline QTextParagPseudoDocument *QTextParag::pseudoDocument() const 1917inline QTextParagraphPseudoDocument *QTextParagraph::pseudoDocument() const
2019{ 1918{
2020 if ( hasdoc ) 1919 if ( hasdoc )
2021 return 0; 1920 return 0;
2022 return (QTextParagPseudoDocument*) docOrPseudo; 1921 return (QTextParagraphPseudoDocument*) docOrPseudo;
2023} 1922}
2024 1923
2025 1924
2026inline QTextTableCell *QTextParag::tableCell() const 1925inline QTextTableCell *QTextParagraph::tableCell() const
2027{ 1926{
2028 return hasdoc ? document()->tableCell () : 0; 1927 return hasdoc ? document()->tableCell () : 0;
2029} 1928}
2030 1929
2031inline QTextCommandHistory *QTextParag::commands() const 1930inline QTextCommandHistory *QTextParagraph::commands() const
2032{ 1931{
2033 return hasdoc ? document()->commands() : pseudoDocument()->commandHistory; 1932 return hasdoc ? document()->commands() : pseudoDocument()->commandHistory;
2034} 1933}
2035 1934
2036 1935
2037inline void QTextParag::setAlignment( int a ) 1936inline int QTextParagraph::alignment() const
2038{
2039 if ( a == (int)align )
2040 return;
2041 align = a;
2042 invalidate( 0 );
2043}
2044
2045inline void QTextParag::setListStyle( QStyleSheetItem::ListStyle ls )
2046{
2047 listS = ls;
2048 invalidate( 0 );
2049}
2050
2051inline QStyleSheetItem::ListStyle QTextParag::listStyle() const
2052{
2053 return listS;
2054}
2055
2056inline QTextFormat *QTextParag::paragFormat() const
2057{ 1937{
2058 return defFormat; 1938 return align;
2059} 1939}
2060 1940
2061inline void QTextParag::registerFloatingItem( QTextCustomItem *i ) 1941inline void QTextParagraph::registerFloatingItem( QTextCustomItem *i )
2062{ 1942{
2063 floatingItems().append( i ); 1943 floatingItems().append( i );
2064} 1944}
2065 1945
2066inline void QTextParag::unregisterFloatingItem( QTextCustomItem *i ) 1946inline void QTextParagraph::unregisterFloatingItem( QTextCustomItem *i )
2067{ 1947{
2068 floatingItems().removeRef( i ); 1948 floatingItems().removeRef( i );
2069} 1949}
2070 1950
2071inline QBrush *QTextParag::background() const 1951inline QBrush *QTextParagraph::background() const
2072{ 1952{
2073 return tableCell() ? tableCell()->backGround() : 0; 1953 return tableCell() ? tableCell()->backGround() : 0;
2074} 1954}
2075 1955
2076inline int QTextParag::documentWidth() const 1956inline int QTextParagraph::documentWidth() const
2077{ 1957{
2078 return hasdoc ? document()->width() : pseudoDocument()->docRect.width(); 1958 return hasdoc ? document()->width() : pseudoDocument()->docRect.width();
2079} 1959}
2080 1960
2081inline int QTextParag::documentVisibleWidth() const 1961inline int QTextParagraph::documentVisibleWidth() const
2082{ 1962{
2083 return hasdoc ? document()->visibleWidth() : pseudoDocument()->docRect.width(); 1963 return hasdoc ? document()->visibleWidth() : pseudoDocument()->docRect.width();
2084} 1964}
2085 1965
2086inline int QTextParag::documentX() const 1966inline int QTextParagraph::documentX() const
2087{ 1967{
2088 return hasdoc ? document()->x() : pseudoDocument()->docRect.x(); 1968 return hasdoc ? document()->x() : pseudoDocument()->docRect.x();
2089} 1969}
2090 1970
2091inline int QTextParag::documentY() const 1971inline int QTextParagraph::documentY() const
2092{ 1972{
2093 return hasdoc ? document()->y() : pseudoDocument()->docRect.y(); 1973 return hasdoc ? document()->y() : pseudoDocument()->docRect.y();
2094} 1974}
2095 1975
2096inline void QTextParag::setExtraData( QTextParagData *data ) 1976inline void QTextParagraph::setExtraData( QTextParagraphData *data )
2097{ 1977{
2098 eData = data; 1978 eData = data;
2099} 1979}
2100 1980
2101inline QTextParagData *QTextParag::extraData() const 1981inline QTextParagraphData *QTextParagraph::extraData() const
2102{ 1982{
2103 return eData; 1983 return eData;
2104} 1984}
2105 1985
2106inline void QTextParag::setNewLinesAllowed( bool b )
2107{
2108 newLinesAllowed = b;
2109}
2110
2111inline bool QTextParag::isNewLinesAllowed() const
2112{
2113 return newLinesAllowed;
2114}
2115
2116// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1986// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2117 1987
2118inline void QTextFormatCollection::setDefaultFormat( QTextFormat *f ) 1988inline void QTextFormatCollection::setDefaultFormat( QTextFormat *f )
diff --git a/noncore/apps/opie-write/qstylesheet.cpp b/noncore/apps/opie-write/qstylesheet.cpp
index 7ab9ec6..67cd828 100644
--- a/noncore/apps/opie-write/qstylesheet.cpp
+++ b/noncore/apps/opie-write/qstylesheet.cpp
@@ -54,6 +54,7 @@ public:
54 QStyleSheetItem::DisplayMode disp; 54 QStyleSheetItem::DisplayMode disp;
55 int fontitalic; 55 int fontitalic;
56 int fontunderline; 56 int fontunderline;
57 int fontstrikeout;
57 int fontweight; 58 int fontweight;
58 int fontsize; 59 int fontsize;
59 int fontsizelog; 60 int fontsizelog;
@@ -78,66 +79,74 @@ public:
78} 79}
79 80
80/*! 81/*!
81 \class QStyleSheetItem qstylesheet.h 82 \class QStyleSheetItem qstylesheet.h
82 \ingroup text 83 \brief The QStyleSheetItem class provides an encapsulation of a set of text styles.
83 \brief The QStyleSheetItem class provides an encapsulation of a set of text styles. 84
84 85 \ingroup text
85 A style sheet item consists of a name and a set of attributes that 86
86 specifiy its font, color, etc. When used in a \link QStyleSheet 87 A style sheet item consists of a name and a set of attributes that
87 style sheet\endlink (see styleSheet()), items define the name() of a 88 specifiy its font, color, etc. When used in a \link QStyleSheet
88 rich text tag and the display property changes associated with it. 89 style sheet\endlink (see styleSheet()), items define the name() of
89 90 a rich text tag and the display property changes associated with
90 The \link QStyleSheetItem::DisplayMode display mode\endlink 91 it.
91 attribute indicates whether the item is a block, an inline element 92
92 or a list element; see setDisplayMode(). The treatment of whitespace 93 The \link QStyleSheetItem::DisplayMode display mode\endlink
93 is controlled by the \link QStyleSheetItem::WhiteSpaceMode white 94 attribute indicates whether the item is a block, an inline element
94 space mode\endlink; see setWhiteSpaceMode(). An item's margins are 95 or a list element; see setDisplayMode(). The treatment of
95 set with setMargin(), and line spacing is set with setLineSpacing(). 96 whitespace is controlled by the \link
96 In the case of list items, the list style is set with 97 QStyleSheetItem::WhiteSpaceMode white space mode\endlink; see
97 setListStyle(). An item may be a hypertext link anchor; see 98 setWhiteSpaceMode(). An item's margins are set with setMargin(),
98 setAnchor(). Other attributes are set with setAlignment(), 99 In the case of list items, the list style is set with
99 setVerticalAlignment(), setFontFamily(), setFontSize(), 100 setListStyle(). An item may be a hypertext link anchor; see
100 setFontWeight(), setFontItalic(), setFontUnderline() and setColor(). 101 setAnchor(). Other attributes are set with setAlignment(),
102 setVerticalAlignment(), setFontFamily(), setFontSize(),
103 setFontWeight(), setFontItalic(), setFontUnderline(),
104 setFontStrikeOut and setColor().
101*/ 105*/
102 106
103/*! \enum QStyleSheetItem::AdditionalStyleValues 107/*! \enum QStyleSheetItem::AdditionalStyleValues
104 \internal 108 \internal
105*/ 109*/
106 110
107/*! \enum QStyleSheetItem::WhiteSpaceMode 111/*!
112 \enum QStyleSheetItem::WhiteSpaceMode
108 113
109 This enum defines the ways in which QStyleSheet can treat whitespace. There are three values at present: 114 This enum defines the ways in which QStyleSheet can treat
115 whitespace.
110 116
111 \value WhiteSpaceNormal any sequence of whitespace (including 117 \value WhiteSpaceNormal any sequence of whitespace (including
112 line-breaks) is equivalent to a single space. 118 line-breaks) is equivalent to a single space.
113 119
114 \value WhiteSpacePre whitespace must be output exactly as given 120 \value WhiteSpacePre whitespace must be output exactly as given
115 in the input. 121 in the input.
116 122
117 \value WhiteSpaceNoWrap multiple spaces are collapsed as with 123 \value WhiteSpaceNoWrap multiple spaces are collapsed as with
118 WhiteSpaceNormal, but no automatic line-breaks occur. To break lines manually, 124 WhiteSpaceNormal, but no automatic line-breaks occur. To break
119 use the \c{<br>} tag. 125 lines manually, use the \c{<br>} tag.
120 126
121*/ 127*/
122 128
123/*! \enum QStyleSheetItem::Margin 129/*!
124 130 \enum QStyleSheetItem::Margin
125 \value MarginLeft left margin 131
126 \value MarginRight right margin 132 \value MarginLeft left margin
127 \value MarginTop top margin 133 \value MarginRight right margin
128 \value MarginBottom bottom margin 134 \value MarginTop top margin
129 \value MarginAll all margins (left, right, top and bottom) 135 \value MarginBottom bottom margin
130 \value MarginVertical top and bottom margins 136 \value MarginAll all margins (left, right, top and bottom)
131 \value MarginHorizontal left and right margins 137 \value MarginVertical top and bottom margins
132 \value MarginFirstLine margin (indentation) of the first line of a paragarph (in addition to the MarginLeft of the paragraph) 138 \value MarginHorizontal left and right margins
139 \value MarginFirstLine margin (indentation) of the first line of
140 a paragarph (in addition to the MarginLeft of the paragraph)
133*/ 141*/
134 142
135/*! 143/*!
136 Constructs a new style named \a name for the stylesheet \a parent. 144 Constructs a new style called \a name for the stylesheet \a
145 parent.
137 146
138 All properties in QStyleSheetItem are initially in the "do not change" state, 147 All properties in QStyleSheetItem are initially in the "do not
139 except \link QStyleSheetItem::DisplayMode display mode\endlink, which defaults 148 change" state, except \link QStyleSheetItem::DisplayMode display
140 to \c DisplayInline. 149 mode\endlink, which defaults to \c DisplayInline.
141*/ 150*/
142QStyleSheetItem::QStyleSheetItem( QStyleSheet* parent, const QString& name ) 151QStyleSheetItem::QStyleSheetItem( QStyleSheet* parent, const QString& name )
143{ 152{
@@ -150,9 +159,9 @@ QStyleSheetItem::QStyleSheetItem( QStyleSheet* parent, const QString& name )
150} 159}
151 160
152/*! 161/*!
153 Copy constructor. Constructs a copy of \a other that is 162 Copy constructor. Constructs a copy of \a other that is not bound
154 not bound to any style sheet. 163 to any style sheet.
155 */ 164*/
156QStyleSheetItem::QStyleSheetItem( const QStyleSheetItem & other ) 165QStyleSheetItem::QStyleSheetItem( const QStyleSheetItem & other )
157{ 166{
158 d = new QStyleSheetItemData; 167 d = new QStyleSheetItemData;
@@ -161,9 +170,9 @@ QStyleSheetItem::QStyleSheetItem( const QStyleSheetItem & other )
161 170
162 171
163/*! 172/*!
164 Destroys the style. Note that QStyleSheetItem objects become owned 173 Destroys the style. Note that QStyleSheetItem objects become
165 by QStyleSheet when they are created. 174 owned by QStyleSheet when they are created.
166 */ 175*/
167QStyleSheetItem::~QStyleSheetItem() 176QStyleSheetItem::~QStyleSheetItem()
168{ 177{
169 delete d; 178 delete d;
@@ -172,8 +181,8 @@ QStyleSheetItem::~QStyleSheetItem()
172 181
173 182
174/*! 183/*!
175 Returns the style sheet this item is in. 184 Returns the style sheet this item is in.
176 */ 185*/
177QStyleSheet* QStyleSheetItem::styleSheet() 186QStyleSheet* QStyleSheetItem::styleSheet()
178{ 187{
179 return d->sheet; 188 return d->sheet;
@@ -181,8 +190,9 @@ QStyleSheet* QStyleSheetItem::styleSheet()
181 190
182/*! 191/*!
183 \overload 192 \overload
184 Returns the style sheet this item is in. 193
185 */ 194 Returns the style sheet this item is in.
195*/
186const QStyleSheet* QStyleSheetItem::styleSheet() const 196const QStyleSheet* QStyleSheetItem::styleSheet() const
187{ 197{
188 return d->sheet; 198 return d->sheet;
@@ -198,6 +208,7 @@ void QStyleSheetItem::init()
198 208
199 d->fontitalic = Undefined; 209 d->fontitalic = Undefined;
200 d->fontunderline = Undefined; 210 d->fontunderline = Undefined;
211 d->fontstrikeout = Undefined;
201 d->fontweight = Undefined; 212 d->fontweight = Undefined;
202 d->fontsize = Undefined; 213 d->fontsize = Undefined;
203 d->fontsizelog = Undefined; 214 d->fontsizelog = Undefined;
@@ -212,14 +223,14 @@ void QStyleSheetItem::init()
212 d->margin[2] = Undefined; 223 d->margin[2] = Undefined;
213 d->margin[3] = Undefined; 224 d->margin[3] = Undefined;
214 d->margin[4] = Undefined; 225 d->margin[4] = Undefined;
215 d->list = QStyleSheetItem::ListDisc; 226 d->list = (ListStyle) Undefined;
216 d->whitespacemode = QStyleSheetItem::WhiteSpaceNormal; 227 d->whitespacemode = (WhiteSpaceMode) Undefined;
217 d->selfnest = TRUE; 228 d->selfnest = TRUE;
218 d->lineSpacing = Undefined; 229 d->lineSpacing = Undefined;
219} 230}
220 231
221/*! 232/*!
222 Returns the name of the style item. 233 Returns the name of the style item.
223*/ 234*/
224QString QStyleSheetItem::name() const 235QString QStyleSheetItem::name() const
225{ 236{
@@ -227,36 +238,37 @@ QString QStyleSheetItem::name() const
227} 238}
228 239
229/*! 240/*!
230 Returns the \link QStyleSheetItem::DisplayMode display mode\endlink 241 Returns the \link QStyleSheetItem::DisplayMode display
231 of the style. 242 mode\endlink of the style.
232 243
233 \sa setDisplayMode() 244 \sa setDisplayMode()
234 */ 245*/
235QStyleSheetItem::DisplayMode QStyleSheetItem::displayMode() const 246QStyleSheetItem::DisplayMode QStyleSheetItem::displayMode() const
236{ 247{
237 return d->disp; 248 return d->disp;
238} 249}
239 250
240/*! \enum QStyleSheetItem::DisplayMode 251/*!
252 \enum QStyleSheetItem::DisplayMode
241 253
242 This enum type defines the way adjacent elements are displayed. The possible values are: 254 This enum type defines the way adjacent elements are displayed.
243 255
244 \value DisplayBlock elements are displayed as a rectangular block 256 \value DisplayBlock elements are displayed as a rectangular block
245 (e.g. \c{<p>...</p>}). 257 (e.g. \c{<p>...</p>}).
246 258
247 \value DisplayInline elements are displayed in a horizontally flowing 259 \value DisplayInline elements are displayed in a horizontally
248 sequence (e.g. \c{<em>...</em>}). 260 flowing sequence (e.g. \c{<em>...</em>}).
249 261
250 \value DisplayListItem elements are displayed in a vertical sequence 262 \value DisplayListItem elements are displayed in a vertical
251 (e.g. \c{<li>...</li>}). 263 sequence (e.g. \c{<li>...</li>}).
252 264
253 \value DisplayNone elements are not displayed at all. 265 \value DisplayNone elements are not displayed at all.
254*/ 266*/
255 267
256/*! 268/*!
257 Sets the display mode of the style to \a m. 269 Sets the display mode of the style to \a m.
258 270
259 \sa displayMode() 271 \sa displayMode()
260 */ 272 */
261void QStyleSheetItem::setDisplayMode(DisplayMode m) 273void QStyleSheetItem::setDisplayMode(DisplayMode m)
262{ 274{
@@ -265,24 +277,25 @@ void QStyleSheetItem::setDisplayMode(DisplayMode m)
265 277
266 278
267/*! 279/*!
268 Returns the alignment of this style. Possible values are AlignAuto, AlignLeft, 280 Returns the alignment of this style. Possible values are \c
269 AlignRight, AlignCenter and AlignJustify. 281 AlignAuto, \c AlignLeft, \c AlignRight, \c AlignCenter or \c
282 AlignJustify.
270 283
271 \sa setAlignment(), Qt::AlignmentFlags 284 \sa setAlignment(), Qt::AlignmentFlags
272 */ 285*/
273int QStyleSheetItem::alignment() const 286int QStyleSheetItem::alignment() const
274{ 287{
275 return d->align; 288 return d->align;
276} 289}
277 290
278/*! 291/*!
279 Sets the alignment to \a f. This only makes sense for styles with a 292 Sets the alignment to \a f. This only makes sense for styles with
280 \link QStyleSheetItem::DisplayMode display mode\endlink of 293 a \link QStyleSheetItem::DisplayMode display mode\endlink of
281 DisplayBlock. Possible values are AlignAuto, AlignLeft, AlignRight, 294 DisplayBlock. Possible values are \c AlignAuto, \c AlignLeft,
282 AlignCenter and AlignJustify. 295 \c AlignRight, \c AlignCenter or \c AlignJustify.
283 296
284 \sa alignment(), displayMode(), Qt::AlignmentFlags 297 \sa alignment(), displayMode(), Qt::AlignmentFlags
285 */ 298*/
286void QStyleSheetItem::setAlignment( int f ) 299void QStyleSheetItem::setAlignment( int f )
287{ 300{
288 d->align = f; 301 d->align = f;
@@ -290,40 +303,41 @@ void QStyleSheetItem::setAlignment( int f )
290 303
291 304
292/*! 305/*!
293 Returns the vertical alignment of the style. Possible values are 306 Returns the vertical alignment of the style. Possible values are
294 VAlignBaseline, VAlignSub and VAlignSuper. 307 \c VAlignBaseline, \c VAlignSub or \c VAlignSuper.
295 308
296 psa setVerticalAlignment() 309 \sa setVerticalAlignment()
297 */ 310*/
298QStyleSheetItem::VerticalAlignment QStyleSheetItem::verticalAlignment() const 311QStyleSheetItem::VerticalAlignment QStyleSheetItem::verticalAlignment() const
299{ 312{
300 return d->valign; 313 return d->valign;
301} 314}
302 315
303/*! \enum QStyleSheetItem::VerticalAlignment 316/*!
317 \enum QStyleSheetItem::VerticalAlignment
304 318
305 This enum type defines the way elements are aligned vertically. This 319 This enum type defines the way elements are aligned vertically.
306 is supported for text elements only. The possible values are: 320 This is only supported for text elements.
307 321
308 \value VAlignBaseline align the baseline of the element (or the 322 \value VAlignBaseline align the baseline of the element (or the
309 bottom, if the element doesn't have a baseline) with the baseline of 323 bottom, if the element doesn't have a baseline) with the
310 the parent 324 baseline of the parent
311 325
312 \value VAlignSub subscript the element 326 \value VAlignSub subscript the element
313 327
314 \value VAlignSuper superscript the element 328 \value VAlignSuper superscript the element
315 329
316*/ 330*/
317 331
318 332
319/*! 333/*!
320 Sets the vertical alignment to \a valign. Possible values are 334 Sets the vertical alignment to \a valign. Possible values are
321 VAlignBaseline, VAlignSub and VAlignSuper. 335 \c VAlignBaseline, \c VAlignSub or \c VAlignSuper.
322 336
323 The vertical alignment property is not inherited. 337 The vertical alignment property is not inherited.
324 338
325 \sa verticalAlignment() 339 \sa verticalAlignment()
326 */ 340*/
327void QStyleSheetItem::setVerticalAlignment( VerticalAlignment valign ) 341void QStyleSheetItem::setVerticalAlignment( VerticalAlignment valign )
328{ 342{
329 d->valign = valign; 343 d->valign = valign;
@@ -331,10 +345,11 @@ void QStyleSheetItem::setVerticalAlignment( VerticalAlignment valign )
331 345
332 346
333/*! 347/*!
334 Returns TRUE if the style sets an italic font; otherwise returns FALSE. 348 Returns TRUE if the style sets an italic font; otherwise returns
349 FALSE.
335 350
336 \sa setFontItalic(), definesFontItalic() 351 \sa setFontItalic(), definesFontItalic()
337 */ 352*/
338bool QStyleSheetItem::fontItalic() const 353bool QStyleSheetItem::fontItalic() const
339{ 354{
340 return d->fontitalic > 0; 355 return d->fontitalic > 0;
@@ -344,51 +359,54 @@ bool QStyleSheetItem::fontItalic() const
344 If \a italic is TRUE sets italic for the style; otherwise sets 359 If \a italic is TRUE sets italic for the style; otherwise sets
345 upright. 360 upright.
346 361
347 \sa fontItalic(), definesFontItalic() 362 \sa fontItalic(), definesFontItalic()
348 */ 363*/
349void QStyleSheetItem::setFontItalic(bool italic) 364void QStyleSheetItem::setFontItalic(bool italic)
350{ 365{
351 d->fontitalic = italic?1:0; 366 d->fontitalic = italic?1:0;
352} 367}
353 368
354/*! 369/*!
355 Returns whether the style defines a font shape. A style 370 Returns TRUE if the style defines a font shape; otherwise returns
356 does not define any shape until setFontItalic() is called. 371 FALSE. A style does not define any shape until setFontItalic() is
372 called.
357 373
358 \sa setFontItalic(), fontItalic() 374 \sa setFontItalic(), fontItalic()
359 */ 375*/
360bool QStyleSheetItem::definesFontItalic() const 376bool QStyleSheetItem::definesFontItalic() const
361{ 377{
362 return d->fontitalic != Undefined; 378 return d->fontitalic != Undefined;
363} 379}
364 380
365/*! 381/*!
366 Returns TRUE if the style sets an underlined font; otherwise returns FALSE. 382 Returns TRUE if the style sets an underlined font; otherwise
383 returns FALSE.
367 384
368 \sa setFontUnderline(), definesFontUnderline() 385 \sa setFontUnderline(), definesFontUnderline()
369 */ 386*/
370bool QStyleSheetItem::fontUnderline() const 387bool QStyleSheetItem::fontUnderline() const
371{ 388{
372 return d->fontunderline > 0; 389 return d->fontunderline > 0;
373} 390}
374 391
375/*! 392/*!
376 If \a underline is TRUE sets underline for the style; otherwise sets 393 If \a underline is TRUE, sets underline for the style; otherwise
377 no underline. 394 sets no underline.
378 395
379 \sa fontUnderline(), definesFontUnderline() 396 \sa fontUnderline(), definesFontUnderline()
380 */ 397*/
381void QStyleSheetItem::setFontUnderline(bool underline) 398void QStyleSheetItem::setFontUnderline(bool underline)
382{ 399{
383 d->fontunderline = underline?1:0; 400 d->fontunderline = underline?1:0;
384} 401}
385 402
386/*! 403/*!
387 Returns whether the style defines a setting for the underline 404 Returns TRUE if the style defines a setting for the underline
388 property of the font. A style does not define this until 405 property of the font; otherwise returns FALSE. A style does not
389 setFontUnderline() is called. 406 define this until setFontUnderline() is called.
390 407
391 \sa setFontUnderline(), fontUnderline() */ 408 \sa setFontUnderline(), fontUnderline()
409*/
392bool QStyleSheetItem::definesFontUnderline() const 410bool QStyleSheetItem::definesFontUnderline() const
393{ 411{
394 return d->fontunderline != Undefined; 412 return d->fontunderline != Undefined;
@@ -396,33 +414,68 @@ bool QStyleSheetItem::definesFontUnderline() const
396 414
397 415
398/*! 416/*!
399 Returns the font weight setting of the style. This is either a 417 Returns TRUE if the style sets a strike out font; otherwise
400 valid QFont::Weight or the value QStyleSheetItem::Undefined. 418 returns FALSE.
401 419
402 \sa setFontWeight(), QFont 420 \sa setFontStrikeOut(), definesFontStrikeOut()
403 */ 421*/
422bool QStyleSheetItem::fontStrikeOut() const
423{
424 return d->fontstrikeout > 0;
425}
426
427/*!
428 If \a strikeOut is TRUE, sets strike out for the style; otherwise
429 sets no strike out.
430
431 \sa fontStrikeOut(), definesFontStrikeOut()
432*/
433void QStyleSheetItem::setFontStrikeOut(bool strikeOut)
434{
435 d->fontstrikeout = strikeOut?1:0;
436}
437
438/*!
439 Returns TRUE if the style defines a setting for the strikeOut
440 property of the font; otherwise returns FALSE. A style does not
441 define this until setFontStrikeOut() is called.
442
443 \sa setFontStrikeOut(), fontStrikeOut()
444*/
445bool QStyleSheetItem::definesFontStrikeOut() const
446{
447 return d->fontstrikeout != Undefined;
448}
449
450
451/*!
452 Returns the font weight setting of the style. This is either a
453 valid \c QFont::Weight or the value \c QStyleSheetItem::Undefined.
454
455 \sa setFontWeight(), QFont
456*/
404int QStyleSheetItem::fontWeight() const 457int QStyleSheetItem::fontWeight() const
405{ 458{
406 return d->fontweight; 459 return d->fontweight;
407} 460}
408 461
409/*! 462/*!
410 Sets the font weight setting of the style to \a w. Valid values are 463 Sets the font weight setting of the style to \a w. Valid values
411 those defined by QFont::Weight. 464 are those defined by \c QFont::Weight.
412 465
413 \sa QFont, fontWeight() 466 \sa QFont, fontWeight()
414 */ 467*/
415void QStyleSheetItem::setFontWeight(int w) 468void QStyleSheetItem::setFontWeight(int w)
416{ 469{
417 d->fontweight = w; 470 d->fontweight = w;
418} 471}
419 472
420/*! 473/*!
421 Returns the logical font size setting of the style. This is either a valid 474 Returns the logical font size setting of the style. This is either
422 size between 1 and 7 or QStyleSheetItem::Undefined. 475 a valid size between 1 and 7 or \c QStyleSheetItem::Undefined.
423 476
424 \sa setLogicalFontSize(), setLogicalFontSizeStep(), QFont::pointSize(), QFont::setPointSize() 477 \sa setLogicalFontSize(), setLogicalFontSizeStep(), QFont::pointSize(), QFont::setPointSize()
425 */ 478*/
426int QStyleSheetItem::logicalFontSize() const 479int QStyleSheetItem::logicalFontSize() const
427{ 480{
428 return d->fontsizelog; 481 return d->fontsizelog;
@@ -430,34 +483,34 @@ int QStyleSheetItem::logicalFontSize() const
430 483
431 484
432/*! 485/*!
433 Sets the logical font size setting of the style to \a s. 486 Sets the logical font size setting of the style to \a s. Valid
434 Valid logical sizes are 1 to 7. 487 logical sizes are 1 to 7.
435 488
436 \sa logicalFontSize(), QFont::pointSize(), QFont::setPointSize() 489 \sa logicalFontSize(), QFont::pointSize(), QFont::setPointSize()
437 */ 490*/
438void QStyleSheetItem::setLogicalFontSize(int s) 491void QStyleSheetItem::setLogicalFontSize(int s)
439{ 492{
440 d->fontsizelog = s; 493 d->fontsizelog = s;
441} 494}
442 495
443/*! 496/*!
444 Returns the logical font size step of this style. 497 Returns the logical font size step of this style.
445 498
446 The default is 0. Tags such as \c big define \c +1; \c small defines 499 The default is 0. Tags such as \c big define \c +1; \c small
447 \c -1. 500 defines \c -1.
448 501
449 \sa setLogicalFontSizeStep() 502 \sa setLogicalFontSizeStep()
450 */ 503*/
451int QStyleSheetItem::logicalFontSizeStep() const 504int QStyleSheetItem::logicalFontSizeStep() const
452{ 505{
453 return d->fontsizestep; 506 return d->fontsizestep;
454} 507}
455 508
456/*! 509/*!
457 Sets the logical font size step of this style to \a s. 510 Sets the logical font size step of this style to \a s.
458 511
459 \sa logicalFontSizeStep() 512 \sa logicalFontSizeStep()
460 */ 513*/
461void QStyleSheetItem::setLogicalFontSizeStep( int s ) 514void QStyleSheetItem::setLogicalFontSizeStep( int s )
462{ 515{
463 d->fontsizestep = s; 516 d->fontsizestep = s;
@@ -466,21 +519,21 @@ void QStyleSheetItem::setLogicalFontSizeStep( int s )
466 519
467 520
468/*! 521/*!
469 Sets the font size setting of the style to \a s points. 522 Sets the font size setting of the style to \a s points.
470 523
471 \sa fontSize(), QFont::pointSize(), QFont::setPointSize() 524 \sa fontSize(), QFont::pointSize(), QFont::setPointSize()
472 */ 525*/
473void QStyleSheetItem::setFontSize(int s) 526void QStyleSheetItem::setFontSize(int s)
474{ 527{
475 d->fontsize = s; 528 d->fontsize = s;
476} 529}
477 530
478/*! 531/*!
479 Returns the font size setting of the style. This is either a valid 532 Returns the font size setting of the style. This is either a valid
480 point size or QStyleSheetItem::Undefined. 533 point size or \c QStyleSheetItem::Undefined.
481 534
482 \sa setFontSize(), QFont::pointSize(), QFont::setPointSize() 535 \sa setFontSize(), QFont::pointSize(), QFont::setPointSize()
483 */ 536*/
484int QStyleSheetItem::fontSize() const 537int QStyleSheetItem::fontSize() const
485{ 538{
486 return d->fontsize; 539 return d->fontsize;
@@ -488,21 +541,21 @@ int QStyleSheetItem::fontSize() const
488 541
489 542
490/*! 543/*!
491 Returns the font family setting of the style. This is either a valid 544 Returns the font family setting of the style. This is either a
492 font family or QString::null if no family has been set. 545 valid font family or QString::null if no family has been set.
493 546
494 \sa setFontFamily(), QFont::family(), QFont::setFamily() 547 \sa setFontFamily(), QFont::family(), QFont::setFamily()
495 */ 548*/
496QString QStyleSheetItem::fontFamily() const 549QString QStyleSheetItem::fontFamily() const
497{ 550{
498 return d->fontfamily; 551 return d->fontfamily;
499} 552}
500 553
501/*! 554/*!
502 Sets the font family setting of the style to \a fam. 555 Sets the font family setting of the style to \a fam.
503 556
504 \sa fontFamily(), QFont::family(), QFont::setFamily() 557 \sa fontFamily(), QFont::family(), QFont::setFamily()
505 */ 558*/
506void QStyleSheetItem::setFontFamily( const QString& fam) 559void QStyleSheetItem::setFontFamily( const QString& fam)
507{ 560{
508 d->fontfamily = fam; 561 d->fontfamily = fam;
@@ -522,7 +575,7 @@ int QStyleSheetItem::numberOfColumns() const
522 575
523 576
524/*!\obsolete 577/*!\obsolete
525 Sets the number of columns for this style. Elements in the style 578 Sets the number of columns for this style. Elements in the style
526 are divided into columns. 579 are divided into columns.
527 580
528 This makes sense only if the style uses a block display mode 581 This makes sense only if the style uses a block display mode
@@ -538,43 +591,43 @@ void QStyleSheetItem::setNumberOfColumns(int ncols)
538 591
539 592
540/*! 593/*!
541 Returns the text color of this style or an invalid color 594 Returns the text color of this style or an invalid color if no
542 if no color has been set. 595 color has been set.
543 596
544 \sa setColor() QColor::isValid() 597 \sa setColor() QColor::isValid()
545 */ 598*/
546QColor QStyleSheetItem::color() const 599QColor QStyleSheetItem::color() const
547{ 600{
548 return d->col; 601 return d->col;
549} 602}
550 603
551/*! 604/*!
552 Sets the text color of this style to \a c. 605 Sets the text color of this style to \a c.
553 606
554 \sa color() 607 \sa color()
555 */ 608*/
556void QStyleSheetItem::setColor( const QColor &c) 609void QStyleSheetItem::setColor( const QColor &c)
557{ 610{
558 d->col = c; 611 d->col = c;
559} 612}
560 613
561/*! 614/*!
562 Returns whether this style is an anchor. 615 Returns whether this style is an anchor.
563 616
564 \sa setAnchor() 617 \sa setAnchor()
565 */ 618*/
566bool QStyleSheetItem::isAnchor() const 619bool QStyleSheetItem::isAnchor() const
567{ 620{
568 return d->anchor; 621 return d->anchor;
569} 622}
570 623
571/*! 624/*!
572 If \a anc is TRUE sets this style to be an anchor (hypertext link); 625 If \a anc is TRUE, sets this style to be an anchor (hypertext
573 otherwise sets it to not be an anchor. Elements in this style have 626 link); otherwise sets it to not be an anchor. Elements in this
574 connections to other documents or anchors. 627 style link to other documents or anchors.
575 628
576 \sa isAnchor() 629 \sa isAnchor()
577 */ 630*/
578void QStyleSheetItem::setAnchor(bool anc) 631void QStyleSheetItem::setAnchor(bool anc)
579{ 632{
580 d->anchor = anc; 633 d->anchor = anc;
@@ -582,19 +635,20 @@ void QStyleSheetItem::setAnchor(bool anc)
582 635
583 636
584/*! 637/*!
585 Returns the whitespace mode. 638 Returns the whitespace mode.
586 639
587 \sa setWhiteSpaceMode() WhiteSpaceMode 640 \sa setWhiteSpaceMode() WhiteSpaceMode
588 */ 641*/
589QStyleSheetItem::WhiteSpaceMode QStyleSheetItem::whiteSpaceMode() const 642QStyleSheetItem::WhiteSpaceMode QStyleSheetItem::whiteSpaceMode() const
590{ 643{
591 return d->whitespacemode; 644 return d->whitespacemode;
592} 645}
593 646
594/*! 647/*!
595 Sets the whitespace mode to \a m. 648 Sets the whitespace mode to \a m.
596 \sa WhiteSpaceMode 649
597 */ 650 \sa WhiteSpaceMode
651*/
598void QStyleSheetItem::setWhiteSpaceMode(WhiteSpaceMode m) 652void QStyleSheetItem::setWhiteSpaceMode(WhiteSpaceMode m)
599{ 653{
600 d->whitespacemode = m; 654 d->whitespacemode = m;
@@ -602,14 +656,14 @@ void QStyleSheetItem::setWhiteSpaceMode(WhiteSpaceMode m)
602 656
603 657
604/*! 658/*!
605 Returns the width of margin \a m in pixels. 659 Returns the width of margin \a m in pixels.
606 660
607 The margin, \a m, can be \c MarginLeft, \c MarginRight, 661 The margin, \a m, can be \c MarginLeft, \c MarginRight, \c
608 \c MarginTop, \c MarginBottom, \c MarginAll, \c MarginVertical or \c 662 MarginTop, \c MarginBottom, \c MarginAll, \c MarginVertical or \c
609 MarginHorizontal. 663 MarginHorizontal.
610 664
611 \sa setMargin() Margin 665 \sa setMargin() Margin
612 */ 666*/
613int QStyleSheetItem::margin(Margin m) const 667int QStyleSheetItem::margin(Margin m) const
614{ 668{
615 return d->margin[m]; 669 return d->margin[m];
@@ -617,14 +671,14 @@ int QStyleSheetItem::margin(Margin m) const
617 671
618 672
619/*! 673/*!
620 Sets the width of margin \a m to \a v pixels. 674 Sets the width of margin \a m to \a v pixels.
621 675
622 The margin, \a m, can be \c MarginLeft, \c MarginRight, 676 The margin, \a m, can be \c MarginLeft, \c MarginRight, \c
623 \c MarginTop, \c MarginBottom, \c MarginAll, \c MarginVertical or \c 677 MarginTop, \c MarginBottom, \c MarginAll, \c MarginVertical or \c
624 MarginHorizontal. The value \a v must be >= 0. 678 MarginHorizontal. The value \a v must be >= 0.
625 679
626 \sa margin() 680 \sa margin()
627 */ 681*/
628void QStyleSheetItem::setMargin(Margin m, int v) 682void QStyleSheetItem::setMargin(Margin m, int v)
629{ 683{
630 if (m == MarginAll ) { 684 if (m == MarginAll ) {
@@ -646,71 +700,74 @@ void QStyleSheetItem::setMargin(Margin m, int v)
646 700
647 701
648/*! 702/*!
649 Returns the list style of the style. 703 Returns the list style of the style.
650 704
651 \sa setListStyle() ListStyle 705 \sa setListStyle() ListStyle
652 */ 706 */
653QStyleSheetItem::ListStyle QStyleSheetItem::listStyle() const 707QStyleSheetItem::ListStyle QStyleSheetItem::listStyle() const
654{ 708{
655 return d->list; 709 return d->list;
656} 710}
657 711
658/*! \enum QStyleSheetItem::ListStyle 712/*!
713 \enum QStyleSheetItem::ListStyle
659 714
660 This enum type defines how the items in a list are prefixed when 715 This enum type defines how the items in a list are prefixed when
661 displayed. The currently defined values are: 716 displayed.
662 717
663 \value ListDisc a filled circle (i.e. a bullet) 718 \value ListDisc a filled circle (i.e. a bullet)
664 \value ListCircle an unfilled circle 719 \value ListCircle an unfilled circle
665 \value ListSquare a filled square 720 \value ListSquare a filled square
666 \value ListDecimal an integer in base 10: \e 1, \e 2, \e 3, ... 721 \value ListDecimal an integer in base 10: \e 1, \e 2, \e 3, ...
667 \value ListLowerAlpha a lowercase letter: \e a, \e b, \e c, ... 722 \value ListLowerAlpha a lowercase letter: \e a, \e b, \e c, ...
668 \value ListUpperAlpha an uppercase letter: \e A, \e B, \e C, ... 723 \value ListUpperAlpha an uppercase letter: \e A, \e B, \e C, ...
669*/ 724*/
725
670/*! 726/*!
671 Sets the list style of the style to \a s. 727 Sets the list style of the style to \a s.
672 728
673 This is used by nested elements that have a display mode of 729 This is used by nested elements that have a display mode of \c
674 \c DisplayListItem. 730 DisplayListItem.
675 731
676 \sa listStyle() DisplayMode ListStyle 732 \sa listStyle() DisplayMode ListStyle
677 */ 733*/
678void QStyleSheetItem::setListStyle(ListStyle s) 734void QStyleSheetItem::setListStyle(ListStyle s)
679{ 735{
680 d->list=s; 736 d->list=s;
681} 737}
682 738
683 739
684/*! Returns a space-separated list of names of styles that may 740/*!
685 contain elements of this style. If nothing has been set, contexts() 741 Returns a space-separated list of names of styles that may contain
686 returns an empty string, which indicates that this style can be 742 elements of this style. If nothing has been set, contexts()
687 nested everywhere. 743 returns an empty string, which indicates that this style can be
744 nested everywhere.
688 745
689 \sa setContexts() 746 \sa setContexts()
690 */ 747*/
691QString QStyleSheetItem::contexts() const 748QString QStyleSheetItem::contexts() const
692{ 749{
693 return d->contxt; 750 return d->contxt;
694} 751}
695 752
696/*! 753/*!
697 Sets a space-separated list of names of styles that may contain 754 Sets a space-separated list of names of styles that may contain
698 elements of this style. If \a c is empty, the style can be nested 755 elements of this style. If \a c is empty, the style can be nested
699 everywhere. 756 everywhere.
700 757
701 \sa contexts() 758 \sa contexts()
702 */ 759*/
703void QStyleSheetItem::setContexts( const QString& c) 760void QStyleSheetItem::setContexts( const QString& c)
704{ 761{
705 d->contxt = QChar(' ') + c + QChar(' '); 762 d->contxt = QChar(' ') + c + QChar(' ');
706} 763}
707 764
708/*! 765/*!
709 Returns TRUE if this style can be nested into an element 766 Returns TRUE if this style can be nested into an element of style
710 of style \a s; otherwise returns FALSE. 767 \a s; otherwise returns FALSE.
711 768
712 \sa contexts(), setContexts() 769 \sa contexts(), setContexts()
713 */ 770*/
714bool QStyleSheetItem::allowedInContext( const QStyleSheetItem* s) const 771bool QStyleSheetItem::allowedInContext( const QStyleSheetItem* s) const
715{ 772{
716 if ( d->contxt.isEmpty() ) 773 if ( d->contxt.isEmpty() )
@@ -720,38 +777,50 @@ bool QStyleSheetItem::allowedInContext( const QStyleSheetItem* s) const
720 777
721 778
722/*! 779/*!
723 Returns TRUE if this style has self-nesting enabled; otherwise 780 Returns TRUE if this style has self-nesting enabled; otherwise
724 returns FALSE. 781 returns FALSE.
725 782
726 \sa setSelfNesting() 783 \sa setSelfNesting()
727 */ 784*/
728bool QStyleSheetItem::selfNesting() const 785bool QStyleSheetItem::selfNesting() const
729{ 786{
730 return d->selfnest; 787 return d->selfnest;
731} 788}
732 789
733/*! 790/*!
734 Sets the self-nesting property for this style to \a nesting. 791 Sets the self-nesting property for this style to \a nesting.
735 792
736 In order to support "dirty" HTML, paragraphs \c{<p>} and list items 793 In order to support "dirty" HTML, paragraphs \c{<p>} and list
737 \c{<li>} are not self-nesting. This means that starting a new 794 items \c{<li>} are not self-nesting. This means that starting a
738 paragraph or list item automatically closes the previous one. 795 new paragraph or list item automatically closes the previous one.
739 796
740 \sa selfNesting() 797 \sa selfNesting()
741 */ 798*/
742void QStyleSheetItem::setSelfNesting( bool nesting ) 799void QStyleSheetItem::setSelfNesting( bool nesting )
743{ 800{
744 d->selfnest = nesting; 801 d->selfnest = nesting;
745} 802}
746 803
747/*! Sets the linespacing to be \a ls pixels */ 804/*
805 Sets the linespacing to be at least \a ls pixels.
806
807 For compatibility with previous Qt releases, small values get
808 treated differently: If \a ls is smaller than the default font
809 line spacing in pixels at parse time, the resulting line spacing
810 is the sum of the default line spacing plus \a ls. We recommend
811 not relying on this behavior.
812*/
748 813
749void QStyleSheetItem::setLineSpacing( int ls ) 814void QStyleSheetItem::setLineSpacing( int ls )
750{ 815{
751 d->lineSpacing = ls; 816 d->lineSpacing = ls;
752} 817}
753 818
754/*! Returns the linespacing */ 819/*!
820 \obsolete
821
822 Returns the linespacing
823*/
755 824
756int QStyleSheetItem::lineSpacing() const 825int QStyleSheetItem::lineSpacing() const
757{ 826{
@@ -767,224 +836,222 @@ int QStyleSheetItem::lineSpacing() const
767 836
768 837
769/*! 838/*!
770 \class QStyleSheet qstylesheet.h 839 \class QStyleSheet qstylesheet.h
771 \ingroup text 840 \ingroup text
772 \brief The QStyleSheet class is a collection of styles for rich text 841 \brief The QStyleSheet class is a collection of styles for rich text
773 rendering and a generator of tags. 842 rendering and a generator of tags.
774 843
775 \ingroup graphics 844 \ingroup graphics
776 \ingroup helpsystem 845 \ingroup helpsystem
777 846
778 By creating QStyleSheetItem objects for a style sheet you build a 847 By creating QStyleSheetItem objects for a style sheet you build a
779 definition of a set of tags. This definition will be used by the 848 definition of a set of tags. This definition will be used by the
780 internal rich text rendering system to parse and display text 849 internal rich text rendering system to parse and display text
781 documents to which the style sheet applies. Rich text is normally 850 documents to which the style sheet applies. Rich text is normally
782 visualized in a QTextView or a QTextBrowser. However, QLabel, 851 visualized in a QTextView or a QTextBrowser. However, QLabel,
783 QWhatsThis and QMessageBox also support it, and other classes are 852 QWhatsThis and QMessageBox also support it, and other classes are
784 likely to follow. With QSimpleRichText it is possible to use the 853 likely to follow. With QSimpleRichText it is possible to use the
785 rich text renderer for custom widgets as well. 854 rich text renderer for custom widgets as well.
786 855
787 The default QStyleSheet object has the following style bindings, 856 The default QStyleSheet object has the following style bindings,
788 sorted by structuring bindings, anchors, character style bindings 857 sorted by structuring bindings, anchors, character style bindings
789 (i.e. inline styles), special elements such as horizontal lines or 858 (i.e. inline styles), special elements such as horizontal lines or
790 images, and other tags. In addition, rich text supports simple HTML 859 images, and other tags. In addition, rich text supports simple
791 tables. 860 HTML tables.
792 861
793 The structuring tags are 862 The structuring tags are
794 \list 863 \table
795 \i \c{<qt>}...\c{</qt>} 864 \header \i Structuring tags \i Notes
796 - A Qt rich text document. It understands the following attributes: 865 \row \i \c{<qt>}...\c{</qt>}
797 \list 866 \i A Qt rich text document. It understands the following
798 \i title 867 attributes:
799 - The caption of the document. This attribute is easily accessible with 868 \list
800 QTextView::documentTitle(). 869 \i \c title -- The caption of the document. This attribute is
801 \i type 870 easily accessible with QTextView::documentTitle().
802 - The type of the document. The default type is \c page . It 871 \i \c type -- The type of the document. The default type is \c
803 indicates that the document is displayed in a page of its 872 page. It indicates that the document is displayed in a
804 own. Another style is \c detail, which can be used to 873 page of its own. Another style is \c detail, which can be
805 explain certain expressions in more detail in a few 874 used to explain certain expressions in more detail in a
806 sentences. The QTextBrowser will then keep the current page 875 few sentences. For \c detail, QTextBrowser will then keep
807 and display the new document in a small popup similar to 876 the current page and display the new document in a small
808 QWhatsThis. Note that links will not work in documents with 877 popup similar to QWhatsThis. Note that links will not work
809 \c{<qt type="detail">...</qt>}. 878 in documents with \c{<qt type="detail">...</qt>}.
810 \i bgcolor 879 \i \c bgcolor -- The background color, for example \c
811 - The background color, for example \c bgcolor="yellow" or \c 880 bgcolor="yellow" or \c bgcolor="#0000FF".
812 bgcolor="#0000FF". 881 \i \c background -- The background pixmap, for example \c
813 \i background 882 background="granite.xpm". The pixmap name will be resolved
814 - The background pixmap, for example \c 883 by a QMimeSourceFactory().
815 background="granit.xpm". The pixmap name will be resolved by 884 \i \c text -- The default text color, for example \c text="red".
816 a QMimeSourceFactory(). 885 \i \c link -- The link color, for example \c link="green".
817 \i text 886 \endlist
818 - The default text color, for example \c text="red". 887 \row \i \c{<h1>...</h1>}
819 \i link 888 \i A top-level heading.
820 - The link color, for example \c link="green". 889 \row \i \c{<h2>...</h2>}
821 \endlist 890 \i A sublevel heading.
822 \i \c{<h1>...</h1>} 891 \row \i \c{<h3>...</h3>}
823 - A top-level heading. 892 \i A sub-sublevel heading.
824 \i \c{<h2>...</h2>} 893 \row \i \c{<p>...</p>}
825 - A sublevel heading. 894 \i A left-aligned paragraph. Adjust the alignment with the \c
826 \i \c{<h3>...</h3>} 895 align attribute. Possible values are \c left, \c right and
827 - A sub-sublevel heading. 896 \c center.
828 \i \c{<p>...</p>} 897 \row \i \c{<center>...}<br>\c{</center>}
829 - A left-aligned paragraph. Adjust the alignment with 898 \i A centered paragraph.
830 the \c align attribute. Possible values are 899 \row \i \c{<blockquote>...}<br>\c{</blockquote>}
831 \c left, \c right and \c center. 900 \i An indented paragraph that is useful for quotes.
832 \i \c{<center>...</center>} 901 \row \i \c{<ul>...</ul>}
833 - A centered paragraph. 902 \i An unordered list. You can also pass a type argument to
834 \i \c{<blockquote>...</blockquote>} 903 define the bullet style. The default is \c type=disc;
835 - An indented paragraph that is useful for quotes. 904 other types are \c circle and \c square.
836 \i \c{<ul>...</ul>} 905 \row \i \c{<ol>...</ol>}
837 - An unordered list. You can also pass a type argument to 906 \i An ordered list. You can also pass a type argument to
838 define the bullet style. The default is \c type=disc; other 907 define the enumeration label style. The default is \c
839 types are \c circle and \c square. 908 type="1"; other types are \c "a" and \c "A".
840 \i \c{<ol>...</ol>} 909 \row \i \c{<li>...</li>}
841 - An ordered list. You can also pass a type argument to define 910 \i A list item. This tag can be used only within the context
842 the enumeration label style. The default is \c type="1"; other 911 of \c{<ol>} or \c{<ul>}.
843 types are \c "a" and \c "A". 912 \row \i \c{<pre>...</pre>}
844 \i <tt>&lt;li&gt;</tt>...<tt>&lt;/li&gt;</tt> 913 \i For larger chunks of code. Whitespaces in the contents are
845 - A list item. This tag can be used only within the context of 914 preserved. For small bits of code use the inline-style \c
846 \c ol or \c ul. 915 code.
847 \i \c{<pre>...</pre>} 916 \endtable
848 - For larger chunks of code. Whitespaces in the contents are preserved. 917
849 For small bits of code use the inline-style \c code. 918 Anchors and links are done with a single tag:
850 \endlist 919 \table
851 920 \header \i Anchor tags \i Notes
852 Anchors and links are done with a single tag: 921 \row \i \c{<a>...</a>}
853 \list 922 \i An anchor or link.
854 \i \c{<a>...</a>} 923 \list
855 - An anchor or link. The reference target is defined in the \c 924 \i A link is created by using an \c href
856 href attribute of the tag as in \c{<a 925 attribute, for example
857 href="target.qml">...</a>}. You can also specify an 926 <br>\c{<a href="target.qml">Link Text</a>}. Links to
858 additional anchor within the specified target document, for 927 targets within a document are achieved in the same way
859 example \c{<a href="target.qml#123">...</a>}. If \c a is 928 as for HTML, e.g.
860 meant to be an anchor, the reference source is given in the 929 <br>\c{<a href="target.qml#subtitle">Link Text</a>}.
861 \c name attribute. 930 \i A target is created by using a \c name
862 \endlist 931 attribute, for example
863 932 <br>\c{<a name="subtitle"><h2>Sub Title</h2></a>}.
864 The default character style bindings are 933 \endlist
865 \list 934 \endtable
866 \i \c{<em>...</em>} 935
867 - Emphasized. By default this is the same as 936 The default character style bindings are
868 \c{<i>...</i>} (italic). 937 \table
869 \i \c{<strong>...</strong>} 938 \header \i Style tags \i Notes
870 - Strong. By default this is the same as 939 \row \i \c{<em>...</em>}
871 \c{<b>...</b>} (bold). 940 \i Emphasized. By default this is the same as \c{<i>...</i>}
872 \i \c{<i>...</i>} 941 (italic).
873 - Italic font style. 942 \row \i \c{<strong>...</strong>}
874 \i \c{<b>...</b>} 943 \i Strong. By default this is the same as \c{<b>...</b>}
875 - Bold font style. 944 (bold).
876 \i \c{<u>...</u>} 945 \row \i \c{<i>...</i>}
877 - Underlined font style. 946 \i Italic font style.
878 \i \c{<big>...</big>} 947 \row \i \c{<b>...</b>}
879 - A larger font size. 948 \i Bold font style.
880 \i \c{<small>...</small>} 949 \row \i \c{<u>...</u>}
881 - A smaller font size. 950 \i Underlined font style.
882 \i \c{<code>...</code>} 951 \row \i \c{<s>...</s>}
883 - Indicates code. By default this is the same as 952 \i Strike out font style.
884 \c{<tt>...</tt>} (typewriter). For 953 \row \i \c{<big>...</big>}
885 larger junks of code use the block-tag \c pre. 954 \i A larger font size.
886 \i \c{<tt>...</tt>} 955 \row \i \c{<small>...</small>}
887 - Typewriter font style. 956 \i A smaller font size.
888 \i \c{<font>...</font>} 957 \row \i \c{<code>...</code>}
889 - Customizes the font size, family and text color. The tag understands 958 \i Indicates code. By default this is the same as
890 the following attributes: 959 \c{<tt>...</tt>} (typewriter). For larger junks of code
891 \list 960 use the block-tag \c{<}\c{pre>}.
892 \i color 961 \row \i \c{<tt>...</tt>}
893 - The text color, for example \c color="red" or \c color="#FF0000". 962 \i Typewriter font style.
894 \i size 963 \row \i \c{<font>...</font>}
895 - The logical size of the font. Logical sizes 1 to 7 are supported. 964 \i Customizes the font size, family and text color. The tag
896 The value may either be absolute (for example, 965 understands the following attributes:
897 \c size=3) or relative (\c size=-2). In the latter case the sizes 966 \list
898 are simply added. 967 \i \c color -- The text color, for example \c color="red" or
899 \i face 968 \c color="#FF0000".
900 - The family of the font, for example \c face=times. 969 \i \c size -- The logical size of the font. Logical sizes 1
901 \endlist 970 to 7 are supported. The value may either be absolute
902 \endlist 971 (for example, \c size=3) or relative (\c size=-2). In
903 972 the latter case the sizes are simply added.
904 Special elements are: 973 \i \c face -- The family of the font, for example \c face=times.
905 \list 974 \endlist
906 \i \c{<img>} 975 \endtable
907 - An image. The image name for the mime source 976
908 factory is given in the source attribute, for example 977 Special elements are:
909 \c{<img src="qt.xpm">} 978 \table
910 The image tag also understands the attributes \c width and \c 979 \header \i Special tags \i Notes
911 height that determine the size of the image. If the pixmap 980 \row \i \c{<img>}
912 does not fit the specified size it will be scaled 981 \i An image. The image name for the mime source factory is
913 automatically (by using QImage::smoothScale()). 982 given in the source attribute, for example
914 983 \c{<img src="qt.xpm">} The image tag also understands the
915 The \c align attribute determines where the image is 984 attributes \c width and \c height that determine the size
916 placed. By default, an image is placed inline just like a 985 of the image. If the pixmap does not fit the specified
917 normal character. Specify \c left or \c right to place the 986 size it will be scaled automatically (by using
918 image at the respective side. 987 QImage::smoothScale()).
919 \i \c{<hr>} 988 <br>
920 - A horizonal line. 989 The \c align attribute determines where the image is
921 \i \c{<br>} 990 placed. By default, an image is placed inline just like a
922 - A line break. 991 normal character. Specify \c left or \c right to place the
923 \endlist 992 image at the respective side.
924 993 \row \i \c{<hr>}
925 Another tag not in any of the above cathegories is 994 \i A horizonal line.
926 \list 995 \row \i \c{<br>}
927 \i \c{<nobr>...</nobr>} 996 \i A line break.
928 - No break. Prevents word wrap. 997 \row \i \c{<nobr>...</nobr>}
929 \endlist 998 \i No break. Prevents word wrap.
930 999 \endtable
931 In addition, rich text supports simple HTML tables. A table consists 1000
932 of one or more rows each of which contains one or more cells. Cells 1001 In addition, rich text supports simple HTML tables. A table
933 are either data cells or header cells, depending on their 1002 consists of one or more rows each of which contains one or more
934 content. Cells which span rows and columns are supported. 1003 cells. Cells are either data cells or header cells, depending on
935 1004 their content. Cells which span rows and columns are supported.
936 \list 1005
937 \i \c{<table>...</table>} 1006 \table
938 - A table. Tables support the following attributes: 1007 \header \i Table tags \i Notes
939 \list 1008 \row \i \c{<table>...</table>}
940 \i bgcolor 1009 \i A table. Tables support the following attributes:
941 - The background color. 1010 \list
942 \i width 1011 \i \c bgcolor -- The background color.
943 - The table width. This is either an absolute pixel width or a relative 1012 \i \c width -- The table width. This is either an absolute
944 percentage of the table's width, for example \c width=80%. 1013 pixel width or a relative percentage of the table's
945 \i border 1014 width, for example \c width=80%.
946 - The width of the table border. The default is 0 (= no border). 1015 \i \c border -- The width of the table border. The default is
947 \i cellspacing 1016 0 (= no border).
948 - Additional space around the table cells. The default is 2. 1017 \i \c cellspacing -- Additional space around the table cells.
949 \i cellpadding 1018 The default is 2.
950 - Additional space around the contents of table cells. The default is 1. 1019 \i \c cellpadding -- Additional space around the contents of
951 \endlist 1020 table cells. The default is 1.
952 \i \c{<tr>...</tr>} 1021 \endlist
953 - A table row. This is only valid within a \c table. Rows support 1022 \row \i \c{<tr>...</tr>}
954 the following attribute: 1023 \i A table row. This is only valid within a \c table. Rows
955 \list 1024 support the following attribute:
956 \i bgcolor 1025 \list
957 - The background color. 1026 \i \c bgcolor -- The background color.
958 \endlist 1027 \endlist
959 \i \c{<th>...</th>} 1028 \row \i \c{<th>...</th>}
960 - A table header cell. Similar to \c td, but defaults to center alignment 1029 \i A table header cell. Similar to \c td, but defaults to
961 and a bold font. 1030 center alignment and a bold font.
962 \i \c{<td>...</td>} 1031 \row \i \c{<td>...</td>}
963 - A table data cell. This is only valid within a \c tr. Cells 1032 \i A table data cell. This is only valid within a \c tr.
964 support the following attributes: 1033 Cells support the following attributes:
965 \list 1034 \list
966 \i bgcolor 1035 \i \c bgcolor -- The background color.
967 - The background color. 1036 \i \c width -- The cell width. This is either an absolute
968 \i width 1037 pixel width or a relative percentage of table's width,
969 - The cell width. This is either an absolute pixel width or a relative 1038 for example \c width=50%.
970 percentage of table's width, for example \c width=50%. 1039 \i \c colspan -- Specifies how many columns this cell spans.
971 \i colspan 1040 The default is 1.
972 - Specifies how many columns this cell spans. The default is 1. 1041 \i \c rowspan -- Specifies how many rows this cell spans. The
973 \i rowspan 1042 default is 1.
974 - Specifies how many rows this cell spans. The default is 1. 1043 \i \c align -- Alignment; possible values are \c left, \c
975 \i align 1044 right, and \c center. The default is left.
976 - Alignment; possible values are \c left, \c right, and \c center. The 1045 \endlist
977 default is left. 1046 \endtable
978 \endlist 1047*/
979 \endlist 1048
980*/ 1049/*!
981 1050 Creates a style sheet called \a name, with parent \a parent. Like
982/*! 1051 any QObject it will be deleted when its parent is destroyed (if
983 Creates a style sheet with parent \a parent and name \a name. Like 1052 the child still exists).
984 any QObject it will be deleted when its parent is 1053
985 destroyed (if the child still exists). 1054 By default the style sheet has the tag definitions defined above.
986
987 By default the style sheet has the tag definitions defined above.
988*/ 1055*/
989QStyleSheet::QStyleSheet( QObject *parent, const char *name ) 1056QStyleSheet::QStyleSheet( QObject *parent, const char *name )
990 : QObject( parent, name ) 1057 : QObject( parent, name )
@@ -993,8 +1060,8 @@ QStyleSheet::QStyleSheet( QObject *parent, const char *name )
993} 1060}
994 1061
995/*! 1062/*!
996 Destroys the style sheet. All styles inserted into the style sheet 1063 Destroys the style sheet. All styles inserted into the style sheet
997 will be deleted. 1064 will be deleted.
998*/ 1065*/
999QStyleSheet::~QStyleSheet() 1066QStyleSheet::~QStyleSheet()
1000{ 1067{
@@ -1018,7 +1085,6 @@ void QStyleSheet::init()
1018 1085
1019 style = new QStyleSheetItem( this, QString::fromLatin1("qt") ); 1086 style = new QStyleSheetItem( this, QString::fromLatin1("qt") );
1020 style->setDisplayMode( QStyleSheetItem::DisplayBlock ); 1087 style->setDisplayMode( QStyleSheetItem::DisplayBlock );
1021 //style->setMargin( QStyleSheetItem::MarginAll, 4 );
1022 1088
1023 style = new QStyleSheetItem( this, QString::fromLatin1("a") ); 1089 style = new QStyleSheetItem( this, QString::fromLatin1("a") );
1024 style->setAnchor( TRUE ); 1090 style->setAnchor( TRUE );
@@ -1047,40 +1113,39 @@ void QStyleSheet::init()
1047 style->setFontWeight( QFont::Bold); 1113 style->setFontWeight( QFont::Bold);
1048 style->setLogicalFontSize(6); 1114 style->setLogicalFontSize(6);
1049 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1115 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1050 style-> setMargin(QStyleSheetItem::MarginTop, 12); 1116 style-> setMargin(QStyleSheetItem::MarginTop, 18);
1051 style-> setMargin(QStyleSheetItem::MarginBottom, 6); 1117 style-> setMargin(QStyleSheetItem::MarginBottom, 12);
1052 1118
1053 style = new QStyleSheetItem( this, QString::fromLatin1("h2") ); 1119 style = new QStyleSheetItem( this, QString::fromLatin1("h2") );
1054 style->setFontWeight( QFont::Bold); 1120 style->setFontWeight( QFont::Bold);
1055 style->setLogicalFontSize(5); 1121 style->setLogicalFontSize(5);
1056 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1122 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1057 style-> setMargin(QStyleSheetItem::MarginTop, 10); 1123 style-> setMargin(QStyleSheetItem::MarginTop, 16);
1058 style-> setMargin(QStyleSheetItem::MarginBottom, 5); 1124 style-> setMargin(QStyleSheetItem::MarginBottom, 12);
1059 1125
1060 style = new QStyleSheetItem( this, QString::fromLatin1("h3") ); 1126 style = new QStyleSheetItem( this, QString::fromLatin1("h3") );
1061 style->setFontWeight( QFont::Bold); 1127 style->setFontWeight( QFont::Bold);
1062 style->setLogicalFontSize(4); 1128 style->setLogicalFontSize(4);
1063 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1129 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1064 style-> setMargin(QStyleSheetItem::MarginTop, 8); 1130 style-> setMargin(QStyleSheetItem::MarginTop, 14);
1065 style-> setMargin(QStyleSheetItem::MarginBottom, 4); 1131 style-> setMargin(QStyleSheetItem::MarginBottom, 12);
1066 1132
1067 style = new QStyleSheetItem( this, QString::fromLatin1("h4") ); 1133 style = new QStyleSheetItem( this, QString::fromLatin1("h4") );
1068 style->setFontWeight( QFont::Bold); 1134 style->setFontWeight( QFont::Bold);
1069 style->setLogicalFontSize(3); 1135 style->setLogicalFontSize(3);
1070 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1136 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1071 style-> setMargin(QStyleSheetItem::MarginTop, 8); 1137 style-> setMargin(QStyleSheetItem::MarginVertical, 12);
1072 style-> setMargin(QStyleSheetItem::MarginBottom, 4);
1073 1138
1074 style = new QStyleSheetItem( this, QString::fromLatin1("h5") ); 1139 style = new QStyleSheetItem( this, QString::fromLatin1("h5") );
1075 style->setFontWeight( QFont::Bold); 1140 style->setFontWeight( QFont::Bold);
1076 style->setLogicalFontSize(2); 1141 style->setLogicalFontSize(2);
1077 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1142 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1078 style-> setMargin(QStyleSheetItem::MarginTop, 8); 1143 style-> setMargin(QStyleSheetItem::MarginTop, 12);
1079 style-> setMargin(QStyleSheetItem::MarginBottom, 4); 1144 style-> setMargin(QStyleSheetItem::MarginBottom, 4);
1080 1145
1081 style = new QStyleSheetItem( this, QString::fromLatin1("p") ); 1146 style = new QStyleSheetItem( this, QString::fromLatin1("p") );
1082 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1147 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1083 style-> setMargin(QStyleSheetItem::MarginVertical, 8); 1148 style-> setMargin(QStyleSheetItem::MarginVertical, 12);
1084 style->setSelfNesting( FALSE ); 1149 style->setSelfNesting( FALSE );
1085 1150
1086 style = new QStyleSheetItem( this, QString::fromLatin1("center") ); 1151 style = new QStyleSheetItem( this, QString::fromLatin1("center") );
@@ -1097,18 +1162,19 @@ void QStyleSheet::init()
1097 1162
1098 style = new QStyleSheetItem( this, QString::fromLatin1("ul") ); 1163 style = new QStyleSheetItem( this, QString::fromLatin1("ul") );
1099 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1164 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1100 style-> setMargin(QStyleSheetItem::MarginVertical, 4); 1165 style->setListStyle( QStyleSheetItem::ListDisc );
1166 style-> setMargin(QStyleSheetItem::MarginVertical, 12);
1167 style->setMargin( QStyleSheetItem::MarginLeft, 40 );
1101 1168
1102 style = new QStyleSheetItem( this, QString::fromLatin1("ol") ); 1169 style = new QStyleSheetItem( this, QString::fromLatin1("ol") );
1103 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1170 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1104 style->setListStyle( QStyleSheetItem::ListDecimal ); 1171 style->setListStyle( QStyleSheetItem::ListDecimal );
1105 style-> setMargin(QStyleSheetItem::MarginVertical, 4); 1172 style-> setMargin(QStyleSheetItem::MarginVertical, 12);
1173 style->setMargin( QStyleSheetItem::MarginLeft, 40 );
1106 1174
1107 style = new QStyleSheetItem( this, QString::fromLatin1("li") ); 1175 style = new QStyleSheetItem( this, QString::fromLatin1("li") );
1108 style->setDisplayMode(QStyleSheetItem::DisplayListItem); 1176 style->setDisplayMode(QStyleSheetItem::DisplayListItem);
1109 style->setSelfNesting( FALSE ); 1177 style->setSelfNesting( FALSE );
1110 style->setContexts(QString::fromLatin1("ol ul"));
1111 style-> setMargin(QStyleSheetItem::MarginVertical, 4);
1112 1178
1113 style = new QStyleSheetItem( this, QString::fromLatin1("code") ); 1179 style = new QStyleSheetItem( this, QString::fromLatin1("code") );
1114 style->setFontFamily( QString::fromLatin1("courier") ); 1180 style->setFontFamily( QString::fromLatin1("courier") );
@@ -1119,6 +1185,7 @@ void QStyleSheet::init()
1119 new QStyleSheetItem(this, QString::fromLatin1("img")); 1185 new QStyleSheetItem(this, QString::fromLatin1("img"));
1120 new QStyleSheetItem(this, QString::fromLatin1("br")); 1186 new QStyleSheetItem(this, QString::fromLatin1("br"));
1121 new QStyleSheetItem(this, QString::fromLatin1("hr")); 1187 new QStyleSheetItem(this, QString::fromLatin1("hr"));
1188
1122 style = new QStyleSheetItem(this, QString::fromLatin1("sub")); 1189 style = new QStyleSheetItem(this, QString::fromLatin1("sub"));
1123 style->setVerticalAlignment( QStyleSheetItem::VAlignSub ); 1190 style->setVerticalAlignment( QStyleSheetItem::VAlignSub );
1124 style = new QStyleSheetItem(this, QString::fromLatin1("sup")); 1191 style = new QStyleSheetItem(this, QString::fromLatin1("sup"));
@@ -1135,9 +1202,13 @@ void QStyleSheet::init()
1135 1202
1136 style = new QStyleSheetItem( this, QString::fromLatin1("head") ); 1203 style = new QStyleSheetItem( this, QString::fromLatin1("head") );
1137 style->setDisplayMode(QStyleSheetItem::DisplayNone); 1204 style->setDisplayMode(QStyleSheetItem::DisplayNone);
1205 style = new QStyleSheetItem( this, QString::fromLatin1("body") );
1206 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1138 style = new QStyleSheetItem( this, QString::fromLatin1("div") ); 1207 style = new QStyleSheetItem( this, QString::fromLatin1("div") );
1139 style->setDisplayMode(QStyleSheetItem::DisplayBlock) ; 1208 style->setDisplayMode(QStyleSheetItem::DisplayBlock) ;
1209 style = new QStyleSheetItem( this, QString::fromLatin1("span") );
1140 style = new QStyleSheetItem( this, QString::fromLatin1("dl") ); 1210 style = new QStyleSheetItem( this, QString::fromLatin1("dl") );
1211 style-> setMargin(QStyleSheetItem::MarginVertical, 8);
1141 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1212 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
1142 style = new QStyleSheetItem( this, QString::fromLatin1("dt") ); 1213 style = new QStyleSheetItem( this, QString::fromLatin1("dt") );
1143 style->setDisplayMode(QStyleSheetItem::DisplayBlock); 1214 style->setDisplayMode(QStyleSheetItem::DisplayBlock);
@@ -1148,10 +1219,15 @@ void QStyleSheet::init()
1148 style->setContexts(QString::fromLatin1("dt dl") ); 1219 style->setContexts(QString::fromLatin1("dt dl") );
1149 style = new QStyleSheetItem( this, QString::fromLatin1("u") ); 1220 style = new QStyleSheetItem( this, QString::fromLatin1("u") );
1150 style->setFontUnderline( TRUE); 1221 style->setFontUnderline( TRUE);
1222 style = new QStyleSheetItem( this, QString::fromLatin1("s") );
1223 style->setFontStrikeOut( TRUE);
1151 style = new QStyleSheetItem( this, QString::fromLatin1("nobr") ); 1224 style = new QStyleSheetItem( this, QString::fromLatin1("nobr") );
1152 style->setWhiteSpaceMode( QStyleSheetItem::WhiteSpaceNoWrap ); 1225 style->setWhiteSpaceMode( QStyleSheetItem::WhiteSpaceNoWrap );
1153 style = new QStyleSheetItem( this, QString::fromLatin1("wsp") ); // qt extension for QTextEdit 1226
1154 style->setWhiteSpaceMode( (QStyleSheetItem::WhiteSpaceMode) 3 ); // WhiteSpaceModeNoCompression 1227 // compatibily with some minor 3.0.x Qt versions that had an
1228 // undocumented <wsp> tag. ### Remove 3.1
1229 style = new QStyleSheetItem( this, QString::fromLatin1("wsp") );
1230 style->setWhiteSpaceMode( QStyleSheetItem::WhiteSpacePre );
1155 1231
1156 // tables 1232 // tables
1157 style = new QStyleSheetItem( this, QString::fromLatin1("table") ); 1233 style = new QStyleSheetItem( this, QString::fromLatin1("table") );
@@ -1173,14 +1249,14 @@ static QStyleSheet* defaultsheet = 0;
1173static QSingleCleanupHandler<QStyleSheet> qt_cleanup_stylesheet; 1249static QSingleCleanupHandler<QStyleSheet> qt_cleanup_stylesheet;
1174 1250
1175/*! 1251/*!
1176 Returns the application-wide default style sheet. This style sheet is 1252 Returns the application-wide default style sheet. This style sheet
1177 used by rich text rendering classes such as QSimpleRichText, 1253 is used by rich text rendering classes such as QSimpleRichText,
1178 QWhatsThis and QMessageBox to define the rendering style and 1254 QWhatsThis and QMessageBox to define the rendering style and
1179 available tags within rich text documents. It serves also as initial 1255 available tags within rich text documents. It also serves as the
1180 style sheet for the more complex render widgets QTextEdit and 1256 initial style sheet for the more complex render widgets, QTextEdit
1181 QTextBrowser. 1257 and QTextBrowser.
1182 1258
1183 \sa setDefaultSheet() 1259 \sa setDefaultSheet()
1184*/ 1260*/
1185QStyleSheet* QStyleSheet::defaultSheet() 1261QStyleSheet* QStyleSheet::defaultSheet()
1186{ 1262{
@@ -1192,11 +1268,11 @@ QStyleSheet* QStyleSheet::defaultSheet()
1192} 1268}
1193 1269
1194/*! 1270/*!
1195 Sets the application-wide default style sheet to \a sheet, deleting 1271 Sets the application-wide default style sheet to \a sheet,
1196 any style sheet previously set. The ownership is transferred to 1272 deleting any style sheet previously set. The ownership is
1197 QStyleSheet. 1273 transferred to QStyleSheet.
1198 1274
1199 \sa defaultSheet() 1275 \sa defaultSheet()
1200*/ 1276*/
1201void QStyleSheet::setDefaultSheet( QStyleSheet* sheet) 1277void QStyleSheet::setDefaultSheet( QStyleSheet* sheet)
1202{ 1278{
@@ -1211,8 +1287,8 @@ void QStyleSheet::setDefaultSheet( QStyleSheet* sheet)
1211} 1287}
1212 1288
1213/*!\internal 1289/*!\internal
1214 Inserts \a style. Any tags generated after this time will be 1290 Inserts \a style. Any tags generated after this time will be
1215 bound to this style. Note that \a style becomes owned by the 1291 bound to this style. Note that \a style becomes owned by the
1216 style sheet and will be deleted when the style sheet is destroyed. 1292 style sheet and will be deleted when the style sheet is destroyed.
1217*/ 1293*/
1218void QStyleSheet::insert( QStyleSheetItem* style ) 1294void QStyleSheet::insert( QStyleSheetItem* style )
@@ -1222,8 +1298,8 @@ void QStyleSheet::insert( QStyleSheetItem* style )
1222 1298
1223 1299
1224/*! 1300/*!
1225 Returns the style with name \a name or 0 if there is no such style. 1301 Returns the style called \a name or 0 if there is no such style.
1226 */ 1302*/
1227QStyleSheetItem* QStyleSheet::item( const QString& name) 1303QStyleSheetItem* QStyleSheet::item( const QString& name)
1228{ 1304{
1229 if ( name.isNull() ) 1305 if ( name.isNull() )
@@ -1233,8 +1309,10 @@ QStyleSheetItem* QStyleSheet::item( const QString& name)
1233 1309
1234/*! 1310/*!
1235 \overload 1311 \overload
1236 Returns the style with name \a name or 0 if there is no such style (const version) 1312
1237 */ 1313 Returns the style called \a name or 0 if there is no such style
1314 (const version)
1315*/
1238const QStyleSheetItem* QStyleSheet::item( const QString& name) const 1316const QStyleSheetItem* QStyleSheet::item( const QString& name) const
1239{ 1317{
1240 if ( name.isNull() ) 1318 if ( name.isNull() )
@@ -1245,21 +1323,22 @@ const QStyleSheetItem* QStyleSheet::item( const QString& name) const
1245 1323
1246/*! 1324/*!
1247 \preliminary 1325 \preliminary
1248 Generates an internal object for the tag called \a name, given the
1249 attributes \a attr, and using additional information provided
1250 by the mime source factory \a factory.
1251 1326
1252 \a context is the optional context of the document, i.e. the path to 1327 Generates an internal object for the tag called \a name, given the
1253 look for relative links. This becomes important if the text contains 1328 attributes \a attr, and using additional information provided by
1254 relative references, for example within image tags. QSimpleRichText 1329 the mime source factory \a factory.
1255 always uses the default mime source factory (see
1256 \l{QMimeSourceFactory::defaultFactory()}) to resolve these references.
1257 The context will then be used to calculate the absolute path. See
1258 QMimeSourceFactory::makeAbsolute() for details.
1259 1330
1260 \a emptyTag and \a doc are for internal use only. 1331 \a context is the optional context of the document, i.e. the path
1332 to look for relative links. This becomes important if the text
1333 contains relative references, for example within image tags.
1334 QSimpleRichText always uses the default mime source factory (see
1335 \l{QMimeSourceFactory::defaultFactory()}) to resolve these
1336 references. The context will then be used to calculate the
1337 absolute path. See QMimeSourceFactory::makeAbsolute() for details.
1261 1338
1262 This function should not (yet) be used in application code. 1339 \a emptyTag and \a doc are for internal use only.
1340
1341 This function should not be used in application code.
1263*/ 1342*/
1264QTextCustomItem* QStyleSheet::tag( const QString& name, 1343QTextCustomItem* QStyleSheet::tag( const QString& name,
1265 const QMap<QString, QString> &attr, 1344 const QMap<QString, QString> &attr,
@@ -1267,32 +1346,28 @@ QTextCustomItem* QStyleSheet::tag( const QString& name,
1267 const QMimeSourceFactory& factory, 1346 const QMimeSourceFactory& factory,
1268 bool /*emptyTag */, QTextDocument *doc ) const 1347 bool /*emptyTag */, QTextDocument *doc ) const
1269{ 1348{
1270 static QString s_img = QString::fromLatin1("img");
1271 static QString s_hr = QString::fromLatin1("hr");
1272
1273 const QStyleSheetItem* style = item( name ); 1349 const QStyleSheetItem* style = item( name );
1274 // first some known tags 1350 // first some known tags
1275 if ( !style ) 1351 if ( !style )
1276 return 0; 1352 return 0;
1277 if ( style->name() == s_img ) 1353 if ( style->name() == "img" )
1278 return new QTextImage( doc, attr, context, (QMimeSourceFactory&)factory ); 1354 return new QTextImage( doc, attr, context, (QMimeSourceFactory&)factory );
1279 if ( style->name() == s_hr ) 1355 if ( style->name() == "hr" )
1280 return new QTextHorizontalLine( doc, attr, context, (QMimeSourceFactory&)factory ); 1356 return new QTextHorizontalLine( doc, attr, context, (QMimeSourceFactory&)factory );
1281 return 0; 1357 return 0;
1282} 1358}
1283 1359
1284 1360
1285/*! 1361/*! Auxiliary function. Converts the plain text string \a plain to a
1286 Auxiliary function. Converts the plain text string \a plain to a 1362 rich text formatted paragraph while preserving most of its look.
1287 rich text formatted paragraph while preserving its look.
1288 1363
1289 \a mode defines the whitespace mode. Possible values are \c 1364 \a mode defines the whitespace mode. Possible values are \c
1290 QStyleSheetItem::WhiteSpacePre (no wrapping, all whitespaces 1365 QStyleSheetItem::WhiteSpacePre (no wrapping, all whitespaces
1291 preserved) and \c QStyleSheetItem::WhiteSpaceNormal (wrapping, 1366 preserved) and \c QStyleSheetItem::WhiteSpaceNormal (wrapping,
1292 simplified whitespaces). 1367 simplified whitespaces).
1293 1368
1294 \sa escape() 1369 \sa escape()
1295 */ 1370*/
1296QString QStyleSheet::convertFromPlainText( const QString& plain, QStyleSheetItem::WhiteSpaceMode mode ) 1371QString QStyleSheet::convertFromPlainText( const QString& plain, QStyleSheetItem::WhiteSpaceMode mode )
1297{ 1372{
1298 int col = 0; 1373 int col = 0;
@@ -1300,41 +1375,53 @@ QString QStyleSheet::convertFromPlainText( const QString& plain, QStyleSheetItem
1300 rich += "<p>"; 1375 rich += "<p>";
1301 for ( int i = 0; i < int(plain.length()); ++i ) { 1376 for ( int i = 0; i < int(plain.length()); ++i ) {
1302 if ( plain[i] == '\n' ){ 1377 if ( plain[i] == '\n' ){
1303 if ( col == 1 ) 1378 int c = 1;
1304 rich += "<p></p>"; 1379 while ( i+1 < int(plain.length()) && plain[i+1] == '\n' ) {
1305 else 1380 i++;
1306 rich += "<br>"; 1381 c++;
1382 }
1383 if ( c == 1)
1384 rich += "<br>\n";
1385 else {
1386 rich += "</p>\n";
1387 while ( --c > 1 )
1388 rich += "<br>\n";
1389 rich += "<p>";
1390 }
1307 col = 0; 1391 col = 0;
1308 } 1392 } else {
1309 else if ( mode == QStyleSheetItem::WhiteSpacePre && plain[i] == '\t' ){ 1393 if ( mode == QStyleSheetItem::WhiteSpacePre && plain[i] == '\t' ){
1310 rich += 0x00a0U;
1311 while ( col % 4 ) {
1312 rich += 0x00a0U; 1394 rich += 0x00a0U;
1313 ++col; 1395 ++col;
1396 while ( col % 8 ) {
1397 rich += 0x00a0U;
1398 ++col;
1399 }
1314 } 1400 }
1401 else if ( mode == QStyleSheetItem::WhiteSpacePre && plain[i].isSpace() )
1402 rich += 0x00a0U;
1403 else if ( plain[i] == '<' )
1404 rich +="&lt;";
1405 else if ( plain[i] == '>' )
1406 rich +="&gt;";
1407 else if ( plain[i] == '&' )
1408 rich +="&amp;";
1409 else
1410 rich += plain[i];
1411 ++col;
1315 } 1412 }
1316 else if ( mode == QStyleSheetItem::WhiteSpacePre && plain[i].isSpace() )
1317 rich += 0x00a0U;
1318 else if ( plain[i] == '<' )
1319 rich +="&lt;";
1320 else if ( plain[i] == '>' )
1321 rich +="&gt;";
1322 else if ( plain[i] == '&' )
1323 rich +="&amp;";
1324 else
1325 rich += plain[i];
1326 ++col;
1327 } 1413 }
1328 rich += "</p>"; 1414 if ( col != 0 )
1415 rich += "</p>";
1329 return rich; 1416 return rich;
1330} 1417}
1331 1418
1332/*! 1419/*!
1333 Auxiliary function. Converts the plain text string \a plain to a 1420 Auxiliary function. Converts the plain text string \a plain to a
1334 rich text formatted string with any HTML meta-characters escaped. 1421 rich text formatted string with any HTML meta-characters escaped.
1335 1422
1336 \sa convertFromPlainText() 1423 \sa convertFromPlainText()
1337 */ 1424*/
1338QString QStyleSheet::escape( const QString& plain) 1425QString QStyleSheet::escape( const QString& plain)
1339{ 1426{
1340 QString rich; 1427 QString rich;
@@ -1354,32 +1441,33 @@ QString QStyleSheet::escape( const QString& plain)
1354// Must doc this enum somewhere, and it is logically related to QStyleSheet 1441// Must doc this enum somewhere, and it is logically related to QStyleSheet
1355 1442
1356/*! 1443/*!
1357 \enum Qt::TextFormat 1444 \enum Qt::TextFormat
1358 1445
1359 This enum is used in widgets that can display both plain text and 1446 This enum is used in widgets that can display both plain text and
1360 rich text, e.g. QLabel. It is used for deciding whether a text 1447 rich text, e.g. QLabel. It is used for deciding whether a text
1361 string should be interpreted as one or the other. This is 1448 string should be interpreted as one or the other. This is normally
1362 normally done by passing one of the enum values to a setTextFormat() 1449 done by passing one of the enum values to a setTextFormat()
1363 function. 1450 function.
1364 1451
1365 \value PlainText The text string is interpreted as a plain text string. 1452 \value PlainText The text string is interpreted as a plain text
1453 string.
1366 1454
1367 \value RichText The text string is interpreted as a rich text string 1455 \value RichText The text string is interpreted as a rich text
1368 using the current QStyleSheet::defaultSheet(). 1456 string using the current QStyleSheet::defaultSheet().
1369 1457
1370 \value AutoText The text string is interpreted as for \c RichText if 1458 \value AutoText The text string is interpreted as for \c RichText
1371 QStyleSheet::mightBeRichText() returns TRUE, otherwise as for \c 1459 if QStyleSheet::mightBeRichText() returns TRUE, otherwise as
1372 PlainText. 1460 \c PlainText.
1373*/ 1461*/
1374 1462
1375/*! 1463/*!
1376 Returns TRUE if the string \a text is likely to be rich text; 1464 Returns TRUE if the string \a text is likely to be rich text;
1377 otherwise returns FALSE. 1465 otherwise returns FALSE.
1378 1466
1379 Note: The function uses a fast and therefore simple heuristic. It 1467 This function uses a fast and therefore simple heuristic. It
1380 mainly checks whether there is something that looks like a tag 1468 mainly checks whether there is something that looks like a tag
1381 before the first line break. Although the result may be correct for 1469 before the first line break. Although the result may be correct
1382 most common cases, there is no guarantee. 1470 for common cases, there is no guarantee.
1383*/ 1471*/
1384bool QStyleSheet::mightBeRichText( const QString& text) 1472bool QStyleSheet::mightBeRichText( const QString& text)
1385{ 1473{
@@ -1413,17 +1501,18 @@ bool QStyleSheet::mightBeRichText( const QString& text)
1413} 1501}
1414 1502
1415 1503
1416/*! \fn void QStyleSheet::error( const QString& msg) const 1504/*!
1505 \fn void QStyleSheet::error( const QString& msg) const
1417 1506
1418 This virtual function is called when an error occurs when 1507 This virtual function is called when an error occurs when
1419 processing rich text. Reimplement it if you need to catch 1508 processing rich text. Reimplement it if you need to catch error
1420 error messages. 1509 messages.
1421 1510
1422 Errors might occur if some rich text strings contain tags that are 1511 Errors might occur if some rich text strings contain tags that are
1423 not understood by the stylesheet, if some tags are nested incorrectly, or 1512 not understood by the stylesheet, if some tags are nested
1424 if tags are not closed properly. 1513 incorrectly, or if tags are not closed properly.
1425 1514
1426 \a msg is the error message. 1515 \a msg is the error message.
1427*/ 1516*/
1428void QStyleSheet::error( const QString& ) const 1517void QStyleSheet::error( const QString& ) const
1429{ 1518{
@@ -1431,16 +1520,15 @@ void QStyleSheet::error( const QString& ) const
1431 1520
1432 1521
1433/*! 1522/*!
1434 Scales the font \a font to the appropriate physical point size 1523 Scales the font \a font to the appropriate physical point size
1435 corresponding to the logical font size \a logicalSize. 1524 corresponding to the logical font size \a logicalSize.
1436 1525
1437 When calling this function, \a font has a point size corresponding to 1526 When calling this function, \a font has a point size corresponding
1438 the logical font size 3. 1527 to the logical font size 3.
1439 1528
1440 Logical font sizes range from 1 to 7, with 1 being the smallest. 1529 Logical font sizes range from 1 to 7, with 1 being the smallest.
1441 1530
1442 \sa QStyleSheetItem::logicalFontSize(), 1531 \sa QStyleSheetItem::logicalFontSize(), QStyleSheetItem::logicalFontSizeStep(), QFont::setPointSize()
1443 QStyleSheetItem::logicalFontSizeStep(), QFont::setPointSize()
1444 */ 1532 */
1445void QStyleSheet::scaleFont( QFont& font, int logicalSize ) const 1533void QStyleSheet::scaleFont( QFont& font, int logicalSize ) const
1446{ 1534{
diff --git a/noncore/apps/opie-write/qstylesheet.h b/noncore/apps/opie-write/qstylesheet.h
index bb209fa..cb786f5 100644
--- a/noncore/apps/opie-write/qstylesheet.h
+++ b/noncore/apps/opie-write/qstylesheet.h
@@ -81,13 +81,13 @@ public:
81 81
82 int alignment() const; 82 int alignment() const;
83 void setAlignment( int f); 83 void setAlignment( int f);
84 84
85 enum VerticalAlignment { 85 enum VerticalAlignment {
86 VAlignBaseline, 86 VAlignBaseline,
87 VAlignSub, 87 VAlignSub,
88 VAlignSuper 88 VAlignSuper
89 }; 89 };
90 90
91 VerticalAlignment verticalAlignment() const; 91 VerticalAlignment verticalAlignment() const;
92 void setVerticalAlignment( VerticalAlignment valign ); 92 void setVerticalAlignment( VerticalAlignment valign );
93 93
@@ -120,6 +120,10 @@ public:
120 void setFontUnderline( bool ); 120 void setFontUnderline( bool );
121 bool definesFontUnderline() const; 121 bool definesFontUnderline() const;
122 122
123 bool fontStrikeOut() const;
124 void setFontStrikeOut( bool );
125 bool definesFontStrikeOut() const;
126
123 bool isAnchor() const; 127 bool isAnchor() const;
124 void setAnchor(bool anc); 128 void setAnchor(bool anc);
125 129
@@ -171,10 +175,10 @@ private:
171 175
172#if defined(Q_TEMPLATEDLL) 176#if defined(Q_TEMPLATEDLL)
173// MOC_SKIP_BEGIN 177// MOC_SKIP_BEGIN
174template class Q_EXPORT QDict<QStyleSheetItem>; 178Q_TEMPLATE_EXTERN template class Q_EXPORT QDict<QStyleSheetItem>;
175template class Q_EXPORT QValueList< QPtrVector<QStyleSheetItem> >; 179Q_TEMPLATE_EXTERN template class Q_EXPORT QValueList< QPtrVector<QStyleSheetItem> >;
176template class Q_EXPORT QPtrVector<QStyleSheetItem>; 180Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrVector<QStyleSheetItem>;
177template class Q_EXPORT QValueList<QStyleSheetItem::ListStyle>; 181Q_TEMPLATE_EXTERN template class Q_EXPORT QValueList<QStyleSheetItem::ListStyle>;
178// MOC_SKIP_END 182// MOC_SKIP_END
179#endif 183#endif
180 184
diff --git a/noncore/apps/opie-write/qt3namespace.h b/noncore/apps/opie-write/qt3namespace.h
index 81c5020..557131a 100644
--- a/noncore/apps/opie-write/qt3namespace.h
+++ b/noncore/apps/opie-write/qt3namespace.h
@@ -2,6 +2,7 @@
2#define QT3NAMESPACE_H 2#define QT3NAMESPACE_H
3 3
4#include <qnamespace.h> 4#include <qnamespace.h>
5#include <qstring.h>
5 6
6#define Q_ASSERT ASSERT 7#define Q_ASSERT ASSERT
7#define Q_WS_QWS 8#define Q_WS_QWS
diff --git a/noncore/apps/opie-write/qtextedit.cpp b/noncore/apps/opie-write/qtextedit.cpp
index 9c5ea79..82401c6 100644
--- a/noncore/apps/opie-write/qtextedit.cpp
+++ b/noncore/apps/opie-write/qtextedit.cpp
@@ -66,6 +66,8 @@
66 66
67using namespace Qt3; 67using namespace Qt3;
68 68
69static bool qt_enable_richtext_copy = FALSE;
70
69struct QUndoRedoInfoPrivate 71struct QUndoRedoInfoPrivate
70{ 72{
71 QTextString text; 73 QTextString text;
@@ -77,11 +79,16 @@ class QTextEditPrivate
77{ 79{
78public: 80public:
79 QTextEditPrivate() 81 QTextEditPrivate()
80 :preeditStart(-1),preeditLength(-1),ensureCursorVisibleInShowEvent(FALSE) {} 82 :preeditStart(-1),preeditLength(-1),ensureCursorVisibleInShowEvent(FALSE)
83 {
84 for ( int i=0; i<7; i++ )
85 id[i] = 0;
86 }
81 int id[ 7 ]; 87 int id[ 7 ];
82 int preeditStart; 88 int preeditStart;
83 int preeditLength; 89 int preeditLength;
84 bool ensureCursorVisibleInShowEvent; 90 bool ensureCursorVisibleInShowEvent;
91 QString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized
85}; 92};
86 93
87} 94}
@@ -90,31 +97,88 @@ static bool block_set_alignment = FALSE;
90 97
91/*! 98/*!
92 \class QTextEdit qtextedit.h 99 \class QTextEdit qtextedit.h
93 \brief The QTextEdit widget provides a sophisticated single-page rich text editor. 100 \brief The QTextEdit widget provides a powerful single-page rich text editor.
94 101
95 \ingroup basic 102 \ingroup basic
96 \ingroup text 103 \ingroup text
97 \mainclass 104 \mainclass
98 105
99 QTextEdit is an advanced WYSIWYG editor supporting rich text 106 \tableofcontents
100 formatting. It is optimized to handle large documents and to 107
101 respond quickly to user input. 108 \section1 Introduction and Concepts
109
110 QTextEdit is an advanced WYSIWYG viewer/editor supporting rich
111 text formatting using HTML-style tags. It is optimized to handle
112 large documents and to respond quickly to user input.
113
114 QTextEdit has three modes of operation:
115 \table
116 \header \i Mode \i Command \i Notes
117 \row \i Plain Text Editor \i setTextFormat(PlainText)
118 \i Set text with setText(); text() returns plain text. Text
119 attributes (e.g. colors) can be set, but plain text is always
120 returned.<sup>1.</sup>
121 \row \i Rich Text Editor \i setTextFormat(RichText)
122 \i Set text with setText(); text() returns rich text. Rich
123 text editing is fairly limited. You can't set margins or
124 insert images for example (although you can read and
125 correctly display files that have margins set and that
126 include images). This mode is mostly useful for editing small
127 amounts of rich text. <sup>2.</sup>
128 \row \i Text Viewer<sup>3.</sup> \i setReadOnly(TRUE)
129 \i Set text with setText() or append() (which has no undo
130 history so is faster and uses less memory); text() returns
131 plain or rich text depending on the textFormat(). This mode
132 can correctly display a large subset of HTML tags.
133 \endtable
134
135 <sup>1.</sup><small>We do \e not recommend using QTextEdit to
136 create syntax highlighting editors because the current API is
137 insufficient for this purpose. We hope to release a more complete
138 API that will support syntax highlighting in a later
139 release.</small>
140
141 <sup>2.</sup><small>A more complete API that supports setting
142 margins, images, etc., is planned for a later Qt release.</small>
143
144 <sup>3.</sup><small>Qt 3.1 will provide a Log Viewer mode which is
145 optimised for the fast and memory efficient display of large
146 amounts of read only text.</small>
147
148 We recommend that you always call setTextFormat() to set the mode
149 you want to use. If you use \c AutoText then setText() and
150 append() will try to determine whether the text they are given is
151 plain text or rich text. If you use \c RichText then setText() and
152 append() will assume that the text they are given is rich text.
153 insert() simply inserts the text it is given.
102 154
103 QTextEdit works on paragraphs and characters. A paragraph is a 155 QTextEdit works on paragraphs and characters. A paragraph is a
104 formatted string which is word-wrapped to fit into the width of 156 formatted string which is word-wrapped to fit into the width of
105 the widget. A document consists of zero or more paragraphs, 157 the widget. By default when reading plain text, two newlines
106 indexed from 0. Characters are indexed on a per-paragraph basis, 158 signify a paragraph. A document consists of zero or more
107 also indexed from 0. The words in the paragraph are aligned in 159 paragraphs, indexed from 0. Characters are indexed on a
108 accordance with the paragraph's alignment(). Paragraphs are 160 per-paragraph basis, also indexed from 0. The words in the
109 separated by hard line breaks. Each character within a paragraph 161 paragraph are aligned in accordance with the paragraph's
110 has its own attributes, for example, font and color. 162 alignment(). Paragraphs are separated by hard line breaks. Each
163 character within a paragraph has its own attributes, for example,
164 font and color.
165
166 The text edit documentation uses the following concepts:
167 \list
168 \i \e{current format} --
169 this is the format at the current cursor position, \e and it
170 is the format of the selected text if any.
171 \i \e{current paragraph} -- the paragraph which contains the
172 cursor.
173 \endlist
111 174
112 QTextEdit can display images (using QMimeSourceFactory), lists and 175 QTextEdit can display images (using QMimeSourceFactory), lists and
113 tables. If the text is too large to view within the text edit's 176 tables. If the text is too large to view within the text edit's
114 viewport, scrollbars will appear. The text edit can load both 177 viewport, scrollbars will appear. The text edit can load both
115 plain text and HTML files (a subset of HTML 3.2 and 4). The 178 plain text and HTML files (a subset of HTML 3.2 and 4). The
116 rendering style and the set of valid tags are defined by a 179 rendering style and the set of valid tags are defined by a
117 styleSheet(). Change the style sheet with \l{setStyleSheet()}; see 180 styleSheet(). Custom tags can be created and placed in a custom
181 style sheet. Change the style sheet with \l{setStyleSheet()}; see
118 QStyleSheet for details. The images identified by image tags are 182 QStyleSheet for details. The images identified by image tags are
119 displayed if they can be interpreted using the text edit's 183 displayed if they can be interpreted using the text edit's
120 \l{QMimeSourceFactory}; see setMimeSourceFactory(). 184 \l{QMimeSourceFactory}; see setMimeSourceFactory().
@@ -134,64 +198,29 @@ static bool block_set_alignment = FALSE;
134 you should call setTextFormat(Qt::PlainText) to preserve such 198 you should call setTextFormat(Qt::PlainText) to preserve such
135 text. 199 text.
136 200
137 The text edit documentation uses the following concepts: 201 Note that we do not intend to add a full-featured web browser
138 \list 202 widget to Qt (because that would easily double Qt's size and only
139 \i <i>current format</i> -- 203 a few applications would benefit from it). The rich
140 this is the format at the current cursor position, \e and it 204 text support in Qt is designed to provide a fast, portable and
141 is the format of the selected text if any. 205 efficient way to add reasonable online help facilities to
142 \i <i>current paragraph</i> -- the paragraph which contains the 206 applications, and to provide a basis for rich text editors.
143 cursor. 207 \section1 Using QTextEdit as a Display Widget
144 \endlist 208
209 QTextEdit can display a large HTML subset, including tables and
210 images.
145 211
146 The text is set or replaced using setText() which deletes any 212 The text is set or replaced using setText() which deletes any
147 existing text and replaces it with the text passed in the 213 existing text and replaces it with the text passed in the
148 setText() call. Text can be inserted with insert(), paste() and 214 setText() call. If you call setText() with legacy HTML (with
149 pasteSubType(). Text can also be cut(). The entire text is deleted 215 setTextFormat(RichText) in force), and then call text(), the text
150 with clear() and the selected text is deleted with 216 that is returned may have different markup, but will render the
151 removeSelectedText(). Selected (marked) text can also be deleted 217 same. Text can be inserted with insert(), paste(), pasteSubType()
152 with del() (which will delete the character to the right of the 218 and append(). Text that is appended does not go into the undo
153 cursor if no text is selected). 219 history; this makes append() faster and consumes less memory. Text
154 220 can also be cut(). The entire text is deleted with clear() and the
155 The current format's attributes are set with setItalic(), 221 selected text is deleted with removeSelectedText(). Selected
156 setBold(), setUnderline(), setFamily() (font family), 222 (marked) text can also be deleted with del() (which will delete
157 setPointSize(), setColor() and setCurrentFont(). The current 223 the character to the right of the cursor if no text is selected).
158 paragraph's style is set with setParagType() and its alignment is
159 set with setAlignment().
160
161 Use setSelection() to select text. The setSelectionAttributes()
162 function is used to indicate how selected text should be
163 displayed. Use hasSelectedText() to find out if any text is
164 selected. The currently selected text's position is available
165 using getSelection() and the selected text itself is returned by
166 selectedText(). The selection can be copied to the clipboard with
167 copy(), or cut to the clipboard with cut(). It can be deleted with
168 removeSelectedText(). The entire text can be selected (or
169 unselected) using selectAll(). QTextEdit supports multiple
170 selections. Most of the selection functions operate on the default
171 selection, selection 0. If the user presses a non-selecting key,
172 e.g. a cursor key without also holding down Shift, all selections
173 are cleared.
174
175 Set and get the position of the cursor with setCursorPosition()
176 and getCursorPosition() respectively. When the cursor is moved,
177 the signals currentFontChanged(), currentColorChanged() and
178 currentAlignmentChanged() are emitted to reflect the font, color
179 and alignment at the new cursor position.
180
181 If the text changes, the textChanged() signal is emitted, and if
182 the user inserts a new line by pressing Return or Enter,
183 returnPressed() is emitted. The isModified() function will return
184 TRUE if the text has been modified.
185
186 QTextEdit provides command-based undo and redo. To set the depth
187 of the command history use setUndoDepth() which defaults to 100
188 steps. To undo or redo the last operation call undo() or redo().
189 The signals undoAvailable() and redoAvailable() indicate whether
190 the undo and redo operations can be executed.
191
192 The indent() function is used to reindent a paragraph. It is
193 useful for code editors, for example in <em>Qt Designer</em>'s
194 code editor \e{Ctrl+I} invokes the indent() function.
195 224
196 Loading and saving text is achieved using setText() and text(), 225 Loading and saving text is achieved using setText() and text(),
197 for example: 226 for example:
@@ -243,6 +272,85 @@ static bool block_set_alignment = FALSE;
243 name="anchor">} with scrollToAnchor(). The find() function can be 272 name="anchor">} with scrollToAnchor(). The find() function can be
244 used to find and select a given string within the text. 273 used to find and select a given string within the text.
245 274
275 A read-only QTextEdit provides the same functionality as the
276 (obsolete) QTextView. (QTextView is still supplied for
277 compatibility with old code.)
278
279 \section2 Read-only key bindings
280
281 When QTextEdit is used read-only the key-bindings are limited to
282 navigation, and text may only be selected with the mouse:
283 \table
284 \header \i Keypresses \i Action
285 \row \i \e{UpArrow} \i Move one line up
286 \row \i \e{DownArrow} \i Move one line down
287 \row \i \e{LeftArrow} \i Move one character left
288 \row \i \e{RightArrow} \i Move one character right
289 \row \i \e{PageUp} \i Move one (viewport) page up
290 \row \i \e{PageDown} \i Move one (viewport) page down
291 \row \i \e{Home} \i Move to the beginning of the text
292 \row \i \e{End} \i Move to the end of the text
293 \row \i \e{Shift+Wheel} \i Scroll the page horizontally (the Wheel is the mouse wheel)
294 \row \i \e{Ctrl+Wheel} \i Zoom the text
295 \endtable
296
297 The text edit may be able to provide some meta-information. For
298 example, the documentTitle() function will return the text from
299 within HTML \c{<title>} tags.
300
301 The text displayed in a text edit has a \e context. The context is
302 a path which the text edit's QMimeSourceFactory uses to resolve
303 the locations of files and images. It is passed to the
304 mimeSourceFactory() when quering data. (See QTextEdit() and
305 \l{context()}.)
306
307 \section1 Using QTextEdit as an Editor
308
309 All the information about using QTextEdit as a display widget also
310 applies here.
311
312 The current format's attributes are set with setItalic(),
313 setBold(), setUnderline(), setFamily() (font family),
314 setPointSize(), setColor() and setCurrentFont(). The current
315 paragraph's alignment is set with setAlignment().
316
317 Use setSelection() to select text. The setSelectionAttributes()
318 function is used to indicate how selected text should be
319 displayed. Use hasSelectedText() to find out if any text is
320 selected. The currently selected text's position is available
321 using getSelection() and the selected text itself is returned by
322 selectedText(). The selection can be copied to the clipboard with
323 copy(), or cut to the clipboard with cut(). It can be deleted with
324 removeSelectedText(). The entire text can be selected (or
325 unselected) using selectAll(). QTextEdit supports multiple
326 selections. Most of the selection functions operate on the default
327 selection, selection 0. If the user presses a non-selecting key,
328 e.g. a cursor key without also holding down Shift, all selections
329 are cleared.
330
331 Set and get the position of the cursor with setCursorPosition()
332 and getCursorPosition() respectively. When the cursor is moved,
333 the signals currentFontChanged(), currentColorChanged() and
334 currentAlignmentChanged() are emitted to reflect the font, color
335 and alignment at the new cursor position.
336
337 If the text changes, the textChanged() signal is emitted, and if
338 the user inserts a new line by pressing Return or Enter,
339 returnPressed() is emitted. The isModified() function will return
340 TRUE if the text has been modified.
341
342 QTextEdit provides command-based undo and redo. To set the depth
343 of the command history use setUndoDepth() which defaults to 100
344 steps. To undo or redo the last operation call undo() or redo().
345 The signals undoAvailable() and redoAvailable() indicate whether
346 the undo and redo operations can be executed.
347
348 The indent() function is used to reindent a paragraph. It is
349 useful for code editors, for example in <em>Qt Designer</em>'s
350 code editor \e{Ctrl+I} invokes the indent() function.
351
352 \section2 Editing key bindings
353
246 The list of key-bindings which are implemented for editing: 354 The list of key-bindings which are implemented for editing:
247 \table 355 \table
248 \header \i Keypresses \i Action 356 \header \i Keypresses \i Action
@@ -295,43 +403,6 @@ static bool block_set_alignment = FALSE;
295 can be changed to overwrite, where new text overwrites any text to 403 can be changed to overwrite, where new text overwrites any text to
296 the right of the cursor, using setOverwriteMode(). 404 the right of the cursor, using setOverwriteMode().
297 405
298 QTextEdit can also be used as read-only text viewer. Call
299 setReadOnly( TRUE ) to disable editing. A read-only QTextEdit
300 provides the same functionality as the (obsolete) QTextView.
301 (QTextView is still supplied for compatibility with old code.)
302
303 When QTextEdit is used read-only the key-bindings are limited to
304 navigation, and text may only be selected with the mouse:
305 \table
306 \header \i Keypresses \i Action
307 \row \i \e{UpArrow} \i Move one line up
308 \row \i \e{DownArrow} \i Move one line down
309 \row \i \e{LeftArrow} \i Move one character left
310 \row \i \e{RightArrow} \i Move one character right
311 \row \i \e{PageUp} \i Move one (viewport) page up
312 \row \i \e{PageDown} \i Move one (viewport) page down
313 \row \i \e{Home} \i Move to the beginning of the text
314 \row \i \e{End} \i Move to the end of the text
315 \row \i \e{Shift+Wheel} \i Scroll the page horizontally (the Wheel is the mouse wheel)
316 \row \i \e{Ctrl+Wheel} \i Zoom the text
317 \endtable
318
319 The text edit may be able to provide some meta-information. For
320 example, the documentTitle() function will return the text from
321 within HTML \c{<title>} tags.
322
323 The text displayed in a text edit has a \e context. The context is
324 a path which the text edit's QMimeSourceFactory uses to resolve
325 the locations of files and images. It is passed to the
326 mimeSourceFactory() when quering data. (See QTextEdit() and
327 \l{context()}.)
328
329 Note that we do not intend to add a full-featured web browser
330 widget to Qt (because that would easily double Qt's size and only
331 a few applications would benefit from it). The rich
332 text support in Qt is designed to provide a fast, portable and
333 efficient way to add reasonable online help facilities to
334 applications, and to provide a basis for rich text editors.
335*/ 406*/
336 407
337/*! \enum QTextEdit::KeyboardAction 408/*! \enum QTextEdit::KeyboardAction
@@ -640,13 +711,15 @@ void QTextEdit::init()
640 inDnD = FALSE; 711 inDnD = FALSE;
641 712
642 doc->setFormatter( new QTextFormatterBreakWords ); 713 doc->setFormatter( new QTextFormatterBreakWords );
714 doc->formatCollection()->defaultFormat()->setFont( QScrollView::font() );
715 doc->formatCollection()->defaultFormat()->setColor( colorGroup().color( QColorGroup::Text ) );
643 currentFormat = doc->formatCollection()->defaultFormat(); 716 currentFormat = doc->formatCollection()->defaultFormat();
644 currentAlignment = Qt3::AlignAuto; 717 currentAlignment = Qt3::AlignAuto;
645 718
646 viewport()->setBackgroundMode( PaletteBase ); 719 viewport()->setBackgroundMode( PaletteBase );
647 viewport()->setAcceptDrops( TRUE ); 720 viewport()->setAcceptDrops( TRUE );
648 resizeContents( 0, doc->lastParag() ? 721 resizeContents( 0, doc->lastParagraph() ?
649 ( doc->lastParag()->paragId() + 1 ) * doc->formatCollection()->defaultFormat()->height() : 0 ); 722 ( doc->lastParagraph()->paragId() + 1 ) * doc->formatCollection()->defaultFormat()->height() : 0 );
650 723
651 setKeyCompression( TRUE ); 724 setKeyCompression( TRUE );
652 viewport()->setMouseTracking( TRUE ); 725 viewport()->setMouseTracking( TRUE );
@@ -658,7 +731,7 @@ void QTextEdit::init()
658 formatTimer = new QTimer( this ); 731 formatTimer = new QTimer( this );
659 connect( formatTimer, SIGNAL( timeout() ), 732 connect( formatTimer, SIGNAL( timeout() ),
660 this, SLOT( formatMore() ) ); 733 this, SLOT( formatMore() ) );
661 lastFormatted = doc->firstParag(); 734 lastFormatted = doc->firstParagraph();
662 735
663 scrollTimer = new QTimer( this ); 736 scrollTimer = new QTimer( this );
664 connect( scrollTimer, SIGNAL( timeout() ), 737 connect( scrollTimer, SIGNAL( timeout() ),
@@ -713,10 +786,10 @@ void QTextEdit::paintDocument( bool drawAll, QPainter *p, int cx, int cy, int cw
713 786
714 lastFormatted = doc->draw( p, cx, cy, cw, ch, g, !drawAll, drawCur, cursor ); 787 lastFormatted = doc->draw( p, cx, cy, cw, ch, g, !drawAll, drawCur, cursor );
715 788
716 if ( lastFormatted == doc->lastParag() ) 789 if ( lastFormatted == doc->lastParagraph() )
717 resizeContents( contentsWidth(), doc->height() ); 790 resizeContents( contentsWidth(), doc->height() );
718 791
719 if ( contentsHeight() < visibleHeight() && ( !doc->lastParag() || doc->lastParag()->isValid() ) && drawAll ) 792 if ( contentsHeight() < visibleHeight() && ( !doc->lastParagraph() || doc->lastParagraph()->isValid() ) && drawAll )
720 p->fillRect( 0, contentsHeight(), visibleWidth(), 793 p->fillRect( 0, contentsHeight(), visibleWidth(),
721 visibleHeight() - contentsHeight(), g.brush( QColorGroup::Base ) ); 794 visibleHeight() - contentsHeight(), g.brush( QColorGroup::Base ) );
722} 795}
@@ -813,10 +886,16 @@ bool QTextEdit::event( QEvent *e )
813 } 886 }
814 } 887 }
815 888
816 if ( e->type() == QEvent::Show && d->ensureCursorVisibleInShowEvent ) { 889 if ( e->type() == QEvent::Show ) {
817 sync(); 890 if ( d->ensureCursorVisibleInShowEvent ) {
818 ensureCursorVisible(); 891 sync();
819 d->ensureCursorVisibleInShowEvent = FALSE; 892 ensureCursorVisible();
893 d->ensureCursorVisibleInShowEvent = FALSE;
894 }
895 if ( !d->scrollToAnchor.isEmpty() ) {
896 scrollToAnchor( d->scrollToAnchor );
897 d->scrollToAnchor = QString::null;
898 }
820 } 899 }
821 return QWidget::event( e ); 900 return QWidget::event( e );
822} 901}
@@ -845,7 +924,7 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
845 selChanged = doc->removeSelection( i ) || selChanged; 924 selChanged = doc->removeSelection( i ) || selChanged;
846 925
847 if ( selChanged ) { 926 if ( selChanged ) {
848 cursor->parag()->document()->nextDoubleBuffered = TRUE; 927 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
849 repaintChanged(); 928 repaintChanged();
850 } 929 }
851 930
@@ -858,7 +937,7 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
858 // a bit hacky, but can't change this without introducing new enum values for move and keeping the 937 // a bit hacky, but can't change this without introducing new enum values for move and keeping the
859 // correct semantics and movement for BiDi and non BiDi text. 938 // correct semantics and movement for BiDi and non BiDi text.
860 CursorAction a; 939 CursorAction a;
861 if ( cursor->parag()->string()->isRightToLeft() == (e->key() == Key_Right) ) 940 if ( cursor->paragraph()->string()->isRightToLeft() == (e->key() == Key_Right) )
862 a = e->state() & ControlButton ? MoveWordBackward : MoveBackward; 941 a = e->state() & ControlButton ? MoveWordBackward : MoveBackward;
863 else 942 else
864 a = e->state() & ControlButton ? MoveWordForward : MoveForward; 943 a = e->state() & ControlButton ? MoveWordForward : MoveForward;
@@ -886,12 +965,17 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
886 case Key_Return: case Key_Enter: 965 case Key_Return: case Key_Enter:
887 if ( doc->hasSelection( QTextDocument::Standard, FALSE ) ) 966 if ( doc->hasSelection( QTextDocument::Standard, FALSE ) )
888 removeSelectedText(); 967 removeSelectedText();
968 if ( textFormat() == Qt::RichText && ( e->state() & ControlButton ) ) {
969 // Ctrl-Enter inserts a line break in rich text mode
970 insert( QString( QChar( 0x2028) ), TRUE, FALSE, TRUE );
971 } else {
889#ifndef QT_NO_CURSOR 972#ifndef QT_NO_CURSOR
890 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 973 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
891#endif 974#endif
892 clearUndoRedoInfo = FALSE; 975 clearUndoRedoInfo = FALSE;
893 doKeyboardAction( ActionReturn ); 976 doKeyboardAction( ActionReturn );
894 emit returnPressed(); 977 emit returnPressed();
978 }
895 break; 979 break;
896 case Key_Delete: 980 case Key_Delete:
897#if defined (Q_WS_WIN) 981#if defined (Q_WS_WIN)
@@ -911,6 +995,10 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
911 case Key_Insert: 995 case Key_Insert:
912 if ( e->state() & ShiftButton ) 996 if ( e->state() & ShiftButton )
913 paste(); 997 paste();
998#if defined (Q_WS_WIN)
999 else if ( e->state() & ControlButton )
1000 copy();
1001#endif
914 break; 1002 break;
915 case Key_Backspace: 1003 case Key_Backspace:
916 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) { 1004 if ( doc->hasSelection( QTextDocument::Standard, TRUE ) ) {
@@ -918,10 +1006,6 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
918 break; 1006 break;
919 } 1007 }
920 1008
921 if ( !cursor->parag()->prev() &&
922 cursor->atParagStart() )
923 break;
924
925 doKeyboardAction( ActionBackspace ); 1009 doKeyboardAction( ActionBackspace );
926 clearUndoRedoInfo = FALSE; 1010 clearUndoRedoInfo = FALSE;
927 1011
@@ -943,41 +1027,50 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
943 ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) { 1027 ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) {
944 clearUndoRedoInfo = FALSE; 1028 clearUndoRedoInfo = FALSE;
945 if ( e->key() == Key_Tab ) { 1029 if ( e->key() == Key_Tab ) {
946 if ( textFormat() == Qt::RichText && 1030 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() ) {
947 cursor->index() == 0 && cursor->parag()->style() && 1031 clearUndoRedo();
948 cursor->parag()->style()->displayMode() == 1032 undoRedoInfo.type = UndoRedoInfo::Style;
949 QStyleSheetItem::DisplayListItem ) { 1033 undoRedoInfo.id = cursor->paragraph()->paragId();
950 cursor->parag()->incDepth(); 1034 undoRedoInfo.eid = undoRedoInfo.id;
1035 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
1036 cursor->paragraph()->setListDepth( cursor->paragraph()->listDepth() +1 );
1037 clearUndoRedo();
951 drawCursor( FALSE ); 1038 drawCursor( FALSE );
952 repaintChanged(); 1039 repaintChanged();
953 drawCursor( TRUE ); 1040 drawCursor( TRUE );
954 break; 1041 break;
955 } 1042 }
956 } 1043 }
957 if ( textFormat() == Qt::RichText && ( !cursor->parag()->style() || 1044
958 cursor->parag()->style()->displayMode() == QStyleSheetItem::DisplayBlock ) && 1045 if ( textFormat() == Qt::RichText && !cursor->paragraph()->isListItem() ) {
959 cursor->index() == 0 && ( e->text()[0] == '-' || e->text()[0] == '*' ) ) { 1046 if ( cursor->index() == 0 && ( e->text()[0] == '-' || e->text()[0] == '*' ) ) {
960 setParagType( QStyleSheetItem::DisplayListItem, QStyleSheetItem::ListDisc ); 1047 clearUndoRedo();
961 cursor->parag()->incDepth(); 1048 undoRedoInfo.type = UndoRedoInfo::Style;
962 drawCursor( FALSE ); 1049 undoRedoInfo.id = cursor->paragraph()->paragId();
963 repaintChanged(); 1050 undoRedoInfo.eid = undoRedoInfo.id;
964 drawCursor( TRUE ); 1051 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
965 } else { 1052 setParagType( QStyleSheetItem::DisplayListItem, QStyleSheetItem::ListDisc );
966 if ( overWrite && !cursor->atParagEnd() ) 1053 clearUndoRedo();
967 cursor->remove(); 1054 drawCursor( FALSE );
968 QString t = e->text(); 1055 repaintChanged();
969 QTextParag *p = cursor->parag(); 1056 drawCursor( TRUE );
970 if ( p && p->string() && p->string()->isRightToLeft() ) { 1057 break;
971 QChar *c = (QChar *)t.unicode(); 1058 }
972 int l = t.length(); 1059 }
973 while( l-- ) { 1060 if ( overWrite && !cursor->atParagEnd() )
974 if ( c->mirrored() ) 1061 cursor->remove();
975 *c = c->mirroredChar(); 1062 QString t = e->text();
976 c++; 1063 QTextParagraph *p = cursor->paragraph();
977 } 1064 if ( p && p->string() && p->string()->isRightToLeft() ) {
1065 QChar *c = (QChar *)t.unicode();
1066 int l = t.length();
1067 while( l-- ) {
1068 if ( c->mirrored() )
1069 *c = c->mirroredChar();
1070 c++;
978 } 1071 }
979 insert( t, TRUE, FALSE, TRUE );
980 } 1072 }
1073 insert( t, TRUE, FALSE, TRUE );
981 break; 1074 break;
982 } else if ( e->state() & ControlButton ) { 1075 } else if ( e->state() & ControlButton ) {
983 switch ( e->key() ) { 1076 switch ( e->key() ) {
@@ -1019,7 +1112,7 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
1019 removeSelectedText(); 1112 removeSelectedText();
1020 break; 1113 break;
1021 } 1114 }
1022 if ( !cursor->parag()->prev() && 1115 if ( !cursor->paragraph()->prev() &&
1023 cursor->atParagStart() ) 1116 cursor->atParagStart() )
1024 break; 1117 break;
1025 1118
@@ -1036,7 +1129,10 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
1036 moveCursor( MoveUp, e->state() & ShiftButton ); 1129 moveCursor( MoveUp, e->state() & ShiftButton );
1037 break; 1130 break;
1038 case Key_Z: 1131 case Key_Z:
1039 undo(); 1132 if(e->state() & ShiftButton)
1133 redo();
1134 else
1135 undo();
1040 break; 1136 break;
1041 case Key_Y: 1137 case Key_Y:
1042 redo(); 1138 redo();
@@ -1063,7 +1159,7 @@ void QTextEdit::keyPressEvent( QKeyEvent *e )
1063 } 1159 }
1064 1160
1065 emit cursorPositionChanged( cursor ); 1161 emit cursorPositionChanged( cursor );
1066 emit cursorPositionChanged( cursor->parag()->paragId(), cursor->index() ); 1162 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
1067 if ( clearUndoRedoInfo ) 1163 if ( clearUndoRedoInfo )
1068 clearUndoRedo(); 1164 clearUndoRedo();
1069 changeIntervalTimer->start( 100, TRUE ); 1165 changeIntervalTimer->start( 100, TRUE );
@@ -1084,187 +1180,137 @@ void QTextEdit::doKeyboardAction( KeyboardAction action )
1084 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough 1180 if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough
1085 return; 1181 return;
1086 1182
1087 lastFormatted = cursor->parag(); 1183 lastFormatted = cursor->paragraph();
1088 drawCursor( FALSE ); 1184 drawCursor( FALSE );
1089 bool doUpdateCurrentFormat = TRUE; 1185 bool doUpdateCurrentFormat = TRUE;
1090 1186
1091 switch ( action ) { 1187 switch ( action ) {
1092 case ActionDelete: { 1188 case ActionDelete:
1093 checkUndoRedoInfo( UndoRedoInfo::Delete ); 1189 if ( !cursor->atParagEnd() ) {
1094 if ( !undoRedoInfo.valid() ) { 1190 checkUndoRedoInfo( UndoRedoInfo::Delete );
1095 undoRedoInfo.id = cursor->parag()->paragId(); 1191 if ( !undoRedoInfo.valid() ) {
1096 undoRedoInfo.index = cursor->index(); 1192 undoRedoInfo.id = cursor->paragraph()->paragId();
1097 undoRedoInfo.d->text = QString::null; 1193 undoRedoInfo.index = cursor->index();
1098 } 1194 undoRedoInfo.d->text = QString::null;
1099 undoRedoInfo.d->text += cursor->parag()->at( cursor->index() )->c; 1195 }
1100 if ( cursor->parag()->at( cursor->index() )->format() ) { 1196 undoRedoInfo.d->text.insert( undoRedoInfo.d->text.length(), cursor->paragraph()->at( cursor->index() ), TRUE );
1101 cursor->parag()->at( cursor->index() )->format()->addRef(); 1197 cursor->remove();
1102 undoRedoInfo.d->text.at( undoRedoInfo.d->text.length() - 1 ).setFormat( cursor->parag()->at( cursor->index() )->format() ); 1198 } else {
1103 } 1199 clearUndoRedo();
1104 QTextParag *old = cursor->parag(); 1200 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1105 if ( cursor->remove() ) { 1201 cursor->gotoNextLetter();
1106 if ( old != cursor->parag() && lastFormatted == old ) 1202 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1107 lastFormatted = cursor->parag() ? cursor->parag()->prev() : 0; 1203 removeSelectedText( QTextDocument::Temp );
1108 undoRedoInfo.d->text += "\n";
1109 } 1204 }
1110 } break; 1205 break;
1111 case ActionBackspace: 1206 case ActionBackspace:
1112 if ( textFormat() == Qt::RichText && 1207 if ( textFormat() == Qt::RichText && cursor->paragraph()->isListItem() && cursor->index() == 0 ) {
1113 cursor->parag()->style() && 1208 clearUndoRedo();
1114 cursor->parag()->style()->displayMode() == QStyleSheetItem::DisplayListItem && 1209 undoRedoInfo.type = UndoRedoInfo::Style;
1115 cursor->index() == 0 ) { 1210 undoRedoInfo.id = cursor->paragraph()->paragId();
1116 cursor->parag()->decDepth(); 1211 undoRedoInfo.eid = undoRedoInfo.id;
1117 lastFormatted = cursor->parag(); 1212 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
1213 int ldepth = cursor->paragraph()->listDepth();
1214 ldepth = QMAX( ldepth-1, 0 );
1215 cursor->paragraph()->setListDepth( ldepth );
1216 if ( ldepth == 0 )
1217 cursor->paragraph()->setListItem( FALSE );
1218 clearUndoRedo();
1219 lastFormatted = cursor->paragraph();
1118 repaintChanged(); 1220 repaintChanged();
1119 drawCursor( TRUE ); 1221 drawCursor( TRUE );
1120 return; 1222 return;
1121 } 1223 }
1122 checkUndoRedoInfo( UndoRedoInfo::Delete ); 1224 if ( !cursor->atParagStart() ) {
1123 if ( !undoRedoInfo.valid() ) { 1225 checkUndoRedoInfo( UndoRedoInfo::Delete );
1124 undoRedoInfo.id = cursor->parag()->paragId(); 1226 if ( !undoRedoInfo.valid() ) {
1125 undoRedoInfo.index = cursor->index(); 1227 undoRedoInfo.id = cursor->paragraph()->paragId();
1126 undoRedoInfo.d->text = QString::null; 1228 undoRedoInfo.index = cursor->index();
1127 } 1229 undoRedoInfo.d->text = QString::null;
1128 cursor->gotoPreviousLetter(); 1230 }
1129 undoRedoInfo.d->text.prepend( QString( cursor->parag()->at( cursor->index() )->c ) ); 1231 cursor->gotoPreviousLetter();
1130 if ( cursor->parag()->at( cursor->index() )->format() ) { 1232 undoRedoInfo.d->text.insert( 0, cursor->paragraph()->at( cursor->index() ), TRUE );
1131 cursor->parag()->at( cursor->index() )->format()->addRef();
1132 undoRedoInfo.d->text.at( 0 ).setFormat( cursor->parag()->at( cursor->index() )->format() );
1133 }
1134 undoRedoInfo.index = cursor->index();
1135 if ( cursor->remove() ) {
1136 undoRedoInfo.d->text.remove( 0, 1 );
1137 undoRedoInfo.d->text.prepend( "\n" );
1138 undoRedoInfo.index = cursor->index(); 1233 undoRedoInfo.index = cursor->index();
1139 undoRedoInfo.id = cursor->parag()->paragId(); 1234 cursor->remove();
1235 lastFormatted = cursor->paragraph();
1236 } else if ( cursor->paragraph()->prev() ){
1237 clearUndoRedo();
1238 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1239 cursor->gotoPreviousLetter();
1240 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1241 removeSelectedText( QTextDocument::Temp );
1140 } 1242 }
1141 lastFormatted = cursor->parag();
1142 break; 1243 break;
1143 case ActionReturn: { 1244 case ActionReturn:
1144 checkUndoRedoInfo( UndoRedoInfo::Return ); 1245 checkUndoRedoInfo( UndoRedoInfo::Return );
1145 if ( !undoRedoInfo.valid() ) { 1246 if ( !undoRedoInfo.valid() ) {
1146 undoRedoInfo.id = cursor->parag()->paragId(); 1247 undoRedoInfo.id = cursor->paragraph()->paragId();
1147 undoRedoInfo.index = cursor->index(); 1248 undoRedoInfo.index = cursor->index();
1148 undoRedoInfo.d->text = QString::null; 1249 undoRedoInfo.d->text = QString::null;
1149 } 1250 }
1150 undoRedoInfo.d->text += "\n"; 1251 undoRedoInfo.d->text += "\n";
1151 cursor->splitAndInsertEmptyParag(); 1252 cursor->splitAndInsertEmptyParagraph();
1152 if ( cursor->parag()->prev() ) { 1253 if ( cursor->paragraph()->prev() ) {
1153 lastFormatted = cursor->parag()->prev(); 1254 lastFormatted = cursor->paragraph()->prev();
1154 lastFormatted->invalidate( 0 ); 1255 lastFormatted->invalidate( 0 );
1155 } 1256 }
1156 doUpdateCurrentFormat = FALSE; 1257 doUpdateCurrentFormat = FALSE;
1157 } break;
1158 case ActionKill:
1159 checkUndoRedoInfo( UndoRedoInfo::Delete );
1160 if ( !undoRedoInfo.valid() ) {
1161 undoRedoInfo.id = cursor->parag()->paragId();
1162 undoRedoInfo.index = cursor->index();
1163 undoRedoInfo.d->text = QString::null;
1164 }
1165 if ( cursor->atParagEnd() ) {
1166 undoRedoInfo.d->text += cursor->parag()->at( cursor->index() )->c;
1167 if ( cursor->parag()->at( cursor->index() )->format() ) {
1168 cursor->parag()->at( cursor->index() )->format()->addRef();
1169 undoRedoInfo.d->text.at( undoRedoInfo.d->text.length() - 1 ).setFormat( cursor->parag()->at( cursor->index() )->format() );
1170 }
1171 QTextParag *old = cursor->parag();
1172 if ( cursor->remove() ) {
1173 if ( old != cursor->parag() && lastFormatted == old )
1174 lastFormatted = cursor->parag() ? cursor->parag()->prev() : 0;
1175 undoRedoInfo.d->text += "\n";
1176 }
1177 } else {
1178 int oldLen = undoRedoInfo.d->text.length();
1179 undoRedoInfo.d->text += cursor->parag()->string()->toString().mid( cursor->index() );
1180 for ( int i = cursor->index(); i < cursor->parag()->length(); ++i ) {
1181 if ( cursor->parag()->at( i )->format() ) {
1182 cursor->parag()->at( i )->format()->addRef();
1183 undoRedoInfo.d->text.at( oldLen + i - cursor->index() ).setFormat( cursor->parag()->at( i )->format() );
1184 }
1185 }
1186 undoRedoInfo.d->text.remove( undoRedoInfo.d->text.length() - 1, 1 );
1187 cursor->killLine();
1188 }
1189 break; 1258 break;
1259 case ActionKill:
1260 clearUndoRedo();
1261 doc->setSelectionStart( QTextDocument::Temp, *cursor );
1262 if ( cursor->atParagEnd() )
1263 cursor->gotoNextLetter();
1264 else
1265 cursor->setIndex( cursor->paragraph()->length() - 1 );
1266 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
1267 removeSelectedText( QTextDocument::Temp );
1268 break;
1190 } 1269 }
1191 1270
1192 formatMore(); 1271 formatMore();
1193 repaintChanged(); 1272 repaintChanged();
1194 ensureCursorVisible(); 1273 ensureCursorVisible();
1195 drawCursor( TRUE ); 1274 drawCursor( TRUE );
1196 1275 updateMicroFocusHint();
1197 if ( hasFocus() || viewport()->hasFocus() ) {
1198 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
1199 if ( !readonly ) {
1200 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
1201 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
1202 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1203 }
1204 }
1205
1206 if ( doUpdateCurrentFormat ) 1276 if ( doUpdateCurrentFormat )
1207 updateCurrentFormat(); 1277 updateCurrentFormat();
1208 setModified(); 1278 setModified();
1209 emit textChanged(); 1279 emit textChanged();
1210} 1280}
1211 1281
1212void QTextEdit::readFormats( QTextCursor &c1, QTextCursor &c2, int oldLen, QTextString &text, bool fillStyles ) 1282void QTextEdit::readFormats( QTextCursor &c1, QTextCursor &c2, QTextString &text, bool fillStyles )
1213{ 1283{
1284 QDataStream styleStream( undoRedoInfo.styleInformation, IO_WriteOnly );
1214 c2.restoreState(); 1285 c2.restoreState();
1215 c1.restoreState(); 1286 c1.restoreState();
1216 if ( c1.parag() == c2.parag() ) { 1287 int lastIndex = text.length();
1217 for ( int i = c1.index(); i < c2.index(); ++i ) { 1288 if ( c1.paragraph() == c2.paragraph() ) {
1218 if ( c1.parag()->at( i )->format() ) { 1289 for ( int i = c1.index(); i < c2.index(); ++i )
1219 c1.parag()->at( i )->format()->addRef(); 1290 text.insert( lastIndex + i - c1.index(), c1.paragraph()->at( i ), TRUE );
1220 text.at( oldLen + i - c1.index() ).setFormat( c1.parag()->at( i )->format() );
1221 }
1222 }
1223 if ( fillStyles ) { 1291 if ( fillStyles ) {
1224 undoRedoInfo.oldAligns[ 0 ] = c1.parag()->alignment(); 1292 styleStream << (int) 1;
1225 undoRedoInfo.oldStyles << c1.parag()->styleSheetItems(); 1293 c1.paragraph()->writeStyleInformation( styleStream );
1226 undoRedoInfo.oldListStyles << c1.parag()->listStyle();
1227 } 1294 }
1228 } else { 1295 } else {
1229 int lastIndex = oldLen;
1230 int i; 1296 int i;
1231 for ( i = c1.index(); i < c1.parag()->length(); ++i ) { 1297 for ( i = c1.index(); i < c1.paragraph()->length()-1; ++i )
1232 if ( c1.parag()->at( i )->format() ) { 1298 text.insert( lastIndex++, c1.paragraph()->at( i ), TRUE );
1233 c1.parag()->at( i )->format()->addRef(); 1299 int num = 2; // start and end, being different
1234 text.at( lastIndex ).setFormat( c1.parag()->at( i )->format() ); 1300 text += "\n"; lastIndex++;
1235 lastIndex++; 1301 QTextParagraph *p = c1.paragraph()->next();
1236 } 1302 while ( p && p != c2.paragraph() ) {
1237 } 1303 for ( i = 0; i < p->length()-1; ++i )
1238 QTextParag *p = c1.parag()->next(); 1304 text.insert( lastIndex++ , p->at( i ), TRUE );
1239 while ( p && p != c2.parag() ) { 1305 text += "\n"; num++; lastIndex++;
1240 for ( int i = 0; i < p->length(); ++i ) {
1241 if ( p->at( i )->format() ) {
1242 p->at( i )->format()->addRef();
1243 text.at( i + lastIndex ).setFormat( p->at( i )->format() );
1244 }
1245 }
1246 lastIndex += p->length();
1247 p = p->next(); 1306 p = p->next();
1248 } 1307 }
1249 for ( i = 0; i < c2.index(); ++i ) { 1308 for ( i = 0; i < c2.index(); ++i )
1250 if ( c2.parag()->at( i )->format() ) { 1309 text.insert( i + lastIndex, c2.paragraph()->at( i ), TRUE );
1251 c2.parag()->at( i )->format()->addRef();
1252 text.at( i + lastIndex ).setFormat( c2.parag()->at( i )->format() );
1253 }
1254 }
1255 if ( fillStyles ) { 1310 if ( fillStyles ) {
1256 QTextParag *p = c1.parag(); 1311 styleStream << num;
1257 i = 0; 1312 for ( QTextParagraph *p = c1.paragraph(); --num >= 0; p = p->next() )
1258 while ( p ) { 1313 p->writeStyleInformation( styleStream );
1259 if ( i < (int)undoRedoInfo.oldAligns.size() )
1260 undoRedoInfo.oldAligns[ i ] = p->alignment();
1261 undoRedoInfo.oldStyles << p->styleSheetItems();
1262 undoRedoInfo.oldListStyles << p->listStyle();
1263 if ( p == c2.parag() )
1264 break;
1265 p = p->next();
1266 ++i;
1267 }
1268 } 1314 }
1269 } 1315 }
1270} 1316}
@@ -1294,9 +1340,11 @@ void QTextEdit::removeSelectedText( int selNum )
1294 return; 1340 return;
1295 1341
1296 QTextCursor c1 = doc->selectionStartCursor( selNum ); 1342 QTextCursor c1 = doc->selectionStartCursor( selNum );
1343 c1.restoreState();
1297 QTextCursor c2 = doc->selectionEndCursor( selNum ); 1344 QTextCursor c2 = doc->selectionEndCursor( selNum );
1345 c2.restoreState();
1298 1346
1299 // ### no support for editing tables yet 1347 // ### no support for editing tables yet, plus security for broken selections
1300 if ( c1.nestedDepth() || c2.nestedDepth() ) 1348 if ( c1.nestedDepth() || c2.nestedDepth() )
1301 return; 1349 return;
1302 1350
@@ -1312,14 +1360,13 @@ void QTextEdit::removeSelectedText( int selNum )
1312 doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index ); 1360 doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index );
1313 undoRedoInfo.d->text = QString::null; 1361 undoRedoInfo.d->text = QString::null;
1314 } 1362 }
1315 int oldLen = undoRedoInfo.d->text.length(); 1363 readFormats( c1, c2, undoRedoInfo.d->text, TRUE );
1316 undoRedoInfo.d->text = doc->selectedText( selNum, FALSE ); 1364
1317 undoRedoInfo.oldAligns.resize( undoRedoInfo.oldAligns.size() + QMAX( 0, c2.parag()->paragId() - c1.parag()->paragId() + 1 ) ); 1365
1318 readFormats( c1, c2, oldLen, undoRedoInfo.d->text, TRUE );
1319 doc->removeSelectedText( selNum, cursor ); 1366 doc->removeSelectedText( selNum, cursor );
1320 if ( cursor->isValid() ) { 1367 if ( cursor->isValid() ) {
1321 ensureCursorVisible(); 1368 ensureCursorVisible();
1322 lastFormatted = cursor->parag(); 1369 lastFormatted = cursor->paragraph();
1323 formatMore(); 1370 formatMore();
1324 repaintChanged(); 1371 repaintChanged();
1325 ensureCursorVisible(); 1372 ensureCursorVisible();
@@ -1334,18 +1381,10 @@ void QTextEdit::removeSelectedText( int selNum )
1334#ifndef QT_NO_CURSOR 1381#ifndef QT_NO_CURSOR
1335 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 1382 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
1336#endif 1383#endif
1337 if ( hasFocus() || viewport()->hasFocus() ) { 1384 updateMicroFocusHint();
1338 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
1339 if ( !readonly ) {
1340 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
1341 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
1342 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1343 }
1344 }
1345 } else { 1385 } else {
1346 cursor->setDocument( doc ); 1386 delete cursor;
1347 cursor->setParag( doc->firstParag() ); 1387 cursor = new QTextCursor( doc );
1348 cursor->setIndex( 0 );
1349 drawCursor( TRUE ); 1388 drawCursor( TRUE );
1350 viewport()->repaint( TRUE ); 1389 viewport()->repaint( TRUE );
1351 } 1390 }
@@ -1365,10 +1404,10 @@ void QTextEdit::moveCursor( CursorAction action, bool select )
1365 drawCursor( FALSE ); 1404 drawCursor( FALSE );
1366 if ( select ) { 1405 if ( select ) {
1367 if ( !doc->hasSelection( QTextDocument::Standard ) ) 1406 if ( !doc->hasSelection( QTextDocument::Standard ) )
1368 doc->setSelectionStart( QTextDocument::Standard, cursor ); 1407 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1369 moveCursor( action ); 1408 moveCursor( action );
1370 if ( doc->setSelectionEnd( QTextDocument::Standard, cursor ) ) { 1409 if ( doc->setSelectionEnd( QTextDocument::Standard, *cursor ) ) {
1371 cursor->parag()->document()->nextDoubleBuffered = TRUE; 1410 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1372 repaintChanged(); 1411 repaintChanged();
1373 } else { 1412 } else {
1374 drawCursor( TRUE ); 1413 drawCursor( TRUE );
@@ -1383,7 +1422,7 @@ void QTextEdit::moveCursor( CursorAction action, bool select )
1383 ensureCursorVisible(); 1422 ensureCursorVisible();
1384 drawCursor( TRUE ); 1423 drawCursor( TRUE );
1385 } else { 1424 } else {
1386 cursor->parag()->document()->nextDoubleBuffered = TRUE; 1425 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1387 repaintChanged(); 1426 repaintChanged();
1388 ensureCursorVisible(); 1427 ensureCursorVisible();
1389 drawCursor( TRUE ); 1428 drawCursor( TRUE );
@@ -1399,14 +1438,7 @@ void QTextEdit::moveCursor( CursorAction action, bool select )
1399 1438
1400 drawCursor( TRUE ); 1439 drawCursor( TRUE );
1401 updateCurrentFormat(); 1440 updateCurrentFormat();
1402 if ( hasFocus() || viewport()->hasFocus() ) { 1441 updateMicroFocusHint();
1403 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
1404 if ( !readonly ) {
1405 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
1406 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
1407 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1408 }
1409 }
1410} 1442}
1411 1443
1412/*! \overload 1444/*! \overload
@@ -1449,19 +1481,11 @@ void QTextEdit::moveCursor( CursorAction action )
1449 cursor->gotoLineEnd(); 1481 cursor->gotoLineEnd();
1450 break; 1482 break;
1451 case MoveEnd: 1483 case MoveEnd:
1452 ensureFormatted( doc->lastParag() ); 1484 ensureFormatted( doc->lastParagraph() );
1453 cursor->gotoEnd(); 1485 cursor->gotoEnd();
1454 break; 1486 break;
1455 } 1487 }
1456 1488 updateMicroFocusHint();
1457 if ( hasFocus() || viewport()->hasFocus() ) {
1458 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
1459 if ( !readonly ) {
1460 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
1461 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
1462 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1463 }
1464 }
1465 updateCurrentFormat(); 1489 updateCurrentFormat();
1466} 1490}
1467 1491
@@ -1470,6 +1494,8 @@ void QTextEdit::moveCursor( CursorAction action )
1470void QTextEdit::resizeEvent( QResizeEvent *e ) 1494void QTextEdit::resizeEvent( QResizeEvent *e )
1471{ 1495{
1472 QScrollView::resizeEvent( e ); 1496 QScrollView::resizeEvent( e );
1497 if ( doc->visibleWidth() == 0 )
1498 doResize();
1473} 1499}
1474 1500
1475/*! \reimp */ 1501/*! \reimp */
@@ -1477,12 +1503,15 @@ void QTextEdit::resizeEvent( QResizeEvent *e )
1477void QTextEdit::viewportResizeEvent( QResizeEvent *e ) 1503void QTextEdit::viewportResizeEvent( QResizeEvent *e )
1478{ 1504{
1479 QScrollView::viewportResizeEvent( e ); 1505 QScrollView::viewportResizeEvent( e );
1480 if ( e->oldSize().width() != e->size().width() ) 1506 if ( e->oldSize().width() != e->size().width() ) {
1507 bool stayAtBottom = e->oldSize().height() != e->size().height() &&
1508 contentsY() > 0 && contentsY() >= doc->height() - e->oldSize().height();
1481 doResize(); 1509 doResize();
1510 if ( stayAtBottom )
1511 scrollToBottom();
1512 }
1482} 1513}
1483 1514
1484static bool blockEnsureCursorVisible = FALSE;
1485
1486/*! 1515/*!
1487 Ensures that the cursor is visible by scrolling the text edit if 1516 Ensures that the cursor is visible by scrolling the text edit if
1488 necessary. 1517 necessary.
@@ -1492,20 +1521,18 @@ static bool blockEnsureCursorVisible = FALSE;
1492 1521
1493void QTextEdit::ensureCursorVisible() 1522void QTextEdit::ensureCursorVisible()
1494{ 1523{
1495 if ( blockEnsureCursorVisible )
1496 return;
1497 if ( !isVisible() ) { 1524 if ( !isVisible() ) {
1498 d->ensureCursorVisibleInShowEvent = TRUE; 1525 d->ensureCursorVisibleInShowEvent = TRUE;
1499 return; 1526 return;
1500 } 1527 }
1501 lastFormatted = cursor->parag(); 1528 lastFormatted = cursor->paragraph();
1502 formatMore(); 1529 formatMore();
1503 QTextStringChar *chr = cursor->parag()->at( cursor->index() ); 1530 QTextStringChar *chr = cursor->paragraph()->at( cursor->index() );
1504 int h = cursor->parag()->lineHeightOfChar( cursor->index() ); 1531 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
1505 int x = cursor->parag()->rect().x() + chr->x + cursor->offsetX(); 1532 int x = cursor->paragraph()->rect().x() + chr->x + cursor->offsetX();
1506 int y = 0; int dummy; 1533 int y = 0; int dummy;
1507 cursor->parag()->lineHeightOfChar( cursor->index(), &dummy, &y ); 1534 cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y );
1508 y += cursor->parag()->rect().y() + cursor->offsetY(); 1535 y += cursor->paragraph()->rect().y() + cursor->offsetY();
1509 int w = 1; 1536 int w = 1;
1510 ensureVisible( x, y + h / 2, w, h / 2 + 2 ); 1537 ensureVisible( x, y + h / 2, w, h / 2 + 2 );
1511} 1538}
@@ -1517,38 +1544,38 @@ void QTextEdit::drawCursor( bool visible )
1517{ 1544{
1518 if ( !isUpdatesEnabled() || 1545 if ( !isUpdatesEnabled() ||
1519 !viewport()->isUpdatesEnabled() || 1546 !viewport()->isUpdatesEnabled() ||
1520 !cursor->parag() || 1547 !cursor->paragraph() ||
1521 !cursor->parag()->isValid() || 1548 !cursor->paragraph()->isValid() ||
1522 !selectedText().isEmpty() || 1549 !selectedText().isEmpty() ||
1523 ( visible && !hasFocus() && !viewport()->hasFocus() && !inDnD ) || 1550 ( visible && !hasFocus() && !viewport()->hasFocus() && !inDnD ) ||
1524 isReadOnly() ) 1551 isReadOnly() )
1525 return; 1552 return;
1526 1553
1527 QPainter p( viewport() ); 1554 QPainter p( viewport() );
1528 QRect r( cursor->topParag()->rect() ); 1555 QRect r( cursor->topParagraph()->rect() );
1529 cursor->parag()->setChanged( TRUE ); 1556 cursor->paragraph()->setChanged( TRUE );
1530 p.translate( -contentsX() + cursor->totalOffsetX(), -contentsY() + cursor->totalOffsetY() ); 1557 p.translate( -contentsX() + cursor->totalOffsetX(), -contentsY() + cursor->totalOffsetY() );
1531 QPixmap *pix = 0; 1558 QPixmap *pix = 0;
1532 QColorGroup cg( colorGroup() ); 1559 QColorGroup cg( colorGroup() );
1533 if ( cursor->parag()->background() ) 1560 if ( cursor->paragraph()->background() )
1534 cg.setBrush( QColorGroup::Base, *cursor->parag()->background() ); 1561 cg.setBrush( QColorGroup::Base, *cursor->paragraph()->background() );
1535 else if ( doc->paper() ) 1562 else if ( doc->paper() )
1536 cg.setBrush( QColorGroup::Base, *doc->paper() ); 1563 cg.setBrush( QColorGroup::Base, *doc->paper() );
1537 p.setBrushOrigin( -contentsX(), -contentsY() ); 1564 p.setBrushOrigin( -contentsX(), -contentsY() );
1538 cursor->parag()->document()->nextDoubleBuffered = TRUE; 1565 cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
1539 if ( !cursor->nestedDepth() ) { 1566 if ( !cursor->nestedDepth() ) {
1540 int h = cursor->parag()->lineHeightOfChar( cursor->index() ); 1567 int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
1541 int dist = 5; 1568 int dist = 5;
1542 if ( ( cursor->parag()->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify ) 1569 if ( ( cursor->paragraph()->alignment() & Qt3::AlignJustify ) == Qt3::AlignJustify )
1543 dist = 50; 1570 dist = 50;
1544 int x = r.x() - cursor->totalOffsetX() + cursor->x() - dist; 1571 int x = r.x() - cursor->totalOffsetX() + cursor->x() - dist;
1545 x = QMAX( x, 0 ); 1572 x = QMAX( x, 0 );
1546 p.setClipRect( QRect( x - contentsX(), 1573 p.setClipRect( QRect( x - contentsX(),
1547 r.y() - cursor->totalOffsetY() + cursor->y() - contentsY(), 2 * dist, h ) ); 1574 r.y() - cursor->totalOffsetY() + cursor->y() - contentsY(), 2 * dist, h ) );
1548 doc->drawParag( &p, cursor->parag(), x, 1575 doc->drawParagraph( &p, cursor->paragraph(), x,
1549 r.y() - cursor->totalOffsetY() + cursor->y(), 2 * dist, h, pix, cg, visible, cursor ); 1576 r.y() - cursor->totalOffsetY() + cursor->y(), 2 * dist, h, pix, cg, visible, cursor );
1550 } else { 1577 } else {
1551 doc->drawParag( &p, cursor->parag(), r.x() - cursor->totalOffsetX(), 1578 doc->drawParagraph( &p, cursor->paragraph(), r.x() - cursor->totalOffsetX(),
1552 r.y() - cursor->totalOffsetY(), r.width(), r.height(), 1579 r.y() - cursor->totalOffsetY(), r.width(), r.height(),
1553 pix, cg, visible, cursor ); 1580 pix, cg, visible, cursor );
1554 } 1581 }
@@ -1602,9 +1629,9 @@ void QTextEdit::contentsMousePressEvent( QMouseEvent *e )
1602 if ( isReadOnly() && linksEnabled() ) { 1629 if ( isReadOnly() && linksEnabled() ) {
1603 QTextCursor c = *cursor; 1630 QTextCursor c = *cursor;
1604 placeCursor( e->pos(), &c, TRUE ); 1631 placeCursor( e->pos(), &c, TRUE );
1605 if ( c.parag() && c.parag()->at( c.index() ) && 1632 if ( c.paragraph() && c.paragraph()->at( c.index() ) &&
1606 c.parag()->at( c.index() )->isAnchor() ) { 1633 c.paragraph()->at( c.index() )->isAnchor() ) {
1607 pressedLink = c.parag()->at( c.index() )->anchorHref(); 1634 pressedLink = c.paragraph()->at( c.index() )->anchorHref();
1608 } 1635 }
1609 } 1636 }
1610 1637
@@ -1622,16 +1649,16 @@ void QTextEdit::contentsMousePressEvent( QMouseEvent *e )
1622 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1649 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1623 if ( !( e->state() & ShiftButton ) ) { 1650 if ( !( e->state() & ShiftButton ) ) {
1624 redraw = doc->removeSelection( QTextDocument::Standard ); 1651 redraw = doc->removeSelection( QTextDocument::Standard );
1625 doc->setSelectionStart( QTextDocument::Standard, cursor ); 1652 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1626 } else { 1653 } else {
1627 redraw = doc->setSelectionEnd( QTextDocument::Standard, cursor ) || redraw; 1654 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1628 } 1655 }
1629 } else { 1656 } else {
1630 if ( isReadOnly() || !( e->state() & ShiftButton ) ) { 1657 if ( isReadOnly() || !( e->state() & ShiftButton ) ) {
1631 doc->setSelectionStart( QTextDocument::Standard, cursor ); 1658 doc->setSelectionStart( QTextDocument::Standard, *cursor );
1632 } else { 1659 } else {
1633 doc->setSelectionStart( QTextDocument::Standard, &c ); 1660 doc->setSelectionStart( QTextDocument::Standard, c );
1634 redraw = doc->setSelectionEnd( QTextDocument::Standard, cursor ) || redraw; 1661 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1635 } 1662 }
1636 } 1663 }
1637 1664
@@ -1714,7 +1741,7 @@ void QTextEdit::contentsMouseReleaseEvent( QMouseEvent * e )
1714 mousePressed = FALSE; 1741 mousePressed = FALSE;
1715 } 1742 }
1716 emit cursorPositionChanged( cursor ); 1743 emit cursorPositionChanged( cursor );
1717 emit cursorPositionChanged( cursor->parag()->paragId(), cursor->index() ); 1744 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
1718 if ( oldCursor != *cursor ) 1745 if ( oldCursor != *cursor )
1719 updateCurrentFormat(); 1746 updateCurrentFormat();
1720 inDoubleClick = FALSE; 1747 inDoubleClick = FALSE;
@@ -1744,13 +1771,13 @@ void QTextEdit::contentsMouseDoubleClickEvent( QMouseEvent * )
1744{ 1771{
1745 QTextCursor c1 = *cursor; 1772 QTextCursor c1 = *cursor;
1746 QTextCursor c2 = *cursor; 1773 QTextCursor c2 = *cursor;
1747 if ( cursor->index() > 0 && !cursor->parag()->at( cursor->index()-1 )->c.isSpace() ) 1774 if ( cursor->index() > 0 && !cursor->paragraph()->at( cursor->index()-1 )->c.isSpace() )
1748 c1.gotoPreviousWord(); 1775 c1.gotoPreviousWord();
1749 if ( !cursor->parag()->at( cursor->index() )->c.isSpace() && !cursor->atParagEnd() ) 1776 if ( !cursor->paragraph()->at( cursor->index() )->c.isSpace() && !cursor->atParagEnd() )
1750 c2.gotoNextWord(); 1777 c2.gotoNextWord();
1751 1778
1752 doc->setSelectionStart( QTextDocument::Standard, &c1 ); 1779 doc->setSelectionStart( QTextDocument::Standard, c1 );
1753 doc->setSelectionEnd( QTextDocument::Standard, &c2 ); 1780 doc->setSelectionEnd( QTextDocument::Standard, c2 );
1754 1781
1755 *cursor = c2; 1782 *cursor = c2;
1756 1783
@@ -1806,9 +1833,42 @@ void QTextEdit::contentsDropEvent( QDropEvent *e )
1806 QString text; 1833 QString text;
1807 bool intern = FALSE; 1834 bool intern = FALSE;
1808 if ( QTextDrag::decode( e, text ) ) { 1835 if ( QTextDrag::decode( e, text ) ) {
1809 if ( ( e->source() == this || 1836 bool hasSel = doc->hasSelection( QTextDocument::Standard );
1810 e->source() == viewport() ) && 1837 bool internalDrag = e->source() == this || e->source() == viewport();
1811 e->action() == QDropEvent::Move ) { 1838 int dropId, dropIndex;
1839 QTextCursor insertCursor = *cursor;
1840 dropId = cursor->paragraph()->paragId();
1841 dropIndex = cursor->index();
1842 if ( hasSel && internalDrag ) {
1843 QTextCursor c1, c2;
1844 int selStartId, selStartIndex;
1845 int selEndId, selEndIndex;
1846 c1 = doc->selectionStartCursor( QTextDocument::Standard );
1847 c1.restoreState();
1848 c2 = doc->selectionEndCursor( QTextDocument::Standard );
1849 c2.restoreState();
1850 selStartId = c1.paragraph()->paragId();
1851 selStartIndex = c1.index();
1852 selEndId = c2.paragraph()->paragId();
1853 selEndIndex = c2.index();
1854 if ( ( ( dropId > selStartId ) ||
1855 ( dropId == selStartId && dropIndex > selStartIndex ) ) &&
1856 ( ( dropId < selEndId ) ||
1857 ( dropId == selEndId && dropIndex <= selEndIndex ) ) )
1858 insertCursor = c1;
1859 if ( dropId == selEndId && dropIndex > selEndIndex ) {
1860 insertCursor = c1;
1861 if ( selStartId == selEndId ) {
1862 insertCursor.setIndex( dropIndex -
1863 ( selEndIndex - selStartIndex ) );
1864 } else {
1865 insertCursor.setIndex( dropIndex - selEndIndex +
1866 selStartIndex );
1867 }
1868 }
1869 }
1870
1871 if ( internalDrag && e->action() == QDropEvent::Move ) {
1812 removeSelectedText(); 1872 removeSelectedText();
1813 intern = TRUE; 1873 intern = TRUE;
1814 } else { 1874 } else {
@@ -1818,7 +1878,8 @@ void QTextEdit::contentsDropEvent( QDropEvent *e )
1818#endif 1878#endif
1819 } 1879 }
1820 drawCursor( FALSE ); 1880 drawCursor( FALSE );
1821 placeCursor( e->pos(), cursor ); 1881 cursor->setParagraph( insertCursor.paragraph() );
1882 cursor->setIndex( insertCursor.index() );
1822 drawCursor( TRUE ); 1883 drawCursor( TRUE );
1823 if ( !cursor->nestedDepth() ) { 1884 if ( !cursor->nestedDepth() ) {
1824 insert( text, FALSE, TRUE, FALSE ); 1885 insert( text, FALSE, TRUE, FALSE );
@@ -1859,13 +1920,13 @@ void QTextEdit::handleMouseMove( const QPoint& pos )
1859 QTextCursor cr = *cursor; 1920 QTextCursor cr = *cursor;
1860 cr.gotoNextWord(); 1921 cr.gotoNextWord();
1861 1922
1862 int diff = QABS( oldCursor.parag()->at( oldCursor.index() )->x - mousePos.x() ); 1923 int diff = QABS( oldCursor.paragraph()->at( oldCursor.index() )->x - mousePos.x() );
1863 int ldiff = QABS( cl.parag()->at( cl.index() )->x - mousePos.x() ); 1924 int ldiff = QABS( cl.paragraph()->at( cl.index() )->x - mousePos.x() );
1864 int rdiff = QABS( cr.parag()->at( cr.index() )->x - mousePos.x() ); 1925 int rdiff = QABS( cr.paragraph()->at( cr.index() )->x - mousePos.x() );
1865 1926
1866 1927
1867 if ( cursor->parag()->lineStartOfChar( cursor->index() ) != 1928 if ( cursor->paragraph()->lineStartOfChar( cursor->index() ) !=
1868 oldCursor.parag()->lineStartOfChar( oldCursor.index() ) ) 1929 oldCursor.paragraph()->lineStartOfChar( oldCursor.index() ) )
1869 diff = 0xFFFFFF; 1930 diff = 0xFFFFFF;
1870 1931
1871 if ( rdiff < diff && rdiff < ldiff ) 1932 if ( rdiff < diff && rdiff < ldiff )
@@ -1880,7 +1941,7 @@ void QTextEdit::handleMouseMove( const QPoint& pos )
1880 1941
1881 bool redraw = FALSE; 1942 bool redraw = FALSE;
1882 if ( doc->hasSelection( QTextDocument::Standard ) ) { 1943 if ( doc->hasSelection( QTextDocument::Standard ) ) {
1883 redraw = doc->setSelectionEnd( QTextDocument::Standard, cursor ) || redraw; 1944 redraw = doc->setSelectionEnd( QTextDocument::Standard, *cursor ) || redraw;
1884 } 1945 }
1885 1946
1886 if ( !redraw ) { 1947 if ( !redraw ) {
@@ -1890,9 +1951,9 @@ void QTextEdit::handleMouseMove( const QPoint& pos )
1890 drawCursor( TRUE ); 1951 drawCursor( TRUE );
1891 } 1952 }
1892 1953
1893 if ( currentFormat && currentFormat->key() != cursor->parag()->at( cursor->index() )->format()->key() ) { 1954 if ( currentFormat && currentFormat->key() != cursor->paragraph()->at( cursor->index() )->format()->key() ) {
1894 currentFormat->removeRef(); 1955 currentFormat->removeRef();
1895 currentFormat = doc->formatCollection()->format( cursor->parag()->at( cursor->index() )->format() ); 1956 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( cursor->index() )->format() );
1896 if ( currentFormat->isMisspelled() ) { 1957 if ( currentFormat->isMisspelled() ) {
1897 currentFormat->removeRef(); 1958 currentFormat->removeRef();
1898 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() ); 1959 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
@@ -1902,8 +1963,8 @@ void QTextEdit::handleMouseMove( const QPoint& pos )
1902 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 1963 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
1903 } 1964 }
1904 1965
1905 if ( currentAlignment != cursor->parag()->alignment() ) { 1966 if ( currentAlignment != cursor->paragraph()->alignment() ) {
1906 currentAlignment = cursor->parag()->alignment(); 1967 currentAlignment = cursor->paragraph()->alignment();
1907 block_set_alignment = TRUE; 1968 block_set_alignment = TRUE;
1908 emit currentAlignmentChanged( currentAlignment ); 1969 emit currentAlignmentChanged( currentAlignment );
1909 block_set_alignment = FALSE; 1970 block_set_alignment = FALSE;
@@ -1925,18 +1986,30 @@ void QTextEdit::placeCursor( const QPoint &pos, QTextCursor *c, bool link )
1925 c = cursor; 1986 c = cursor;
1926 1987
1927 c->restoreState(); 1988 c->restoreState();
1928 QTextParag *s = doc->firstParag(); 1989 QTextParagraph *s = doc->firstParagraph();
1929 c->place( pos, s, link ); 1990 c->place( pos, s, link );
1991 updateMicroFocusHint();
1992}
1993
1994
1995void QTextEdit::updateMicroFocusHint()
1996{
1997 QTextCursor c( *cursor );
1998 if ( d->preeditStart != -1 )
1999 c.setIndex( d->preeditStart );
2000
1930 if ( hasFocus() || viewport()->hasFocus() ) { 2001 if ( hasFocus() || viewport()->hasFocus() ) {
1931 int h = cursor->parag()->lineHeightOfChar( cursor->index() ); 2002 int h = c.paragraph()->lineHeightOfChar( cursor->index() );
1932 if ( !readonly ) { 2003 if ( !readonly ) {
1933 QFont f = cursor->parag()->at( cursor->index() )->format()->font(); 2004 QFont f = c.paragraph()->at( c.index() )->format()->font();
1934 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(), 2005 setMicroFocusHint( c.x() - contentsX() + frameWidth(),
1935 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE ); 2006 c.y() + cursor->paragraph()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
1936 } 2007 }
1937 } 2008 }
1938} 2009}
1939 2010
2011
2012
1940void QTextEdit::formatMore() 2013void QTextEdit::formatMore()
1941{ 2014{
1942 if ( !lastFormatted ) 2015 if ( !lastFormatted )
@@ -1944,7 +2017,7 @@ void QTextEdit::formatMore()
1944 2017
1945 int bottom = contentsHeight(); 2018 int bottom = contentsHeight();
1946 int lastBottom = -1; 2019 int lastBottom = -1;
1947 int to = !sender() ? 2 : 20; 2020 int to = 20;
1948 bool firstVisible = FALSE; 2021 bool firstVisible = FALSE;
1949 QRect cr( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2022 QRect cr( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
1950 for ( int i = 0; ( i < to || firstVisible ) && lastFormatted; ++i ) { 2023 for ( int i = 0; ( i < to || firstVisible ) && lastFormatted; ++i ) {
@@ -1961,10 +2034,14 @@ void QTextEdit::formatMore()
1961 lastBottom = -1; 2034 lastBottom = -1;
1962 } 2035 }
1963 2036
1964 if ( bottom > contentsHeight() ) 2037 if ( bottom > contentsHeight() ) {
1965 resizeContents( contentsWidth(), QMAX( doc->height(), bottom ) ); 2038 resizeContents( contentsWidth(), QMAX( doc->height(), bottom ) );
1966 else if ( lastBottom != -1 && lastBottom < contentsHeight() ) 2039 } else if ( lastBottom != -1 && lastBottom < contentsHeight() ) {
1967 resizeContents( contentsWidth(), QMAX( doc->height(), lastBottom ) ); 2040 resizeContents( contentsWidth(), QMAX( doc->height(), lastBottom ) );
2041 if ( contentsHeight() < visibleHeight() )
2042 updateContents( 0, contentsHeight(), visibleWidth(),
2043 visibleHeight() - contentsHeight() );
2044 }
1968 2045
1969 if ( lastFormatted ) 2046 if ( lastFormatted )
1970 formatTimer->start( interval, TRUE ); 2047 formatTimer->start( interval, TRUE );
@@ -1980,7 +2057,7 @@ void QTextEdit::doResize()
1980 resizeContents( 0, 0 ); 2057 resizeContents( 0, 0 );
1981 doc->setWidth( visibleWidth() ); 2058 doc->setWidth( visibleWidth() );
1982 doc->invalidate(); 2059 doc->invalidate();
1983 lastFormatted = doc->firstParag(); 2060 lastFormatted = doc->firstParagraph();
1984 interval = 0; 2061 interval = 0;
1985 formatMore(); 2062 formatMore();
1986 repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE ); 2063 repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE );
@@ -2001,16 +2078,7 @@ bool QTextEdit::eventFilter( QObject *o, QEvent *e )
2001 if ( e->type() == QEvent::FocusIn ) { 2078 if ( e->type() == QEvent::FocusIn ) {
2002 blinkTimer->start( QApplication::cursorFlashTime() / 2 ); 2079 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
2003 drawCursor( TRUE ); 2080 drawCursor( TRUE );
2004 2081 updateMicroFocusHint();
2005 if ( !readonly ) {
2006 // make sure the micro focus hint is updated...
2007 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2008 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2009 cursor->y() + cursor->parag()->rect().y() -
2010 contentsY() + frameWidth(), 0,
2011 cursor->parag()->lineHeightOfChar( cursor->index() ),
2012 TRUE );
2013 }
2014 } else if ( e->type() == QEvent::FocusOut ) { 2082 } else if ( e->type() == QEvent::FocusOut ) {
2015 blinkTimer->stop(); 2083 blinkTimer->stop();
2016 drawCursor( FALSE ); 2084 drawCursor( FALSE );
@@ -2020,14 +2088,14 @@ bool QTextEdit::eventFilter( QObject *o, QEvent *e )
2020 return QScrollView::eventFilter( o, e ); 2088 return QScrollView::eventFilter( o, e );
2021} 2089}
2022 2090
2023/*! 2091/*! Inserts \a text at the current cursor position. If \a indent is
2024 Inserts \a text at the current cursor position. If \a indent is TRUE, 2092 TRUE, the paragraph is re-indented. If \a checkNewLine is TRUE,
2025 the paragraph is re-indented. If \a checkNewLine is TRUE, newline 2093 newline characters in \a text result in hard line breaks (i.e. new
2026 characters in \a text result in hard line breaks (i.e. new 2094 paragraphs). If \a checkNewLine is FALSE and there are newlines in
2027 paragraphs). If \a checkNewLine is FALSE the behaviour of the editor 2095 \a text, the behavior is undefined. If \a checkNewLine is FALSE the
2028 is undefined if the \a text contains newlines. If \a removeSelected is 2096 behaviour of the editor is undefined if the \a text contains
2029 TRUE, any selected text (in selection 0) is removed before the text is 2097 newlines. If \a removeSelected is TRUE, any selected text (in
2030 inserted. 2098 selection 0) is removed before the text is inserted.
2031 2099
2032 \sa paste() pasteSubType() 2100 \sa paste() pasteSubType()
2033*/ 2101*/
@@ -2046,20 +2114,20 @@ void QTextEdit::insert( const QString &text, bool indent, bool checkNewLine, boo
2046 if ( undoEnabled && !isReadOnly() ) { 2114 if ( undoEnabled && !isReadOnly() ) {
2047 checkUndoRedoInfo( UndoRedoInfo::Insert ); 2115 checkUndoRedoInfo( UndoRedoInfo::Insert );
2048 if ( !undoRedoInfo.valid() ) { 2116 if ( !undoRedoInfo.valid() ) {
2049 undoRedoInfo.id = cursor->parag()->paragId(); 2117 undoRedoInfo.id = cursor->paragraph()->paragId();
2050 undoRedoInfo.index = cursor->index(); 2118 undoRedoInfo.index = cursor->index();
2051 undoRedoInfo.d->text = QString::null; 2119 undoRedoInfo.d->text = QString::null;
2052 } 2120 }
2053 oldLen = undoRedoInfo.d->text.length(); 2121 oldLen = undoRedoInfo.d->text.length();
2054 } 2122 }
2055 2123
2056 lastFormatted = checkNewLine && cursor->parag()->prev() ? 2124 lastFormatted = checkNewLine && cursor->paragraph()->prev() ?
2057 cursor->parag()->prev() : cursor->parag(); 2125 cursor->paragraph()->prev() : cursor->paragraph();
2058 QTextCursor oldCursor = *cursor; 2126 QTextCursor oldCursor = *cursor;
2059 cursor->insert( txt, checkNewLine ); 2127 cursor->insert( txt, checkNewLine );
2060 if ( doc->useFormatCollection() ) { 2128 if ( doc->useFormatCollection() ) {
2061 doc->setSelectionStart( QTextDocument::Temp, &oldCursor ); 2129 doc->setSelectionStart( QTextDocument::Temp, oldCursor );
2062 doc->setSelectionEnd( QTextDocument::Temp, cursor ); 2130 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
2063 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format ); 2131 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format );
2064 doc->removeSelection( QTextDocument::Temp ); 2132 doc->removeSelection( QTextDocument::Temp );
2065 } 2133 }
@@ -2075,41 +2143,35 @@ void QTextEdit::insert( const QString &text, bool indent, bool checkNewLine, boo
2075 undoRedoInfo.d->text += txt; 2143 undoRedoInfo.d->text += txt;
2076 if ( !doc->preProcessor() ) { 2144 if ( !doc->preProcessor() ) {
2077 for ( int i = 0; i < (int)txt.length(); ++i ) { 2145 for ( int i = 0; i < (int)txt.length(); ++i ) {
2078 if ( txt[ i ] != '\n' && c2.parag()->at( c2.index() )->format() ) { 2146 if ( txt[ i ] != '\n' && c2.paragraph()->at( c2.index() )->format() ) {
2079 c2.parag()->at( c2.index() )->format()->addRef(); 2147 c2.paragraph()->at( c2.index() )->format()->addRef();
2080 undoRedoInfo.d->text.setFormat( oldLen + i, c2.parag()->at( c2.index() )->format(), TRUE ); 2148 undoRedoInfo.d->text.setFormat( oldLen + i, c2.paragraph()->at( c2.index() )->format(), TRUE );
2081 } 2149 }
2082 c2.gotoNextLetter(); 2150 c2.gotoNextLetter();
2083 } 2151 }
2084 } 2152 }
2085 } 2153 }
2086 2154
2087 setModified();
2088 emit textChanged();
2089 if ( !removeSelected ) { 2155 if ( !removeSelected ) {
2090 doc->setSelectionStart( QTextDocument::Standard, &oldCursor ); 2156 doc->setSelectionStart( QTextDocument::Standard, oldCursor );
2091 doc->setSelectionEnd( QTextDocument::Standard, cursor ); 2157 doc->setSelectionEnd( QTextDocument::Standard, *cursor );
2092 repaintChanged(); 2158 repaintChanged();
2093 } 2159 }
2094 if ( hasFocus() || viewport()->hasFocus() ) { 2160 updateMicroFocusHint();
2095 int h = cursor->parag()->lineHeightOfChar( cursor->index() ); 2161 setModified();
2096 if ( !readonly ) { 2162 emit textChanged();
2097 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2098 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2099 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
2100 }
2101 }
2102} 2163}
2103 2164
2104/*! Inserts \a text in the paragraph \a para and position \a index */ 2165/*! Inserts \a text in the paragraph \a para and position \a index */
2105 2166
2106void QTextEdit::insertAt( const QString &text, int para, int index ) 2167void QTextEdit::insertAt( const QString &text, int para, int index )
2107{ 2168{
2108 QTextParag *p = doc->paragAt( para ); 2169 removeSelection( QTextDocument::Standard );
2170 QTextParagraph *p = doc->paragAt( para );
2109 if ( !p ) 2171 if ( !p )
2110 return; 2172 return;
2111 QTextCursor tmp = *cursor; 2173 QTextCursor tmp = *cursor;
2112 cursor->setParag( p ); 2174 cursor->setParagraph( p );
2113 cursor->setIndex( index ); 2175 cursor->setIndex( index );
2114 insert( text, FALSE, TRUE, FALSE ); 2176 insert( text, FALSE, TRUE, FALSE );
2115 *cursor = tmp; 2177 *cursor = tmp;
@@ -2122,13 +2184,13 @@ void QTextEdit::insertAt( const QString &text, int para, int index )
2122 2184
2123void QTextEdit::insertParagraph( const QString &text, int para ) 2185void QTextEdit::insertParagraph( const QString &text, int para )
2124{ 2186{
2125 QTextParag *p = doc->paragAt( para ); 2187 QTextParagraph *p = doc->paragAt( para );
2126 if ( p ) { 2188 if ( p ) {
2127 QTextCursor tmp( doc ); 2189 QTextCursor tmp( doc );
2128 tmp.setParag( p ); 2190 tmp.setParagraph( p );
2129 tmp.setIndex( 0 ); 2191 tmp.setIndex( 0 );
2130 tmp.insert( text, TRUE ); 2192 tmp.insert( text, TRUE );
2131 tmp.splitAndInsertEmptyParag(); 2193 tmp.splitAndInsertEmptyParagraph();
2132 repaintChanged(); 2194 repaintChanged();
2133 } else { 2195 } else {
2134 append( text ); 2196 append( text );
@@ -2139,28 +2201,28 @@ void QTextEdit::insertParagraph( const QString &text, int para )
2139 2201
2140void QTextEdit::removeParagraph( int para ) 2202void QTextEdit::removeParagraph( int para )
2141{ 2203{
2142 QTextParag *p = doc->paragAt( para ); 2204 QTextParagraph *p = doc->paragAt( para );
2143 if ( !p ) 2205 if ( !p )
2144 return; 2206 return;
2145 for ( int i = 0; i < doc->numSelections(); ++i ) 2207 for ( int i = 0; i < doc->numSelections(); ++i )
2146 doc->removeSelection( i ); 2208 doc->removeSelection( i );
2147 2209
2148 if ( p == doc->firstParag() && p == doc->lastParag() ) { 2210 if ( p == doc->firstParagraph() && p == doc->lastParagraph() ) {
2149 p->remove( 0, p->length() - 1 ); 2211 p->remove( 0, p->length() - 1 );
2150 repaintChanged(); 2212 repaintChanged();
2151 return; 2213 return;
2152 } 2214 }
2153 drawCursor( FALSE ); 2215 drawCursor( FALSE );
2154 bool resetCursor = cursor->parag() == p; 2216 bool resetCursor = cursor->paragraph() == p;
2155 if ( p->prev() ) 2217 if ( p->prev() )
2156 p->prev()->setNext( p->next() ); 2218 p->prev()->setNext( p->next() );
2157 else 2219 else
2158 doc->setFirstParag( p->next() ); 2220 doc->setFirstParagraph( p->next() );
2159 if ( p->next() ) 2221 if ( p->next() )
2160 p->next()->setPrev( p->prev() ); 2222 p->next()->setPrev( p->prev() );
2161 else 2223 else
2162 doc->setLastParag( p->prev() ); 2224 doc->setLastParagraph( p->prev() );
2163 QTextParag *start = p->next(); 2225 QTextParagraph *start = p->next();
2164 int h = p->rect().height(); 2226 int h = p->rect().height();
2165 delete p; 2227 delete p;
2166 p = start; 2228 p = start;
@@ -2174,7 +2236,7 @@ void QTextEdit::removeParagraph( int para )
2174 } 2236 }
2175 2237
2176 if ( resetCursor ) { 2238 if ( resetCursor ) {
2177 cursor->setParag( doc->firstParag() ); 2239 cursor->setParagraph( doc->firstParagraph() );
2178 cursor->setIndex( 0 ); 2240 cursor->setIndex( 0 );
2179 } 2241 }
2180 repaintChanged(); 2242 repaintChanged();
@@ -2217,16 +2279,9 @@ void QTextEdit::undo()
2217 ensureCursorVisible(); 2279 ensureCursorVisible();
2218 repaintChanged(); 2280 repaintChanged();
2219 drawCursor( TRUE ); 2281 drawCursor( TRUE );
2282 updateMicroFocusHint();
2220 setModified(); 2283 setModified();
2221 emit textChanged(); 2284 emit textChanged();
2222 if ( hasFocus() || viewport()->hasFocus() ) {
2223 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
2224 if ( !readonly ) {
2225 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2226 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2227 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
2228 }
2229 }
2230} 2285}
2231 2286
2232/*! 2287/*!
@@ -2262,16 +2317,9 @@ void QTextEdit::redo()
2262 repaintChanged(); 2317 repaintChanged();
2263 ensureCursorVisible(); 2318 ensureCursorVisible();
2264 drawCursor( TRUE ); 2319 drawCursor( TRUE );
2320 updateMicroFocusHint();
2265 setModified(); 2321 setModified();
2266 emit textChanged(); 2322 emit textChanged();
2267 if ( hasFocus() || viewport()->hasFocus() ) {
2268 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
2269 if ( !readonly ) {
2270 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2271 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2272 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
2273 }
2274 }
2275} 2323}
2276 2324
2277/*! 2325/*!
@@ -2289,14 +2337,7 @@ void QTextEdit::paste()
2289 if ( isReadOnly() ) 2337 if ( isReadOnly() )
2290 return; 2338 return;
2291 pasteSubType( "plain" ); 2339 pasteSubType( "plain" );
2292 if ( hasFocus() || viewport()->hasFocus() ) { 2340 updateMicroFocusHint();
2293 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
2294 if ( !readonly ) {
2295 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2296 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2297 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
2298 }
2299 }
2300#endif 2341#endif
2301} 2342}
2302 2343
@@ -2337,18 +2378,13 @@ void QTextEdit::cut()
2337 if ( isReadOnly() ) 2378 if ( isReadOnly() )
2338 return; 2379 return;
2339 2380
2340 if ( doc->hasSelection( QTextDocument::Standard ) ) { 2381 QString t;
2341 doc->copySelectedText( QTextDocument::Standard ); 2382 if ( doc->hasSelection( QTextDocument::Standard ) &&
2383 !( t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ) ).isEmpty() ) {
2384 QApplication::clipboard()->setText( t );
2342 removeSelectedText(); 2385 removeSelectedText();
2343 } 2386 }
2344 if ( hasFocus() || viewport()->hasFocus() ) { 2387 updateMicroFocusHint();
2345 int h = cursor->parag()->lineHeightOfChar( cursor->index() );
2346 if ( !readonly ) {
2347 QFont f = cursor->parag()->at( cursor->index() )->format()->font();
2348 setMicroFocusHint( cursor->x() - contentsX() + frameWidth(),
2349 cursor->y() + cursor->parag()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE );
2350 }
2351 }
2352} 2388}
2353 2389
2354/*! Copies any selected text (from selection 0) to the clipboard. 2390/*! Copies any selected text (from selection 0) to the clipboard.
@@ -2358,8 +2394,10 @@ void QTextEdit::cut()
2358 2394
2359void QTextEdit::copy() 2395void QTextEdit::copy()
2360{ 2396{
2361 if ( !doc->selectedText( QTextDocument::Standard ).isEmpty() ) 2397 QString t = doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy );
2362 doc->copySelectedText( QTextDocument::Standard ); 2398 if ( doc->hasSelection( QTextDocument::Standard ) &&
2399 !t.isEmpty() && t.simplifyWhiteSpace() != "<selstart/>" )
2400 QApplication::clipboard()->setText( t );
2363} 2401}
2364 2402
2365/*! 2403/*!
@@ -2412,17 +2450,17 @@ void QTextEdit::setFormat( QTextFormat *f, int flags )
2412{ 2450{
2413 if ( doc->hasSelection( QTextDocument::Standard ) ) { 2451 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2414 drawCursor( FALSE ); 2452 drawCursor( FALSE );
2415 QString str = doc->selectedText( QTextDocument::Standard );
2416 QTextCursor c1 = doc->selectionStartCursor( QTextDocument::Standard ); 2453 QTextCursor c1 = doc->selectionStartCursor( QTextDocument::Standard );
2454 c1.restoreState();
2417 QTextCursor c2 = doc->selectionEndCursor( QTextDocument::Standard ); 2455 QTextCursor c2 = doc->selectionEndCursor( QTextDocument::Standard );
2456 c2.restoreState();
2418 clearUndoRedo(); 2457 clearUndoRedo();
2419 undoRedoInfo.type = UndoRedoInfo::Format; 2458 undoRedoInfo.type = UndoRedoInfo::Format;
2420 undoRedoInfo.id = c1.parag()->paragId(); 2459 undoRedoInfo.id = c1.paragraph()->paragId();
2421 undoRedoInfo.index = c1.index(); 2460 undoRedoInfo.index = c1.index();
2422 undoRedoInfo.eid = c2.parag()->paragId(); 2461 undoRedoInfo.eid = c2.paragraph()->paragId();
2423 undoRedoInfo.eindex = c2.index(); 2462 undoRedoInfo.eindex = c2.index();
2424 undoRedoInfo.d->text = str; 2463 readFormats( c1, c2, undoRedoInfo.d->text );
2425 readFormats( c1, c2, 0, undoRedoInfo.d->text );
2426 undoRedoInfo.format = f; 2464 undoRedoInfo.format = f;
2427 undoRedoInfo.flags = flags; 2465 undoRedoInfo.flags = flags;
2428 clearUndoRedo(); 2466 clearUndoRedo();
@@ -2443,12 +2481,12 @@ void QTextEdit::setFormat( QTextFormat *f, int flags )
2443 emit currentFontChanged( currentFormat->font() ); 2481 emit currentFontChanged( currentFormat->font() );
2444 emit currentColorChanged( currentFormat->color() ); 2482 emit currentColorChanged( currentFormat->color() );
2445 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 2483 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
2446 if ( cursor->index() == cursor->parag()->length() - 1 ) { 2484 if ( cursor->index() == cursor->paragraph()->length() - 1 ) {
2447 currentFormat->addRef(); 2485 currentFormat->addRef();
2448 cursor->parag()->string()->setFormat( cursor->index(), currentFormat, TRUE ); 2486 cursor->paragraph()->string()->setFormat( cursor->index(), currentFormat, TRUE );
2449 if ( cursor->parag()->length() == 1 ) { 2487 if ( cursor->paragraph()->length() == 1 ) {
2450 cursor->parag()->invalidate( 0 ); 2488 cursor->paragraph()->invalidate( 0 );
2451 cursor->parag()->format(); 2489 cursor->paragraph()->format();
2452 repaintChanged(); 2490 repaintChanged();
2453 } 2491 }
2454 } 2492 }
@@ -2467,7 +2505,12 @@ void QTextEdit::setPalette( const QPalette &p )
2467 } 2505 }
2468} 2506}
2469 2507
2470/*! 2508/*! \internal
2509
2510 \warning In Qt 3.1 we will provide a cleaer API for the
2511 functionality which is provided by this function and in Qt 4.0 this
2512 function will go away.
2513
2471 Sets the paragraph style of the current paragraph 2514 Sets the paragraph style of the current paragraph
2472 to \a dm. If \a dm is QStyleSheetItem::DisplayListItem, the 2515 to \a dm. If \a dm is QStyleSheetItem::DisplayListItem, the
2473 type of the list item is set to \a listStyle. 2516 type of the list item is set to \a listStyle.
@@ -2481,49 +2524,37 @@ void QTextEdit::setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::
2481 return; 2524 return;
2482 2525
2483 drawCursor( FALSE ); 2526 drawCursor( FALSE );
2484 if ( !doc->hasSelection( QTextDocument::Standard ) ) { 2527 QTextParagraph *start = cursor->paragraph();
2485 clearUndoRedo(); 2528 QTextParagraph *end = start;
2486 undoRedoInfo.type = UndoRedoInfo::ParagType; 2529 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2487 QValueList< QPtrVector<QStyleSheetItem> > oldStyles; 2530 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph();
2488 undoRedoInfo.oldStyles.clear(); 2531 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph();
2489 undoRedoInfo.oldStyles << cursor->parag()->styleSheetItems(); 2532 if ( end->paragId() < start->paragId() )
2490 undoRedoInfo.oldListStyles.clear(); 2533 return; // do not trust our selections
2491 undoRedoInfo.oldListStyles << cursor->parag()->listStyle(); 2534 }
2492 undoRedoInfo.list = dm == QStyleSheetItem::DisplayListItem; 2535
2493 undoRedoInfo.listStyle = listStyle; 2536 clearUndoRedo();
2494 undoRedoInfo.id = cursor->parag()->paragId(); 2537 undoRedoInfo.type = UndoRedoInfo::Style;
2495 undoRedoInfo.eid = cursor->parag()->paragId(); 2538 undoRedoInfo.id = start->paragId();
2496 undoRedoInfo.d->text = " "; 2539 undoRedoInfo.eid = end->paragId();
2497 undoRedoInfo.index = 1; 2540 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
2498 clearUndoRedo(); 2541
2499 cursor->parag()->setList( dm == QStyleSheetItem::DisplayListItem, listStyle ); 2542 while ( start != end->next() ) {
2500 repaintChanged(); 2543 start->setListStyle( listStyle );
2501 } else { 2544 if ( dm == QStyleSheetItem::DisplayListItem ) {
2502 QTextParag *start = doc->selectionStart( QTextDocument::Standard ); 2545 start->setListItem( TRUE );
2503 QTextParag *end = doc->selectionEnd( QTextDocument::Standard ); 2546 if( start->listDepth() == 0 )
2504 lastFormatted = start; 2547 start->setListDepth( 1 );
2505 clearUndoRedo(); 2548 } else if ( start->isListItem() ) {
2506 undoRedoInfo.type = UndoRedoInfo::ParagType; 2549 start->setListItem( FALSE );
2507 undoRedoInfo.id = start->paragId(); 2550 start->setListDepth( QMAX( start->listDepth()-1, 0 ) );
2508 undoRedoInfo.eid = end->paragId();
2509 undoRedoInfo.list = dm == QStyleSheetItem::DisplayListItem;
2510 undoRedoInfo.listStyle = listStyle;
2511 undoRedoInfo.oldStyles.clear();
2512 undoRedoInfo.oldListStyles.clear();
2513 while ( start ) {
2514 undoRedoInfo.oldStyles << start->styleSheetItems();
2515 undoRedoInfo.oldListStyles << start->listStyle();
2516 start->setList( dm == QStyleSheetItem::DisplayListItem, listStyle );
2517 if ( start == end )
2518 break;
2519 start = start->next();
2520 } 2551 }
2521 undoRedoInfo.d->text = " "; 2552 start = start->next();
2522 undoRedoInfo.index = 1;
2523 clearUndoRedo();
2524 repaintChanged();
2525 formatMore();
2526 } 2553 }
2554
2555 clearUndoRedo();
2556 repaintChanged();
2557 formatMore();
2527 drawCursor( TRUE ); 2558 drawCursor( TRUE );
2528 setModified(); 2559 setModified();
2529 emit textChanged(); 2560 emit textChanged();
@@ -2534,7 +2565,6 @@ void QTextEdit::setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::
2534 are \c Qt::AlignLeft, \c Qt::AlignRight, Qt::AlignJustify and 2565 are \c Qt::AlignLeft, \c Qt::AlignRight, Qt::AlignJustify and
2535 Qt::AlignCenter (which centers horizontally). 2566 Qt::AlignCenter (which centers horizontally).
2536 2567
2537 \sa setParagType()
2538*/ 2568*/
2539 2569
2540void QTextEdit::setAlignment( int a ) 2570void QTextEdit::setAlignment( int a )
@@ -2543,50 +2573,29 @@ void QTextEdit::setAlignment( int a )
2543 return; 2573 return;
2544 2574
2545 drawCursor( FALSE ); 2575 drawCursor( FALSE );
2546 if ( !doc->hasSelection( QTextDocument::Standard ) ) { 2576 QTextParagraph *start = cursor->paragraph();
2547 if ( cursor->parag()->alignment() != a ) { 2577 QTextParagraph *end = start;
2548 clearUndoRedo(); 2578 if ( doc->hasSelection( QTextDocument::Standard ) ) {
2549 undoRedoInfo.type = UndoRedoInfo::Alignment; 2579 start = doc->selectionStartCursor( QTextDocument::Standard ).topParagraph();
2550 QMemArray<int> oa( 1 ); 2580 end = doc->selectionEndCursor( QTextDocument::Standard ).topParagraph();
2551 oa[ 0 ] = cursor->parag()->alignment(); 2581 if ( end->paragId() < start->paragId() )
2552 undoRedoInfo.oldAligns = oa; 2582 return; // do not trust our selections
2553 undoRedoInfo.newAlign = a;
2554 undoRedoInfo.id = cursor->parag()->paragId();
2555 undoRedoInfo.eid = cursor->parag()->paragId();
2556 undoRedoInfo.d->text = " ";
2557 undoRedoInfo.index = 1;
2558 clearUndoRedo();
2559 cursor->parag()->setAlignment( a );
2560 repaintChanged();
2561 }
2562 } else {
2563 QTextParag *start = doc->selectionStart( QTextDocument::Standard );
2564 QTextParag *end = doc->selectionEnd( QTextDocument::Standard );
2565 lastFormatted = start;
2566 int len = end->paragId() - start->paragId() + 1;
2567 clearUndoRedo();
2568 undoRedoInfo.type = UndoRedoInfo::Alignment;
2569 undoRedoInfo.id = start->paragId();
2570 undoRedoInfo.eid = end->paragId();
2571 QMemArray<int> oa( QMAX( 0, len ) );
2572 int i = 0;
2573 while ( start ) {
2574 if ( i < (int)oa.size() )
2575 oa[ i ] = start->alignment();
2576 start->setAlignment( a );
2577 if ( start == end )
2578 break;
2579 start = start->next();
2580 ++i;
2581 }
2582 undoRedoInfo.oldAligns = oa;
2583 undoRedoInfo.newAlign = a;
2584 undoRedoInfo.d->text = " ";
2585 undoRedoInfo.index = 1;
2586 clearUndoRedo();
2587 repaintChanged();
2588 formatMore();
2589 } 2583 }
2584
2585 clearUndoRedo();
2586 undoRedoInfo.type = UndoRedoInfo::Style;
2587 undoRedoInfo.id = start->paragId();
2588 undoRedoInfo.eid = end->paragId();
2589 undoRedoInfo.styleInformation = QTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
2590
2591 while ( start != end->next() ) {
2592 start->setAlignment( a );
2593 start = start->next();
2594 }
2595
2596 clearUndoRedo();
2597 repaintChanged();
2598 formatMore();
2590 drawCursor( TRUE ); 2599 drawCursor( TRUE );
2591 if ( currentAlignment != a ) { 2600 if ( currentAlignment != a ) {
2592 currentAlignment = a; 2601 currentAlignment = a;
@@ -2602,10 +2611,10 @@ void QTextEdit::updateCurrentFormat()
2602 if ( i > 0 ) 2611 if ( i > 0 )
2603 --i; 2612 --i;
2604 if ( doc->useFormatCollection() && 2613 if ( doc->useFormatCollection() &&
2605 ( !currentFormat || currentFormat->key() != cursor->parag()->at( i )->format()->key() ) ) { 2614 ( !currentFormat || currentFormat->key() != cursor->paragraph()->at( i )->format()->key() ) ) {
2606 if ( currentFormat ) 2615 if ( currentFormat )
2607 currentFormat->removeRef(); 2616 currentFormat->removeRef();
2608 currentFormat = doc->formatCollection()->format( cursor->parag()->at( i )->format() ); 2617 currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( i )->format() );
2609 if ( currentFormat->isMisspelled() ) { 2618 if ( currentFormat->isMisspelled() ) {
2610 currentFormat->removeRef(); 2619 currentFormat->removeRef();
2611 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() ); 2620 currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
@@ -2615,8 +2624,8 @@ void QTextEdit::updateCurrentFormat()
2615 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() ); 2624 emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
2616 } 2625 }
2617 2626
2618 if ( currentAlignment != cursor->parag()->alignment() ) { 2627 if ( currentAlignment != cursor->paragraph()->alignment() ) {
2619 currentAlignment = cursor->parag()->alignment(); 2628 currentAlignment = cursor->paragraph()->alignment();
2620 block_set_alignment = TRUE; 2629 block_set_alignment = TRUE;
2621 emit currentAlignmentChanged( currentAlignment ); 2630 emit currentAlignmentChanged( currentAlignment );
2622 block_set_alignment = FALSE; 2631 block_set_alignment = FALSE;
@@ -2778,7 +2787,8 @@ QString QTextEdit::text( int para ) const
2778 2787
2779void QTextEdit::setText( const QString &text, const QString &context ) 2788void QTextEdit::setText( const QString &text, const QString &context )
2780{ 2789{
2781 if ( !isModified() && this->context() == context && this->text() == text ) 2790 if ( !isModified() && isReadOnly() &&
2791 this->context() == context && this->text() == text )
2782 return; 2792 return;
2783 2793
2784 emit undoAvailable( FALSE ); 2794 emit undoAvailable( FALSE );
@@ -2799,10 +2809,9 @@ void QTextEdit::setText( const QString &text, const QString &context )
2799 resizeContents( 0, 0 ); 2809 resizeContents( 0, 0 );
2800 } 2810 }
2801 2811
2802 cursor->setDocument( doc ); 2812 lastFormatted = doc->firstParagraph();
2803 lastFormatted = doc->firstParag(); 2813 delete cursor;
2804 cursor->setParag( doc->firstParag() ); 2814 cursor = new QTextCursor( doc );
2805 cursor->setIndex( 0 );
2806 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 2815 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
2807 2816
2808 if ( isModified() ) 2817 if ( isModified() )
@@ -2810,6 +2819,7 @@ void QTextEdit::setText( const QString &text, const QString &context )
2810 emit textChanged(); 2819 emit textChanged();
2811 formatMore(); 2820 formatMore();
2812 updateCurrentFormat(); 2821 updateCurrentFormat();
2822 d->scrollToAnchor = QString::null;
2813} 2823}
2814 2824
2815/*! 2825/*!
@@ -2847,9 +2857,9 @@ void QTextEdit::setText( const QString &text, const QString &context )
2847 \a expr is found; otherwise returns FALSE. 2857 \a expr is found; otherwise returns FALSE.
2848 2858
2849 If \a para and \a index are both null the search begins from the 2859 If \a para and \a index are both null the search begins from the
2850 start of the text. If \a para and \a index are both not null, the 2860 current cursor position. If \a para and \a index are both not
2851 search begins from the \e *\a index character position in the \e 2861 null, the search begins from the \e *\a index character position
2852 *\a para paragraph. 2862 in the \e *\a para paragraph.
2853 2863
2854 If \a cs is TRUE the search is case sensitive, otherwise it is 2864 If \a cs is TRUE the search is case sensitive, otherwise it is
2855 case insensitive. If \a wo is TRUE the search looks for whole word 2865 case insensitive. If \a wo is TRUE the search looks for whole word
@@ -2873,14 +2883,34 @@ bool QTextEdit::find( const QString &expr, bool cs, bool wo, bool forward,
2873 int *para, int *index ) 2883 int *para, int *index )
2874{ 2884{
2875 drawCursor( FALSE ); 2885 drawCursor( FALSE );
2876 doc->removeSelection( QTextDocument::Standard );
2877#ifndef QT_NO_CURSOR 2886#ifndef QT_NO_CURSOR
2878 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor ); 2887 viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
2879#endif 2888#endif
2880 bool found = doc->find( expr, cs, wo, forward, para, index, cursor ); 2889 QTextCursor findcur = *cursor;
2881 ensureCursorVisible(); 2890 if ( para && index ) {
2891 if ( doc->paragAt( *para ) )
2892 findcur.gotoPosition( doc->paragAt(*para), *index );
2893 else
2894 findcur.gotoEnd();
2895 } else if ( doc->hasSelection( QTextDocument::Standard ) ){
2896 // maks sure we do not find the same selection again
2897 if ( forward )
2898 findcur.gotoNextLetter();
2899 else
2900 findcur.gotoPreviousLetter();
2901 }
2902 removeSelection( QTextDocument::Standard );
2903 bool found = doc->find( findcur, expr, cs, wo, forward );
2904 if ( found ) {
2905 if ( para )
2906 *para = findcur.paragraph()->paragId();
2907 if ( index )
2908 *index = findcur.index();
2909 *cursor = findcur;
2910 repaintChanged();
2911 ensureCursorVisible();
2912 }
2882 drawCursor( TRUE ); 2913 drawCursor( TRUE );
2883 repaintChanged();
2884 return found; 2914 return found;
2885} 2915}
2886 2916
@@ -2902,7 +2932,7 @@ void QTextEdit::blinkCursor()
2902 2932
2903void QTextEdit::setCursorPosition( int para, int index ) 2933void QTextEdit::setCursorPosition( int para, int index )
2904{ 2934{
2905 QTextParag *p = doc->paragAt( para ); 2935 QTextParagraph *p = doc->paragAt( para );
2906 if ( !p ) 2936 if ( !p )
2907 return; 2937 return;
2908 2938
@@ -2910,12 +2940,13 @@ void QTextEdit::setCursorPosition( int para, int index )
2910 index = p->length() - 1; 2940 index = p->length() - 1;
2911 2941
2912 drawCursor( FALSE ); 2942 drawCursor( FALSE );
2913 cursor->setParag( p ); 2943 cursor->setParagraph( p );
2914 cursor->setIndex( index ); 2944 cursor->setIndex( index );
2915 ensureCursorVisible(); 2945 ensureCursorVisible();
2916 drawCursor( TRUE ); 2946 drawCursor( TRUE );
2947 updateCurrentFormat();
2917 emit cursorPositionChanged( cursor ); 2948 emit cursorPositionChanged( cursor );
2918 emit cursorPositionChanged( cursor->parag()->paragId(), cursor->index() ); 2949 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
2919} 2950}
2920 2951
2921/*! 2952/*!
@@ -2930,7 +2961,7 @@ void QTextEdit::getCursorPosition( int *para, int *index ) const
2930{ 2961{
2931 if ( !para || !index ) 2962 if ( !para || !index )
2932 return; 2963 return;
2933 *para = cursor->parag()->paragId(); 2964 *para = cursor->paragraph()->paragId();
2934 *index = cursor->index(); 2965 *index = cursor->index();
2935} 2966}
2936 2967
@@ -2958,10 +2989,10 @@ void QTextEdit::setSelection( int paraFrom, int indexFrom,
2958 } 2989 }
2959 if ( selNum > doc->numSelections() - 1 ) 2990 if ( selNum > doc->numSelections() - 1 )
2960 doc->addSelection( selNum ); 2991 doc->addSelection( selNum );
2961 QTextParag *p1 = doc->paragAt( paraFrom ); 2992 QTextParagraph *p1 = doc->paragAt( paraFrom );
2962 if ( !p1 ) 2993 if ( !p1 )
2963 return; 2994 return;
2964 QTextParag *p2 = doc->paragAt( paraTo ); 2995 QTextParagraph *p2 = doc->paragAt( paraTo );
2965 if ( !p2 ) 2996 if ( !p2 )
2966 return; 2997 return;
2967 2998
@@ -2973,12 +3004,12 @@ void QTextEdit::setSelection( int paraFrom, int indexFrom,
2973 drawCursor( FALSE ); 3004 drawCursor( FALSE );
2974 QTextCursor c = *cursor; 3005 QTextCursor c = *cursor;
2975 QTextCursor oldCursor = *cursor; 3006 QTextCursor oldCursor = *cursor;
2976 c.setParag( p1 ); 3007 c.setParagraph( p1 );
2977 c.setIndex( indexFrom ); 3008 c.setIndex( indexFrom );
2978 cursor->setParag( p2 ); 3009 cursor->setParagraph( p2 );
2979 cursor->setIndex( indexTo ); 3010 cursor->setIndex( indexTo );
2980 doc->setSelectionStart( selNum, &c ); 3011 doc->setSelectionStart( selNum, c );
2981 doc->setSelectionEnd( selNum, cursor ); 3012 doc->setSelectionEnd( selNum, *cursor );
2982 repaintChanged(); 3013 repaintChanged();
2983 ensureCursorVisible(); 3014 ensureCursorVisible();
2984 if ( selNum != QTextDocument::Standard ) 3015 if ( selNum != QTextDocument::Standard )
@@ -3056,7 +3087,7 @@ Qt::TextFormat QTextEdit::textFormat() const
3056 3087
3057int QTextEdit::paragraphs() const 3088int QTextEdit::paragraphs() const
3058{ 3089{
3059 return doc->lastParag()->paragId() + 1; 3090 return doc->lastParagraph()->paragId() + 1;
3060} 3091}
3061 3092
3062/*! 3093/*!
@@ -3066,7 +3097,7 @@ int QTextEdit::paragraphs() const
3066 3097
3067int QTextEdit::linesOfParagraph( int para ) const 3098int QTextEdit::linesOfParagraph( int para ) const
3068{ 3099{
3069 QTextParag *p = doc->paragAt( para ); 3100 QTextParagraph *p = doc->paragAt( para );
3070 if ( !p ) 3101 if ( !p )
3071 return -1; 3102 return -1;
3072 return p->lines(); 3103 return p->lines();
@@ -3079,7 +3110,7 @@ int QTextEdit::linesOfParagraph( int para ) const
3079 3110
3080int QTextEdit::paragraphLength( int para ) const 3111int QTextEdit::paragraphLength( int para ) const
3081{ 3112{
3082 QTextParag *p = doc->paragAt( para ); 3113 QTextParagraph *p = doc->paragAt( para );
3083 if ( !p ) 3114 if ( !p )
3084 return -1; 3115 return -1;
3085 return p->length() - 1; 3116 return p->length() - 1;
@@ -3095,7 +3126,7 @@ int QTextEdit::paragraphLength( int para ) const
3095 3126
3096int QTextEdit::lines() const 3127int QTextEdit::lines() const
3097{ 3128{
3098 QTextParag *p = doc->firstParag(); 3129 QTextParagraph *p = doc->firstParagraph();
3099 int l = 0; 3130 int l = 0;
3100 while ( p ) { 3131 while ( p ) {
3101 l += p->lines(); 3132 l += p->lines();
@@ -3115,7 +3146,7 @@ int QTextEdit::lines() const
3115 3146
3116int QTextEdit::lineOfChar( int para, int index ) 3147int QTextEdit::lineOfChar( int para, int index )
3117{ 3148{
3118 QTextParag *p = doc->paragAt( para ); 3149 QTextParagraph *p = doc->paragAt( para );
3119 if ( !p ) 3150 if ( !p )
3120 return -1; 3151 return -1;
3121 3152
@@ -3248,7 +3279,7 @@ void QTextEdit::startDrag()
3248#ifndef QT_NO_DRAGANDDROP 3279#ifndef QT_NO_DRAGANDDROP
3249 mousePressed = FALSE; 3280 mousePressed = FALSE;
3250 inDoubleClick = FALSE; 3281 inDoubleClick = FALSE;
3251 QDragObject *drag = new QTextDrag( doc->selectedText( QTextDocument::Standard ), viewport() ); 3282 QDragObject *drag = new QTextDrag( doc->selectedText( QTextDocument::Standard, qt_enable_richtext_copy ), viewport() );
3252 if ( isReadOnly() ) { 3283 if ( isReadOnly() ) {
3253 drag->dragCopy(); 3284 drag->dragCopy();
3254 } else { 3285 } else {
@@ -3285,22 +3316,20 @@ void QTextEdit::UndoRedoInfo::clear()
3285{ 3316{
3286 if ( valid() ) { 3317 if ( valid() ) {
3287 if ( type == Insert || type == Return ) 3318 if ( type == Insert || type == Return )
3288 doc->addCommand( new QTextInsertCommand( doc, id, index, d->text.rawData(), oldStyles, oldListStyles, oldAligns ) ); 3319 doc->addCommand( new QTextInsertCommand( doc, id, index, d->text.rawData(), styleInformation ) );
3289 else if ( type == Format ) 3320 else if ( type == Format )
3290 doc->addCommand( new QTextFormatCommand( doc, id, index, eid, eindex, d->text.rawData(), format, flags ) ); 3321 doc->addCommand( new QTextFormatCommand( doc, id, index, eid, eindex, d->text.rawData(), format, flags ) );
3291 else if ( type == Alignment ) 3322 else if ( type == Style )
3292 doc->addCommand( new QTextAlignmentCommand( doc, id, eid, newAlign, oldAligns ) ); 3323 doc->addCommand( new QTextStyleCommand( doc, id, eid, styleInformation ) );
3293 else if ( type == ParagType ) 3324 else if ( type != Invalid ) {
3294 doc->addCommand( new QTextParagTypeCommand( doc, id, eid, list, listStyle, oldStyles, oldListStyles ) ); 3325 doc->addCommand( new QTextDeleteCommand( doc, id, index, d->text.rawData(), styleInformation ) );
3295 else if ( type != Invalid ) 3326 }
3296 doc->addCommand( new QTextDeleteCommand( doc, id, index, d->text.rawData(), oldStyles, oldListStyles, oldAligns ) );
3297 } 3327 }
3328 type = Invalid;
3298 d->text = QString::null; 3329 d->text = QString::null;
3299 id = -1; 3330 id = -1;
3300 index = -1; 3331 index = -1;
3301 oldStyles.clear(); 3332 styleInformation = QByteArray();
3302 oldListStyles.clear();
3303 oldAligns.resize( 0 );
3304} 3333}
3305 3334
3306 3335
@@ -3340,7 +3369,7 @@ QTextEdit::UndoRedoInfo::~UndoRedoInfo()
3340 3369
3341bool QTextEdit::UndoRedoInfo::valid() const 3370bool QTextEdit::UndoRedoInfo::valid() const
3342{ 3371{
3343 return d->text.length() > 0 && id >= 0 && index >= 0; 3372 return id >= 0 && type != Invalid;
3344} 3373}
3345 3374
3346/*! 3375/*!
@@ -3409,10 +3438,7 @@ QBrush QTextEdit::paper() const
3409 3438
3410void QTextEdit::setLinkUnderline( bool b ) 3439void QTextEdit::setLinkUnderline( bool b )
3411{ 3440{
3412 if ( b == doc->underlineLinks() )
3413 return;
3414 doc->setUnderlineLinks( b ); 3441 doc->setUnderlineLinks( b );
3415 updateStyles();
3416} 3442}
3417 3443
3418bool QTextEdit::linkUnderline() const 3444bool QTextEdit::linkUnderline() const
@@ -3465,10 +3491,9 @@ int QTextEdit::heightForWidth( int w ) const
3465void QTextEdit::append( const QString &text ) 3491void QTextEdit::append( const QString &text )
3466{ 3492{
3467 // flush and clear the undo/redo stack if necessary 3493 // flush and clear the undo/redo stack if necessary
3468 if ( isReadOnly() && undoRedoInfo.valid() ) { 3494 undoRedoInfo.clear();
3469 undoRedoInfo.clear(); 3495 doc->commands()->clear();
3470 doc->commands()->clear(); 3496
3471 }
3472 doc->removeSelection( QTextDocument::Standard ); 3497 doc->removeSelection( QTextDocument::Standard );
3473 TextFormat f = doc->textFormat(); 3498 TextFormat f = doc->textFormat();
3474 if ( f == AutoText ) { 3499 if ( f == AutoText ) {
@@ -3477,35 +3502,37 @@ void QTextEdit::append( const QString &text )
3477 else 3502 else
3478 f = PlainText; 3503 f = PlainText;
3479 } 3504 }
3480 if ( f == PlainText ) { 3505
3481 QTextCursor oldc( *cursor ); 3506 drawCursor( FALSE );
3482 ensureFormatted( doc->lastParag() ); 3507 QTextCursor oldc( *cursor );
3483 bool scrollToEnd = contentsY() >= contentsHeight() - visibleHeight() - 3508 ensureFormatted( doc->lastParagraph() );
3484 ( horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0 ); 3509 bool atBottom = contentsY() >= contentsHeight() - visibleHeight();
3485 if ( !scrollToEnd ) 3510 cursor->gotoEnd();
3486 blockEnsureCursorVisible = TRUE; 3511 if ( cursor->index() > 0 )
3487 cursor->gotoEnd(); 3512 cursor->splitAndInsertEmptyParagraph();
3488 if ( cursor->index() > 0 ) 3513 QTextCursor oldCursor2 = *cursor;
3489 cursor->splitAndInsertEmptyParag(); 3514
3490 QTextCursor oldCursor2 = *cursor; 3515 if ( f == Qt::PlainText ) {
3491 cursor->insert( text, TRUE ); 3516 cursor->insert( text, TRUE );
3492 if ( doc->useFormatCollection() && currentFormat != cursor->parag()->at( cursor->index() )->format() ) { 3517 if ( doc->useFormatCollection() &&
3493 doc->setSelectionStart( QTextDocument::Temp, &oldCursor2 ); 3518 currentFormat != cursor->paragraph()->at( cursor->index() )->format() ) {
3494 doc->setSelectionEnd( QTextDocument::Temp, cursor ); 3519 doc->setSelectionStart( QTextDocument::Temp, oldCursor2 );
3520 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
3495 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format ); 3521 doc->setFormat( QTextDocument::Temp, currentFormat, QTextFormat::Format );
3496 doc->removeSelection( QTextDocument::Temp ); 3522 doc->removeSelection( QTextDocument::Temp );
3497 } 3523 }
3498 formatMore(); 3524 } else {
3499 repaintChanged(); 3525 if ( cursor->paragraph()->prev() )
3500 ensureCursorVisible(); 3526 cursor->paragraph()->prev()->invalidate(0); // vertical margins might have to change
3501 drawCursor( TRUE );
3502 *cursor = oldc;
3503 if ( !scrollToEnd )
3504 blockEnsureCursorVisible = FALSE;
3505 } else if ( f == RichText ) {
3506 doc->setRichTextInternal( text ); 3527 doc->setRichTextInternal( text );
3507 repaintChanged();
3508 } 3528 }
3529 formatMore();
3530 repaintChanged();
3531 if ( atBottom )
3532 scrollToBottom();
3533 *cursor = oldc;
3534 if ( !isReadOnly() )
3535 cursorVisible = TRUE;
3509 setModified(); 3536 setModified();
3510 emit textChanged(); 3537 emit textChanged();
3511} 3538}
@@ -3617,7 +3644,7 @@ QString QTextEdit::documentTitle() const
3617 return doc->attributes()[ "title" ]; 3644 return doc->attributes()[ "title" ];
3618} 3645}
3619 3646
3620void QTextEdit::makeParagVisible( QTextParag *p ) 3647void QTextEdit::makeParagVisible( QTextParagraph *p )
3621{ 3648{
3622 setContentsPos( contentsX(), QMIN( p->rect().y(), contentsHeight() - visibleHeight() ) ); 3649 setContentsPos( contentsX(), QMIN( p->rect().y(), contentsHeight() - visibleHeight() ) );
3623} 3650}
@@ -3630,23 +3657,29 @@ void QTextEdit::makeParagVisible( QTextParag *p )
3630 3657
3631void QTextEdit::scrollToAnchor( const QString& name ) 3658void QTextEdit::scrollToAnchor( const QString& name )
3632{ 3659{
3660 if ( !isVisible() ) {
3661 d->scrollToAnchor = name;
3662 return;
3663 }
3633 if ( name.isEmpty() ) 3664 if ( name.isEmpty() )
3634 return; 3665 return;
3635 sync(); 3666 sync();
3636 QTextCursor cursor( doc ); 3667 QTextCursor cursor( doc );
3637 QTextParag* last = doc->lastParag(); 3668 QTextParagraph* last = doc->lastParagraph();
3638 do { 3669 for (;;) {
3639 QTextStringChar* c = cursor.parag()->at( cursor.index() ); 3670 QTextStringChar* c = cursor.paragraph()->at( cursor.index() );
3640 if( c->isAnchor() ) { 3671 if( c->isAnchor() ) {
3641 QString a = c->anchorName(); 3672 QString a = c->anchorName();
3642 if ( a == name || 3673 if ( a == name ||
3643 (a.contains( '#' ) && QStringList::split( '#', a ).contains( name ) ) ) { 3674 (a.contains( '#' ) && QStringList::split( '#', a ).contains( name ) ) ) {
3644 setContentsPos( contentsX(), QMIN( cursor.parag()->rect().top() + cursor.totalOffsetY(), contentsHeight() - visibleHeight() ) ); 3675 setContentsPos( contentsX(), QMIN( cursor.paragraph()->rect().top() + cursor.totalOffsetY(), contentsHeight() - visibleHeight() ) );
3645 return; 3676 break;
3646 } 3677 }
3647 } 3678 }
3679 if ( cursor.paragraph() == last && cursor.atParagEnd() )
3680 break;
3648 cursor.gotoNextLetter(); 3681 cursor.gotoNextLetter();
3649 } while( cursor.parag() != last || !cursor.atParagEnd() ); 3682 }
3650} 3683}
3651 3684
3652/*! If there is an anchor at position \a pos (in contents 3685/*! If there is an anchor at position \a pos (in contents
@@ -3658,7 +3691,7 @@ QString QTextEdit::anchorAt( const QPoint& pos )
3658{ 3691{
3659 QTextCursor c( doc ); 3692 QTextCursor c( doc );
3660 placeCursor( pos, &c ); 3693 placeCursor( pos, &c );
3661 return c.parag()->at( c.index() )->anchorHref(); 3694 return c.paragraph()->at( c.index() )->anchorHref();
3662} 3695}
3663 3696
3664void QTextEdit::documentWidthChanged( int w ) 3697void QTextEdit::documentWidthChanged( int w )
@@ -3666,15 +3699,13 @@ void QTextEdit::documentWidthChanged( int w )
3666 resizeContents( QMAX( visibleWidth(), w), contentsHeight() ); 3699 resizeContents( QMAX( visibleWidth(), w), contentsHeight() );
3667} 3700}
3668 3701
3669/*! 3702/*! \internal
3670 Updates all the rendering styles used to display the text. You will 3703
3671 probably want to call this function after calling setStyleSheet(). 3704 This function does nothing
3672*/ 3705*/
3673 3706
3674void QTextEdit::updateStyles() 3707void QTextEdit::updateStyles()
3675{ 3708{
3676 doc->updateStyles();
3677 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3678} 3709}
3679 3710
3680void QTextEdit::setDocument( QTextDocument *dc ) 3711void QTextEdit::setDocument( QTextDocument *dc )
@@ -3682,8 +3713,10 @@ void QTextEdit::setDocument( QTextDocument *dc )
3682 if ( dc == doc ) 3713 if ( dc == doc )
3683 return; 3714 return;
3684 doc = dc; 3715 doc = dc;
3685 cursor->setDocument( doc ); 3716 delete cursor;
3717 cursor = new QTextCursor( doc );
3686 clearUndoRedo(); 3718 clearUndoRedo();
3719 undoRedoInfo.doc = doc;
3687 lastFormatted = 0; 3720 lastFormatted = 0;
3688} 3721}
3689 3722
@@ -3703,7 +3736,52 @@ void QTextEdit::pasteSubType( const QCString& subtype )
3703{ 3736{
3704 QCString st = subtype; 3737 QCString st = subtype;
3705 QString t = QApplication::clipboard()->text(st); 3738 QString t = QApplication::clipboard()->text(st);
3739 if ( doc->hasSelection( QTextDocument::Standard ) )
3740 removeSelectedText();
3706 if ( !t.isEmpty() ) { 3741 if ( !t.isEmpty() ) {
3742 if ( t.startsWith( "<selstart/>" ) ) {
3743 t.remove( 0, 11 );
3744 QTextCursor oldC = *cursor;
3745 lastFormatted = cursor->paragraph();
3746 if ( lastFormatted->prev() )
3747 lastFormatted = lastFormatted->prev();
3748 doc->setRichTextInternal( t, cursor );
3749
3750 if ( undoEnabled && !isReadOnly() ) {
3751 doc->setSelectionStart( QTextDocument::Temp, oldC );
3752 doc->setSelectionEnd( QTextDocument::Temp, *cursor );
3753
3754 checkUndoRedoInfo( UndoRedoInfo::Insert );
3755 if ( !undoRedoInfo.valid() ) {
3756 undoRedoInfo.id = oldC.paragraph()->paragId();
3757 undoRedoInfo.index = oldC.index();
3758 undoRedoInfo.d->text = QString::null;
3759 }
3760 int oldLen = undoRedoInfo.d->text.length();
3761 if ( !doc->preProcessor() ) {
3762 QString txt = doc->selectedText( QTextDocument::Temp );
3763 undoRedoInfo.d->text += txt;
3764 for ( int i = 0; i < (int)txt.length(); ++i ) {
3765 if ( txt[ i ] != '\n' && oldC.paragraph()->at( oldC.index() )->format() ) {
3766 oldC.paragraph()->at( oldC.index() )->format()->addRef();
3767 undoRedoInfo.d->text.
3768 setFormat( oldLen + i, oldC.paragraph()->at( oldC.index() )->format(), TRUE );
3769 }
3770 oldC.gotoNextLetter();
3771 }
3772 }
3773 undoRedoInfo.clear();
3774 removeSelection( QTextDocument::Temp );
3775 }
3776
3777 formatMore();
3778 setModified();
3779 emit textChanged();
3780 repaintChanged();
3781 ensureCursorVisible();
3782 return;
3783 }
3784
3707#if defined(Q_OS_WIN32) 3785#if defined(Q_OS_WIN32)
3708 // Need to convert CRLF to LF 3786 // Need to convert CRLF to LF
3709 int index = t.find( QString::fromLatin1("\r\n"), 0 ); 3787 int index = t.find( QString::fromLatin1("\r\n"), 0 );
@@ -3838,7 +3916,7 @@ void QTextEdit::setWordWrap( WordWrap mode )
3838 doc->setMinimumWidth( -1 ); 3916 doc->setMinimumWidth( -1 );
3839 doc->invalidate(); 3917 doc->invalidate();
3840 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 3918 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3841 lastFormatted = doc->firstParag(); 3919 lastFormatted = doc->firstParagraph();
3842 interval = 0; 3920 interval = 0;
3843 formatMore(); 3921 formatMore();
3844 break; 3922 break;
@@ -3899,7 +3977,7 @@ void QTextEdit::setWrapColumnOrWidth( int value )
3899 } 3977 }
3900 doc->invalidate(); 3978 doc->invalidate();
3901 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 3979 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3902 lastFormatted = doc->firstParag(); 3980 lastFormatted = doc->firstParagraph();
3903 interval = 0; 3981 interval = 0;
3904 formatMore(); 3982 formatMore();
3905} 3983}
@@ -3952,7 +4030,7 @@ void QTextEdit::setWrapPolicy( WrapPolicy policy )
3952 document()->setFormatter( formatter ); 4030 document()->setFormatter( formatter );
3953 doc->invalidate(); 4031 doc->invalidate();
3954 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4032 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3955 lastFormatted = doc->firstParag(); 4033 lastFormatted = doc->firstParagraph();
3956 interval = 0; 4034 interval = 0;
3957 formatMore(); 4035 formatMore();
3958} 4036}
@@ -3979,14 +4057,13 @@ void QTextEdit::clear()
3979 if ( cursor->isValid() ) 4057 if ( cursor->isValid() )
3980 cursor->restoreState(); 4058 cursor->restoreState();
3981 doc->clear( TRUE ); 4059 doc->clear( TRUE );
3982 cursor->setDocument( doc ); 4060 delete cursor;
3983 cursor->setParag( doc->firstParag() ); 4061 cursor = new QTextCursor( doc );
3984 cursor->setIndex( 0 );
3985 lastFormatted = 0; 4062 lastFormatted = 0;
3986 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4063 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
3987 4064
3988 emit cursorPositionChanged( cursor ); 4065 emit cursorPositionChanged( cursor );
3989 emit cursorPositionChanged( cursor->parag()->paragId(), cursor->index() ); 4066 emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
3990} 4067}
3991 4068
3992int QTextEdit::undoDepth() const 4069int QTextEdit::undoDepth() const
@@ -4025,7 +4102,7 @@ void QTextEdit::setTabStopWidth( int ts )
4025{ 4102{
4026 document()->setTabStops( ts ); 4103 document()->setTabStops( ts );
4027 doc->invalidate(); 4104 doc->invalidate();
4028 lastFormatted = doc->firstParag(); 4105 lastFormatted = doc->firstParagraph();
4029 interval = 0; 4106 interval = 0;
4030 formatMore(); 4107 formatMore();
4031 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 4108 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
@@ -4046,7 +4123,13 @@ void QTextEdit::clearUndoRedo()
4046 emit redoAvailable( doc->commands()->isRedoAvailable() ); 4123 emit redoAvailable( doc->commands()->isRedoAvailable() );
4047} 4124}
4048 4125
4049/*! This function gets the format of the character at position \a 4126/*! \internal
4127
4128 \warning In Qt 3.1 we will provide a cleaer API for the
4129 functionality which is provided by this function and in Qt 4.0 this
4130 function will go away.
4131
4132 This function gets the format of the character at position \a
4050 index in paragraph \a para. Sets \a font to the character's font, \a 4133 index in paragraph \a para. Sets \a font to the character's font, \a
4051 color to the character's color and \a verticalAlignment to the 4134 color to the character's color and \a verticalAlignment to the
4052 character's vertical alignment. 4135 character's vertical alignment.
@@ -4059,7 +4142,7 @@ bool QTextEdit::getFormat( int para, int index, QFont *font, QColor *color, Vert
4059{ 4142{
4060 if ( !font || !color ) 4143 if ( !font || !color )
4061 return FALSE; 4144 return FALSE;
4062 QTextParag *p = doc->paragAt( para ); 4145 QTextParagraph *p = doc->paragAt( para );
4063 if ( !p ) 4146 if ( !p )
4064 return FALSE; 4147 return FALSE;
4065 if ( index < 0 || index >= p->length() ) 4148 if ( index < 0 || index >= p->length() )
@@ -4070,7 +4153,13 @@ bool QTextEdit::getFormat( int para, int index, QFont *font, QColor *color, Vert
4070 return TRUE; 4153 return TRUE;
4071} 4154}
4072 4155
4073/*! This function gets the format of the paragraph \a para. Sets \a 4156/*! \internal
4157
4158 \warning In Qt 3.1 we will provide a cleaer API for the
4159 functionality which is provided by this function and in Qt 4.0 this
4160 function will go away.
4161
4162 This function gets the format of the paragraph \a para. Sets \a
4074 font to the paragraphs's font, \a color to the paragraph's color, \a 4163 font to the paragraphs's font, \a color to the paragraph's color, \a
4075 verticalAlignment to the paragraph's vertical alignment, \a 4164 verticalAlignment to the paragraph's vertical alignment, \a
4076 alignment to the paragraph's alignment, \a displayMode to the 4165 alignment to the paragraph's alignment, \a displayMode to the
@@ -4090,14 +4179,14 @@ bool QTextEdit::getParagraphFormat( int para, QFont *font, QColor *color,
4090{ 4179{
4091 if ( !font || !color || !alignment || !displayMode || !listStyle ) 4180 if ( !font || !color || !alignment || !displayMode || !listStyle )
4092 return FALSE; 4181 return FALSE;
4093 QTextParag *p = doc->paragAt( para ); 4182 QTextParagraph *p = doc->paragAt( para );
4094 if ( !p ) 4183 if ( !p )
4095 return FALSE; 4184 return FALSE;
4096 *font = p->paragFormat()->font(); 4185 *font = p->at(0)->format()->font();
4097 *color = p->paragFormat()->color(); 4186 *color = p->at(0)->format()->color();
4098 *verticalAlignment = (VerticalAlignment)p->paragFormat()->vAlign(); 4187 *verticalAlignment = (VerticalAlignment)p->at(0)->format()->vAlign();
4099 *alignment = p->alignment(); 4188 *alignment = p->alignment();
4100 *displayMode = p->style() ? p->style()->displayMode() : QStyleSheetItem::DisplayBlock; 4189 *displayMode = p->isListItem() ? QStyleSheetItem::DisplayListItem : QStyleSheetItem::DisplayBlock;
4101 *listStyle = p->listStyle(); 4190 *listStyle = p->listStyle();
4102 *listDepth = p->listDepth(); 4191 *listDepth = p->listDepth();
4103 return TRUE; 4192 return TRUE;
@@ -4155,10 +4244,14 @@ QPopupMenu *QTextEdit::createPopupMenu( const QPoint& pos )
4155} 4244}
4156 4245
4157/*! \overload 4246/*! \overload
4247 \obsolete
4158 This function is called to create a right mouse button popup menu. 4248 This function is called to create a right mouse button popup menu.
4159 If you want to create a custom popup menu, reimplement this function 4249 If you want to create a custom popup menu, reimplement this function
4160 and return the created popup menu. Ownership of the popup menu is 4250 and return the created popup menu. Ownership of the popup menu is
4161 transferred to the caller. 4251 transferred to the caller.
4252
4253 This function is only called if createPopupMenu( const QPoint & )
4254 returns 0.
4162*/ 4255*/
4163 4256
4164QPopupMenu *QTextEdit::createPopupMenu() 4257QPopupMenu *QTextEdit::createPopupMenu()
@@ -4173,21 +4266,8 @@ void QTextEdit::setFont( const QFont &f )
4173 QFont old( QScrollView::font() ); 4266 QFont old( QScrollView::font() );
4174 QScrollView::setFont( f ); 4267 QScrollView::setFont( f );
4175 doc->setMinimumWidth( -1 ); 4268 doc->setMinimumWidth( -1 );
4176 4269 doc->setDefaultFormat( f, doc->formatCollection()->defaultFormat()->color() );
4177 // ### that is a bit hacky 4270 lastFormatted = doc->firstParagraph();
4178 static short diff = 1;
4179 diff *= -1;
4180 doc->setWidth( visibleWidth() + diff );
4181
4182 int s = f.pointSize();
4183 bool usePixels = FALSE;
4184 if ( s == -1 ) {
4185 s = f.pixelSize();
4186 usePixels = TRUE;
4187 }
4188 doc->updateFontSizes( s, usePixels );
4189 doc->updateFontAttributes( f, old );
4190 lastFormatted = doc->firstParag();
4191 formatMore(); 4271 formatMore();
4192 repaintChanged(); 4272 repaintChanged();
4193} 4273}
@@ -4273,10 +4353,9 @@ void QTextEdit::zoomTo( int size )
4273 4353
4274void QTextEdit::sync() 4354void QTextEdit::sync()
4275{ 4355{
4276 QTextParag *p = lastFormatted; 4356 while ( lastFormatted ) {
4277 while ( p ) { 4357 lastFormatted->format();
4278 p->format(); 4358 lastFormatted = lastFormatted->next();
4279 p = p->next();
4280 } 4359 }
4281 resizeContents( contentsWidth(), doc->height() ); 4360 resizeContents( contentsWidth(), doc->height() );
4282} 4361}
@@ -4360,7 +4439,7 @@ QRect QTextEdit::paragraphRect( int para ) const
4360{ 4439{
4361 QTextEdit *that = (QTextEdit *)this; 4440 QTextEdit *that = (QTextEdit *)this;
4362 that->sync(); 4441 that->sync();
4363 QTextParag *p = doc->paragAt( para ); 4442 QTextParagraph *p = doc->paragAt( para );
4364 if ( !p ) 4443 if ( !p )
4365 return QRect( -1, -1, -1, -1 ); 4444 return QRect( -1, -1, -1, -1 );
4366 return p->rect(); 4445 return p->rect();
@@ -4374,9 +4453,9 @@ QRect QTextEdit::paragraphRect( int para ) const
4374int QTextEdit::paragraphAt( const QPoint &pos ) const 4453int QTextEdit::paragraphAt( const QPoint &pos ) const
4375{ 4454{
4376 QTextCursor c( doc ); 4455 QTextCursor c( doc );
4377 c.place( pos, doc->firstParag() ); 4456 c.place( pos, doc->firstParagraph() );
4378 if ( c.parag() ) 4457 if ( c.paragraph() )
4379 return c.parag()->paragId(); 4458 return c.paragraph()->paragId();
4380 return -1; 4459 return -1;
4381} 4460}
4382 4461
@@ -4390,10 +4469,10 @@ int QTextEdit::paragraphAt( const QPoint &pos ) const
4390int QTextEdit::charAt( const QPoint &pos, int *para ) const 4469int QTextEdit::charAt( const QPoint &pos, int *para ) const
4391{ 4470{
4392 QTextCursor c( doc ); 4471 QTextCursor c( doc );
4393 c.place( pos, doc->firstParag() ); 4472 c.place( pos, doc->firstParagraph() );
4394 if ( c.parag() ) { 4473 if ( c.paragraph() ) {
4395 if ( para ) 4474 if ( para )
4396 *para = c.parag()->paragId(); 4475 *para = c.paragraph()->paragId();
4397 return c.index(); 4476 return c.index();
4398 } 4477 }
4399 return -1; 4478 return -1;
@@ -4403,7 +4482,7 @@ int QTextEdit::charAt( const QPoint &pos, int *para ) const
4403 4482
4404void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg ) 4483void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg )
4405{ 4484{
4406 QTextParag *p = doc->paragAt( para ); 4485 QTextParagraph *p = doc->paragAt( para );
4407 if ( !p ) 4486 if ( !p )
4408 return; 4487 return;
4409 p->setBackgroundColor( bg ); 4488 p->setBackgroundColor( bg );
@@ -4416,7 +4495,7 @@ void QTextEdit::setParagraphBackgroundColor( int para, const QColor &bg )
4416 4495
4417void QTextEdit::clearParagraphBackground( int para ) 4496void QTextEdit::clearParagraphBackground( int para )
4418{ 4497{
4419 QTextParag *p = doc->paragAt( para ); 4498 QTextParagraph *p = doc->paragAt( para );
4420 if ( !p ) 4499 if ( !p )
4421 return; 4500 return;
4422 p->clearBackgroundColor(); 4501 p->clearBackgroundColor();
@@ -4430,7 +4509,7 @@ void QTextEdit::clearParagraphBackground( int para )
4430 4509
4431QColor QTextEdit::paragraphBackgroundColor( int para ) const 4510QColor QTextEdit::paragraphBackgroundColor( int para ) const
4432{ 4511{
4433 QTextParag *p = doc->paragAt( para ); 4512 QTextParagraph *p = doc->paragAt( para );
4434 if ( !p ) 4513 if ( !p )
4435 return QColor(); 4514 return QColor();
4436 QColor *c = p->backgroundColor(); 4515 QColor *c = p->backgroundColor();
@@ -4469,7 +4548,7 @@ bool QTextEdit::isRedoAvailable() const
4469 return doc->commands()->isRedoAvailable(); 4548 return doc->commands()->isRedoAvailable();
4470} 4549}
4471 4550
4472void QTextEdit::ensureFormatted( QTextParag *p ) 4551void QTextEdit::ensureFormatted( QTextParagraph *p )
4473{ 4552{
4474 while ( !p->isValid() ) { 4553 while ( !p->isValid() ) {
4475 if ( !lastFormatted ) 4554 if ( !lastFormatted )
@@ -4486,11 +4565,11 @@ void QTextEdit::updateCursor( const QPoint & pos )
4486 placeCursor( pos, &c, TRUE ); 4565 placeCursor( pos, &c, TRUE );
4487 4566
4488#ifndef QT_NO_NETWORKPROTOCOL 4567#ifndef QT_NO_NETWORKPROTOCOL
4489 if ( c.parag() && c.parag()->at( c.index() ) && 4568 if ( c.paragraph() && c.paragraph()->at( c.index() ) &&
4490 c.parag()->at( c.index() )->isAnchor() && 4569 c.paragraph()->at( c.index() )->isAnchor() &&
4491 !c.parag()->at( c.index() )->anchorHref().isEmpty() ) { 4570 !c.paragraph()->at( c.index() )->anchorHref().isEmpty() ) {
4492 if ( c.index() < c.parag()->length() - 1 ) 4571 if ( c.index() < c.paragraph()->length() - 1 )
4493 onLink = c.parag()->at( c.index() )->anchorHref(); 4572 onLink = c.paragraph()->at( c.index() )->anchorHref();
4494 else 4573 else
4495 onLink = QString::null; 4574 onLink = QString::null;
4496 4575
diff --git a/noncore/apps/opie-write/qtextedit.h b/noncore/apps/opie-write/qtextedit.h
index b4e5701..64e8f45 100644
--- a/noncore/apps/opie-write/qtextedit.h
+++ b/noncore/apps/opie-write/qtextedit.h
@@ -61,9 +61,11 @@ class QTextString;
61class QTextDocument; 61class QTextDocument;
62class QTextCursor; 62class QTextCursor;
63class QTextCommand; 63class QTextCommand;
64class QTextParag; 64class QTextParagraph;
65class QTextFormat; 65class QTextFormat;
66class QTextEdit;
66class QTextBrowser; 67class QTextBrowser;
68class QTextString;
67class QTextEditPrivate; 69class QTextEditPrivate;
68 70
69class Q_EXPORT QTextEdit : public QScrollView 71class Q_EXPORT QTextEdit : public QScrollView
@@ -196,12 +198,17 @@ public:
196 QFont font() const; 198 QFont font() const;
197 int alignment() const; 199 int alignment() const;
198 int undoDepth() const; 200 int undoDepth() const;
201
202 // do not use, will go away
199 virtual bool getFormat( int para, int index, QFont *font, QColor *color, VerticalAlignment *verticalAlignment ); 203 virtual bool getFormat( int para, int index, QFont *font, QColor *color, VerticalAlignment *verticalAlignment );
204 // do not use, will go away
200 virtual bool getParagraphFormat( int para, QFont *font, QColor *color, 205 virtual bool getParagraphFormat( int para, QFont *font, QColor *color,
201 VerticalAlignment *verticalAlignment, int *alignment, 206 VerticalAlignment *verticalAlignment, int *alignment,
202 QStyleSheetItem::DisplayMode *displayMode, 207 QStyleSheetItem::DisplayMode *displayMode,
203 QStyleSheetItem::ListStyle *listStyle, 208 QStyleSheetItem::ListStyle *listStyle,
204 int *listDepth ); 209 int *listDepth );
210
211
205 bool isOverwriteMode() const { return overWrite; } 212 bool isOverwriteMode() const { return overWrite; }
206 QColor paragraphBackgroundColor( int para ) const; 213 QColor paragraphBackgroundColor( int para ) const;
207 214
@@ -257,7 +264,10 @@ public slots:
257 virtual void setFont( const QFont &f ); 264 virtual void setFont( const QFont &f );
258 virtual void setVerticalAlignment( VerticalAlignment a ); 265 virtual void setVerticalAlignment( VerticalAlignment a );
259 virtual void setAlignment( int a ); 266 virtual void setAlignment( int a );
267
268 // do not use, will go away
260 virtual void setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::ListStyle listStyle ); 269 virtual void setParagType( QStyleSheetItem::DisplayMode dm, QStyleSheetItem::ListStyle listStyle );
270
261 virtual void setCursorPosition( int parag, int index ); 271 virtual void setCursorPosition( int parag, int index );
262 virtual void setSelection( int parag_from, int index_from, int parag_to, int index_to, int selNum = 0 ); 272 virtual void setSelection( int parag_from, int index_from, int parag_to, int index_to, int selNum = 0 );
263 virtual void setSelectionAttributes( int selNum, const QColor &back, bool invertText ); 273 virtual void setSelectionAttributes( int selNum, const QColor &back, bool invertText );
@@ -346,7 +356,7 @@ private slots:
346 356
347private: 357private:
348 struct Q_EXPORT UndoRedoInfo { 358 struct Q_EXPORT UndoRedoInfo {
349 enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected, Format, Alignment, ParagType }; 359 enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected, Format, Style };
350 360
351 UndoRedoInfo( QTextDocument *dc ); 361 UndoRedoInfo( QTextDocument *dc );
352 ~UndoRedoInfo(); 362 ~UndoRedoInfo();
@@ -362,12 +372,7 @@ private:
362 int flags; 372 int flags;
363 Type type; 373 Type type;
364 QTextDocument *doc; 374 QTextDocument *doc;
365 QMemArray<int> oldAligns; 375 QByteArray styleInformation;
366 int newAlign;
367 bool list;
368 QStyleSheetItem::ListStyle listStyle;
369 QValueList< QPtrVector<QStyleSheetItem> > oldStyles;
370 QValueList<QStyleSheetItem::ListStyle> oldListStyles;
371 }; 376 };
372 377
373private: 378private:
@@ -379,7 +384,7 @@ private:
379 void checkUndoRedoInfo( UndoRedoInfo::Type t ); 384 void checkUndoRedoInfo( UndoRedoInfo::Type t );
380 void updateCurrentFormat(); 385 void updateCurrentFormat();
381 bool handleReadOnlyKeyEvent( QKeyEvent *e ); 386 bool handleReadOnlyKeyEvent( QKeyEvent *e );
382 void makeParagVisible( QTextParag *p ); 387 void makeParagVisible( QTextParagraph *p );
383#ifndef QT_NO_MIME 388#ifndef QT_NO_MIME
384 QCString pickSpecial(QMimeSource* ms, bool always_ask, const QPoint&); 389 QCString pickSpecial(QMimeSource* ms, bool always_ask, const QPoint&);
385#endif 390#endif
@@ -391,18 +396,19 @@ private:
391 virtual void emitHighlighted( const QString & ) {} 396 virtual void emitHighlighted( const QString & ) {}
392 virtual void emitLinkClicked( const QString & ) {} 397 virtual void emitLinkClicked( const QString & ) {}
393 398
394 void readFormats( QTextCursor &c1, QTextCursor &c2, int oldLen, QTextString &text, bool fillStyles = FALSE ); 399 void readFormats( QTextCursor &c1, QTextCursor &c2, QTextString &text, bool fillStyles = FALSE );
395 void clearUndoRedo(); 400 void clearUndoRedo();
396 void paintDocument( bool drawAll, QPainter *p, int cx = -1, int cy = -1, int cw = -1, int ch = -1 ); 401 void paintDocument( bool drawAll, QPainter *p, int cx = -1, int cy = -1, int cw = -1, int ch = -1 );
397 void moveCursor( CursorAction action ); 402 void moveCursor( CursorAction action );
398 void ensureFormatted( QTextParag *p ); 403 void ensureFormatted( QTextParagraph *p );
399 void placeCursor( const QPoint &pos, QTextCursor *c, bool link ); 404 void placeCursor( const QPoint &pos, QTextCursor *c, bool link );
405 void updateMicroFocusHint();
400 406
401private: 407private:
402 QTextDocument *doc; 408 QTextDocument *doc;
403 QTextCursor *cursor; 409 QTextCursor *cursor;
404 QTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer; 410 QTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer;
405 QTextParag *lastFormatted; 411 QTextParagraph *lastFormatted;
406 int interval; 412 int interval;
407 UndoRedoInfo undoRedoInfo; 413 UndoRedoInfo undoRedoInfo;
408 QTextFormat *currentFormat; 414 QTextFormat *currentFormat;