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