00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kotextobject.h"
00021 #include "kotextparag.h"
00022 #include "koparagcounter.h"
00023 #include "kozoomhandler.h"
00024 #include "kocommand.h"
00025 #include "kostyle.h"
00026 #include "koFontDia.h"
00027 #include "kooasiscontext.h"
00028 #include "kovariable.h"
00029 #include "koAutoFormat.h"
00030 #include <koxmlns.h>
00031 #include <kodom.h>
00032
00033 #include <klocale.h>
00034 #include <kdebug.h>
00035 #include <kapplication.h>
00036
00037 #include <qtimer.h>
00038 #include <qregexp.h>
00039 #include <qprogressdialog.h>
00040
00041 #include <assert.h>
00042
00043
00044
00045
00046 const char KoTextObject::s_customItemChar = '#';
00047
00048 struct KoTextObject::KoTextObjectPrivate
00049 {
00050 public:
00051 KoTextObjectPrivate() {
00052 afterFormattingEmitted = false;
00053 abortFormatting = false;
00054 }
00055 bool afterFormattingEmitted;
00056 bool abortFormatting;
00057 };
00058
00059 KoTextObject::KoTextObject( KoZoomHandler *zh, const QFont& defaultFont,
00060 const QString &defaultLanguage, bool hyphenation,
00061 KoParagStyle* defaultStyle, int tabStopWidth,
00062 QObject* parent, const char *name )
00063 : QObject( parent, name ), m_defaultStyle( defaultStyle ), undoRedoInfo( this )
00064 {
00065 textdoc = new KoTextDocument( zh, new KoTextFormatCollection( defaultFont, QColor(),defaultLanguage, hyphenation ) );
00066 if ( tabStopWidth != -1 )
00067 textdoc->setTabStops( tabStopWidth );
00068 init();
00069 }
00070
00071 KoTextObject::KoTextObject( KoTextDocument* _textdoc, KoParagStyle* defaultStyle,
00072 QObject* parent, const char *name )
00073 : QObject( parent, name ), m_defaultStyle( defaultStyle ), undoRedoInfo( this )
00074 {
00075 textdoc = _textdoc;
00076 init();
00077 }
00078
00079 void KoTextObject::init()
00080 {
00081 d = new KoTextObjectPrivate;
00082 m_needsSpellCheck = true;
00083 m_protectContent = false;
00084 m_visible=true;
00085 m_availableHeight = -1;
00086 m_lastFormatted = textdoc->firstParag();
00087 m_highlightSelectionAdded = false;
00088 interval = 0;
00089 changeIntervalTimer = new QTimer( this );
00090 connect( changeIntervalTimer, SIGNAL( timeout() ),
00091 this, SLOT( doChangeInterval() ) );
00092
00093 formatTimer = new QTimer( this );
00094 connect( formatTimer, SIGNAL( timeout() ),
00095 this, SLOT( formatMore() ) );
00096
00097
00098 if ( m_lastFormatted && m_defaultStyle )
00099 m_lastFormatted->applyStyle( m_defaultStyle );
00100
00101 connect( textdoc, SIGNAL( paragraphDeleted( KoTextParag* ) ),
00102 this, SIGNAL( paragraphDeleted( KoTextParag* ) ) );
00103 connect( textdoc, SIGNAL( paragraphDeleted( KoTextParag* ) ),
00104 this, SLOT( slotParagraphDeleted( KoTextParag* ) ) );
00105 connect( textdoc, SIGNAL( newCommand( KCommand* ) ),
00106 this, SIGNAL( newCommand( KCommand* ) ) );
00107 connect( textdoc, SIGNAL( repaintChanged() ),
00108 this, SLOT( emitRepaintChanged() ) );
00109
00110 connect( this, SIGNAL(paragraphModified( KoTextParag*, int, int , int ) ),
00111 this, SLOT(slotParagraphModified(KoTextParag *, int, int , int)));
00112 connect( this, SIGNAL(paragraphCreated( KoTextParag* )),
00113 this, SLOT(slotParagraphCreated(KoTextParag *)));
00114 }
00115
00116 KoTextObject::~KoTextObject()
00117 {
00118
00119
00120 undoRedoInfo.clear();
00121 delete textdoc; textdoc = 0;
00122 delete d;
00123 }
00124
00125 int KoTextObject::availableHeight() const
00126 {
00127 if ( m_availableHeight == -1 )
00128 emit const_cast<KoTextObject *>(this)->availableHeightNeeded();
00129 Q_ASSERT( m_availableHeight != -1 );
00130 return m_availableHeight;
00131 }
00132
00133 void KoTextObject::slotParagraphModified(KoTextParag *parag, int _type, int , int)
00134 {
00135 if ( _type == ChangeFormat)
00136 return;
00137 m_needsSpellCheck = true;
00138 if (parag )
00139 parag->string()->setNeedsSpellCheck( true );
00140 }
00141
00142 void KoTextObject::slotParagraphCreated(KoTextParag * parag)
00143 {
00144 m_needsSpellCheck = true;
00145 if (parag )
00146 parag->string()->setNeedsSpellCheck( true );
00147 }
00148
00149 void KoTextObject::slotParagraphDeleted(KoTextParag * )
00150 {
00151
00152 }
00153
00154 int KoTextObject::docFontSize( KoTextFormat * format ) const
00155 {
00156 Q_ASSERT( format );
00157 return format->pointSize();
00158 }
00159
00160 int KoTextObject::zoomedFontSize( int docFontSize ) const
00161 {
00162 kdDebug(32500) << "KoTextObject::zoomedFontSize: docFontSize=" << docFontSize
00163 << " - in LU: " << KoTextZoomHandler::ptToLayoutUnitPt( docFontSize ) << endl;
00164 return KoTextZoomHandler::ptToLayoutUnitPt( docFontSize );
00165 }
00166
00167
00168 class KoHasCustomItemVisitor : public KoParagVisitor
00169 {
00170 public:
00171 KoHasCustomItemVisitor() : KoParagVisitor() { }
00172
00173 virtual bool visit( KoTextParag *parag, int start, int end )
00174 {
00175 for ( int i = start ; i < end ; ++i )
00176 {
00177 KoTextStringChar * ch = parag->at( i );
00178 if ( ch->isCustom() )
00179 return false;
00180 }
00181 return true;
00182 }
00183 };
00184
00185 bool KoTextObject::selectionHasCustomItems( int selectionId ) const
00186 {
00187 KoHasCustomItemVisitor visitor;
00188 bool noneFound = textdoc->visitSelection( selectionId, &visitor );
00189 return !noneFound;
00190 }
00191
00192 void KoTextObject::slotAfterUndoRedo()
00193 {
00194 formatMore( 2 );
00195 emit repaintChanged( this );
00196 emit updateUI( true );
00197 emit showCursor();
00198 emit ensureCursorVisible();
00199 }
00200
00201 void KoTextObject::clearUndoRedoInfo()
00202 {
00203 undoRedoInfo.clear();
00204 }
00205
00206
00207 void KoTextObject::checkUndoRedoInfo( KoTextCursor * cursor, UndoRedoInfo::Type t )
00208 {
00209 if ( undoRedoInfo.valid() && ( t != undoRedoInfo.type || cursor != undoRedoInfo.cursor ) ) {
00210 undoRedoInfo.clear();
00211 }
00212 undoRedoInfo.type = t;
00213 undoRedoInfo.cursor = cursor;
00214 }
00215
00216 void KoTextObject::undo()
00217 {
00218 undoRedoInfo.clear();
00219 emit hideCursor();
00220 KoTextCursor *cursor = new KoTextCursor( textdoc );
00221 KoTextCursor *c = textdoc->undo( cursor );
00222 if ( !c ) {
00223 delete cursor;
00224 emit showCursor();
00225 return;
00226 }
00227
00228
00229
00230 emit setCursor( c );
00231 setLastFormattedParag( textdoc->firstParag() );
00232 delete cursor;
00233 QTimer::singleShot( 0, this, SLOT( slotAfterUndoRedo() ) );
00234 }
00235
00236 void KoTextObject::redo()
00237 {
00238 undoRedoInfo.clear();
00239 emit hideCursor();
00240 KoTextCursor *cursor = new KoTextCursor( textdoc );
00241 KoTextCursor *c = textdoc->redo( cursor );
00242 if ( !c ) {
00243 delete cursor;
00244 emit showCursor();
00245 return;
00246 }
00247 emit setCursor( c );
00248 setLastFormattedParag( textdoc->firstParag() );
00249 delete cursor;
00250 QTimer::singleShot( 0, this, SLOT( slotAfterUndoRedo() ) );
00251 }
00252
00253 KoTextObject::UndoRedoInfo::UndoRedoInfo( KoTextObject *to )
00254 : type( Invalid ), textobj(to), cursor( 0 )
00255 {
00256 text = QString::null;
00257 id = -1;
00258 index = -1;
00259 placeHolderCmd = 0L;
00260 }
00261
00262 bool KoTextObject::UndoRedoInfo::valid() const
00263 {
00264 return text.length() > 0 && id >= 0 && index >= 0;
00265 }
00266
00267 void KoTextObject::UndoRedoInfo::clear()
00268 {
00269 if ( valid() ) {
00270 KoTextDocument* textdoc = textobj->textDocument();
00271 switch (type) {
00272 case Insert:
00273 case Return:
00274 {
00275 KoTextDocCommand * cmd = new KoTextInsertCommand( textdoc, id, index, text.rawData(), customItemsMap, oldParagLayouts );
00276 textdoc->addCommand( cmd );
00277 Q_ASSERT( placeHolderCmd );
00278
00279 if ( !customItemsMap.isEmpty() )
00280 {
00281 CustomItemsMap::Iterator it = customItemsMap.begin();
00282 for ( ; it != customItemsMap.end(); ++it )
00283 {
00284 KoTextCustomItem * item = it.data();
00285 KCommand * itemCmd = item->createCommand();
00286 if ( itemCmd )
00287 placeHolderCmd->addCommand( itemCmd );
00288 }
00289 placeHolderCmd->addCommand( new KoTextCommand( textobj, QString::null ) );
00290 }
00291 else
00292 {
00293 placeHolderCmd->addCommand( new KoTextCommand( textobj, QString::null ) );
00294 }
00295 } break;
00296 case Delete:
00297 case RemoveSelected:
00298 {
00299 KoTextDocCommand * cmd = textobj->deleteTextCommand( textdoc, id, index, text.rawData(), customItemsMap, oldParagLayouts );
00300 textdoc->addCommand( cmd );
00301 Q_ASSERT( placeHolderCmd );
00302 placeHolderCmd->addCommand( new KoTextCommand( textobj, QString::null ) );
00303
00304 if ( !customItemsMap.isEmpty() )
00305 {
00306 customItemsMap.deleteAll( placeHolderCmd );
00307 }
00308 } break;
00309 case Invalid:
00310 break;
00311 }
00312 }
00313 type = Invalid;
00314
00315
00316 text = QString::null;
00317 id = -1;
00318 index = -1;
00319 oldParagLayouts.clear();
00320 customItemsMap.clear();
00321 placeHolderCmd = 0L;
00322 }
00323
00324 void KoTextObject::copyCharFormatting( KoTextParag *parag, int position, int index , bool moveCustomItems )
00325 {
00326 KoTextStringChar * ch = parag->at( position );
00327 if ( ch->format() ) {
00328 ch->format()->addRef();
00329 undoRedoInfo.text.at( index ).setFormat( ch->format() );
00330 }
00331 if ( ch->isCustom() )
00332 {
00333 kdDebug(32500) << "KoTextObject::copyCharFormatting moving custom item " << ch->customItem() << " to text's " << index << " char" << endl;
00334 undoRedoInfo.customItemsMap.insert( index, ch->customItem() );
00335
00336
00337 if ( moveCustomItems )
00338 parag->removeCustomItem(position);
00339
00340 }
00341 }
00342
00343
00344 void KoTextObject::readFormats( KoTextCursor &c1, KoTextCursor &c2, bool copyParagLayouts, bool moveCustomItems )
00345 {
00346
00347 int oldLen = undoRedoInfo.text.length();
00348 if ( c1.parag() == c2.parag() ) {
00349 undoRedoInfo.text += c1.parag()->string()->toString().mid( c1.index(), c2.index() - c1.index() );
00350 for ( int i = c1.index(); i < c2.index(); ++i )
00351 copyCharFormatting( c1.parag(), i, oldLen + i - c1.index(), moveCustomItems );
00352 } else {
00353 int lastIndex = oldLen;
00354 int i;
00355
00356
00357 undoRedoInfo.text += c1.parag()->string()->toString().mid( c1.index(), c1.parag()->length() - 1 - c1.index() ) + '\n';
00358 for ( i = c1.index(); i < c1.parag()->length(); ++i, ++lastIndex )
00359 copyCharFormatting( c1.parag(), i, lastIndex, moveCustomItems );
00360
00361 KoTextParag *p = c1.parag()->next();
00362 while ( p && p != c2.parag() ) {
00363 undoRedoInfo.text += p->string()->toString().left( p->length() - 1 ) + '\n';
00364
00365 for ( i = 0; i < p->length(); ++i )
00366 copyCharFormatting( p, i, i + lastIndex, moveCustomItems );
00367 lastIndex += p->length();
00368
00369 p = p->next();
00370 }
00371
00372 undoRedoInfo.text += c2.parag()->string()->toString().left( c2.index() );
00373 for ( i = 0; i < c2.index(); ++i )
00374 copyCharFormatting( c2.parag(), i, i + lastIndex, moveCustomItems );
00375 }
00376
00377 if ( copyParagLayouts ) {
00378 KoTextParag *p = c1.parag();
00379 while ( p ) {
00380 undoRedoInfo.oldParagLayouts << p->paragLayout();
00381 if ( p == c2.parag() )
00382 break;
00383 p = p->next();
00384 }
00385 }
00386 }
00387
00388 void KoTextObject::newPlaceHolderCommand( const QString & name )
00389 {
00390 Q_ASSERT( !undoRedoInfo.placeHolderCmd );
00391 if ( undoRedoInfo.placeHolderCmd ) kdDebug(32500) << kdBacktrace();
00392 undoRedoInfo.placeHolderCmd = new KMacroCommand( name );
00393 emit newCommand( undoRedoInfo.placeHolderCmd );
00394 }
00395
00396 void KoTextObject::storeParagUndoRedoInfo( KoTextCursor * cursor, int selectionId )
00397 {
00398 undoRedoInfo.clear();
00399 undoRedoInfo.oldParagLayouts.clear();
00400 undoRedoInfo.text = " ";
00401 undoRedoInfo.index = 1;
00402 if ( cursor && !textdoc->hasSelection( selectionId, true ) ) {
00403 KoTextParag * p = cursor->parag();
00404 undoRedoInfo.id = p->paragId();
00405 undoRedoInfo.eid = p->paragId();
00406 undoRedoInfo.oldParagLayouts << p->paragLayout();
00407 }
00408 else{
00409 Q_ASSERT( textdoc->hasSelection( selectionId, true ) );
00410 KoTextParag *start = textdoc->selectionStart( selectionId );
00411 KoTextParag *end = textdoc->selectionEnd( selectionId );
00412 undoRedoInfo.id = start->paragId();
00413 undoRedoInfo.eid = end->paragId();
00414 for ( ; start && start != end->next() ; start = start->next() )
00415 {
00416 undoRedoInfo.oldParagLayouts << start->paragLayout();
00417
00418 }
00419 }
00420 }
00421
00422 void KoTextObject::doKeyboardAction( KoTextCursor * cursor, KoTextFormat * & , KeyboardAction action )
00423 {
00424 KoTextParag * parag = cursor->parag();
00425 setLastFormattedParag( parag );
00426 emit hideCursor();
00427 bool doUpdateCurrentFormat = true;
00428 switch ( action ) {
00429 case ActionDelete: {
00430 checkUndoRedoInfo( cursor, UndoRedoInfo::Delete );
00431 if ( !undoRedoInfo.valid() ) {
00432 newPlaceHolderCommand( i18n("Delete Text") );
00433 undoRedoInfo.id = parag->paragId();
00434 undoRedoInfo.index = cursor->index();
00435 undoRedoInfo.text = QString::null;
00436 undoRedoInfo.oldParagLayouts << parag->paragLayout();
00437 }
00438 if ( !cursor->atParagEnd() )
00439 {
00440 KoTextStringChar * ch = parag->at( cursor->index() );
00441 undoRedoInfo.text += ch->c;
00442 copyCharFormatting( parag, cursor->index(), undoRedoInfo.text.length()-1, true );
00443 }
00444 KoParagLayout paragLayout;
00445 if ( parag->next() )
00446 paragLayout = parag->next()->paragLayout();
00447
00448 KoTextParag *old = cursor->parag();
00449 if ( cursor->remove() ) {
00450 if ( old != cursor->parag() && m_lastFormatted == old )
00451 m_lastFormatted = cursor->parag() ? cursor->parag()->prev() : 0;
00452 undoRedoInfo.text += "\n";
00453 undoRedoInfo.oldParagLayouts << paragLayout;
00454 } else
00455 emit paragraphModified( old, RemoveChar, cursor->index(), 1 );
00456 } break;
00457 case ActionBackspace: {
00458
00459 if ( parag->counter() && parag->counter()->style() != KoParagCounter::STYLE_NONE && cursor->index() == 0 ) {
00460
00461
00462 KoParagCounter c;
00463 c.setDepth( parag->counter()->depth() );
00464 KCommand *cmd=setCounterCommand( cursor, c );
00465 if(cmd)
00466 emit newCommand(cmd);
00467 }
00468 else if ( !cursor->atParagStart() )
00469 {
00470 checkUndoRedoInfo( cursor, UndoRedoInfo::Delete );
00471 if ( !undoRedoInfo.valid() ) {
00472 newPlaceHolderCommand( i18n("Delete Text") );
00473 undoRedoInfo.id = parag->paragId();
00474 undoRedoInfo.index = cursor->index();
00475 undoRedoInfo.text = QString::null;
00476 undoRedoInfo.oldParagLayouts << parag->paragLayout();
00477 }
00478 undoRedoInfo.text.insert( 0, cursor->parag()->at( cursor->index()-1 ) );
00479 copyCharFormatting( cursor->parag(), cursor->index()-1, 0, true );
00480 undoRedoInfo.index = cursor->index()-1;
00481
00482 cursor->removePreviousChar();
00483 emit paragraphModified( cursor->parag(), RemoveChar, cursor->index(),1 );
00484 m_lastFormatted = cursor->parag();
00485 } else if ( parag->prev() ) {
00486 emit paragraphDeleted( cursor->parag() );
00487 clearUndoRedoInfo();
00488 textdoc->setSelectionStart( KoTextDocument::Temp, cursor );
00489 cursor->gotoPreviousLetter();
00490 textdoc->setSelectionEnd( KoTextDocument::Temp, cursor );
00491 removeSelectedText( cursor, KoTextDocument::Temp, i18n( "Delete Text" ) );
00492 emit paragraphModified( cursor->parag(), AddChar, cursor->index(), cursor->parag()->length() - cursor->index() );
00493 }
00494 } break;
00495 case ActionReturn: {
00496 checkUndoRedoInfo( cursor, UndoRedoInfo::Return );
00497 if ( !undoRedoInfo.valid() ) {
00498 newPlaceHolderCommand( i18n("Insert Text") );
00499 undoRedoInfo.id = cursor->parag()->paragId();
00500 undoRedoInfo.index = cursor->index();
00501 undoRedoInfo.text = QString::null;
00502 }
00503 undoRedoInfo.text += "\n";
00504 if ( cursor->parag() )
00505 {
00506 QString last_line = cursor->parag()->toString();
00507 last_line.remove(0,last_line.find(' ')+1);
00508
00509 if( last_line.isEmpty() && cursor->parag()->counter() && cursor->parag()->counter()->numbering() == KoParagCounter::NUM_LIST )
00510 {
00511 KoParagCounter c;
00512 KCommand *cmd=setCounterCommand( cursor, c );
00513 if(cmd)
00514 emit newCommand(cmd);
00515 setLastFormattedParag( cursor->parag() );
00516 cursor->parag()->setNoCounter();
00517
00518 formatMore( 2 );
00519 emit repaintChanged( this );
00520 emit ensureCursorVisible();
00521 emit showCursor();
00522 emit updateUI( doUpdateCurrentFormat );
00523 return;
00524 }
00525 else
00526 cursor->splitAndInsertEmptyParag();
00527 }
00528
00529 Q_ASSERT( cursor->parag()->prev() );
00530 setLastFormattedParag( cursor->parag() );
00531
00532 doUpdateCurrentFormat = false;
00533 KoParagStyle * style = cursor->parag()->prev()->style();
00534 if ( style )
00535 {
00536 KoParagStyle * newStyle = style->followingStyle();
00537 if ( newStyle && style != newStyle )
00538 {
00539 doUpdateCurrentFormat = true;
00540
00541
00542 }
00543 }
00544 emit paragraphCreated( cursor->parag() );
00545
00546 } break;
00547 case ActionKill:
00548
00549 if ( !cursor->atParagEnd() || cursor->parag()->next() ) {
00550 checkUndoRedoInfo( cursor, UndoRedoInfo::Delete );
00551 if ( !undoRedoInfo.valid() ) {
00552 newPlaceHolderCommand( i18n("Delete Text") );
00553 undoRedoInfo.id = cursor->parag()->paragId();
00554 undoRedoInfo.index = cursor->index();
00555 undoRedoInfo.text = QString::null;
00556 undoRedoInfo.oldParagLayouts << parag->paragLayout();
00557 }
00558 if ( cursor->atParagEnd() ) {
00559
00560 KoParagLayout paragLayout = parag->next()->paragLayout();
00561 if ( cursor->remove() )
00562 {
00563 m_lastFormatted = cursor->parag();
00564 undoRedoInfo.text += "\n";
00565 undoRedoInfo.oldParagLayouts << paragLayout;
00566 }
00567 } else {
00568 int oldLen = undoRedoInfo.text.length();
00569 undoRedoInfo.text += cursor->parag()->string()->toString().mid( cursor->index() );
00570 for ( int i = cursor->index(); i < cursor->parag()->length(); ++i )
00571 copyCharFormatting( cursor->parag(), i, oldLen + i - cursor->index(), true );
00572 cursor->killLine();
00573 emit paragraphModified( cursor->parag(), RemoveChar, cursor->index(), cursor->parag()->length()-cursor->index() );
00574 }
00575 }
00576 break;
00577 }
00578
00579 if ( !undoRedoInfo.customItemsMap.isEmpty() )
00580 clearUndoRedoInfo();
00581
00582 formatMore( 2 );
00583 emit repaintChanged( this );
00584 emit ensureCursorVisible();
00585 emit showCursor();
00586 emit updateUI( doUpdateCurrentFormat );
00587 }
00588
00589 void KoTextObject::insert( KoTextCursor * cursor, KoTextFormat * currentFormat,
00590 const QString &txt, bool checkNewLine,
00591 bool removeSelected, const QString & commandName,
00592 CustomItemsMap customItemsMap, int selectionId, bool repaint )
00593 {
00594 if ( protectContent() )
00595 return;
00596
00597 bool tinyRepaint = !checkNewLine;
00598 if ( repaint )
00599 emit hideCursor();
00600 if ( textdoc->hasSelection( selectionId, true ) && removeSelected ) {
00601 if( customItemsMap.isEmpty())
00602 {
00603 emitNewCommand(replaceSelectionCommand( cursor, txt, selectionId, commandName, repaint ));
00604 return;
00605 }
00606 else
00607 {
00608 KCommand* removeSelCmd = removeSelectedTextCommand( cursor, selectionId );
00609 if (removeSelCmd)
00610 emitNewCommand( removeSelCmd );
00611 tinyRepaint = false;
00612 }
00613 }
00614 KoTextCursor c2 = *cursor;
00615 if ( !customItemsMap.isEmpty() )
00616 clearUndoRedoInfo();
00617 checkUndoRedoInfo( cursor, UndoRedoInfo::Insert );
00618 if ( !undoRedoInfo.valid() ) {
00619 if ( !commandName.isNull() )
00620 newPlaceHolderCommand( commandName );
00621 undoRedoInfo.id = cursor->parag()->paragId();
00622 undoRedoInfo.index = cursor->index();
00623 undoRedoInfo.text = QString::null;
00624 }
00625 int oldLen = undoRedoInfo.text.length();
00626 KoTextCursor oldCursor = *cursor;
00627 bool wasChanged = cursor->parag()->hasChanged();
00628 int origLine;
00629 oldCursor.parag()->lineStartOfChar( oldCursor.index(), 0, &origLine );
00630
00631 cursor->insert( txt, checkNewLine );
00632 setLastFormattedParag( checkNewLine ? oldCursor.parag() : cursor->parag() );
00633
00634 if ( !customItemsMap.isEmpty() ) {
00635 customItemsMap.insertItems( oldCursor, txt.length() );
00636 undoRedoInfo.customItemsMap = customItemsMap;
00637 tinyRepaint = false;
00638 }
00639
00640 textdoc->setSelectionStart( KoTextDocument::Temp, &oldCursor );
00641 textdoc->setSelectionEnd( KoTextDocument::Temp, cursor );
00642
00643 textdoc->setFormat( KoTextDocument::Temp, currentFormat, KoTextFormat::Format );
00644 textdoc->setFormat( KoTextDocument::InputMethodPreedit, currentFormat, KoTextFormat::Format );
00645 textdoc->removeSelection( KoTextDocument::Temp );
00646
00647 if ( !customItemsMap.isEmpty() ) {
00648
00649 CustomItemsMap::Iterator it = customItemsMap.begin();
00650 for ( ; it != customItemsMap.end(); ++it )
00651 it.data()->resize();
00652 }
00653
00654
00655
00656
00657 #if 0
00658 KoTextParag *parag = cursor->parag();
00659 if ( !checkNewLine && m_lastFormatted == parag && ( !parag->next() || parag->next()->isValid() ) )
00660 {
00661 parag->format();
00662 m_lastFormatted = m_lastFormatted->next();
00663 }
00664 #endif
00665
00666
00667 ensureFormatted( cursor->parag() );
00668
00669
00670
00671
00672 if ( !checkNewLine && tinyRepaint && !wasChanged )
00673 {
00674
00675
00676 Q_ASSERT( cursor->parag() == oldCursor.parag() );
00677 KoTextParag* parag = cursor->parag();
00678
00679
00680
00681 parag->setChanged( false );
00682 parag->setLineChanged( origLine - 1 );
00683 }
00684
00685 if ( repaint ) {
00686 emit repaintChanged( this );
00687 emit ensureCursorVisible();
00688 emit showCursor();
00689
00690 if ( oldCursor.index() == 0 && oldCursor.parag()->alignment() == Qt::AlignAuto )
00691 emit updateUI( true );
00692
00693 }
00694 undoRedoInfo.text += txt;
00695 for ( int i = 0; i < (int)txt.length(); ++i ) {
00696 if ( txt[ oldLen + i ] != '\n' )
00697 copyCharFormatting( c2.parag(), c2.index(), oldLen + i, false );
00698 c2.gotoNextLetter();
00699 }
00700
00701 if ( !removeSelected ) {
00702
00703
00704 if ( textdoc->removeSelection( selectionId ) && repaint )
00705 selectionChangedNotify();
00706 }
00707 if ( !customItemsMap.isEmpty() ) {
00708 clearUndoRedoInfo();
00709 }
00710
00711
00712 emit paragraphModified( oldCursor.parag(), AddChar, cursor->index(), txt.length() );
00713
00714
00715
00716 }
00717
00718 void KoTextObject::pasteText( KoTextCursor * cursor, const QString & text, KoTextFormat * currentFormat, bool removeSelected )
00719 {
00720 if ( protectContent() )
00721 return;
00722 kdDebug(32500) << "KoTextObject::pasteText cursor parag=" << cursor->parag()->paragId() << endl;
00723 QString t = text;
00724
00725 QRegExp crlf( QString::fromLatin1("\r\n") );
00726 t.replace( crlf, QChar('\n') );
00727
00728 for ( int i=0; (uint) i<t.length(); i++ ) {
00729 if ( t[ i ] < ' ' && t[ i ] != '\n' && t[ i ] != '\t' )
00730 t[ i ] = ' ';
00731 }
00732 if ( !t.isEmpty() )
00733 {
00734 insert( cursor, currentFormat, t, true , removeSelected, i18n("Paste Text") );
00735 formatMore( 2 );
00736 emit repaintChanged( this );
00737 }
00738 }
00739
00740 KCommand* KoTextObject::setParagLayoutCommand( KoTextCursor * cursor, const KoParagLayout& paragLayout,
00741 int selectionId, int paragLayoutFlags,
00742 int marginIndex, bool createUndoRedo )
00743 {
00744 if ( protectContent() )
00745 return 0;
00746 storeParagUndoRedoInfo( cursor, selectionId );
00747 undoRedoInfo.type = UndoRedoInfo::Invalid;
00748 if ( paragLayoutFlags != 0 )
00749 {
00750 emit hideCursor();
00751 if ( !textdoc->hasSelection( selectionId, true ) ) {
00752 cursor->parag()->setParagLayout( paragLayout, paragLayoutFlags, marginIndex );
00753 setLastFormattedParag( cursor->parag() );
00754 } else {
00755 KoTextParag *start = textdoc->selectionStart( selectionId );
00756 KoTextParag *end = textdoc->selectionEnd( selectionId );
00757 for ( ; start && start != end->next() ; start = start->next() ) {
00758 if ( paragLayoutFlags == KoParagLayout::BulletNumber && start->length() <= 1 )
00759 continue;
00760 start->setParagLayout( paragLayout, paragLayoutFlags, marginIndex );
00761 }
00762 setLastFormattedParag( start );
00763 }
00764
00765 formatMore( 2 );
00766 emit repaintChanged( this );
00767 emit showCursor();
00768 emit updateUI( true );
00769
00770 if ( createUndoRedo )
00771 {
00772
00773 KoTextDocCommand * cmd = new KoTextParagCommand( textdoc, undoRedoInfo.id, undoRedoInfo.eid,
00774 undoRedoInfo.oldParagLayouts,
00775 paragLayout, paragLayoutFlags,
00776 (QStyleSheetItem::Margin)marginIndex );
00777 textdoc->addCommand( cmd );
00778 return new KoTextCommand( this, "related to KoTextParagCommand" );
00779 }
00780 }
00781 return 0;
00782 }
00783
00784
00785 void KoTextObject::applyStyle( KoTextCursor * cursor, const KoParagStyle * newStyle,
00786 int selectionId,
00787 int paragLayoutFlags, int formatFlags,
00788 bool createUndoRedo, bool interactive )
00789 {
00790 KCommand *cmd = applyStyleCommand( cursor, newStyle, selectionId,
00791 paragLayoutFlags, formatFlags,
00792 createUndoRedo, interactive );
00793 if ( createUndoRedo && cmd )
00794 emit newCommand( cmd );
00795 else
00796 Q_ASSERT( !cmd );
00797 }
00798
00799 KCommand *KoTextObject::applyStyleCommand( KoTextCursor * cursor, const KoParagStyle * newStyle,
00800 int selectionId,
00801 int paragLayoutFlags, int formatFlags,
00802 bool createUndoRedo, bool interactive )
00803 {
00804 if ( protectContent())
00805 return 0L;
00806 if ( interactive )
00807 emit hideCursor();
00808 if ( !textdoc->hasSelection( selectionId, true ) && !cursor)
00809 return 0L;
00815 KMacroCommand * macroCmd = createUndoRedo ? new KMacroCommand( i18n("Apply Style %1").
00816 arg(newStyle->displayName() ) ) : 0;
00817
00818
00819
00820 KCommand* cmd = setParagLayoutCommand( cursor, newStyle->paragLayout(), selectionId, paragLayoutFlags, -1, createUndoRedo );
00821 if ( cmd )
00822 macroCmd->addCommand( cmd );
00823
00824
00825
00826 KoTextParag * firstParag;
00827 KoTextParag * lastParag;
00828 if ( !textdoc->hasSelection( selectionId, true ) ) {
00829
00830 firstParag = cursor->parag();
00831 lastParag = cursor->parag();
00832 }
00833 else
00834 {
00835 firstParag = textdoc->selectionStart( selectionId );
00836 lastParag = textdoc->selectionEnd( selectionId );
00837 }
00838
00839 if ( formatFlags != 0 )
00840 {
00841 KoTextFormat * newFormat = textdoc->formatCollection()->format( &newStyle->format() );
00842
00843 if ( createUndoRedo )
00844 {
00845 QValueList<KoTextFormat *> lstFormats;
00846
00847 for ( KoTextParag * parag = firstParag ; parag && parag != lastParag->next() ; parag = parag->next() )
00848 {
00849
00850 lstFormats.append( parag->paragFormat() );
00851 }
00852 KoTextCursor c1( textdoc );
00853 c1.setParag( firstParag );
00854 c1.setIndex( 0 );
00855 KoTextCursor c2( textdoc );
00856 c2.setParag( lastParag );
00857 c2.setIndex( lastParag->string()->length() );
00858 undoRedoInfo.clear();
00859 undoRedoInfo.type = UndoRedoInfo::Invalid;
00860 readFormats( c1, c2 );
00861
00862 KoTextDocCommand * cmd = new KoTextFormatCommand( textdoc, firstParag->paragId(), 0,
00863 lastParag->paragId(), c2.index(),
00864 undoRedoInfo.text.rawData(), newFormat,
00865 formatFlags );
00866 textdoc->addCommand( cmd );
00867 macroCmd->addCommand( new KoTextCommand( this, "related to KoTextFormatCommand" ) );
00868
00869
00870 cmd = new KoParagFormatCommand( textdoc, firstParag->paragId(), lastParag->paragId(),
00871 lstFormats, newFormat );
00872 textdoc->addCommand( cmd );
00873 macroCmd->addCommand( new KoTextCommand( this, "related to KoParagFormatCommand" ) );
00874 }
00875
00876
00877 for ( KoTextParag * parag = firstParag ; parag && parag != lastParag->next() ; parag = parag->next() )
00878 {
00879
00880
00881 parag->setFormat( 0, parag->string()->length(), newFormat, true, formatFlags );
00882 parag->setFormat( newFormat );
00883 }
00884
00885
00886 }
00887
00888
00889 QPtrListIterator<KoTextCustomItem> cit( textdoc->allCustomItems() );
00890 for ( ; cit.current() ; ++cit )
00891 cit.current()->resize();
00892
00893
00894 if ( interactive )
00895 {
00896 setLastFormattedParag( firstParag );
00897 formatMore( 2 );
00898 emit repaintChanged( this );
00899 emit updateUI( true );
00900 emit showCursor();
00901 }
00902
00903 undoRedoInfo.clear();
00904
00905 return macroCmd;
00906 }
00907
00908 void KoTextObject::applyStyleChange( KoStyleChangeDefMap changed )
00909 {
00910 #if 0 //#ifndef NDEBUG
00911 kdDebug(32500) << "KoTextObject::applyStyleChange " << changed.count() << " styles." << endl;
00912 for( KoStyleChangeDefMap::const_iterator it = changed.begin(); it != changed.end(); ++it ) {
00913 kdDebug(32500) << " " << it.key()->name()
00914 << " paragLayoutChanged=" << (*it).paragLayoutChanged
00915 << " formatChanged=" << (*it).formatChanged
00916 << endl;
00917 }
00918 #endif
00919
00920 KoTextParag *p = textdoc->firstParag();
00921 while ( p ) {
00922 KoStyleChangeDefMap::Iterator it = changed.find( p->style() );
00923 if ( it != changed.end() )
00924 {
00925 if ( (*it).paragLayoutChanged == -1 || (*it).formatChanged == -1 )
00926 {
00927 p->setStyle( m_defaultStyle );
00928
00929 }
00930 else
00931 {
00932
00933 KoTextCursor cursor( textdoc );
00934 cursor.setParag( p );
00935 cursor.setIndex( 0 );
00936
00937 applyStyle( &cursor, it.key(),
00938 -1,
00939 (*it).paragLayoutChanged, (*it).formatChanged,
00940 false, false );
00941 }
00942 } else {
00943
00944 }
00945
00946 p = p->next();
00947 }
00948 setLastFormattedParag( textdoc->firstParag() );
00949 formatMore( 2 );
00950 emit repaintChanged( this );
00951 emit updateUI( true );
00952 }
00953
00955 KCommand *KoTextObject::setFormatCommand( const KoTextFormat *format, int flags, bool zoomFont )
00956 {
00957 textdoc->selectAll( KoTextDocument::Temp );
00958 KCommand *cmd = setFormatCommand( 0L, 0L, format, flags, zoomFont, KoTextDocument::Temp );
00959 textdoc->removeSelection( KoTextDocument::Temp );
00960 return cmd;
00961 }
00962
00963 KCommand * KoTextObject::setFormatCommand( KoTextCursor * cursor, KoTextFormat ** pCurrentFormat, const KoTextFormat *format, int flags, bool , int selectionId )
00964 {
00965 KCommand *ret = 0;
00966 if ( protectContent() )
00967 return ret;
00968
00969 KoTextFormat* newFormat = 0;
00970
00971
00972
00973 bool isNewFormat = ( pCurrentFormat && *pCurrentFormat && (*pCurrentFormat)->key() != format->key() );
00974 if ( isNewFormat || !pCurrentFormat )
00975 {
00976 #if 0
00977 int origFontSize = 0;
00978 if ( zoomFont )
00979 {
00980 origFontSize = format->pointSize();
00981 format->setPointSize( zoomedFontSize( origFontSize ) );
00982
00983 }
00984 #endif
00985
00986 if ( pCurrentFormat )
00987 (*pCurrentFormat)->removeRef();
00988
00989 newFormat = textdoc->formatCollection()->format( format );
00990 if ( newFormat->isMisspelled() ) {
00991 KoTextFormat fNoMisspelled( *newFormat );
00992 newFormat->removeRef();
00993 fNoMisspelled.setMisspelled( false );
00994 newFormat = textdoc->formatCollection()->format( &fNoMisspelled );
00995 }
00996 if ( pCurrentFormat )
00997 (*pCurrentFormat) = newFormat;
00998 }
00999
01000 if ( textdoc->hasSelection( selectionId, true ) ) {
01001 emit hideCursor();
01002 KoTextCursor c1 = textdoc->selectionStartCursor( selectionId );
01003 KoTextCursor c2 = textdoc->selectionEndCursor( selectionId );
01004 undoRedoInfo.clear();
01005 int id = c1.parag()->paragId();
01006 int index = c1.index();
01007 int eid = c2.parag()->paragId();
01008 int eindex = c2.index();
01009 readFormats( c1, c2 );
01010
01011 textdoc->setFormat( selectionId, format, flags );
01012 if ( !undoRedoInfo.customItemsMap.isEmpty() )
01013 {
01014
01015 CustomItemsMap::Iterator it = undoRedoInfo.customItemsMap.begin();
01016 for ( ; it != undoRedoInfo.customItemsMap.end(); ++it )
01017 it.data()->resize();
01018 }
01019 KoTextFormatCommand *cmd = new KoTextFormatCommand(
01020 textdoc, id, index, eid, eindex, undoRedoInfo.text.rawData(),
01021 format, flags );
01022 textdoc->addCommand( cmd );
01023 ret = new KoTextCommand( this, i18n("Format Text") );
01024 undoRedoInfo.clear();
01025 setLastFormattedParag( c1.parag() );
01026 formatMore( 2 );
01027 emit repaintChanged( this );
01028 emit showCursor();
01029 }
01030 if ( isNewFormat ) {
01031 emit showCurrentFormat();
01032
01033 if ( cursor && cursor->index() == cursor->parag()->length() - 1 ) {
01034 newFormat->addRef();
01035 cursor->parag()->string()->setFormat( cursor->index(), newFormat, TRUE );
01036 if ( cursor->parag()->length() == 1 ) {
01037 newFormat->addRef();
01038 cursor->parag()->setFormat( newFormat );
01039 cursor->parag()->invalidate(0);
01040 cursor->parag()->format();
01041 emit repaintChanged( this );
01042 }
01043 }
01044 }
01045 return ret;
01046 }
01047
01048 void KoTextObject::setFormat( KoTextCursor * cursor, KoTextFormat ** currentFormat, KoTextFormat *format, int flags, bool zoomFont )
01049 {
01050 if ( protectContent() )
01051 return;
01052 KCommand *cmd = setFormatCommand( cursor, currentFormat, format, flags, zoomFont );
01053 if (cmd)
01054 emit newCommand( cmd );
01055 }
01056
01057 void KoTextObject::emitNewCommand(KCommand *cmd)
01058 {
01059 if(cmd)
01060 emit newCommand( cmd );
01061 }
01062
01063 KCommand *KoTextObject::setCounterCommand( KoTextCursor * cursor, const KoParagCounter & counter, int selectionId )
01064 {
01065 if ( protectContent() )
01066 return 0L;
01067 const KoParagCounter * curCounter = 0L;
01068 if(cursor)
01069 curCounter=cursor->parag()->counter();
01070 if ( !textdoc->hasSelection( selectionId, true ) &&
01071 curCounter && counter == *curCounter ) {
01072 return 0L;
01073 }
01074 emit hideCursor();
01075 storeParagUndoRedoInfo( cursor, selectionId );
01076 if ( !textdoc->hasSelection( selectionId, true ) && cursor) {
01077 cursor->parag()->setCounter( counter );
01078 setLastFormattedParag( cursor->parag() );
01079 } else {
01080 KoTextParag *start = textdoc->selectionStart( selectionId );
01081 KoTextParag *end = textdoc->selectionEnd( selectionId );
01082 #if 0
01083
01084 if ( start != end && end->length() <= 1 )
01085 {
01086 end = end->prev();
01087 undoRedoInfo.eid = end->paragId();
01088 }
01089 #endif
01090 setLastFormattedParag( start );
01091 for ( ; start && start != end->next() ; start = start->next() )
01092 {
01093 if ( start->length() > 1 )
01094 start->setCounter( counter );
01095 }
01096 }
01097 formatMore( 2 );
01098 emit repaintChanged( this );
01099 if ( !undoRedoInfo.newParagLayout.counter )
01100 undoRedoInfo.newParagLayout.counter = new KoParagCounter;
01101 *undoRedoInfo.newParagLayout.counter = counter;
01102 KoTextParagCommand *cmd = new KoTextParagCommand(
01103 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01104 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01105 KoParagLayout::BulletNumber );
01106 textdoc->addCommand( cmd );
01107
01108 undoRedoInfo.clear();
01109 emit showCursor();
01110 emit updateUI( true );
01111 return new KoTextCommand( this, i18n("Change List Type") );
01112 }
01113
01114 KCommand * KoTextObject::setAlignCommand( KoTextCursor * cursor, int align, int selectionId )
01115 {
01116 if ( protectContent() )
01117 return 0L;
01118 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01119 (int)cursor->parag()->alignment() == align )
01120 return 0L;
01121
01122 emit hideCursor();
01123 storeParagUndoRedoInfo( cursor ,selectionId );
01124 if ( !textdoc->hasSelection( selectionId, true ) &&cursor ) {
01125 cursor->parag()->setAlign(align);
01126 setLastFormattedParag( cursor->parag() );
01127 }
01128 else
01129 {
01130 KoTextParag *start = textdoc->selectionStart( selectionId );
01131 KoTextParag *end = textdoc->selectionEnd( selectionId );
01132 setLastFormattedParag( start );
01133 for ( ; start && start != end->next() ; start = start->next() )
01134 start->setAlign(align);
01135 }
01136 formatMore( 2 );
01137 emit repaintChanged( this );
01138 undoRedoInfo.newParagLayout.alignment = align;
01139 KoTextParagCommand *cmd = new KoTextParagCommand(
01140 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01141 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01142 KoParagLayout::Alignment );
01143 textdoc->addCommand( cmd );
01144 undoRedoInfo.clear();
01145 emit showCursor();
01146 emit updateUI( true );
01147 return new KoTextCommand( this, i18n("Change Alignment") );
01148 }
01149
01150 KCommand * KoTextObject::setMarginCommand( KoTextCursor * cursor, QStyleSheetItem::Margin m, double margin , int selectionId ) {
01151 if ( protectContent() )
01152 return 0L;
01153
01154
01155
01156 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01157 cursor->parag()->margin(m) == margin )
01158 return 0L;
01159
01160 emit hideCursor();
01161 storeParagUndoRedoInfo( cursor, selectionId );
01162 if ( !textdoc->hasSelection( selectionId, true )&&cursor ) {
01163 cursor->parag()->setMargin(m, margin);
01164 setLastFormattedParag( cursor->parag() );
01165 }
01166 else
01167 {
01168 KoTextParag *start = textdoc->selectionStart( selectionId );
01169 KoTextParag *end = textdoc->selectionEnd( selectionId );
01170 setLastFormattedParag( start );
01171 for ( ; start && start != end->next() ; start = start->next() )
01172 start->setMargin(m, margin);
01173 }
01174 formatMore( 2 );
01175 emit repaintChanged( this );
01176 undoRedoInfo.newParagLayout.margins[m] = margin;
01177 KoTextParagCommand *cmd = new KoTextParagCommand(
01178 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01179 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01180 KoParagLayout::Margins, m );
01181 textdoc->addCommand( cmd );
01182 QString name;
01183 if ( m == QStyleSheetItem::MarginFirstLine )
01184 name = i18n("Change First Line Indent");
01185 else if ( m == QStyleSheetItem::MarginLeft || m == QStyleSheetItem::MarginRight )
01186 name = i18n("Change Indent");
01187 else
01188 name = i18n("Change Paragraph Spacing");
01189 undoRedoInfo.clear();
01190 emit showCursor();
01191 emit updateUI( true );
01192 return new KoTextCommand( this, name );
01193 }
01194
01195 KCommand * KoTextObject::setLineSpacingCommand( KoTextCursor * cursor, double spacing, KoParagLayout::SpacingType _type, int selectionId )
01196 {
01197 if ( protectContent() )
01198 return 0L;
01199
01200
01201
01202
01203 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01204 cursor->parag()->kwLineSpacing() == spacing
01205 && cursor->parag()->kwLineSpacingType() == _type)
01206 return 0L;
01207
01208 emit hideCursor();
01209 storeParagUndoRedoInfo( cursor, selectionId );
01210 if ( !textdoc->hasSelection( selectionId, true ) && cursor ) {
01211 cursor->parag()->setLineSpacing(spacing);
01212 cursor->parag()->setLineSpacingType( _type);
01213 setLastFormattedParag( cursor->parag() );
01214 }
01215 else
01216 {
01217 KoTextParag *start = textdoc->selectionStart( selectionId );
01218 KoTextParag *end = textdoc->selectionEnd( selectionId );
01219 setLastFormattedParag( start );
01220 for ( ; start && start != end->next() ; start = start->next() )
01221 {
01222 start->setLineSpacing(spacing);
01223 start->setLineSpacingType( _type);
01224 }
01225 }
01226 formatMore( 2 );
01227 emit repaintChanged( this );
01228 undoRedoInfo.newParagLayout.setLineSpacingValue( spacing );
01229 undoRedoInfo.newParagLayout.lineSpacingType = _type;
01230 KoTextParagCommand *cmd = new KoTextParagCommand(
01231 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01232 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01233 KoParagLayout::LineSpacing );
01234 textdoc->addCommand( cmd );
01235
01236 undoRedoInfo.clear();
01237 emit showCursor();
01238 return new KoTextCommand( this, i18n("Change Line Spacing") );
01239 }
01240
01241
01242 KCommand * KoTextObject::setBordersCommand( KoTextCursor * cursor, const KoBorder& leftBorder, const KoBorder& rightBorder, const KoBorder& topBorder, const KoBorder& bottomBorder , int selectionId )
01243 {
01244 if ( protectContent() )
01245 return 0L;
01246 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01247 cursor->parag()->leftBorder() ==leftBorder &&
01248 cursor->parag()->rightBorder() ==rightBorder &&
01249 cursor->parag()->topBorder() ==topBorder &&
01250 cursor->parag()->bottomBorder() ==bottomBorder )
01251 return 0L;
01252
01253 emit hideCursor();
01254 bool borderOutline = false;
01255 storeParagUndoRedoInfo( cursor, selectionId );
01256 if ( !textdoc->hasSelection( selectionId, true ) ) {
01257 cursor->parag()->setLeftBorder(leftBorder);
01258 cursor->parag()->setRightBorder(rightBorder);
01259 cursor->parag()->setBottomBorder(bottomBorder);
01260 cursor->parag()->setTopBorder(topBorder);
01261 setLastFormattedParag( cursor->parag() );
01262 }
01263 else
01264 {
01265 KoTextParag *start = textdoc->selectionStart( selectionId );
01266 KoTextParag *end = textdoc->selectionEnd( selectionId );
01267 setLastFormattedParag( start );
01268 KoBorder tmpBorder;
01269 tmpBorder.setPenWidth(0);
01270 for ( ; start && start != end->next() ; start = start->next() )
01271 {
01272 start->setLeftBorder(leftBorder);
01273 start->setRightBorder(rightBorder);
01274
01275 start->setTopBorder(tmpBorder);
01276 start->setBottomBorder(tmpBorder);
01277 }
01278 end->setBottomBorder(bottomBorder);
01279 textdoc->selectionStart( selectionId )->setTopBorder(topBorder);
01280 borderOutline = true;
01281 }
01282 formatMore( 2 );
01283 emit repaintChanged( this );
01284 undoRedoInfo.newParagLayout.leftBorder=leftBorder;
01285 undoRedoInfo.newParagLayout.rightBorder=rightBorder;
01286 undoRedoInfo.newParagLayout.topBorder=topBorder;
01287 undoRedoInfo.newParagLayout.bottomBorder=bottomBorder;
01288
01289 KoTextParagCommand *cmd = new KoTextParagCommand(
01290 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01291 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01292 KoParagLayout::Borders, (QStyleSheetItem::Margin)-1, borderOutline);
01293 textdoc->addCommand( cmd );
01294
01295 undoRedoInfo.clear();
01296 emit showCursor();
01297 emit updateUI( true );
01298 return new KoTextCommand( this, i18n("Change Borders") );
01299 }
01300
01301
01302 KCommand * KoTextObject::setTabListCommand( KoTextCursor * cursor, const KoTabulatorList &tabList, int selectionId )
01303 {
01304 if ( protectContent() )
01305 return 0L;
01306 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01307 cursor->parag()->tabList() == tabList )
01308 return 0L;
01309
01310 emit hideCursor();
01311 storeParagUndoRedoInfo( cursor, selectionId );
01312
01313 if ( !textdoc->hasSelection( selectionId, true ) && cursor ) {
01314 cursor->parag()->setTabList( tabList );
01315 setLastFormattedParag( cursor->parag() );
01316 }
01317 else
01318 {
01319 KoTextParag *start = textdoc->selectionStart( selectionId );
01320 KoTextParag *end = textdoc->selectionEnd( selectionId );
01321 setLastFormattedParag( start );
01322 for ( ; start && start != end->next() ; start = start->next() )
01323 start->setTabList( tabList );
01324 }
01325
01326 formatMore( 2 );
01327 emit repaintChanged( this );
01328 undoRedoInfo.newParagLayout.setTabList( tabList );
01329 KoTextParagCommand *cmd = new KoTextParagCommand(
01330 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01331 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01332 KoParagLayout::Tabulator);
01333 textdoc->addCommand( cmd );
01334 undoRedoInfo.clear();
01335 emit showCursor();
01336 emit updateUI( true );
01337 return new KoTextCommand( this, i18n("Change Tabulator") );
01338 }
01339
01340 KCommand * KoTextObject::setParagDirectionCommand( KoTextCursor * cursor, QChar::Direction d, int selectionId )
01341 {
01342 if ( protectContent() )
01343 return 0L;
01344 if ( !textdoc->hasSelection( selectionId, true ) && cursor &&
01345 cursor->parag()->direction() == d )
01346 return 0L;
01347
01348 emit hideCursor();
01349 storeParagUndoRedoInfo( cursor, selectionId );
01350
01351 if ( !textdoc->hasSelection( selectionId, true ) && cursor ) {
01352 cursor->parag()->setDirection( d );
01353 setLastFormattedParag( cursor->parag() );
01354 }
01355 else
01356 {
01357 KoTextParag *start = textdoc->selectionStart( selectionId );
01358 KoTextParag *end = textdoc->selectionEnd( selectionId );
01359 setLastFormattedParag( start );
01360 for ( ; start && start != end->next() ; start = start->next() )
01361 start->setDirection( d );
01362 }
01363
01364 formatMore( 2 );
01365 emit repaintChanged( this );
01367 #if 0
01368 undoRedoInfo.newParagLayout.direction = d;
01369 KoTextParagCommand *cmd = new KoTextParagCommand(
01370 textdoc, undoRedoInfo.id, undoRedoInfo.eid,
01371 undoRedoInfo.oldParagLayouts, undoRedoInfo.newParagLayout,
01372 KoParagLayout::Shadow);
01373 textdoc->addCommand( cmd );
01374 #endif
01375 undoRedoInfo.clear();
01376 emit showCursor();
01377 emit updateUI( true );
01378 #if 0
01379 return new KoTextCommand( this, i18n("Change Shadow") );
01380 #else
01381 return 0L;
01382 #endif
01383 }
01384
01385 void KoTextObject::removeSelectedText( KoTextCursor * cursor, int selectionId, const QString & cmdName, bool createUndoRedo )
01386 {
01387 if ( protectContent() )
01388 return ;
01389 emit hideCursor();
01390 if( createUndoRedo)
01391 {
01392 checkUndoRedoInfo( cursor, UndoRedoInfo::RemoveSelected );
01393 if ( !undoRedoInfo.valid() ) {
01394 textdoc->selectionStart( selectionId, undoRedoInfo.id, undoRedoInfo.index );
01395 undoRedoInfo.text = QString::null;
01396 newPlaceHolderCommand( cmdName.isNull() ? i18n("Remove Selected Text") : cmdName );
01397 }
01398 }
01399 KoTextCursor c1 = textdoc->selectionStartCursor( selectionId );
01400 KoTextCursor c2 = textdoc->selectionEndCursor( selectionId );
01401 readFormats( c1, c2, true, true );
01402
01403
01404 textdoc->removeSelectedText( selectionId, cursor );
01405
01406 setLastFormattedParag( cursor->parag() );
01407 formatMore( 2 );
01408 emit repaintChanged( this );
01409 emit ensureCursorVisible();
01410 emit updateUI( true );
01411 emit showCursor();
01412 if(selectionId==KoTextDocument::Standard || selectionId==KoTextDocument::InputMethodPreedit)
01413 selectionChangedNotify();
01414 if ( createUndoRedo)
01415 undoRedoInfo.clear();
01416 }
01417
01418 KCommand * KoTextObject::removeSelectedTextCommand( KoTextCursor * cursor, int selectionId, bool repaint )
01419 {
01420 if ( protectContent() )
01421 return 0L;
01422 if ( !textdoc->hasSelection( selectionId, true ) )
01423 return 0L;
01424
01425 undoRedoInfo.clear();
01426 textdoc->selectionStart( selectionId, undoRedoInfo.id, undoRedoInfo.index );
01427 Q_ASSERT( undoRedoInfo.id >= 0 );
01428
01429 KoTextCursor c1 = textdoc->selectionStartCursor( selectionId );
01430 KoTextCursor c2 = textdoc->selectionEndCursor( selectionId );
01431 readFormats( c1, c2, true, true );
01432
01433 textdoc->removeSelectedText( selectionId, cursor );
01434
01435 KMacroCommand *macroCmd = new KMacroCommand( i18n("Remove Selected Text") );
01436
01437 KoTextDocCommand *cmd = deleteTextCommand( textdoc, undoRedoInfo.id, undoRedoInfo.index,
01438 undoRedoInfo.text.rawData(),
01439 undoRedoInfo.customItemsMap,
01440 undoRedoInfo.oldParagLayouts );
01441 textdoc->addCommand(cmd);
01442 macroCmd->addCommand(new KoTextCommand( this, QString::null ));
01443
01444 if(!undoRedoInfo.customItemsMap.isEmpty())
01445 undoRedoInfo.customItemsMap.deleteAll( macroCmd );
01446
01447 undoRedoInfo.type = UndoRedoInfo::Invalid;
01448 undoRedoInfo.clear();
01449 if ( repaint )
01450 selectionChangedNotify();
01451 return macroCmd;
01452 }
01453
01454 KCommand* KoTextObject::replaceSelectionCommand( KoTextCursor * cursor, const QString & replacement,
01455 int selectionId, const QString & cmdName, bool repaint,
01456 bool checkNewLine )
01457 {
01458 if ( protectContent() )
01459 return 0L;
01460 if ( repaint )
01461 emit hideCursor();
01462 KMacroCommand * macroCmd = new KMacroCommand( cmdName );
01463
01464
01465 KoTextCursor c1 = textdoc->selectionStartCursor( selectionId );
01466 KoTextFormat * format = c1.parag()->at( c1.index() )->format();
01467 format->addRef();
01468
01469
01470 KCommand* removeSelCmd = removeSelectedTextCommand( cursor, selectionId, repaint );
01471 if ( removeSelCmd )
01472 macroCmd->addCommand( removeSelCmd );
01473
01474
01475 insert( cursor, format,
01476 replacement, checkNewLine, false, QString::null ,
01477 CustomItemsMap(), selectionId, repaint );
01478
01479 KoTextDocCommand * cmd = new KoTextInsertCommand( textdoc, undoRedoInfo.id, undoRedoInfo.index,
01480 undoRedoInfo.text.rawData(),
01481 CustomItemsMap(), undoRedoInfo.oldParagLayouts );
01482 textdoc->addCommand( cmd );
01483 macroCmd->addCommand( new KoTextCommand( this, QString::null ) );
01484
01485 undoRedoInfo.type = UndoRedoInfo::Invalid;
01486 undoRedoInfo.clear();
01487
01488 format->removeRef();
01489
01490 setLastFormattedParag( c1.parag() );
01491 if ( repaint )
01492 {
01493 formatMore( 2 );
01494 emit repaintChanged( this );
01495 emit ensureCursorVisible();
01496 emit updateUI( true );
01497 emit showCursor();
01498 if(selectionId==KoTextDocument::Standard)
01499 selectionChangedNotify();
01500 }
01501 return macroCmd;
01502 }
01503
01504 KCommand * KoTextObject::insertParagraphCommand( KoTextCursor *cursor )
01505 {
01506 if ( protectContent() )
01507 return 0L;
01508 return replaceSelectionCommand( cursor, "\n", KoTextDocument::Standard, QString::null );
01509 }
01510
01511 void KoTextObject::highlightPortion( KoTextParag * parag, int index, int length, bool repaint )
01512 {
01513 if ( !m_highlightSelectionAdded )
01514 {
01515 textdoc->addSelection( HighlightSelection );
01516 textdoc->setSelectionColor( HighlightSelection,
01517 QApplication::palette().color( QPalette::Active, QColorGroup::Dark ) );
01518 textdoc->setInvertSelectionText( HighlightSelection, true );
01519 m_highlightSelectionAdded = true;
01520 }
01521
01522 removeHighlight(repaint);
01523 KoTextCursor cursor( textdoc );
01524 cursor.setParag( parag );
01525 cursor.setIndex( index );
01526 textdoc->setSelectionStart( HighlightSelection, &cursor );
01527 cursor.setIndex( index + length );
01528 textdoc->setSelectionEnd( HighlightSelection, &cursor );
01529 if ( repaint ) {
01530 parag->setChanged( true );
01531 emit repaintChanged( this );
01532 }
01533 }
01534
01535 void KoTextObject::removeHighlight(bool repaint)
01536 {
01537 if ( textdoc->hasSelection( HighlightSelection, true ) )
01538 {
01539 KoTextParag * oldParag = textdoc->selectionStart( HighlightSelection );
01540 oldParag->setChanged( true );
01541 textdoc->removeSelection( HighlightSelection );
01542 }
01543 if ( repaint )
01544 emit repaintChanged( this );
01545 }
01546
01547 void KoTextObject::selectAll( bool select )
01548 {
01549 if ( !select )
01550 textdoc->removeSelection( KoTextDocument::Standard );
01551 else
01552 textdoc->selectAll( KoTextDocument::Standard );
01553 selectionChangedNotify();
01554 }
01555
01556 void KoTextObject::selectionChangedNotify( bool enableActions )
01557 {
01558 emit repaintChanged( this );
01559 if ( enableActions )
01560 emit selectionChanged( hasSelection() );
01561 }
01562
01563 void KoTextObject::setViewArea( QWidget* w, int maxY )
01564 {
01565 m_mapViewAreas.replace( w, maxY );
01566 }
01567
01568 void KoTextObject::setLastFormattedParag( KoTextParag *parag )
01569 {
01570
01571 if ( !m_lastFormatted || !parag || m_lastFormatted->paragId() >= parag->paragId() ) {
01572 m_lastFormatted = parag;
01573 }
01574 }
01575
01576 void KoTextObject::ensureFormatted( KoTextParag * parag, bool emitAfterFormatting )
01577 {
01578 if ( !textdoc->lastParag() )
01579 return;
01580
01581 if ( !parag->isValid() && m_lastFormatted == 0 )
01582 m_lastFormatted = parag;
01583
01584 while ( !parag->isValid() )
01585 {
01586 if ( !m_lastFormatted ) {
01587 kdWarning() << "ensureFormatted for parag " << parag << " " << parag->paragId() << " still not formatted, but m_lastFormatted==0" << endl;
01588 return;
01589 }
01590
01591 bool ret = formatMore( QMAX( 1, parag->paragId() - m_lastFormatted->paragId() ), emitAfterFormatting );
01592 if ( !ret ) {
01593
01594 break;
01595 }
01596 }
01597
01598 }
01599
01600 bool KoTextObject::formatMore( int count , bool emitAfterFormatting )
01601 {
01602 if ( ( !m_lastFormatted && d->afterFormattingEmitted )
01603 || !m_visible || m_availableHeight == -1 )
01604 return false;
01605
01606 if ( !textdoc->lastParag() )
01607 return false;
01608
01609 if ( d->abortFormatting ) {
01610 d->abortFormatting = false;
01611 return false;
01612 }
01613
01614 if ( count == 0 )
01615 {
01616 formatTimer->start( interval, TRUE );
01617 return true;
01618 }
01619
01620 int bottom = 0;
01621 if ( m_lastFormatted )
01622 {
01623 d->afterFormattingEmitted = false;
01624
01625 int viewsBottom = 0;
01626 QMapIterator<QWidget *, int> mapIt = m_mapViewAreas.begin();
01627 for ( ; mapIt != m_mapViewAreas.end() ; ++mapIt )
01628 viewsBottom = QMAX( viewsBottom, mapIt.data() );
01629
01630 #ifdef DEBUG_FORMAT_MORE
01631 kdDebug(32500) << "formatMore " << name()
01632 << " lastFormatted id=" << m_lastFormatted->paragId()
01633 << " lastFormatted's top=" << m_lastFormatted->rect().top()
01634 << " lastFormatted's height=" << m_lastFormatted->rect().height()
01635 << " count=" << count << " viewsBottom=" << viewsBottom
01636 << " availableHeight=" << m_availableHeight << endl;
01637 #endif
01638 if ( m_lastFormatted->prev() == 0 )
01639 {
01640 emit formattingFirstParag();
01641 #ifdef TIMING_FORMAT
01642 kdDebug(32500) << "formatMore " << name() << ". First parag -> starting timer" << endl;
01643 m_time.start();
01644 #endif
01645 }
01646
01647
01648
01649
01650 int i;
01651 for ( i = 0;
01652 m_lastFormatted && bottom + m_lastFormatted->rect().height() <= m_availableHeight &&
01653 ( i < count || bottom <= viewsBottom ) ; ++i )
01654 {
01655 KoTextParag* parag = m_lastFormatted;
01656 #ifdef DEBUG_FORMAT_MORE
01657 kdDebug(32500) << "formatMore formatting " << parag << " id=" << parag->paragId() << endl;
01658 #endif
01659 assert( parag->string() );
01660 parag->format();
01661 bottom = parag->rect().top() + parag->rect().height();
01662 #if 0 //def DEBUG_FORMAT_MORE
01663 kdDebug(32500) << "formatMore(inside) top=" << parag->rect().top()
01664 << " height=" << parag->rect().height()
01665 << " bottom=" << bottom << " m_lastFormatted(next parag) = " << m_lastFormatted->next() << endl;
01666 #endif
01667
01668
01669 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_CHAPTER
01670 && parag->counter()->depth() == 0 )
01671 emit chapterParagraphFormatted( parag );
01672
01673 if ( d->abortFormatting ) {
01674 #ifdef DEBUG_FORMAT_MORE
01675 kdDebug(32500) << "formatMore formatting aborted. " << endl;
01676 #endif
01677 d->abortFormatting = false;
01678 return false;
01679 }
01680
01681 if ( parag != m_lastFormatted )
01682 kdWarning() << "Some code changed m_lastFormatted during formatting! Was " << parag->paragId() << ", is now " << m_lastFormatted->paragId() << endl;
01683 #if 0 // This happens now that formatting can 'abort' (e.g. due to page not yet created)
01684 else if (!parag->isValid())
01685 kdWarning() << "PARAGRAPH " << parag->paragId() << " STILL INVALID AFTER FORMATTING" << endl;
01686 #endif
01687 m_lastFormatted = parag->next();
01688 }
01689 }
01690 else
01691 {
01692 QRect rect = textdoc->lastParag()->rect();
01693 bottom = rect.top() + rect.height();
01694 }
01695 #ifdef DEBUG_FORMAT_MORE
01696 QString id;
01697 if ( m_lastFormatted ) id = QString(" (%1)").arg(m_lastFormatted->paragId());
01698 kdDebug(32500) << "formatMore finished formatting. "
01699 << " bottom=" << bottom
01700 << " m_lastFormatted=" << m_lastFormatted << id
01701 << endl;
01702 #endif
01703
01704 if ( emitAfterFormatting )
01705 {
01706 d->afterFormattingEmitted = true;
01707 bool abort = false;
01708
01709 if ( ( bottom > m_availableHeight ) ||
01710 ( m_lastFormatted && bottom + m_lastFormatted->rect().height() > m_availableHeight ) )
01711 abort = true;
01712 emit afterFormatting( bottom, m_lastFormatted, &abort );
01713 if ( abort )
01714 return false;
01715 else if ( m_lastFormatted )
01716 return formatMore( 2 );
01717 }
01718
01719
01720 if ( m_lastFormatted )
01721 {
01722 formatTimer->start( interval, TRUE );
01723 #ifdef DEBUG_FORMAT_MORE
01724 kdDebug(32500) << name() << " formatMore: will have to format more. formatTimer->start with interval=" << interval << endl;
01725 #endif
01726 }
01727 else
01728 {
01729 interval = QMAX( 0, interval );
01730 #ifdef DEBUG_FORMAT_MORE
01731 kdDebug(32500) << name() << " formatMore: all formatted interval=" << interval << endl;
01732 #endif
01733 #ifdef TIMING_FORMAT
01734
01735 kdDebug(32500) << "formatMore: " << name() << " all formatted. Took "
01736 << (double)(m_time.elapsed()) / 1000 << " seconds." << endl;
01737 #endif
01738 }
01739 return true;
01740 }
01741
01742 void KoTextObject::abortFormatting()
01743 {
01744 d->abortFormatting = true;
01745 }
01746
01747 void KoTextObject::doChangeInterval()
01748 {
01749
01750 interval = 0;
01751 }
01752
01753 void KoTextObject::typingStarted()
01754 {
01755
01756 changeIntervalTimer->stop();
01757 interval = 10;
01758 }
01759
01760 void KoTextObject::typingDone()
01761 {
01762 changeIntervalTimer->start( 100, TRUE );
01763 }
01764
01765
01766
01767 KCommand *KoTextObject::changeCaseOfTextParag( int cursorPosStart, int cursorPosEnd,
01768 KoChangeCaseDia::TypeOfCase _type,
01769 KoTextCursor *cursor, KoTextParag *parag )
01770 {
01771 if ( protectContent() )
01772 return 0L;
01773
01774 KMacroCommand * macroCmd = new KMacroCommand( i18n("Change Case") );
01775 KoTextFormat *curFormat = parag->paragraphFormat();
01776 const QString text = parag->string()->toString().mid( cursorPosStart, cursorPosEnd - cursorPosStart );
01777 int posStart = cursorPosStart;
01778 int posEnd = cursorPosStart;
01779 KoTextCursor c1( textdoc );
01780 KoTextCursor c2( textdoc );
01781
01782 for ( int i = cursorPosStart; i < cursorPosEnd; ++i )
01783 {
01784 KoTextStringChar & ch = *(parag->at(i));
01785 KoTextFormat * newFormat = ch.format();
01786 if( ch.isCustom() )
01787 {
01788 posEnd = i;
01789 c1.setParag( parag );
01790 c1.setIndex( posStart );
01791 c2.setParag( parag );
01792 c2.setIndex( posEnd );
01793
01794
01795 const QString repl = text.mid( posStart, posEnd - posStart );
01796 textdoc->setSelectionStart( KoTextDocument::Temp, &c1 );
01797 textdoc->setSelectionEnd( KoTextDocument::Temp, &c2 );
01798 macroCmd->addCommand(replaceSelectionCommand(
01799 cursor, textChangedCase(repl,_type),
01800 KoTextDocument::Temp, QString::null, false, false ));
01801 do
01802 {
01803 ++i;
01804 }
01805 while( parag->at(i)->isCustom() && i != cursorPosEnd);
01806 posStart=i;
01807 posEnd=i;
01808 }
01809 else
01810 {
01811 if ( newFormat != curFormat )
01812 {
01813 posEnd=i;
01814 c1.setParag( parag );
01815 c1.setIndex( posStart );
01816 c2.setParag( parag );
01817 c2.setIndex( posEnd );
01818
01819
01820 const QString repl = text.mid( posStart, posEnd - posStart );
01821 textdoc->setSelectionStart( KoTextDocument::Temp, &c1 );
01822 textdoc->setSelectionEnd( KoTextDocument::Temp, &c2 );
01823 macroCmd->addCommand(replaceSelectionCommand(
01824 cursor, textChangedCase(repl,_type),
01825 KoTextDocument::Temp, QString::null, false, false ));
01826 posStart=i;
01827 posEnd=i;
01828 curFormat = newFormat;
01829 }
01830 }
01831 }
01832 if ( posStart != cursorPosEnd )
01833 {
01834
01835 c1.setParag( parag );
01836 c1.setIndex( posStart );
01837 c2.setParag( parag );
01838 c2.setIndex( cursorPosEnd );
01839
01840 textdoc->setSelectionStart( KoTextDocument::Temp, &c1 );
01841 textdoc->setSelectionEnd( KoTextDocument::Temp, &c2 );
01842 const QString repl = text.mid( posStart, cursorPosEnd - posStart );
01843 macroCmd->addCommand(replaceSelectionCommand(
01844 cursor, textChangedCase(repl,_type),
01845 KoTextDocument::Temp, QString::null, false, false ));
01846 }
01847 return macroCmd;
01848
01849 }
01850
01851 KCommand *KoTextObject::changeCaseOfText(KoTextCursor *cursor,KoChangeCaseDia::TypeOfCase _type)
01852 {
01853 if ( protectContent() )
01854 return 0L;
01855 KMacroCommand * macroCmd = new KMacroCommand( i18n("Change Case") );
01856
01857 KoTextCursor start = textdoc->selectionStartCursor( KoTextDocument::Standard );
01858 KoTextCursor end = textdoc->selectionEndCursor( KoTextDocument::Standard );
01859 emit hideCursor();
01860
01861 if ( start.parag() == end.parag() )
01862 {
01863 int endIndex = QMIN( start.parag()->length() - 1, end.index() );
01864 macroCmd->addCommand( changeCaseOfTextParag( start.index(), endIndex, _type,
01865 cursor, start.parag() ) );
01866 }
01867 else
01868 {
01869 macroCmd->addCommand( changeCaseOfTextParag( start.index(), start.parag()->length() - 1, _type,
01870 cursor, start.parag() ) );
01871 KoTextParag *p = start.parag()->next();
01872 while ( p && p != end.parag() )
01873 {
01874 macroCmd->addCommand( changeCaseOfTextParag(0, p->length() - 1, _type, cursor, p ) );
01875 p = p->next();
01876 }
01877 int endIndex = QMIN( p->length() - 1, end.index() );
01878 macroCmd->addCommand( changeCaseOfTextParag(0, endIndex, _type, cursor, end.parag() ));
01879 }
01880 formatMore( 2 );
01881 emit repaintChanged( this );
01882 emit ensureCursorVisible();
01883 emit updateUI( true );
01884 emit showCursor();
01885 return macroCmd;
01886 }
01887
01888 QString KoTextObject::textChangedCase(const QString& _text,KoChangeCaseDia::TypeOfCase _type)
01889 {
01890 QString text(_text);
01891 switch(_type)
01892 {
01893 case KoChangeCaseDia::UpperCase:
01894 text=text.upper();
01895 break;
01896 case KoChangeCaseDia::LowerCase:
01897 text=text.lower();
01898 break;
01899 case KoChangeCaseDia::TitleCase:
01900 for(uint i=0;i<text.length();i++)
01901 {
01902 if(text.at(i)!=' ')
01903 {
01904 QChar prev = text.at(QMAX(i-1,0));
01905 if(i==0 || prev == ' ' || prev == '\n' || prev == '\t')
01906 text=text.replace(i, 1, text.at(i).upper() );
01907 else
01908 text=text.replace(i, 1, text.at(i).lower() );
01909 }
01910 }
01911 break;
01912 case KoChangeCaseDia::ToggleCase:
01913 for(uint i=0;i<text.length();i++)
01914 {
01915 QString repl=QString(text.at(i));
01916 if(text.at(i)!=text.at(i).upper())
01917 repl=repl.upper();
01918 else if(text.at(i).lower()!=text.at(i))
01919 repl=repl.lower();
01920 text=text.replace(i, 1, repl );
01921 }
01922 break;
01923 case KoChangeCaseDia::SentenceCase:
01924 for(uint i=0;i<text.length();i++)
01925 {
01926 if(text.at(i)!=' ')
01927 {
01928 QChar prev = text.at(QMAX(i-1,0));
01929 if(i==0 || prev == '\n' ||prev.isPunct())
01930 text=text.replace(i, 1, text.at(i).upper() );
01931 }
01932 }
01933 break;
01934 default:
01935 kdDebug(32500)<<"Error in changeCaseOfText !\n";
01936 break;
01937
01938 }
01939 return text;
01940 }
01941
01942
01943 KoTextFormat * KoTextObject::currentFormat() const
01944 {
01945
01946
01947 KoTextStringChar *ch = textdoc->firstParag()->at( 0 );
01948 return ch->format();
01949 }
01950
01951 const KoParagLayout * KoTextObject::currentParagLayoutFormat() const
01952 {
01953 KoTextParag * parag = textdoc->firstParag();
01954 return &(parag->paragLayout());
01955 }
01956
01957 bool KoTextObject::rtl() const
01958 {
01959 return textdoc->firstParag()->string()->isRightToLeft();
01960 }
01961
01962 void KoTextObject::loadOasisContent( const QDomElement &bodyElem, KoOasisContext& context, KoStyleCollection * styleColl )
01963 {
01964 textDocument()->clear(false);
01965 setLastFormattedParag( 0L );
01966
01967 KoTextParag *lastParagraph = textDocument()->loadOasisText( bodyElem, context, 0, styleColl, 0 );
01968
01969 if ( !lastParagraph )
01970 {
01971
01972 textDocument()->clear( true );
01973 textDocument()->firstParag()->setStyle( styleColl->findStyle( "Standard" ) );
01974 }
01975 else
01976 textDocument()->setLastParag( lastParagraph );
01977
01978 setLastFormattedParag( textDocument()->firstParag() );
01979 }
01980
01981 KoTextCursor KoTextObject::pasteOasisText( const QDomElement &bodyElem, KoOasisContext& context,
01982 KoTextCursor& cursor, KoStyleCollection * styleColl )
01983 {
01984 KoTextCursor resultCursor( cursor );
01985 KoTextParag* lastParagraph = cursor.parag();
01986 bool removeNewline = false;
01987 uint pos = cursor.index();
01988 if ( pos == 0 && lastParagraph->length() <= 1 ) {
01989
01990 lastParagraph = lastParagraph->prev();
01991 lastParagraph = textDocument()->loadOasisText( bodyElem, context, lastParagraph, styleColl, cursor.parag() );
01992 if ( lastParagraph ) {
01993 resultCursor.setParag( lastParagraph );
01994 resultCursor.setIndex( lastParagraph->length() - 1 );
01995 }
01996 removeNewline = true;
01997 } else {
01998
01999
02000 for ( QDomNode text (bodyElem.firstChild()); !text.isNull(); text = text.nextSibling() )
02001 {
02002 QDomElement tag = text.toElement();
02003 if ( tag.isNull() ) continue;
02004 context.styleStack().save();
02005
02006
02007
02008 QDomElement tagToLoad = tag;
02009 if ( tag.localName() == "numbered-paragraph" ) {
02010 QDomElement npchild;
02011 forEachElement( npchild, tag )
02012 {
02013 if ( npchild.localName() == "p" || npchild.localName() == "h" ) {
02014 tagToLoad = npchild;
02015 break;
02016 }
02017 }
02018
02019 }
02020 if ( tagToLoad.localName() == "p" || tagToLoad.localName() == "h" ) {
02021 context.fillStyleStack( tagToLoad, KoXmlNS::text, "style-name" );
02022 lastParagraph->loadOasisSpan( tagToLoad, context, pos );
02023 lastParagraph->setChanged( true );
02024 lastParagraph->invalidate( 0 );
02025 context.styleStack().restore();
02026
02027 const_cast<QDomElement &>( bodyElem ).removeChild( tag );
02028 }
02029 break;
02030 }
02031 resultCursor.setParag( lastParagraph );
02032 resultCursor.setIndex( pos );
02033
02034 lastParagraph = textDocument()->loadOasisText( bodyElem, context, lastParagraph, styleColl, lastParagraph->next() );
02035 if ( lastParagraph != resultCursor.parag() )
02036 {
02037 removeNewline = true;
02038 resultCursor.setParag( lastParagraph );
02039 resultCursor.setIndex( lastParagraph->length() - 1 );
02040 }
02041 }
02042 KoTextParag* p = resultCursor.parag();
02043 if ( p ) p = p->next();
02044
02045 if ( removeNewline && resultCursor.remove() ) {
02046 if ( m_lastFormatted == p ) {
02047 m_lastFormatted = resultCursor.parag();
02048 }
02049 }
02050 return resultCursor;
02051 }
02052
02053 void KoTextObject::saveOasisContent( KoXmlWriter& writer, KoSavingContext& context ) const
02054 {
02055 textDocument()->saveOasisContent( writer, context );
02056 }
02057
02058 KCommand *KoTextObject::setParagLayoutFormatCommand( KoParagLayout *newLayout,int flags,int marginIndex)
02059 {
02060 if ( protectContent() )
02061 return 0L;
02062 textdoc->selectAll( KoTextDocument::Temp );
02063 KoTextCursor *cursor = new KoTextCursor( textdoc );
02064 KCommand* cmd = setParagLayoutCommand( cursor, *newLayout, KoTextDocument::Temp,
02065 flags, marginIndex, true );
02066 textdoc->removeSelection( KoTextDocument::Temp );
02067 delete cursor;
02068 return cmd;
02069 }
02070
02071 void KoTextObject::setFormat( KoTextFormat * newFormat, int flags, bool zoomFont )
02072 {
02073 if ( protectContent() )
02074 return ;
02075
02076 textdoc->selectAll( KoTextDocument::Temp );
02077 KCommand *cmd = setFormatCommand( 0L, 0L, newFormat,
02078 flags, zoomFont, KoTextDocument::Temp );
02079 textdoc->removeSelection( KoTextDocument::Temp );
02080 if (cmd)
02081 emit newCommand( cmd );
02082
02083 KoTextFormat format = *currentFormat();
02084
02085 emit showFormatObject(format);
02086 }
02087
02088 KCommand *KoTextObject::setChangeCaseOfTextCommand(KoChangeCaseDia::TypeOfCase _type)
02089 {
02090 if ( protectContent() )
02091 return 0L;
02092 textdoc->selectAll( KoTextDocument::Standard );
02093 KoTextCursor *cursor = new KoTextCursor( textdoc );
02094 KCommand* cmd = changeCaseOfText(cursor, _type);
02095 textdoc->removeSelection( KoTextDocument::Standard );
02096 delete cursor;
02097 return cmd;
02098 }
02099
02100 void KoTextObject::setNeedSpellCheck(bool b)
02101 {
02102 m_needsSpellCheck = b;
02103 for (KoTextParag * parag = textdoc->firstParag(); parag ; parag = parag->next())
02104 parag->string()->setNeedsSpellCheck( b );
02105 }
02106
02107 bool KoTextObject::statistics( QProgressDialog *progress, ulong & charsWithSpace, ulong & charsWithoutSpace, ulong & words, ulong & sentences, ulong & syllables, ulong & lines, bool selected )
02108 {
02109
02110
02111
02112 QStringList subs_syl;
02113 subs_syl << "cial" << "tia" << "cius" << "cious" << "giu" << "ion" << "iou";
02114 QStringList subs_syl_regexp;
02115 subs_syl_regexp << "sia$" << "ely$";
02116
02117 QStringList add_syl;
02118 add_syl << "ia" << "riet" << "dien" << "iu" << "io" << "ii";
02119 QStringList add_syl_regexp;
02120 add_syl_regexp << "[aeiouym]bl$" << "[aeiou]{3}" << "^mc" << "ism$"
02121 << "[^l]lien" << "^coa[dglx]." << "[^gq]ua[^auieo]" << "dnt$";
02122
02123 QString s;
02124 KoTextParag * parag = textdoc->firstParag();
02125 for ( ; parag ; parag = parag->next() )
02126 {
02127 if ( progress )
02128 {
02129 progress->setProgress(progress->progress()+1);
02130
02131 kapp->processEvents();
02132 if ( progress->wasCancelled() )
02133 return false;
02134 }
02135
02136
02137
02138
02139
02140
02141
02142 bool hasTrailingSpace = true;
02143 if ( !selected ) {
02144 s = parag->string()->toString();
02145 lines += parag->lines();
02146 } else {
02147 if ( parag->hasSelection( KoTextDocument::Standard ) ) {
02148 hasTrailingSpace = false;
02149 s = parag->string()->toString();
02150 if ( !( parag->fullSelected( KoTextDocument::Standard ) ) ) {
02151 s = s.mid( parag->selectionStart( KoTextDocument::Standard ), parag->selectionEnd( KoTextDocument::Standard ) - parag->selectionStart( KoTextDocument::Standard ) );
02152 lines+=numberOfparagraphLineSelected(parag);
02153 }
02154 else
02155 lines += parag->lines();
02156 } else {
02157 continue;
02158 }
02159 }
02160
02161
02162 for ( uint i = 0 ; i < s.length() - ( hasTrailingSpace ? 1 : 0 ) ; ++i )
02163 {
02164 QChar ch = s[i];
02165 ++charsWithSpace;
02166 if ( !ch.isSpace() )
02167 ++charsWithoutSpace;
02168 }
02169
02170
02171
02172
02173
02174
02175
02176 QRegExp re("\\s+");
02177 QStringList wordlist = QStringList::split(re, s);
02178 words += wordlist.count();
02179 re.setCaseSensitive(false);
02180 for ( QStringList::Iterator it = wordlist.begin(); it != wordlist.end(); ++it ) {
02181 QString word = *it;
02182 re.setPattern("[!?.,:_\"-]");
02183 word.remove(re);
02184 if ( word.length() <= 3 ) {
02185 syllables++;
02186 continue;
02187 }
02188 re.setPattern("e$");
02189 word.remove(re);
02190 re.setPattern("[^aeiouy]+");
02191 QStringList syls = QStringList::split(re, word);
02192 int word_syllables = 0;
02193 for ( QStringList::Iterator it = subs_syl.begin(); it != subs_syl.end(); ++it ) {
02194 if( word.find(*it, 0, false) != -1 )
02195 word_syllables--;
02196 }
02197 for ( QStringList::Iterator it = subs_syl_regexp.begin(); it != subs_syl_regexp.end(); ++it ) {
02198 re.setPattern(*it);
02199 if( word.find(re) != -1 )
02200 word_syllables--;
02201 }
02202 for ( QStringList::Iterator it = add_syl.begin(); it != add_syl.end(); ++it ) {
02203 if( word.find(*it, 0, false) != -1 )
02204 word_syllables++;
02205 }
02206 for ( QStringList::Iterator it = add_syl_regexp.begin(); it != add_syl_regexp.end(); ++it ) {
02207 re.setPattern(*it);
02208 if( word.find(re) != -1 )
02209 word_syllables++;
02210 }
02211 word_syllables += syls.count();
02212 if ( word_syllables == 0 )
02213 word_syllables = 1;
02214 syllables += word_syllables;
02215 }
02216 re.setCaseSensitive(true);
02217
02218
02219
02220 s = s.stripWhiteSpace();
02221 QChar lastchar = s.at(s.length());
02222 if( ! s.isEmpty() && ! KoAutoFormat::isMark( lastchar ) ) {
02223 s = s + ".";
02224 }
02225 re.setPattern("[.?!]+");
02226 s.replace(re, ".");
02227 re.setPattern("\\d\\.\\d");
02228 s.replace(re, "0,0");
02229 re.setPattern("[A-Z]\\.+");
02230 s.replace(re, "*");
02231 for ( uint i = 0 ; i < s.length() ; ++i )
02232 {
02233 QChar ch = s[i];
02234 if ( KoAutoFormat::isMark( ch ) )
02235 ++sentences;
02236 }
02237 }
02238 return true;
02239 }
02240
02241 int KoTextObject::numberOfparagraphLineSelected( KoTextParag *parag)
02242 {
02243 int indexOfLineStart;
02244 int lineStart;
02245 int lineEnd;
02246 KoTextCursor c1 = textdoc->selectionStartCursor( KoTextDocument::Standard );
02247 KoTextCursor c2 = textdoc->selectionEndCursor( KoTextDocument::Standard );
02248 parag->lineStartOfChar( c1.index(), &indexOfLineStart, &lineStart );
02249
02250 parag->lineStartOfChar( c2.index(), &indexOfLineStart, &lineEnd );
02251 return (lineEnd - lineStart+1);
02252 }
02253
02254 KoVariable* KoTextObject::variableAtPoint( const QPoint& iPoint ) const
02255 {
02256 KoTextCursor cursor( textDocument() );
02257 int variablePosition = -1;
02258 cursor.place( iPoint, textDocument()->firstParag(), false, &variablePosition );
02259 if ( variablePosition == -1 )
02260 return 0;
02261 return variableAtPosition( cursor.parag(), variablePosition );
02262 }
02263
02264 KoVariable* KoTextObject::variableAtPosition( KoTextParag* parag, int index ) const
02265 {
02266 KoTextStringChar * ch = parag->at( index );
02267 if ( ch->isCustom() )
02268 return dynamic_cast<KoVariable *>( ch->customItem() );
02269 return 0;
02270 }
02271
02272 const char * KoTextObject::acceptSelectionMimeType()
02273 {
02274 return "application/vnd.oasis.opendocument.";
02275 }
02276
02277 QCString KoTextObject::providesOasis( QMimeSource* mime )
02278 {
02279 const char* fmt;
02280 const char* acceptMimeType = acceptSelectionMimeType();
02281 for ( int i = 0; (fmt = mime->format(i)); ++i )
02282 {
02283 if ( QString( fmt ).startsWith( acceptMimeType ) )
02284 {
02285 return fmt;
02286 }
02287 }
02288 return "";
02289 }
02290
02291 #ifndef NDEBUG
02292 void KoTextObject::printRTDebug(int info)
02293 {
02294 KoTextParag* lastParag = 0;
02295 for (KoTextParag * parag = textdoc->firstParag(); parag ; parag = parag->next())
02296 {
02297 assert( parag->prev() == lastParag );
02298 parag->printRTDebug( info );
02299 lastParag = parag;
02300 }
02301 if ( info == 1 )
02302 textdoc->formatCollection()->debug();
02303 }
02304 #endif
02305
02307
02308 KCommand *KoTextFormatInterface::setBoldCommand(bool on)
02309 {
02310 KoTextFormat format( *currentFormat() );
02311 format.setBold( on );
02312 return setFormatCommand( &format, KoTextFormat::Bold );
02313 }
02314
02315 KCommand *KoTextFormatInterface::setItalicCommand( bool on)
02316 {
02317 KoTextFormat format( *currentFormat() );
02318 format.setItalic( on );
02319 return setFormatCommand( &format, KoTextFormat::Italic );
02320 }
02321
02322 KCommand *KoTextFormatInterface::setUnderlineCommand( bool on )
02323 {
02324 KoTextFormat format( *currentFormat() );
02325 format.setUnderlineType( on ? KoTextFormat::U_SIMPLE : KoTextFormat::U_NONE);
02326 return setFormatCommand( &format, KoTextFormat::ExtendUnderLine );
02327 }
02328
02329 KCommand *KoTextFormatInterface::setUnderlineColorCommand( const QColor &color )
02330 {
02331 KoTextFormat format( *currentFormat() );
02332 format.setTextUnderlineColor( color);
02333 return setFormatCommand( &format, KoTextFormat::ExtendUnderLine );
02334 }
02335
02336 KCommand *KoTextFormatInterface::setDoubleUnderlineCommand( bool on )
02337 {
02338 KoTextFormat format( *currentFormat() );
02339 format.setUnderlineType( on ? KoTextFormat::U_DOUBLE : KoTextFormat::U_NONE);
02340 return setFormatCommand( &format, KoTextFormat::ExtendUnderLine );
02341 }
02342
02343 KCommand *KoTextFormatInterface::setStrikeOutCommand( bool on )
02344 {
02345 KoTextFormat format( *currentFormat() );
02346 format.setStrikeOutType( on ? KoTextFormat::S_SIMPLE : KoTextFormat::S_NONE);
02347 return setFormatCommand( &format, KoTextFormat::StrikeOut );
02348 }
02349
02350 KCommand *KoTextFormatInterface::setTextBackgroundColorCommand(const QColor & col)
02351 {
02352 KoTextFormat format( *currentFormat() );
02353 format.setTextBackgroundColor( col );
02354 return setFormatCommand( &format, KoTextFormat::TextBackgroundColor );
02355 }
02356
02357 KCommand *KoTextFormatInterface::setPointSizeCommand( int s )
02358 {
02359 KoTextFormat format( *currentFormat() );
02360 format.setPointSize( s );
02361 return setFormatCommand( &format, KoTextFormat::Size, true );
02362 }
02363
02364 KCommand *KoTextFormatInterface::setFamilyCommand(const QString &font)
02365 {
02366 KoTextFormat format( *currentFormat() );
02367 format.setFamily( font );
02368 return setFormatCommand( &format, KoTextFormat::Family );
02369 }
02370
02371 QColor KoTextFormatInterface::textBackgroundColor() const
02372 {
02373 return currentFormat()->textBackgroundColor();
02374 }
02375
02376 QColor KoTextFormatInterface::textUnderlineColor()const
02377 {
02378 return currentFormat()->textUnderlineColor();
02379 }
02380
02381 QColor KoTextFormatInterface::textColor() const
02382 {
02383 return currentFormat()->color();
02384 }
02385
02386 bool KoTextFormatInterface::textUnderline()const
02387 {
02388 return currentFormat()->underline();
02389 }
02390
02391 bool KoTextFormatInterface::textDoubleUnderline()const
02392 {
02393 return currentFormat()->doubleUnderline();
02394 }
02395
02396 bool KoTextFormatInterface::textBold()const
02397 {
02398 return currentFormat()->font().bold();
02399 }
02400
02401 bool KoTextFormatInterface::textStrikeOut()const
02402 {
02403 return currentFormat()->font().strikeOut();
02404 }
02405
02406 bool KoTextFormatInterface::textItalic() const
02407 {
02408 return currentFormat()->font().italic();
02409 }
02410
02411 bool KoTextFormatInterface::textSubScript() const
02412 {
02413 return (currentFormat()->vAlign()==KoTextFormat::AlignSubScript);
02414 }
02415
02416 bool KoTextFormatInterface::textSuperScript() const
02417 {
02418 return (currentFormat()->vAlign()==KoTextFormat::AlignSuperScript);
02419 }
02420
02421 double KoTextFormatInterface::shadowDistanceX() const
02422 {
02423 return currentFormat()->shadowDistanceX();
02424 }
02425
02426 double KoTextFormatInterface::shadowDistanceY() const
02427 {
02428 return currentFormat()->shadowDistanceY();
02429 }
02430
02431 QColor KoTextFormatInterface::shadowColor() const
02432 {
02433 return currentFormat()->shadowColor();
02434 }
02435
02436 KoTextFormat::AttributeStyle KoTextFormatInterface::fontAttribute() const
02437 {
02438 return currentFormat()->attributeFont();
02439 }
02440
02441 double KoTextFormatInterface::relativeTextSize() const
02442 {
02443 return currentFormat()->relativeTextSize();
02444 }
02445
02446 int KoTextFormatInterface::offsetFromBaseLine()const
02447 {
02448 return currentFormat()->offsetFromBaseLine();
02449 }
02450
02451 bool KoTextFormatInterface::wordByWord()const
02452 {
02453 return currentFormat()->wordByWord();
02454 }
02455
02456 bool KoTextFormatInterface::hyphenation()const
02457 {
02458 return currentFormat()->hyphenation();
02459 }
02460
02461 KoTextFormat::UnderlineType KoTextFormatInterface::underlineType()const
02462 {
02463 return currentFormat()->underlineType();
02464 }
02465
02466 KoTextFormat::StrikeOutType KoTextFormatInterface::strikeOutType()const
02467 {
02468 return currentFormat()->strikeOutType();
02469 }
02470
02471 KoTextFormat::UnderlineStyle KoTextFormatInterface::underlineStyle()const
02472 {
02473 return currentFormat()->underlineStyle();
02474 }
02475
02476 KoTextFormat::StrikeOutStyle KoTextFormatInterface::strikeOutStyle()const
02477 {
02478 return currentFormat()->strikeOutStyle();
02479 }
02480
02481 QFont KoTextFormatInterface::textFont() const
02482 {
02483 QFont fn( currentFormat()->font() );
02484
02485
02486 return fn;
02487 }
02488
02489 QString KoTextFormatInterface::textFontFamily()const
02490 {
02491 return currentFormat()->font().family();
02492 }
02493
02494 QString KoTextFormatInterface::language() const
02495 {
02496 return currentFormat()->language();
02497 }
02498
02499 KCommand *KoTextFormatInterface::setTextColorCommand(const QColor &color)
02500 {
02501 KoTextFormat format( *currentFormat() );
02502 format.setColor( color );
02503 return setFormatCommand( &format, KoTextFormat::Color );
02504 }
02505
02506 KCommand *KoTextFormatInterface::setTextSubScriptCommand(bool on)
02507 {
02508 KoTextFormat format( *currentFormat() );
02509 if(!on)
02510 format.setVAlign(KoTextFormat::AlignNormal);
02511 else
02512 format.setVAlign(KoTextFormat::AlignSubScript);
02513 return setFormatCommand( &format, KoTextFormat::VAlign );
02514 }
02515
02516 KCommand *KoTextFormatInterface::setTextSuperScriptCommand(bool on)
02517 {
02518 KoTextFormat format( *currentFormat() );
02519 if(!on)
02520 format.setVAlign(KoTextFormat::AlignNormal);
02521 else
02522 format.setVAlign(KoTextFormat::AlignSuperScript);
02523 return setFormatCommand( &format, KoTextFormat::VAlign );
02524 }
02525
02526 KCommand *KoTextFormatInterface::setDefaultFormatCommand()
02527 {
02528 KoTextFormatCollection * coll = currentFormat()->parent();
02529 Q_ASSERT(coll);
02530 if(coll)
02531 {
02532 KoTextFormat * format = coll->defaultFormat();
02533 return setFormatCommand( format, KoTextFormat::Format );
02534 } else {
02535 kdDebug() << "useless call to setDefaultFormatCommand at: " << kdBacktrace() << endl;
02536 }
02537 return 0;
02538 }
02539
02540 KCommand *KoTextFormatInterface::setAlignCommand(int align)
02541 {
02542 KoParagLayout format( *currentParagLayoutFormat() );
02543 format.alignment=align;
02544 return setParagLayoutFormatCommand(&format,KoParagLayout::Alignment);
02545 }
02546
02547 KCommand *KoTextFormatInterface::setHyphenationCommand( bool _b )
02548 {
02549 KoTextFormat format( *currentFormat() );
02550 format.setHyphenation( _b );
02551 return setFormatCommand( &format, KoTextFormat::Hyphenation);
02552 }
02553
02554
02555 KCommand *KoTextFormatInterface::setShadowTextCommand( double shadowDistanceX, double shadowDistanceY, const QColor& shadowColor )
02556 {
02557 KoTextFormat format( *currentFormat() );
02558 format.setShadow( shadowDistanceX, shadowDistanceY, shadowColor );
02559 return setFormatCommand( &format, KoTextFormat::ShadowText );
02560 }
02561
02562 KCommand *KoTextFormatInterface::setFontAttributeCommand( KoTextFormat::AttributeStyle _att)
02563 {
02564 KoTextFormat format( *currentFormat() );
02565 format.setAttributeFont( _att );
02566 return setFormatCommand( &format, KoTextFormat::Attribute );
02567 }
02568
02569 KCommand *KoTextFormatInterface::setRelativeTextSizeCommand( double _size )
02570 {
02571 KoTextFormat format( *currentFormat() );
02572 format.setRelativeTextSize( _size );
02573 return setFormatCommand( &format, KoTextFormat::VAlign );
02574 }
02575
02576 KCommand *KoTextFormatInterface::setOffsetFromBaseLineCommand( int _offset )
02577 {
02578 KoTextFormat format( *currentFormat() );
02579 format.setOffsetFromBaseLine( _offset );
02580 return setFormatCommand( &format, KoTextFormat::OffsetFromBaseLine );
02581 }
02582
02583 KCommand *KoTextFormatInterface::setWordByWordCommand( bool _b )
02584 {
02585 KoTextFormat format( *currentFormat() );
02586 format.setWordByWord( _b );
02587 return setFormatCommand( &format, KoTextFormat::WordByWord );
02588 }
02589
02590 #if 0
02591 void KoTextFormatInterface::setAlign(int align)
02592 {
02593 KCommand *cmd = setAlignCommand( align );
02594 emitNewCommand( cmd );
02595 }
02596
02597 void KoTextFormatInterface::setMargin(QStyleSheetItem::Margin m, double margin)
02598 {
02599 KCommand *cmd = setMarginCommand( m, margin );
02600 emitNewCommand( cmd );
02601 }
02602
02603 void KoTextFormatInterface::setTabList(const KoTabulatorList & tabList )
02604 {
02605 KCommand *cmd = setTabListCommand( tabList );
02606 emitNewCommand( cmd );
02607 }
02608
02609 void KoTextFormatInterface::setCounter(const KoParagCounter & counter )
02610 {
02611 KCommand *cmd = setCounterCommand( counter );
02612 emitNewCommand( cmd );
02613 }
02614
02615 void KoTextFormatInterface::setParagLayoutFormat( KoParagLayout *newLayout, int flags, int marginIndex)
02616 {
02617 KCommand *cmd = setParagLayoutFormatCommand(newLayout, flags, marginIndex);
02618 emitNewCommand( cmd );
02619 }
02620 #endif
02621
02622 KCommand *KoTextFormatInterface::setMarginCommand(QStyleSheetItem::Margin m, double margin)
02623 {
02624 KoParagLayout format( *currentParagLayoutFormat() );
02625 format.margins[m]=margin;
02626 return setParagLayoutFormatCommand(&format,KoParagLayout::Margins,(int)m);
02627 }
02628
02629 KCommand *KoTextFormatInterface::setTabListCommand(const KoTabulatorList & tabList )
02630 {
02631 KoParagLayout format( *currentParagLayoutFormat() );
02632 format.setTabList(tabList);
02633 return setParagLayoutFormatCommand(&format,KoParagLayout::Tabulator);
02634 }
02635
02636 KCommand *KoTextFormatInterface::setCounterCommand(const KoParagCounter & counter )
02637 {
02638 KoParagLayout format( *currentParagLayoutFormat() );
02639 if(!format.counter)
02640 format.counter = new KoParagCounter;
02641 *format.counter = counter;
02642 return setParagLayoutFormatCommand(&format,KoParagLayout::BulletNumber);
02643 }
02644
02645 KCommand *KoTextFormatInterface::setLanguageCommand(const QString &_lang)
02646 {
02647 KoTextFormat format( *currentFormat() );
02648 format.setLanguage(_lang);
02649 return setFormatCommand( &format, KoTextFormat::Language );
02650 }
02651
02652 KoTextDocCommand *KoTextFormatInterface::deleteTextCommand( KoTextDocument *textdoc, int id, int index, const QMemArray<KoTextStringChar> & str, const CustomItemsMap & customItemsMap, const QValueList<KoParagLayout> & oldParagLayouts )
02653 {
02654 return textdoc->deleteTextCommand( textdoc, id, index, str, customItemsMap, oldParagLayouts );
02655 }
02656
02657 #include "kotextobject.moc"