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