00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoTextView.h"
00021 #include "KoTextParag.h"
00022 #include "KoParagCounter.h"
00023 #include "KoTextObject.h"
00024 #include "KoTextViewIface.h"
00025 #include "KoStyleCollection.h"
00026 #include "KoBgSpellCheck.h"
00027 #include "KoVariable.h"
00028
00029 #include <klocale.h>
00030 #include <kstandarddirs.h>
00031 #include <kstdaccel.h>
00032 #include <kdebug.h>
00033 #include <kinstance.h>
00034 #include <kdatatool.h>
00035 #include <krun.h>
00036 #include <kmessagebox.h>
00037 #include <kcommand.h>
00038 #include <kbookmarkmanager.h>
00039 #include <kbookmark.h>
00040 #include <kurldrag.h>
00041
00042 #include <qapplication.h>
00043 #include <qtimer.h>
00044 #include <qclipboard.h>
00045
00046 class KoTextView::KoTextViewPrivate
00047 {
00048 public:
00049 KoTextViewPrivate()
00050 {
00051 m_currentUnicodeNumber = 0;
00052 m_backSpeller = 0;
00053 }
00054
00055 void appendDigit( int digit ) { m_currentUnicodeNumber = 10 * m_currentUnicodeNumber + digit; }
00056 int currentUnicodeNumber() const { return m_currentUnicodeNumber; }
00057 void clearCurrentUnicodeNumber() { m_currentUnicodeNumber = 0; }
00058
00059 KoBgSpellCheck* m_backSpeller;
00060
00061 private:
00062 int m_currentUnicodeNumber;
00063 };
00064
00065 KoTextView::KoTextView( KoTextObject *textobj )
00066 {
00067 d = new KoTextViewPrivate;
00068 m_bReadWrite = true;
00069 m_textobj = textobj;
00070 dcop=0;
00071 connect( m_textobj, SIGNAL( hideCursor() ), this, SLOT( hideCursor() ) );
00072 connect( m_textobj, SIGNAL( showCursor() ), this, SLOT( showCursor() ) );
00073 connect( m_textobj, SIGNAL( setCursor( KoTextCursor * ) ), this, SLOT( setCursor( KoTextCursor * ) ) );
00074 connect( m_textobj, SIGNAL( updateUI(bool, bool) ), this, SLOT( updateUI(bool, bool) ) );
00075 connect( m_textobj, SIGNAL( showCurrentFormat() ), this, SLOT( showCurrentFormat() ) );
00076 connect( m_textobj, SIGNAL( ensureCursorVisible() ), this, SLOT( ensureCursorVisible() ) );
00077
00078 m_cursor = new KoTextCursor( m_textobj->textDocument() );
00079
00080 m_cursorVisible = false;
00081
00082 showCursor();
00083 blinkTimer = new QTimer( this );
00084 connect( blinkTimer, SIGNAL( timeout() ),
00085 this, SLOT( blinkCursor() ) );
00086 if ( QApplication::cursorFlashTime() > 0 )
00087 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
00088
00089 dragStartTimer = new QTimer( this );
00090 connect( dragStartTimer, SIGNAL( timeout() ),
00091 this, SLOT( startDrag() ) );
00092
00093 m_textobj->formatMore( 2 );
00094
00095 blinkCursorVisible = FALSE;
00096 inDoubleClick = FALSE;
00097 mightStartDrag = FALSE;
00098 possibleTripleClick = FALSE;
00099 afterTripleClick = FALSE;
00100 m_currentFormat = 0;
00101 m_variablePosition =-1;
00102 m_overwriteMode = false;
00103
00104 }
00105
00106 KoTextView::~KoTextView()
00107 {
00108 delete m_cursor;
00109 delete d;
00110 delete dcop;
00111 delete blinkTimer;
00112 delete dragStartTimer;
00113 }
00114
00115 KoTextViewIface* KoTextView::dcopObject()
00116 {
00117 if ( !dcop )
00118 dcop = new KoTextViewIface( this );
00119
00120 return dcop;
00121 }
00122
00123 void KoTextView::terminate(bool removeselection)
00124 {
00125 textObject()->clearUndoRedoInfo();
00126 if ( removeselection && textDocument()->removeSelection( KoTextDocument::Standard ) )
00127 textObject()->selectionChangedNotify();
00128 hideCursor();
00129 }
00130
00131 void KoTextView::deleteWordRight()
00132 {
00133 if ( textObject()->hasSelection() ) {
00134 textObject()->removeSelectedText( m_cursor );
00135 return;
00136 }
00137 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00138
00139 do {
00140 m_cursor->gotoRight();
00141 } while ( !m_cursor->atParagEnd()
00142 && !m_cursor->parag()->at( m_cursor->index() )->c.isSpace() );
00143 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00144 textObject()->removeSelectedText( m_cursor, KoTextDocument::Standard, i18n("Remove Word") );
00145 }
00146
00147 void KoTextView::deleteWordLeft()
00148 {
00149 if ( textObject()->hasSelection() ) {
00150 textObject()->removeSelectedText( m_cursor );
00151 return;
00152 }
00153 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00154
00155 do {
00156 m_cursor->gotoLeft();
00157 } while ( !m_cursor->atParagStart()
00158 && !m_cursor->parag()->at( m_cursor->index()-1 )->c.isSpace() );
00159 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00160 textObject()->removeSelectedText( m_cursor, KoTextDocument::Standard, i18n("Remove Word") );
00161 }
00162
00163
00164 void KoTextView::handleKeyPressEvent( QKeyEvent * e, QWidget *widget, const QPoint &pos)
00165 {
00166 textObject()->typingStarted();
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 bool clearUndoRedoInfo = TRUE;
00178 if ( KShortcut( KKey( e ) ) == KStdAccel::deleteWordBack() )
00179 {
00180 if ( m_cursor->parag()->string()->isRightToLeft() )
00181 deleteWordRight();
00182 else
00183 deleteWordLeft();
00184 clearUndoRedoInfo = TRUE;
00185 } else if ( KShortcut( KKey( e ) ) == KStdAccel::deleteWordForward() )
00186 {
00187 if ( m_cursor->parag()->string()->isRightToLeft() )
00188 deleteWordLeft();
00189 else
00190 deleteWordRight();
00191 clearUndoRedoInfo = TRUE;
00192 }
00193 else
00194 switch ( e->key() ) {
00195 case Key_Left:
00196 case Key_Right: {
00197 if (!doToolTipCompletion(m_cursor, m_cursor->parag(), m_cursor->index() - 1, e->key()) )
00198 {
00199
00200
00201 CursorAction a;
00202 if ( m_cursor->parag()->string()->isRightToLeft() == (e->key() == Key_Right) )
00203 a = e->state() & ControlButton ? MoveWordBackward : MoveBackward;
00204 else
00205 a = e->state() & ControlButton ? MoveWordForward : MoveForward;
00206 moveCursor( a, e->state() & ShiftButton );
00207 }
00208 break;
00209 }
00210 case Key_Up:
00211 moveCursor( e->state() & ControlButton ? MoveParagUp : MoveUp, e->state() & ShiftButton );
00212 break;
00213 case Key_Down:
00214 moveCursor( e->state() & ControlButton ? MoveParagDown : MoveDown, e->state() & ShiftButton );
00215 break;
00216 case Key_Home:
00217 moveCursor( e->state() & ControlButton ? MoveHome : MoveLineStart, e->state() & ShiftButton );
00218 break;
00219 case Key_End:
00220 if (!doToolTipCompletion(m_cursor, m_cursor->parag(), m_cursor->index() - 1, e->key()) )
00221 moveCursor( e->state() & ControlButton ? MoveEnd : MoveLineEnd, e->state() & ShiftButton );
00222 break;
00223 case Key_Prior:
00224 moveCursor( e->state() & ControlButton ? MovePgUp : MoveViewportUp, e->state() & ShiftButton );
00225 break;
00226 case Key_Next:
00227 moveCursor( e->state() & ControlButton ? MovePgDown : MoveViewportDown, e->state() & ShiftButton );
00228 break;
00229 case Key_Return: case Key_Enter:
00230
00231 if (!doToolTipCompletion(m_cursor, m_cursor->parag(), m_cursor->index() - 1, e->key()) )
00232 if ( (e->state() & (ShiftButton|ControlButton)) == 0 )
00233 {
00234 if ( textObject()->hasSelection() )
00235 textObject()->removeSelectedText( m_cursor );
00236 clearUndoRedoInfo = FALSE;
00237 textObject()->doKeyboardAction( m_cursor, m_currentFormat, KoTextObject::ActionReturn );
00238 Q_ASSERT( m_cursor->parag()->prev() );
00239 if ( m_cursor->parag()->prev() )
00240 doAutoFormat( m_cursor, m_cursor->parag()->prev(),
00241 m_cursor->parag()->prev()->length() - 1, '\n' );
00242 }
00243 clearUndoRedoInfo = true;
00244 break;
00245 case Key_Delete:
00246 if ( textObject()->hasSelection() ) {
00247 textObject()->removeSelectedText( m_cursor );
00248 break;
00249 }
00250
00251 textObject()->doKeyboardAction( m_cursor, m_currentFormat, KoTextObject::ActionDelete );
00252
00253 clearUndoRedoInfo = FALSE;
00254 break;
00255 case Key_Backtab:
00256 if (e->state() & ShiftButton && m_cursor->parag() && m_cursor->atParagStart() && m_cursor->parag()->counter() && textDecreaseIndent())
00257 break;
00258 break;
00259 case Key_Backspace:
00260 if ( textObject()->hasSelection() ) {
00261 textObject()->removeSelectedText( m_cursor );
00262 break;
00263 }
00264 textObject()->doKeyboardAction( m_cursor, m_currentFormat, KoTextObject::ActionBackspace );
00265
00266 clearUndoRedoInfo = FALSE;
00267 break;
00268 case Key_F16:
00269 emit copy();
00270 break;
00271 case Key_F18:
00272 emit paste();
00273 break;
00274 case Key_F20:
00275 emit cut();
00276 break;
00277 case Key_Direction_L: {
00278 if ( m_cursor->parag() && m_cursor->parag()->direction() != QChar::DirL )
00279 {
00280 KCommand* cmd = textObject()->setParagDirectionCommand( m_cursor, QChar::DirL );
00281 textObject()->emitNewCommand( cmd );
00282 }
00283 break;
00284 }
00285 case Key_Direction_R: {
00286 if ( m_cursor->parag() && m_cursor->parag()->direction() != QChar::DirR )
00287 {
00288 KCommand* cmd = textObject()->setParagDirectionCommand( m_cursor, QChar::DirR );
00289 textObject()->emitNewCommand( cmd );
00290 }
00291 break;
00292 }
00293 default: {
00294
00295 if (e->key() == Qt::Key_Tab)
00296 {
00297 if (doToolTipCompletion(m_cursor, m_cursor->parag(), m_cursor->index() - 1, e->key()) )
00298 break;
00299 if ( m_cursor->parag() && m_cursor->atParagStart() && m_cursor->parag()->counter() )
00300 {
00301 textIncreaseIndent();
00302 break;
00303 }
00304 }
00305
00306 if ( e->key() == Qt::Key_Space )
00307 {
00308 if (doToolTipCompletion(m_cursor, m_cursor->parag(), m_cursor->index() - 1, e->key()) )
00309 break;
00310 }
00311 if ( e->text().length() &&
00312 ( !e->ascii() || e->ascii() >= 32 ) ||
00313 ( e->text() == "\t" && !( e->state() & ControlButton ) ) ) {
00314 clearUndoRedoInfo = FALSE;
00315 QString text = e->text();
00316
00317 if ( d->m_backSpeller ) {
00318 d->m_backSpeller->setIntraWordEditing( m_cursor->parag(), m_cursor->index() );
00319 }
00320
00321
00322 if ( ( e->state() & AltButton ) && text[0].isDigit() )
00323 {
00324 while ( text[0].isDigit() ) {
00325 d->appendDigit( text[0].digitValue() );
00326 text.remove( 0, 1 );
00327 }
00328 }
00329 if ( !text.isEmpty() )
00330 {
00331
00332 KoTextParag *p = m_cursor->parag();
00333 if ( p && p->string() && p->string()->isRightToLeft() ) {
00334 QChar *c = (QChar *)text.unicode();
00335 int l = text.length();
00336 while( l-- ) {
00337 if ( c->mirrored() )
00338 *c = c->mirroredChar();
00339 c++;
00340 }
00341 }
00342
00343 if( !doIgnoreDoubleSpace( p, m_cursor->index()-1, text[ text.length() - 1 ] ) )
00344 {
00345
00346
00347
00348 insertText( text );
00349
00350 doAutoFormat( m_cursor, m_cursor->parag(), m_cursor->index() - 1, text[ text.length() - 1 ] );
00351 }
00352 showToolTipBox(m_cursor->parag(), m_cursor->index()-1, widget,pos);
00353 }
00354 else
00355 removeToolTipCompletion();
00356
00357 }
00358
00359
00360
00361 else
00362 {
00363 if ( e->state() & ControlButton )
00364 switch ( e->key() )
00365 {
00366 case Key_F16:
00367 copy();
00368 break;
00369 case Key_A:
00370 moveCursor( MoveLineStart, e->state() & ShiftButton );
00371 break;
00372 case Key_E:
00373 moveCursor( MoveLineEnd, e->state() & ShiftButton );
00374 break;
00375 case Key_K:
00376 textObject()->doKeyboardAction( m_cursor, m_currentFormat, KoTextObject::ActionKill );
00377 break;
00378 case Key_Insert:
00379 copy();
00380 break;
00381 case Key_Space:
00382 insertNonbreakingSpace();
00383 break;
00384 }
00385 }
00386 break;
00387 }
00388 }
00389
00390 if ( clearUndoRedoInfo ) {
00391 textObject()->clearUndoRedoInfo();
00392 if ( d->m_backSpeller )
00393 d->m_backSpeller->setIntraWordEditing( 0, 0 );
00394 }
00395
00396 textObject()->typingDone();
00397 }
00398
00399 void KoTextView::setOverwriteMode( bool overwriteMode )
00400 {
00401 m_overwriteMode = overwriteMode;
00402 }
00403
00404 void KoTextView::insertText( const QString &text )
00405 {
00406 int insertFlags = KoTextObject::DefaultInsertFlags;
00407 if ( m_overwriteMode )
00408 insertFlags |= KoTextObject::OverwriteMode;
00409 textObject()->insert( m_cursor, m_currentFormat, text, i18n("Insert Text"), KoTextDocument::Standard, insertFlags );
00410 }
00411
00412 void KoTextView::newParagraph()
00413 {
00414 textObject()->insert( m_cursor, m_currentFormat, "\n", i18n("Insert Text"), KoTextDocument::Standard, KoTextObject::CheckNewLine );
00415 }
00416
00417 void KoTextView::handleKeyReleaseEvent( QKeyEvent * e )
00418 {
00419 if ( e->key() == Key_Alt && d->currentUnicodeNumber() >= 32 )
00420 {
00421 QString text = QChar( d->currentUnicodeNumber() );
00422 d->clearCurrentUnicodeNumber();
00423 insertText( text );
00424 doAutoFormat( m_cursor, m_cursor->parag(),
00425 m_cursor->index() - 1, text[ text.length() - 1 ] );
00426 }
00427 }
00428
00429 void KoTextView::handleImStartEvent( QIMEvent * )
00430 {
00431
00432 }
00433
00434 void KoTextView::handleImComposeEvent( QIMEvent * e )
00435 {
00436
00437 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00438 textDocument()->removeSelection( KoTextDocument::Standard );
00439 if ( textDocument()->hasSelection( KoTextDocument::InputMethodPreedit ) )
00440 textDocument()->removeSelectedText( KoTextDocument::InputMethodPreedit, m_cursor );
00441
00442
00443 int preeditStartIdx = m_cursor->index();
00444 textDocument()->setSelectionStart( KoTextDocument::InputMethodPreedit, m_cursor );
00445 textObject()->insert( m_cursor, m_currentFormat, e->text(), i18n("Insert Text"),
00446 KoTextDocument::Standard,
00447 KoTextObject::DoNotRepaint );
00448 textDocument()->setSelectionEnd( KoTextDocument::InputMethodPreedit, m_cursor );
00449
00450
00451 int preeditSelStart = preeditStartIdx + e->cursorPos();
00452 int preeditSelEnd = preeditSelStart + e->selectionLength();
00453 m_cursor->setIndex( preeditSelStart );
00454 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00455 m_cursor->setIndex( preeditSelEnd );
00456 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00457
00458
00459 m_cursor->setIndex( preeditSelStart );
00460
00461 textObject()->emitUpdateUI( true );
00462 textObject()->emitShowCursor();
00463 textObject()->selectionChangedNotify();
00464 }
00465
00466 void KoTextView::handleImEndEvent( QIMEvent * e )
00467 {
00468
00469 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00470 textDocument()->removeSelection( KoTextDocument::Standard );
00471 if ( textDocument()->hasSelection( KoTextDocument::InputMethodPreedit ) )
00472 textDocument()->removeSelectedText( KoTextDocument::InputMethodPreedit, m_cursor );
00473
00474 insertText( e->text() );
00475
00476 textObject()->emitUpdateUI( true );
00477 textObject()->emitShowCursor();
00478 textObject()->selectionChangedNotify();
00479 }
00480
00481 void KoTextView::completion()
00482 {
00483 (void) doCompletion(m_cursor, m_cursor->parag(),
00484 m_cursor->index() - 1);
00485 }
00486
00487 void KoTextView::moveCursor( CursorAction action, bool select )
00488 {
00489 hideCursor();
00490 bool cursorMoved = false;
00491 if ( select ) {
00492 if ( !textDocument()->hasSelection( KoTextDocument::Standard ) )
00493 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00494 cursorMoved = moveCursor( action );
00495 if ( textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor ) ) {
00496 textObject()->selectionChangedNotify();
00497 }
00498 } else {
00499 bool redraw = textDocument()->removeSelection( KoTextDocument::Standard );
00500 cursorMoved = moveCursor( action );
00501 if ( redraw ) {
00502 textObject()->selectionChangedNotify();
00503 }
00504 }
00505
00506 if ( cursorMoved )
00507 {
00508 ensureCursorVisible();
00509
00510 }
00511 showCursor();
00512 }
00513
00514 bool KoTextView::moveCursor( CursorAction action )
00515 {
00516 bool cursorMoved = true;
00517 switch ( action ) {
00518 case MoveBackward:
00519 m_cursor->gotoPreviousLetter();
00520 break;
00521 case MoveWordBackward:
00522 m_cursor->gotoPreviousWord();
00523 break;
00524 case MoveForward:
00525 m_cursor->gotoNextLetter();
00526 break;
00527 case MoveWordForward:
00528 m_cursor->gotoNextWord();
00529 break;
00530 case MoveUp:
00531 m_cursor->gotoUp();
00532 break;
00533 case MoveDown:
00534 m_cursor->gotoDown();
00535 break;
00536 case MoveViewportUp:
00537 cursorMoved = pgUpKeyPressed();
00538 break;
00539 case MoveViewportDown:
00540 cursorMoved = pgDownKeyPressed();
00541 break;
00542 case MovePgUp:
00543 ctrlPgUpKeyPressed();
00544 break;
00545 case MovePgDown:
00546 ctrlPgDownKeyPressed();
00547 break;
00548 case MoveLineStart:
00549 m_cursor->gotoLineStart();
00550 break;
00551 case MoveHome:
00552 m_cursor->gotoHome();
00553 break;
00554 case MoveLineEnd:
00555 m_cursor->gotoLineEnd();
00556 break;
00557 case MoveEnd:
00558 textObject()->ensureFormatted( textDocument()->lastParag() );
00559 m_cursor->gotoEnd();
00560 break;
00561 case MoveParagUp: {
00562 KoTextParag * parag = m_cursor->parag()->prev();
00563 if ( m_cursor->index()==0 && parag )
00564 {
00565 m_cursor->setParag( parag );
00566 m_cursor->setIndex( 0 );
00567 }
00568 else m_cursor->setIndex( 0 );
00569 } break;
00570 case MoveParagDown: {
00571 KoTextParag * parag = m_cursor->parag()->next();
00572 if ( parag )
00573 {
00574 m_cursor->setParag( parag );
00575 m_cursor->setIndex( 0 );
00576 }
00577 } break;
00578 }
00579
00580 updateUI( true );
00581 return cursorMoved;
00582 }
00583
00584 KoTextCursor KoTextView::selectWordUnderCursor( const KoTextCursor& cursor, int selectionId )
00585 {
00586 KoTextCursor c1 = cursor;
00587 KoTextCursor c2 = cursor;
00588 if ( cursor.index() > 0 && !cursor.parag()->at( cursor.index()-1 )->c.isSpace() )
00589 c1.gotoWordLeft();
00590 if ( !cursor.parag()->at( cursor.index() )->c.isSpace() && !cursor.atParagEnd() )
00591 c2.gotoWordRight();
00592
00593
00594
00595
00596 KoTextString *s = cursor.parag()->string();
00597 bool beginFound = false;
00598 for ( int i = c1.index(); i< c2.index(); i++)
00599 {
00600 const QChar ch = s->at(i).c;
00601
00602
00603 const bool isWordDelimiter = ch.isSpace()
00604 || ch.category() == QChar::Punctuation_Open
00605 || ch.category() == QChar::Punctuation_Close
00606 || ch.category() == QChar::Punctuation_Other
00607 ;
00608
00609 if( !beginFound && !isWordDelimiter )
00610 {
00611 c1.setIndex(i);
00612 beginFound = true;
00613 }
00614 else if ( beginFound && isWordDelimiter )
00615 {
00616 c2.setIndex(i);
00617 break;
00618 }
00619 }
00620
00621 textDocument()->setSelectionStart( selectionId, &c1 );
00622 textDocument()->setSelectionEnd( selectionId, &c2 );
00623 return c2;
00624 }
00625
00626 KoTextCursor KoTextView::selectParagUnderCursor( const KoTextCursor& cursor, int selectionId, bool copyAndNotify )
00627 {
00628 KoTextCursor c1 = cursor;
00629 KoTextCursor c2 = cursor;
00630 c1.setIndex(0);
00631 c2.setIndex(c1.parag()->string()->length() - 1);
00632 textDocument()->setSelectionStart( selectionId, &c1 );
00633 textDocument()->setSelectionEnd( selectionId, &c2 );
00634 if ( copyAndNotify )
00635 {
00636 textObject()->selectionChangedNotify();
00637
00638 QApplication::clipboard()->setSelectionMode( true );
00639 emit copy();
00640 QApplication::clipboard()->setSelectionMode( false );
00641 }
00642 return c2;
00643 }
00644
00645 void KoTextView::extendParagraphSelection( const QPoint& iPoint )
00646 {
00647 hideCursor();
00648 KoTextCursor oldCursor = *m_cursor;
00649 placeCursor( iPoint );
00650
00651 bool redraw = FALSE;
00652 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00653 {
00654 redraw = textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00655 if ( textDocument()->isSelectionSwapped( KoTextDocument::Standard ) )
00656 m_cursor->setIndex( 0 );
00657 else
00658 m_cursor->setIndex( m_cursor->parag()->string()->length() - 1 );
00659 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00660 }
00661
00662
00663
00664 if ( redraw )
00665 textObject()->selectionChangedNotify( false );
00666
00667 showCursor();
00668 }
00669
00670 QString KoTextView::wordUnderCursor( const KoTextCursor& cursor )
00671 {
00672 selectWordUnderCursor( cursor, KoTextDocument::Temp );
00673 QString text = textObject()->selectedText( KoTextDocument::Temp );
00674 bool hasCustomItems = textObject()->selectionHasCustomItems( KoTextDocument::Temp );
00675 textDocument()->removeSelection( KoTextDocument::Temp );
00676 if( !hasCustomItems )
00677 return text;
00678 return QString::null;
00679 }
00680
00681 bool KoTextView::handleMousePressEvent( QMouseEvent *e, const QPoint &iPoint, bool canStartDrag, bool insertDirectCursor )
00682 {
00683 bool addParag = false;
00684 mightStartDrag = FALSE;
00685 hideCursor();
00686
00687 if (possibleTripleClick)
00688 {
00689 handleMouseTripleClickEvent( e, iPoint );
00690 return addParag;
00691 }
00692
00693 KoTextCursor oldCursor = *m_cursor;
00694 addParag = placeCursor( iPoint, insertDirectCursor&& isReadWrite() );
00695 ensureCursorVisible();
00696
00697 if ( e->button() != LeftButton )
00698 {
00699 showCursor();
00700 return addParag;
00701 }
00702
00703 KoLinkVariable* lv = linkVariable();
00704 if ( lv && openLink( lv ) )
00705 {
00706 return addParag;
00707 }
00708
00709 KoTextDocument * textdoc = textDocument();
00710 if ( canStartDrag && textdoc->inSelection( KoTextDocument::Standard, iPoint ) ) {
00711 mightStartDrag = TRUE;
00712 m_textobj->emitShowCursor();
00713 dragStartTimer->start( QApplication::startDragTime(), TRUE );
00714 dragStartPos = e->pos();
00715 return addParag;
00716 }
00717
00718 bool redraw = FALSE;
00719 if ( textdoc->hasSelection( KoTextDocument::Standard ) ) {
00720 if ( !( e->state() & ShiftButton ) ) {
00721 redraw = textdoc->removeSelection( KoTextDocument::Standard );
00722 textdoc->setSelectionStart( KoTextDocument::Standard, m_cursor );
00723 } else {
00724 redraw = textdoc->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00725 }
00726 } else {
00727 if ( !( e->state() & ShiftButton ) ) {
00728 textdoc->setSelectionStart( KoTextDocument::Standard, m_cursor );
00729 } else {
00730 textdoc->setSelectionStart( KoTextDocument::Standard, &oldCursor );
00731 redraw = textdoc->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00732 }
00733 }
00734
00735
00736 if ( !redraw ) {
00737 showCursor();
00738 } else {
00739 textObject()->selectionChangedNotify();
00740 }
00741 return addParag;
00742 }
00743
00744 void KoTextView::handleMouseMoveEvent( QMouseEvent*, const QPoint& iPoint )
00745 {
00746 hideCursor();
00747 KoTextCursor oldCursor = *m_cursor;
00748 placeCursor( iPoint );
00749
00750
00751 if ( inDoubleClick ) {
00752 KoTextCursor cl = *m_cursor;
00753 cl.gotoWordLeft();
00754 KoTextCursor cr = *m_cursor;
00755 cr.gotoWordRight();
00756
00757 int diff = QABS( oldCursor.parag()->at( oldCursor.index() )->x - iPoint.x() );
00758 int ldiff = QABS( cl.parag()->at( cl.index() )->x - iPoint.x() );
00759 int rdiff = QABS( cr.parag()->at( cr.index() )->x - iPoint.x() );
00760
00761 if ( m_cursor->parag()->lineStartOfChar( m_cursor->index() ) !=
00762 oldCursor.parag()->lineStartOfChar( oldCursor.index() ) )
00763 diff = 0xFFFFFF;
00764
00765 if ( rdiff < diff && rdiff < ldiff )
00766 *m_cursor = cr;
00767 else if ( ldiff < diff && ldiff < rdiff )
00768 *m_cursor = cl;
00769 else
00770 *m_cursor = oldCursor;
00771 }
00772
00773 bool redraw = FALSE;
00774 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00775 redraw = textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00776 else
00777 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00778
00779 if ( redraw )
00780 textObject()->selectionChangedNotify( false );
00781
00782 showCursor();
00783 }
00784
00785 void KoTextView::handleMouseReleaseEvent()
00786 {
00787 if ( dragStartTimer->isActive() )
00788 dragStartTimer->stop();
00789 if ( mightStartDrag ) {
00790 textObject()->selectAll( FALSE );
00791 mightStartDrag = false;
00792 }
00793 else
00794 {
00795 if ( textDocument()->selectionStartCursor( KoTextDocument::Standard ) == textDocument()->selectionEndCursor( KoTextDocument::Standard ) )
00796 {
00797 textDocument()->removeSelection( KoTextDocument::Standard );
00798 }
00799
00800 textObject()->selectionChangedNotify();
00801
00802
00803 QApplication::clipboard()->setSelectionMode( true );
00804 emit copy();
00805 QApplication::clipboard()->setSelectionMode( false );
00806 }
00807
00808 inDoubleClick = FALSE;
00809 m_textobj->emitShowCursor();
00810 }
00811
00812 void KoTextView::handleMouseDoubleClickEvent( QMouseEvent*ev, const QPoint& i )
00813 {
00814
00815
00816 if(afterTripleClick)
00817 {
00818 handleMousePressEvent( ev, i );
00819 return;
00820 }
00821
00822 inDoubleClick = TRUE;
00823 *m_cursor = selectWordUnderCursor( *m_cursor );
00824 textObject()->selectionChangedNotify();
00825
00826 QApplication::clipboard()->setSelectionMode( true );
00827 emit copy();
00828 QApplication::clipboard()->setSelectionMode( false );
00829
00830 possibleTripleClick=true;
00831
00832 QTimer::singleShot(QApplication::doubleClickInterval(),this,SLOT(tripleClickTimeout()));
00833 }
00834
00835 void KoTextView::tripleClickTimeout()
00836 {
00837 possibleTripleClick=false;
00838 }
00839
00840 void KoTextView::handleMouseTripleClickEvent( QMouseEvent*ev, const QPoint& )
00841 {
00842 if ( ev->button() != LeftButton)
00843 {
00844 showCursor();
00845 return;
00846 }
00847 afterTripleClick= true;
00848 inDoubleClick = FALSE;
00849 *m_cursor = selectParagUnderCursor( *m_cursor );
00850 QTimer::singleShot(QApplication::doubleClickInterval(),this,SLOT(afterTripleClickTimeout()));
00851 }
00852
00853 void KoTextView::afterTripleClickTimeout()
00854 {
00855 afterTripleClick=false;
00856 }
00857
00858 bool KoTextView::maybeStartDrag( QMouseEvent* e )
00859 {
00860 if ( mightStartDrag ) {
00861 dragStartTimer->stop();
00862 if ( ( e->pos() - dragStartPos ).manhattanLength() > QApplication::startDragDistance() )
00863 startDrag();
00864 return true;
00865 }
00866 return false;
00867 }
00868
00869 bool KoTextView::insertParagraph(const QPoint &pos)
00870 {
00871 KoTextParag *last = textDocument()->lastParag();
00872 KoTextFormat *f = 0;
00873 KoParagStyle *style = last->style();
00874 KoParagCounter *counter = last->counter();
00875 int diff = (pos.y()- textDocument()->height());
00876 f = last->at( last->length()-1 )->format();
00877 int height =f->height();
00878 int nbParag = (diff / height);
00879 QFontMetrics fm = f->refFontMetrics();
00880 for (int i = 0; i < nbParag ;i++)
00881 {
00882 KoTextParag *s=textDocument()->createParag( textDocument(), last );
00883 if ( f )
00884 s->setFormat( 0, 1, f, TRUE );
00885 if ( style )
00886 s->setStyle( style );
00887 s->setCounter( counter );
00888 last = s;
00889 }
00890 bool createParag = (nbParag > 0 );
00891 if ( createParag )
00892 {
00893 if ( pos.x() + f->width(' ') >= textDocument()->width())
00894 {
00895
00896
00897 last->setAlignment( Qt::AlignRight );
00898 }
00899 else
00900 {
00901 int nbSpace = pos.x()/f->width(' ');
00902 QString tmp;
00903 for (int i = 0; i< nbSpace; i++)
00904 {
00905 tmp+=' ';
00906 }
00907 last->insert( 0, tmp );
00908 }
00909 }
00910 return createParag;
00911
00912 }
00913
00914 bool KoTextView::placeCursor( const QPoint &pos, bool insertDirectCursor )
00915 {
00916 bool addParag = false;
00917 if ( insertDirectCursor && (pos.y()>textDocument()->height()) )
00918 addParag = insertParagraph(pos);
00919 KoTextParag *s = 0L;
00920 if ( addParag )
00921 s = textDocument()->lastParag();
00922 else
00923 s = textDocument()->firstParag();
00924 m_cursor->place( pos, s, false, &m_variablePosition );
00925 if ( m_variablePosition != -1 )
00926 kdDebug() << k_funcinfo << " m_variablePosition set to " << m_variablePosition << endl;
00927 updateUI( true );
00928 return addParag;
00929 }
00930
00931 void KoTextView::blinkCursor()
00932 {
00933
00934
00935 if ( !m_cursorVisible )
00936 return;
00937 bool cv = m_cursorVisible;
00938 blinkCursorVisible = !blinkCursorVisible;
00939 drawCursor( blinkCursorVisible );
00940 m_cursorVisible = cv;
00941 }
00942
00943 void KoTextView::drawCursor( bool visible )
00944 {
00945 m_cursorVisible = visible;
00946
00947 }
00948
00949 void KoTextView::focusInEvent()
00950 {
00951 if ( QApplication::cursorFlashTime() > 0 )
00952 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
00953 showCursor();
00954 }
00955
00956 void KoTextView::focusOutEvent()
00957 {
00958 blinkTimer->stop();
00959 hideCursor();
00960 }
00961
00962
00963
00964
00965
00966
00967 KCommand* KoTextView::setFormatCommand( const KoTextFormat * newFormat, int flags, bool zoomFont)
00968 {
00969 return textObject()->setFormatCommand( m_cursor, &m_currentFormat, newFormat, flags, zoomFont );
00970 }
00971
00972 void KoTextView::dragStarted()
00973 {
00974 mightStartDrag = FALSE;
00975 inDoubleClick = FALSE;
00976 }
00977
00978 void KoTextView::applyStyle( const KoParagStyle * style )
00979 {
00980 if ( style )
00981 {
00982 textObject()->applyStyle( m_cursor, style );
00983 showCurrentFormat();
00984 }
00985 }
00986
00987 void KoTextView::updateUI( bool updateFormat, bool )
00988 {
00989
00990
00991 if ( updateFormat )
00992 {
00993 int i = cursor()->index();
00994 if ( i > 0 )
00995 --i;
00996 #ifdef DEBUG_FORMATS
00997 if ( currentFormat() )
00998 kdDebug(32500) << "KoTextView::updateUI old currentFormat=" << currentFormat()
00999 << " " << currentFormat()->key()
01000 << " parag format=" << cursor()->parag()->at( i )->format()->key() << endl;
01001 else
01002 kdDebug(32500) << "KoTextView::updateUI old currentFormat=0" << endl;
01003 #endif
01004 if ( !currentFormat() || currentFormat()->key() != cursor()->parag()->at( i )->format()->key() )
01005 {
01006 if ( currentFormat() )
01007 currentFormat()->removeRef();
01008 #ifdef DEBUG_FORMATS
01009 kdDebug(32500) << "Setting currentFormat from format " << cursor()->parag()->at( i )->format()
01010 << " ( character " << i << " in paragraph " << cursor()->parag()->paragId() << " )" << endl;
01011 #endif
01012 setCurrentFormat( textDocument()->formatCollection()->format( cursor()->parag()->at( i )->format() ) );
01013 if ( currentFormat()->isMisspelled() ) {
01014 KoTextFormat fNoMisspelled( *currentFormat() );
01015 fNoMisspelled.setMisspelled( false );
01016 currentFormat()->removeRef();
01017 setCurrentFormat( textDocument()->formatCollection()->format( &fNoMisspelled ) );
01018 }
01019 showCurrentFormat();
01020 }
01021 }
01022 }
01023
01024 void KoTextView::showCurrentFormat()
01025 {
01026
01027 KoTextFormat format = *currentFormat();
01028
01029 showFormat( &format );
01030 }
01031
01032 KCommand * KoTextView::setCounterCommand( const KoParagCounter & counter )
01033 {
01034 return textObject()->setCounterCommand( m_cursor, counter );
01035 }
01036 KCommand * KoTextView::setAlignCommand( int align )
01037 {
01038 return textObject()->setAlignCommand( m_cursor, align );
01039 }
01040 KCommand * KoTextView::setLineSpacingCommand( double spacing, KoParagLayout::SpacingType _type)
01041 {
01042 return textObject()->setLineSpacingCommand( m_cursor, spacing, _type);
01043 }
01044 KCommand * KoTextView::setBordersCommand( const KoBorder& leftBorder, const KoBorder& rightBorder, const KoBorder& bottomBorder, const KoBorder& topBorder )
01045 {
01046 return textObject()->setBordersCommand( m_cursor, leftBorder, rightBorder, bottomBorder, topBorder );
01047 }
01048 KCommand * KoTextView::setJoinBordersCommand( bool join )
01049 {
01050 return textObject()->setJoinBordersCommand( m_cursor, join );
01051 }
01052 KCommand * KoTextView::setMarginCommand( QStyleSheetItem::Margin m, double margin )
01053 {
01054 return textObject()->setMarginCommand( m_cursor, m, margin );
01055 }
01056 KCommand * KoTextView::setTabListCommand( const KoTabulatorList & tabList )
01057 {
01058 return textObject()->setTabListCommand( m_cursor, tabList );
01059 }
01060 KCommand * KoTextView::setBackgroundColorCommand( const QColor & color )
01061 {
01062 return textObject()->setBackgroundColorCommand( m_cursor, color );
01063 }
01064
01065 KoTextDocument * KoTextView::textDocument() const
01066 {
01067 return textObject()->textDocument();
01068 }
01069
01070 KoVariable *KoTextView::variable()
01071 {
01072 if ( m_variablePosition < 0 )
01073 return 0;
01074
01075 return textObject()->variableAtPosition( m_cursor->parag(), m_variablePosition );
01076 }
01077
01078 KoLinkVariable * KoTextView::linkVariable()
01079 {
01080 return dynamic_cast<KoLinkVariable *>(variable());
01081 }
01082
01083 QPtrList<KAction> KoTextView::dataToolActionList(KInstance * instance, const QString& word, bool & _singleWord )
01084 {
01085 m_singleWord = false;
01086 m_wordUnderCursor = QString::null;
01087 QString text;
01088 if ( textObject()->hasSelection() )
01089 {
01090 text = textObject()->selectedText();
01091 if ( text.find(' ') == -1 && text.find('\t') == -1 && text.find(KoTextObject::customItemChar()) == -1 )
01092 {
01093 m_singleWord = true;
01094 }
01095 else
01096 {
01097 m_singleWord = false;
01098
01099 if( text.find(KoTextObject::customItemChar())!=-1)
01100 text = QString::null;
01101 }
01102 }
01103 else
01104 {
01105 if ( !word.isEmpty() )
01106 {
01107 m_singleWord = true;
01108 m_wordUnderCursor = word;
01109 text = word;
01110 }
01111 }
01112
01113 if ( text.isEmpty() || textObject()->protectContent())
01114 return QPtrList<KAction>();
01115
01116
01117 QValueList<KDataToolInfo> tools;
01118 tools +=KDataToolInfo::query( "QString", "text/plain", instance );
01119
01120
01121 if ( m_singleWord )
01122 {
01123 _singleWord = true;
01124 tools += KDataToolInfo::query( "QString", "application/x-singleword", instance );
01125 }
01126
01127 tools += KDataToolInfo::query( "KoTextString", "application/x-qrichtext", instance );
01128
01129 return KDataToolAction::dataToolActionList( tools, this, SLOT( slotToolActivated( const KDataToolInfo &, const QString & ) ) );
01130 }
01131
01132 QString KoTextView::currentWordOrSelection() const
01133 {
01134 if ( textObject()->hasSelection() )
01135 return textObject()->selectedText();
01136 else
01137 return m_wordUnderCursor;
01138 }
01139
01140 void KoTextView::slotToolActivated( const KDataToolInfo & info, const QString & command )
01141 {
01142 KDataTool* tool = info.createTool( );
01143 if ( !tool )
01144 {
01145 kdWarning() << "Could not create Tool !" << endl;
01146 return;
01147 }
01148
01149 kdDebug(32500) << "KWTextFrameSetEdit::slotToolActivated command=" << command
01150 << " dataType=" << info.dataType() << endl;
01151
01152 QString text;
01153 if ( textObject()->hasSelection() )
01154 text = textObject()->selectedText();
01155 else
01156 text = m_wordUnderCursor;
01157
01158
01159 QString mimetype = "application/x-qrichtext";
01160 QString datatype = "KoTextString";
01161
01162 if ( !info.mimeTypes().contains( mimetype ) )
01163 {
01164 mimetype = "text/plain";
01165 datatype = "QString";
01166 }
01167
01168 if ( !info.mimeTypes().contains( mimetype ) && m_singleWord )
01169 mimetype = "application/x-singleword";
01170
01171 kdDebug(32500) << "Running tool with datatype=" << datatype << " mimetype=" << mimetype << endl;
01172
01173 QString origText = text;
01174 if ( tool->run( command, &text, datatype, mimetype) )
01175 {
01176 kdDebug(32500) << "Tool ran. Text is now " << text << endl;
01177 if ( origText != text )
01178 {
01179 if ( !textObject()->hasSelection() )
01180 {
01181
01182 selectWordUnderCursor( *m_cursor );
01183 }
01184
01185 textObject()->emitNewCommand( textObject()->replaceSelectionCommand(
01186 cursor(), text, i18n("Replace Word") ));
01187 }
01188 }
01189 delete tool;
01190 }
01191
01192 bool KoTextView::openLink( KoLinkVariable* variable )
01193 {
01194 kdDebug() << k_funcinfo << variable->url() << endl;
01195 KURL url( variable->url() );
01196 if( url.isValid() )
01197 {
01198 (void) new KRun( url );
01199 return true;
01200 }
01201 else
01202 {
01203 KMessageBox::sorry( 0, i18n("%1 is not a valid link.").arg( variable->url() ) );
01204 return false;
01205 }
01206 }
01207
01208
01209 void KoTextView::insertSoftHyphen()
01210 {
01211 textObject()->insert( cursor(), currentFormat(), QChar(0xad) ,
01212 i18n("Insert Soft Hyphen") );
01213 }
01214
01215 void KoTextView::insertLineBreak()
01216 {
01217 textObject()->insert( cursor(), currentFormat(), QChar('\n'),
01218 i18n("Insert Line Break") );
01219 }
01220
01221 void KoTextView::insertNonbreakingSpace()
01222 {
01223 textObject()->insert( cursor(), currentFormat(), QChar(0xa0) ,
01224 i18n("Insert Non-Breaking Space") );
01225 }
01226
01227 void KoTextView::insertNonbreakingHyphen()
01228 {
01229 textObject()->insert( cursor(), currentFormat(), QChar(0x2013),
01230 i18n("Insert Non-Breaking Hyphen") );
01231 }
01232
01233 void KoTextView::insertSpecialChar(QChar _c, const QString& font)
01234 {
01235 KoTextFormat * newFormat = new KoTextFormat(*currentFormat());
01236 newFormat->setFamily( font );
01237 if ( textObject()->hasSelection() )
01238 {
01239 KoTextFormat * lastFormat = currentFormat();
01240
01241 KCommand *cmd = textObject()->setFormatCommand( cursor(), &lastFormat, newFormat, KoTextFormat::Family );
01242
01243 KMacroCommand* macroCmd = new KMacroCommand( i18n("Insert Special Char") );
01244 macroCmd->addCommand( cmd );
01245 macroCmd->addCommand( textObject()->replaceSelectionCommand(
01246 cursor(), _c, QString::null) );
01247 textObject()->emitNewCommand( macroCmd );
01248 }
01249 else
01250 {
01251 textObject()->insert( cursor(), newFormat, _c, i18n("Insert Special Char"));
01252 delete newFormat;
01253 }
01254 }
01255
01256 const KoParagLayout * KoTextView::currentParagLayoutFormat() const
01257 {
01258 KoTextParag * parag = m_cursor->parag();
01259 return &(parag->paragLayout());
01260 }
01261
01262 bool KoTextView::rtl() const
01263 {
01264 return m_cursor->parag()->string()->isRightToLeft();
01265 }
01266
01267 KCommand* KoTextView::setParagLayoutFormatCommand( KoParagLayout *newLayout, int flags, int marginIndex )
01268 {
01269 return textObject()->setParagLayoutCommand( m_cursor, *newLayout, KoTextDocument::Standard,
01270 flags, marginIndex, true );
01271 }
01272
01273
01274 void KoTextView::increaseNumberingLevel( const KoStyleCollection* styleCollection )
01275 {
01276
01277 KoParagStyle* style = 0;
01278 int level = 0;
01279 KoParagCounter* counter = m_cursor->parag()->counter();
01280 if ( counter )
01281 level = counter->depth() + 1;
01282 if ( m_cursor->parag()->style()->isOutline() )
01283 {
01284 QValueVector<KoParagStyle *> outlineStyles = styleCollection->outlineStyles();
01285 while ( level < 10 && !style ) {
01286 style = outlineStyles[ level ];
01287 ++level;
01288 }
01289 if ( !style )
01290 style = styleCollection->defaultStyle();
01291 }
01292 else
01293 {
01294
01295 style = styleCollection->numberedStyleForLevel( level );
01296 if ( !style ) {
01297 KoParagCounter c;
01298 if (counter) {
01299 c = *counter;
01300 c.setDepth( level );
01301 c.setDisplayLevels( c.displayLevels() + 1 );
01302 } else {
01303
01304 c.setNumbering(KoParagCounter::NUM_LIST);
01305 c.setStyle(KoParagCounter::STYLE_NUM);
01306 }
01307 KCommand* command = textObject()->setCounterCommand( m_cursor, c );
01308 textObject()->emitNewCommand( command );
01309 }
01310 }
01311 if ( style )
01312 textObject()->applyStyle( m_cursor, style );
01313 }
01314
01315
01316 void KoTextView::decreaseNumberingLevel( const KoStyleCollection* styleCollection )
01317 {
01318
01319 KoParagCounter* counter = m_cursor->parag()->counter();
01320 int level = 9;
01321 if ( counter )
01322 level = counter->depth() - 1;
01323 KoParagStyle* style = 0;
01324 if ( m_cursor->parag()->style()->isOutline() || !counter )
01325 {
01326 if ( level == -1 )
01327 return;
01328 QValueVector<KoParagStyle *> outlineStyles = styleCollection->outlineStyles();
01329 while ( level >= 0 && !style ) {
01330 style = outlineStyles[ level ];
01331 --level;
01332 }
01333 }
01334 else
01335 {
01336 if ( level == -1 )
01337 style = styleCollection->defaultStyle();
01338 else
01339 {
01340 style = styleCollection->numberedStyleForLevel( level );
01341 if ( !style ) {
01342 KoParagCounter c( *counter );
01343 c.setDepth( level );
01344 if ( c.displayLevels() > 1 ) {
01345 c.setDisplayLevels( c.displayLevels() - 1 );
01346 }
01347 KCommand* command = textObject()->setCounterCommand( m_cursor, c );
01348 textObject()->emitNewCommand( command );
01349 }
01350 }
01351 }
01352 if ( style )
01353 textObject()->applyStyle( m_cursor, style );
01354 }
01355
01356 KCommand *KoTextView::setChangeCaseOfTextCommand(KoChangeCaseDia::TypeOfCase _type)
01357 {
01358 QString text;
01359 if ( textObject()->hasSelection() )
01360 text = textObject()->selectedText();
01361 if(!text.isEmpty())
01362 return textObject()->changeCaseOfText(cursor(), _type);
01363 else
01364 return 0L;
01365 }
01366
01367 KCommand *KoTextView::prepareDropMove( KoTextCursor dropCursor )
01368 {
01369 Q_ASSERT( textDocument()->hasSelection( KoTextDocument::Standard ) );
01370
01371 KoTextCursor startSel = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01372 KoTextCursor endSel = textDocument()->selectionEndCursor( KoTextDocument::Standard );
01373 bool inSelection = false;
01374 if ( startSel.parag() == endSel.parag() )
01375 inSelection = dropCursor.parag() == startSel.parag()
01376 && dropCursor.index() >= startSel.index()
01377 && dropCursor.index() <= endSel.index();
01378 else
01379 {
01380
01381 inSelection = dropCursor.parag() == startSel.parag() && dropCursor.index() >= startSel.index();
01382 if ( !inSelection )
01383 {
01384
01385 KoTextParag *p = startSel.parag()->next();
01386 while ( !inSelection && p && p != endSel.parag() )
01387 {
01388 inSelection = ( p == dropCursor.parag() );
01389 p = p->next();
01390 }
01391
01392 if ( !inSelection )
01393 inSelection = dropCursor.parag() == endSel.parag() && dropCursor.index() <= endSel.index();
01394 }
01395 }
01396 if ( inSelection || m_textobj->protectContent() )
01397 {
01398 textDocument()->removeSelection( KoTextDocument::Standard );
01399 textObject()->selectionChangedNotify();
01400 hideCursor();
01401 *cursor() = dropCursor;
01402 showCursor();
01403 ensureCursorVisible();
01404 return 0L;
01405 }
01406 if ( textObject()->protectContent() )
01407 {
01408 textDocument()->removeSelection( KoTextDocument::Standard );
01409 textObject()->selectionChangedNotify();
01410 }
01411
01412
01413
01414 if ( endSel.parag() == dropCursor.parag() )
01415 {
01416
01417 if ( startSel.parag() != dropCursor.parag() || startSel.index() < dropCursor.index() )
01418 {
01419
01420
01421
01422 int dropIndex = dropCursor.index();
01423 dropCursor.setParag( startSel.parag() );
01424
01425 dropCursor.setIndex( dropIndex - QMIN( endSel.index(), dropIndex ) + startSel.index() );
01426 }
01427 kdDebug(32500) << "dropCursor: parag=" << dropCursor.parag()->paragId() << " index=" << dropCursor.index() << endl;
01428 }
01429 KCommand* cmd = textObject()->removeSelectedTextCommand( cursor(), KoTextDocument::Standard );
01430
01431 hideCursor();
01432 *cursor() = dropCursor;
01433 showCursor();
01434
01435 return cmd;
01436 }
01437
01438
01439 void KoTextView::copyTextOfComment()
01440 {
01441 KoNoteVariable *var = dynamic_cast<KoNoteVariable *>( variable() );
01442 if( var )
01443 {
01444 KURL::List lst;
01445 lst.append( var->note() );
01446 QApplication::clipboard()->setSelectionMode(true);
01447 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01448 QApplication::clipboard()->setSelectionMode(false);
01449 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01450 }
01451 }
01452
01453 void KoTextView::removeComment()
01454 {
01455 KoNoteVariable *var = dynamic_cast<KoNoteVariable *>( variable() );
01456 if( var )
01457 {
01458 m_cursor->setIndex( m_variablePosition );
01459 textDocument()->setSelectionStart( KoTextDocument::Temp, m_cursor );
01460 m_cursor->setIndex( m_variablePosition + 1 );
01461 textDocument()->setSelectionEnd( KoTextDocument::Temp, m_cursor );
01462 textObject()->removeSelectedText( m_cursor, KoTextDocument::Temp, i18n("Remove Comment") );
01463 }
01464 }
01465
01466 KoParagStyle * KoTextView::createStyleFromSelection(const QString & name)
01467 {
01468 KoTextCursor cursor = *m_cursor;
01469 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
01470 cursor = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01471 KoParagStyle * style = new KoParagStyle (name);
01472 KoParagLayout layout(cursor.parag()->paragLayout());
01473 layout.style = style;
01474 style->setFollowingStyle( style );
01475 style->format() = *(cursor.parag()->at(cursor.index())->format());
01476
01477 style->paragLayout() = layout;
01478
01479 cursor.parag()->setParagLayout( style->paragLayout() );
01480 return style;
01481 }
01482
01483 void KoTextView::updateStyleFromSelection( KoParagStyle* style )
01484 {
01485 KoTextCursor cursor = *m_cursor;
01486 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
01487 cursor = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01488
01489 style->paragLayout() = cursor.parag()->paragLayout();
01490 style->paragLayout().style = style;
01491 style->format() = *(cursor.parag()->at(cursor.index())->format());
01492 }
01493
01494 void KoTextView::addBookmarks(const QString &url)
01495 {
01496 QString filename = locateLocal( "data", QString::fromLatin1("konqueror/bookmarks.xml") );
01497 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename,false );
01498 KBookmarkGroup group = bookManager->root();
01499 group.addBookmark( bookManager, url, KURL( url));
01500 bookManager->save();
01501
01502 }
01503
01504 void KoTextView::copyLink()
01505 {
01506 KoLinkVariable * var=linkVariable();
01507 if(var)
01508 {
01509 KURL::List lst;
01510 lst.append( var->url() );
01511 QApplication::clipboard()->setSelectionMode(true);
01512 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01513 QApplication::clipboard()->setSelectionMode(false);
01514 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01515 }
01516 }
01517
01518 void KoTextView::removeLink()
01519 {
01520 KoLinkVariable * var=linkVariable();
01521 if(var)
01522 {
01523 KoTextCursor c1 = *m_cursor;
01524 KoTextCursor c2 = *m_cursor;
01525 c1.setIndex(var->index());
01526 c2.setIndex(var->index()+1);
01527 textDocument()->setSelectionStart( KoTextDocument::Temp, &c1 );
01528 textDocument()->setSelectionEnd( KoTextDocument::Temp, &c2 );
01529 KCommand *cmd=textObject()->replaceSelectionCommand( &c1, var->value(),
01530 i18n("Remove Link"), KoTextDocument::Temp );
01531 if ( cmd )
01532 textObject()->emitNewCommand( cmd );
01533 }
01534 }
01535
01536 void KoTextView::setBackSpeller( KoBgSpellCheck* backSpeller )
01537 {
01538 d->m_backSpeller = backSpeller;
01539 }
01540
01541 #include "KoTextView.moc"
01542 class KoBgSpellCheck;