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 default:
00385 clearUndoRedoInfo = FALSE;
00386 break;
00387 }
00388 }
00389 else
00390 {
00391 clearUndoRedoInfo = FALSE;
00392 }
00393 }
00394 break;
00395 }
00396 }
00397
00398 if ( clearUndoRedoInfo ) {
00399 textObject()->clearUndoRedoInfo();
00400 if ( d->m_backSpeller )
00401 d->m_backSpeller->setIntraWordEditing( 0, 0 );
00402 }
00403
00404 textObject()->typingDone();
00405 }
00406
00407 void KoTextView::setOverwriteMode( bool overwriteMode )
00408 {
00409 m_overwriteMode = overwriteMode;
00410 }
00411
00412 void KoTextView::insertText( const QString &text )
00413 {
00414 int insertFlags = KoTextObject::DefaultInsertFlags;
00415 if ( m_overwriteMode )
00416 insertFlags |= KoTextObject::OverwriteMode;
00417 textObject()->insert( m_cursor, m_currentFormat, text, i18n("Insert Text"), KoTextDocument::Standard, insertFlags );
00418 }
00419
00420 void KoTextView::newParagraph()
00421 {
00422 textObject()->insert( m_cursor, m_currentFormat, "\n", i18n("Insert Text"), KoTextDocument::Standard, KoTextObject::CheckNewLine );
00423 }
00424
00425 void KoTextView::handleKeyReleaseEvent( QKeyEvent * e )
00426 {
00427 if ( e->key() == Key_Alt && d->currentUnicodeNumber() >= 32 )
00428 {
00429 QString text = QChar( d->currentUnicodeNumber() );
00430 d->clearCurrentUnicodeNumber();
00431 insertText( text );
00432 doAutoFormat( m_cursor, m_cursor->parag(),
00433 m_cursor->index() - 1, text[ text.length() - 1 ] );
00434 }
00435 }
00436
00437 void KoTextView::handleImStartEvent( QIMEvent * )
00438 {
00439
00440 }
00441
00442 void KoTextView::handleImComposeEvent( QIMEvent * e )
00443 {
00444
00445 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00446 textDocument()->removeSelection( KoTextDocument::Standard );
00447 if ( textDocument()->hasSelection( KoTextDocument::InputMethodPreedit ) )
00448 textDocument()->removeSelectedText( KoTextDocument::InputMethodPreedit, m_cursor );
00449
00450
00451 int preeditStartIdx = m_cursor->index();
00452 textDocument()->setSelectionStart( KoTextDocument::InputMethodPreedit, m_cursor );
00453 textObject()->insert( m_cursor, m_currentFormat, e->text(), i18n("Insert Text"),
00454 KoTextDocument::Standard,
00455 KoTextObject::DoNotRepaint );
00456 textDocument()->setSelectionEnd( KoTextDocument::InputMethodPreedit, m_cursor );
00457
00458
00459 int preeditSelStart = preeditStartIdx + e->cursorPos();
00460 int preeditSelEnd = preeditSelStart + e->selectionLength();
00461 m_cursor->setIndex( preeditSelStart );
00462 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00463 m_cursor->setIndex( preeditSelEnd );
00464 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00465
00466
00467 m_cursor->setIndex( preeditSelStart );
00468
00469 textObject()->emitUpdateUI( true );
00470 textObject()->emitShowCursor();
00471 textObject()->selectionChangedNotify();
00472 }
00473
00474 void KoTextView::handleImEndEvent( QIMEvent * e )
00475 {
00476
00477 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00478 textDocument()->removeSelection( KoTextDocument::Standard );
00479 if ( textDocument()->hasSelection( KoTextDocument::InputMethodPreedit ) )
00480 textDocument()->removeSelectedText( KoTextDocument::InputMethodPreedit, m_cursor );
00481
00482 insertText( e->text() );
00483
00484 textObject()->emitUpdateUI( true );
00485 textObject()->emitShowCursor();
00486 textObject()->selectionChangedNotify();
00487 }
00488
00489 void KoTextView::completion()
00490 {
00491 (void) doCompletion(m_cursor, m_cursor->parag(),
00492 m_cursor->index() - 1);
00493 }
00494
00495 void KoTextView::moveCursor( CursorAction action, bool select )
00496 {
00497 hideCursor();
00498 bool cursorMoved = false;
00499 if ( select ) {
00500 if ( !textDocument()->hasSelection( KoTextDocument::Standard ) )
00501 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00502 cursorMoved = moveCursor( action );
00503 if ( textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor ) ) {
00504 textObject()->selectionChangedNotify();
00505 }
00506 } else {
00507 bool redraw = textDocument()->removeSelection( KoTextDocument::Standard );
00508 cursorMoved = moveCursor( action );
00509 if ( redraw ) {
00510 textObject()->selectionChangedNotify();
00511 }
00512 }
00513
00514 if ( cursorMoved )
00515 {
00516 ensureCursorVisible();
00517
00518 }
00519 showCursor();
00520 }
00521
00522 bool KoTextView::moveCursor( CursorAction action )
00523 {
00524 bool cursorMoved = true;
00525 switch ( action ) {
00526 case MoveBackward:
00527 m_cursor->gotoPreviousLetter();
00528 break;
00529 case MoveWordBackward:
00530 m_cursor->gotoPreviousWord();
00531 break;
00532 case MoveForward:
00533 m_cursor->gotoNextLetter();
00534 break;
00535 case MoveWordForward:
00536 m_cursor->gotoNextWord();
00537 break;
00538 case MoveUp:
00539 m_cursor->gotoUp();
00540 break;
00541 case MoveDown:
00542 m_cursor->gotoDown();
00543 break;
00544 case MoveViewportUp:
00545 cursorMoved = pgUpKeyPressed();
00546 break;
00547 case MoveViewportDown:
00548 cursorMoved = pgDownKeyPressed();
00549 break;
00550 case MovePgUp:
00551 ctrlPgUpKeyPressed();
00552 break;
00553 case MovePgDown:
00554 ctrlPgDownKeyPressed();
00555 break;
00556 case MoveLineStart:
00557 m_cursor->gotoLineStart();
00558 break;
00559 case MoveHome:
00560 m_cursor->gotoHome();
00561 break;
00562 case MoveLineEnd:
00563 m_cursor->gotoLineEnd();
00564 break;
00565 case MoveEnd:
00566 textObject()->ensureFormatted( textDocument()->lastParag() );
00567 m_cursor->gotoEnd();
00568 break;
00569 case MoveParagUp: {
00570 KoTextParag * parag = m_cursor->parag()->prev();
00571 if ( m_cursor->index()==0 && parag )
00572 {
00573 m_cursor->setParag( parag );
00574 m_cursor->setIndex( 0 );
00575 }
00576 else m_cursor->setIndex( 0 );
00577 } break;
00578 case MoveParagDown: {
00579 KoTextParag * parag = m_cursor->parag()->next();
00580 if ( parag )
00581 {
00582 m_cursor->setParag( parag );
00583 m_cursor->setIndex( 0 );
00584 }
00585 } break;
00586 }
00587
00588 updateUI( true );
00589 return cursorMoved;
00590 }
00591
00592 KoTextCursor KoTextView::selectWordUnderCursor( const KoTextCursor& cursor, int selectionId )
00593 {
00594 KoTextCursor c1 = cursor;
00595 KoTextCursor c2 = cursor;
00596 if ( cursor.index() > 0 && !cursor.parag()->at( cursor.index()-1 )->c.isSpace() )
00597 c1.gotoWordLeft();
00598 if ( !cursor.parag()->at( cursor.index() )->c.isSpace() && !cursor.atParagEnd() )
00599 c2.gotoWordRight();
00600
00601
00602
00603
00604 KoTextString *s = cursor.parag()->string();
00605 bool beginFound = false;
00606 for ( int i = c1.index(); i< c2.index(); i++)
00607 {
00608 const QChar ch = s->at(i).c;
00609
00610
00611 const bool isWordDelimiter = ch.isSpace()
00612 || ch.category() == QChar::Punctuation_Open
00613 || ch.category() == QChar::Punctuation_Close
00614 || ch.category() == QChar::Punctuation_Other
00615 ;
00616
00617 if( !beginFound && !isWordDelimiter )
00618 {
00619 c1.setIndex(i);
00620 beginFound = true;
00621 }
00622 else if ( beginFound && isWordDelimiter )
00623 {
00624 c2.setIndex(i);
00625 break;
00626 }
00627 }
00628
00629 textDocument()->setSelectionStart( selectionId, &c1 );
00630 textDocument()->setSelectionEnd( selectionId, &c2 );
00631 return c2;
00632 }
00633
00634 KoTextCursor KoTextView::selectParagUnderCursor( const KoTextCursor& cursor, int selectionId, bool copyAndNotify )
00635 {
00636 KoTextCursor c1 = cursor;
00637 KoTextCursor c2 = cursor;
00638 c1.setIndex(0);
00639 c2.setIndex(c1.parag()->string()->length() - 1);
00640 textDocument()->setSelectionStart( selectionId, &c1 );
00641 textDocument()->setSelectionEnd( selectionId, &c2 );
00642 if ( copyAndNotify )
00643 {
00644 textObject()->selectionChangedNotify();
00645
00646 QApplication::clipboard()->setSelectionMode( true );
00647 emit copy();
00648 QApplication::clipboard()->setSelectionMode( false );
00649 }
00650 return c2;
00651 }
00652
00653 void KoTextView::extendParagraphSelection( const QPoint& iPoint )
00654 {
00655 hideCursor();
00656 KoTextCursor oldCursor = *m_cursor;
00657 placeCursor( iPoint );
00658
00659 bool redraw = FALSE;
00660 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00661 {
00662 redraw = textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00663 if ( textDocument()->isSelectionSwapped( KoTextDocument::Standard ) )
00664 m_cursor->setIndex( 0 );
00665 else
00666 m_cursor->setIndex( m_cursor->parag()->string()->length() - 1 );
00667 textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor );
00668 }
00669
00670
00671
00672 if ( redraw )
00673 textObject()->selectionChangedNotify( false );
00674
00675 showCursor();
00676 }
00677
00678 QString KoTextView::wordUnderCursor( const KoTextCursor& cursor )
00679 {
00680 selectWordUnderCursor( cursor, KoTextDocument::Temp );
00681 QString text = textObject()->selectedText( KoTextDocument::Temp );
00682 bool hasCustomItems = textObject()->selectionHasCustomItems( KoTextDocument::Temp );
00683 textDocument()->removeSelection( KoTextDocument::Temp );
00684 if( !hasCustomItems )
00685 return text;
00686 return QString::null;
00687 }
00688
00689 bool KoTextView::handleMousePressEvent( QMouseEvent *e, const QPoint &iPoint, bool canStartDrag, bool insertDirectCursor )
00690 {
00691 bool addParag = false;
00692 mightStartDrag = FALSE;
00693 hideCursor();
00694
00695 if (possibleTripleClick)
00696 {
00697 handleMouseTripleClickEvent( e, iPoint );
00698 return addParag;
00699 }
00700
00701 KoTextCursor oldCursor = *m_cursor;
00702 addParag = placeCursor( iPoint, insertDirectCursor&& isReadWrite() );
00703 ensureCursorVisible();
00704
00705 if ( e->button() != LeftButton )
00706 {
00707 showCursor();
00708 return addParag;
00709 }
00710
00711 KoLinkVariable* lv = linkVariable();
00712 if ( lv && openLink( lv ) )
00713 {
00714 return addParag;
00715 }
00716
00717 KoTextDocument * textdoc = textDocument();
00718 if ( canStartDrag && textdoc->inSelection( KoTextDocument::Standard, iPoint ) ) {
00719 mightStartDrag = TRUE;
00720 m_textobj->emitShowCursor();
00721 dragStartTimer->start( QApplication::startDragTime(), TRUE );
00722 dragStartPos = e->pos();
00723 return addParag;
00724 }
00725
00726 bool redraw = FALSE;
00727 if ( textdoc->hasSelection( KoTextDocument::Standard ) ) {
00728 if ( !( e->state() & ShiftButton ) ) {
00729 redraw = textdoc->removeSelection( KoTextDocument::Standard );
00730 textdoc->setSelectionStart( KoTextDocument::Standard, m_cursor );
00731 } else {
00732 redraw = textdoc->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00733 }
00734 } else {
00735 if ( !( e->state() & ShiftButton ) ) {
00736 textdoc->setSelectionStart( KoTextDocument::Standard, m_cursor );
00737 } else {
00738 textdoc->setSelectionStart( KoTextDocument::Standard, &oldCursor );
00739 redraw = textdoc->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00740 }
00741 }
00742
00743
00744 if ( !redraw ) {
00745 showCursor();
00746 } else {
00747 textObject()->selectionChangedNotify();
00748 }
00749 return addParag;
00750 }
00751
00752 void KoTextView::handleMouseMoveEvent( QMouseEvent*, const QPoint& iPoint )
00753 {
00754 hideCursor();
00755 KoTextCursor oldCursor = *m_cursor;
00756 placeCursor( iPoint );
00757
00758
00759 if ( inDoubleClick ) {
00760 KoTextCursor cl = *m_cursor;
00761 cl.gotoWordLeft();
00762 KoTextCursor cr = *m_cursor;
00763 cr.gotoWordRight();
00764
00765 int diff = QABS( oldCursor.parag()->at( oldCursor.index() )->x - iPoint.x() );
00766 int ldiff = QABS( cl.parag()->at( cl.index() )->x - iPoint.x() );
00767 int rdiff = QABS( cr.parag()->at( cr.index() )->x - iPoint.x() );
00768
00769 if ( m_cursor->parag()->lineStartOfChar( m_cursor->index() ) !=
00770 oldCursor.parag()->lineStartOfChar( oldCursor.index() ) )
00771 diff = 0xFFFFFF;
00772
00773 if ( rdiff < diff && rdiff < ldiff )
00774 *m_cursor = cr;
00775 else if ( ldiff < diff && ldiff < rdiff )
00776 *m_cursor = cl;
00777 else
00778 *m_cursor = oldCursor;
00779 }
00780
00781 bool redraw = FALSE;
00782 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
00783 redraw = textDocument()->setSelectionEnd( KoTextDocument::Standard, m_cursor ) || redraw;
00784 else
00785 textDocument()->setSelectionStart( KoTextDocument::Standard, m_cursor );
00786
00787 if ( redraw )
00788 textObject()->selectionChangedNotify( false );
00789
00790 showCursor();
00791 }
00792
00793 void KoTextView::handleMouseReleaseEvent()
00794 {
00795 if ( dragStartTimer->isActive() )
00796 dragStartTimer->stop();
00797 if ( mightStartDrag ) {
00798 textObject()->selectAll( FALSE );
00799 mightStartDrag = false;
00800 }
00801 else
00802 {
00803 if ( textDocument()->selectionStartCursor( KoTextDocument::Standard ) == textDocument()->selectionEndCursor( KoTextDocument::Standard ) )
00804 {
00805 textDocument()->removeSelection( KoTextDocument::Standard );
00806 }
00807
00808 textObject()->selectionChangedNotify();
00809
00810
00811 QApplication::clipboard()->setSelectionMode( true );
00812 emit copy();
00813 QApplication::clipboard()->setSelectionMode( false );
00814 }
00815
00816 inDoubleClick = FALSE;
00817 m_textobj->emitShowCursor();
00818 }
00819
00820 void KoTextView::handleMouseDoubleClickEvent( QMouseEvent*ev, const QPoint& i )
00821 {
00822
00823
00824 if(afterTripleClick)
00825 {
00826 handleMousePressEvent( ev, i );
00827 return;
00828 }
00829
00830 inDoubleClick = TRUE;
00831 *m_cursor = selectWordUnderCursor( *m_cursor );
00832 textObject()->selectionChangedNotify();
00833
00834 QApplication::clipboard()->setSelectionMode( true );
00835 emit copy();
00836 QApplication::clipboard()->setSelectionMode( false );
00837
00838 possibleTripleClick=true;
00839
00840 QTimer::singleShot(QApplication::doubleClickInterval(),this,SLOT(tripleClickTimeout()));
00841 }
00842
00843 void KoTextView::tripleClickTimeout()
00844 {
00845 possibleTripleClick=false;
00846 }
00847
00848 void KoTextView::handleMouseTripleClickEvent( QMouseEvent*ev, const QPoint& )
00849 {
00850 if ( ev->button() != LeftButton)
00851 {
00852 showCursor();
00853 return;
00854 }
00855 afterTripleClick= true;
00856 inDoubleClick = FALSE;
00857 *m_cursor = selectParagUnderCursor( *m_cursor );
00858 QTimer::singleShot(QApplication::doubleClickInterval(),this,SLOT(afterTripleClickTimeout()));
00859 }
00860
00861 void KoTextView::afterTripleClickTimeout()
00862 {
00863 afterTripleClick=false;
00864 }
00865
00866 bool KoTextView::maybeStartDrag( QMouseEvent* e )
00867 {
00868 if ( mightStartDrag ) {
00869 dragStartTimer->stop();
00870 if ( ( e->pos() - dragStartPos ).manhattanLength() > QApplication::startDragDistance() )
00871 startDrag();
00872 return true;
00873 }
00874 return false;
00875 }
00876
00877 bool KoTextView::insertParagraph(const QPoint &pos)
00878 {
00879 KoTextParag *last = textDocument()->lastParag();
00880 KoTextFormat *f = 0;
00881 KoParagStyle *style = last->style();
00882 KoParagCounter *counter = last->counter();
00883 int diff = (pos.y()- textDocument()->height());
00884 f = last->at( last->length()-1 )->format();
00885 int height =f->height();
00886 int nbParag = (diff / height);
00887 QFontMetrics fm = f->refFontMetrics();
00888 for (int i = 0; i < nbParag ;i++)
00889 {
00890 KoTextParag *s=textDocument()->createParag( textDocument(), last );
00891 s->setFormat( 0, 1, f, TRUE );
00892 if ( style )
00893 s->setStyle( style );
00894 s->setCounter( counter );
00895 last = s;
00896 }
00897 bool createParag = (nbParag > 0 );
00898 if ( createParag )
00899 {
00900 if ( pos.x() + f->width(' ') >= textDocument()->width())
00901 {
00902
00903
00904 last->setAlignment( Qt::AlignRight );
00905 }
00906 else
00907 {
00908 int nbSpace = pos.x()/f->width(' ');
00909 QString tmp;
00910 for (int i = 0; i< nbSpace; i++)
00911 {
00912 tmp+=' ';
00913 }
00914 last->insert( 0, tmp );
00915 }
00916 }
00917 return createParag;
00918
00919 }
00920
00921 bool KoTextView::placeCursor( const QPoint &pos, bool insertDirectCursor )
00922 {
00923 bool addParag = false;
00924 if ( insertDirectCursor && (pos.y()>textDocument()->height()) )
00925 addParag = insertParagraph(pos);
00926 KoTextParag *s = 0L;
00927 if ( addParag )
00928 s = textDocument()->lastParag();
00929 else
00930 s = textDocument()->firstParag();
00931 m_cursor->place( pos, s, false, &m_variablePosition );
00932 if ( m_variablePosition != -1 )
00933 kdDebug() << k_funcinfo << " m_variablePosition set to " << m_variablePosition << endl;
00934 updateUI( true );
00935 return addParag;
00936 }
00937
00938 void KoTextView::blinkCursor()
00939 {
00940
00941
00942 if ( !m_cursorVisible )
00943 return;
00944 bool cv = m_cursorVisible;
00945 blinkCursorVisible = !blinkCursorVisible;
00946 drawCursor( blinkCursorVisible );
00947 m_cursorVisible = cv;
00948 }
00949
00950 void KoTextView::drawCursor( bool visible )
00951 {
00952 m_cursorVisible = visible;
00953
00954 }
00955
00956 void KoTextView::focusInEvent()
00957 {
00958 if ( QApplication::cursorFlashTime() > 0 )
00959 blinkTimer->start( QApplication::cursorFlashTime() / 2 );
00960 showCursor();
00961 }
00962
00963 void KoTextView::focusOutEvent()
00964 {
00965 blinkTimer->stop();
00966 hideCursor();
00967 }
00968
00969
00970
00971
00972
00973
00974 KCommand* KoTextView::setFormatCommand( const KoTextFormat * newFormat, int flags, bool zoomFont)
00975 {
00976 return textObject()->setFormatCommand( m_cursor, &m_currentFormat, newFormat, flags, zoomFont );
00977 }
00978
00979 void KoTextView::dragStarted()
00980 {
00981 mightStartDrag = FALSE;
00982 inDoubleClick = FALSE;
00983 }
00984
00985 void KoTextView::applyStyle( const KoParagStyle * style )
00986 {
00987 if ( style )
00988 {
00989 textObject()->applyStyle( m_cursor, style );
00990 showCurrentFormat();
00991 }
00992 }
00993
00994 void KoTextView::updateUI( bool updateFormat, bool )
00995 {
00996
00997
00998 if ( updateFormat )
00999 {
01000 int i = cursor()->index();
01001 if ( i > 0 )
01002 --i;
01003 #ifdef DEBUG_FORMATS
01004 if ( currentFormat() )
01005 kdDebug(32500) << "KoTextView::updateUI old currentFormat=" << currentFormat()
01006 << " " << currentFormat()->key()
01007 << " parag format=" << cursor()->parag()->at( i )->format()->key() << endl;
01008 else
01009 kdDebug(32500) << "KoTextView::updateUI old currentFormat=0" << endl;
01010 #endif
01011 if ( !currentFormat() || currentFormat()->key() != cursor()->parag()->at( i )->format()->key() )
01012 {
01013 if ( currentFormat() )
01014 currentFormat()->removeRef();
01015 #ifdef DEBUG_FORMATS
01016 kdDebug(32500) << "Setting currentFormat from format " << cursor()->parag()->at( i )->format()
01017 << " ( character " << i << " in paragraph " << cursor()->parag()->paragId() << " )" << endl;
01018 #endif
01019 setCurrentFormat( textDocument()->formatCollection()->format( cursor()->parag()->at( i )->format() ) );
01020 if ( currentFormat()->isMisspelled() ) {
01021 KoTextFormat fNoMisspelled( *currentFormat() );
01022 fNoMisspelled.setMisspelled( false );
01023 currentFormat()->removeRef();
01024 setCurrentFormat( textDocument()->formatCollection()->format( &fNoMisspelled ) );
01025 }
01026 showCurrentFormat();
01027 }
01028 }
01029 }
01030
01031 void KoTextView::showCurrentFormat()
01032 {
01033
01034 KoTextFormat format = *currentFormat();
01035
01036 showFormat( &format );
01037 }
01038
01039 KCommand * KoTextView::setCounterCommand( const KoParagCounter & counter )
01040 {
01041 return textObject()->setCounterCommand( m_cursor, counter );
01042 }
01043 KCommand * KoTextView::setAlignCommand( int align )
01044 {
01045 return textObject()->setAlignCommand( m_cursor, align );
01046 }
01047 KCommand * KoTextView::setLineSpacingCommand( double spacing, KoParagLayout::SpacingType _type)
01048 {
01049 return textObject()->setLineSpacingCommand( m_cursor, spacing, _type);
01050 }
01051 KCommand * KoTextView::setBordersCommand( const KoBorder& leftBorder, const KoBorder& rightBorder, const KoBorder& bottomBorder, const KoBorder& topBorder )
01052 {
01053 return textObject()->setBordersCommand( m_cursor, leftBorder, rightBorder, bottomBorder, topBorder );
01054 }
01055 KCommand * KoTextView::setJoinBordersCommand( bool join )
01056 {
01057 return textObject()->setJoinBordersCommand( m_cursor, join );
01058 }
01059 KCommand * KoTextView::setMarginCommand( QStyleSheetItem::Margin m, double margin )
01060 {
01061 return textObject()->setMarginCommand( m_cursor, m, margin );
01062 }
01063 KCommand * KoTextView::setTabListCommand( const KoTabulatorList & tabList )
01064 {
01065 return textObject()->setTabListCommand( m_cursor, tabList );
01066 }
01067 KCommand * KoTextView::setBackgroundColorCommand( const QColor & color )
01068 {
01069 return textObject()->setBackgroundColorCommand( m_cursor, color );
01070 }
01071
01072 KoTextDocument * KoTextView::textDocument() const
01073 {
01074 return textObject()->textDocument();
01075 }
01076
01077 KoVariable *KoTextView::variable()
01078 {
01079 if ( m_variablePosition < 0 )
01080 return 0;
01081
01082 return textObject()->variableAtPosition( m_cursor->parag(), m_variablePosition );
01083 }
01084
01085 KoLinkVariable * KoTextView::linkVariable()
01086 {
01087 return dynamic_cast<KoLinkVariable *>(variable());
01088 }
01089
01090 QPtrList<KAction> KoTextView::dataToolActionList(KInstance * instance, const QString& word, bool & _singleWord )
01091 {
01092 m_singleWord = false;
01093 m_wordUnderCursor = QString::null;
01094 QString text;
01095 if ( textObject()->hasSelection() )
01096 {
01097 text = textObject()->selectedText();
01098 if ( text.find(' ') == -1 && text.find('\t') == -1 && text.find(KoTextObject::customItemChar()) == -1 )
01099 {
01100 m_singleWord = true;
01101 }
01102 else
01103 {
01104 m_singleWord = false;
01105
01106 if( text.find(KoTextObject::customItemChar())!=-1)
01107 text = QString::null;
01108 }
01109 }
01110 else
01111 {
01112 if ( !word.isEmpty() )
01113 {
01114 m_singleWord = true;
01115 m_wordUnderCursor = word;
01116 text = word;
01117 }
01118 }
01119
01120 if ( text.isEmpty() || textObject()->protectContent())
01121 return QPtrList<KAction>();
01122
01123
01124 QValueList<KDataToolInfo> tools;
01125 tools +=KDataToolInfo::query( "QString", "text/plain", instance );
01126
01127
01128 if ( m_singleWord )
01129 {
01130 _singleWord = true;
01131 tools += KDataToolInfo::query( "QString", "application/x-singleword", instance );
01132 }
01133
01134 tools += KDataToolInfo::query( "KoTextString", "application/x-qrichtext", instance );
01135
01136 return KDataToolAction::dataToolActionList( tools, this, SLOT( slotToolActivated( const KDataToolInfo &, const QString & ) ) );
01137 }
01138
01139 QString KoTextView::currentWordOrSelection() const
01140 {
01141 if ( textObject()->hasSelection() )
01142 return textObject()->selectedText();
01143 else
01144 return m_wordUnderCursor;
01145 }
01146
01147 void KoTextView::slotToolActivated( const KDataToolInfo & info, const QString & command )
01148 {
01149 KDataTool* tool = info.createTool( );
01150 if ( !tool )
01151 {
01152 kdWarning() << "Could not create Tool !" << endl;
01153 return;
01154 }
01155
01156 kdDebug(32500) << "KWTextFrameSetEdit::slotToolActivated command=" << command
01157 << " dataType=" << info.dataType() << endl;
01158
01159 QString text;
01160 if ( textObject()->hasSelection() )
01161 text = textObject()->selectedText();
01162 else
01163 text = m_wordUnderCursor;
01164
01165
01166 QString mimetype = "application/x-qrichtext";
01167 QString datatype = "KoTextString";
01168
01169 if ( !info.mimeTypes().contains( mimetype ) )
01170 {
01171 mimetype = "text/plain";
01172 datatype = "QString";
01173 }
01174
01175 if ( !info.mimeTypes().contains( mimetype ) && m_singleWord )
01176 mimetype = "application/x-singleword";
01177
01178 kdDebug(32500) << "Running tool with datatype=" << datatype << " mimetype=" << mimetype << endl;
01179
01180 QString origText = text;
01181 if ( tool->run( command, &text, datatype, mimetype) )
01182 {
01183 kdDebug(32500) << "Tool ran. Text is now " << text << endl;
01184 if ( origText != text )
01185 {
01186 if ( !textObject()->hasSelection() )
01187 {
01188
01189 selectWordUnderCursor( *m_cursor );
01190 }
01191
01192 textObject()->emitNewCommand( textObject()->replaceSelectionCommand(
01193 cursor(), text, i18n("Replace Word") ));
01194 }
01195 }
01196 delete tool;
01197 }
01198
01199 bool KoTextView::openLink( KoLinkVariable* variable )
01200 {
01201 kdDebug() << k_funcinfo << variable->url() << endl;
01202 KURL url( variable->url() );
01203 if( url.isValid() )
01204 {
01205 (void) new KRun( url );
01206 return true;
01207 }
01208 else
01209 {
01210 KMessageBox::sorry( 0, i18n("%1 is not a valid link.").arg( variable->url() ) );
01211 return false;
01212 }
01213 }
01214
01215
01216 void KoTextView::insertSoftHyphen()
01217 {
01218 textObject()->insert( cursor(), currentFormat(), QChar(0xad) ,
01219 i18n("Insert Soft Hyphen") );
01220 }
01221
01222 void KoTextView::insertLineBreak()
01223 {
01224 textObject()->insert( cursor(), currentFormat(), QChar('\n'),
01225 i18n("Insert Line Break") );
01226 }
01227
01228 void KoTextView::insertNonbreakingSpace()
01229 {
01230 textObject()->insert( cursor(), currentFormat(), QChar(0xa0) ,
01231 i18n("Insert Non-Breaking Space") );
01232 }
01233
01234 void KoTextView::insertNonbreakingHyphen()
01235 {
01236 textObject()->insert( cursor(), currentFormat(), QChar(0x2013),
01237 i18n("Insert Non-Breaking Hyphen") );
01238 }
01239
01240 void KoTextView::insertSpecialChar(QChar _c, const QString& font)
01241 {
01242 KoTextFormat * newFormat = new KoTextFormat(*currentFormat());
01243 newFormat->setFamily( font );
01244 if ( textObject()->hasSelection() )
01245 {
01246 KoTextFormat * lastFormat = currentFormat();
01247
01248 KCommand *cmd = textObject()->setFormatCommand( cursor(), &lastFormat, newFormat, KoTextFormat::Family );
01249
01250 KMacroCommand* macroCmd = new KMacroCommand( i18n("Insert Special Char") );
01251 macroCmd->addCommand( cmd );
01252 macroCmd->addCommand( textObject()->replaceSelectionCommand(
01253 cursor(), _c, QString::null) );
01254 textObject()->emitNewCommand( macroCmd );
01255 }
01256 else
01257 {
01258 textObject()->insert( cursor(), newFormat, _c, i18n("Insert Special Char"));
01259 delete newFormat;
01260 }
01261 }
01262
01263 const KoParagLayout * KoTextView::currentParagLayoutFormat() const
01264 {
01265 KoTextParag * parag = m_cursor->parag();
01266 return &(parag->paragLayout());
01267 }
01268
01269 bool KoTextView::rtl() const
01270 {
01271 return m_cursor->parag()->string()->isRightToLeft();
01272 }
01273
01274 KCommand* KoTextView::setParagLayoutFormatCommand( KoParagLayout *newLayout, int flags, int marginIndex )
01275 {
01276 return textObject()->setParagLayoutCommand( m_cursor, *newLayout, KoTextDocument::Standard,
01277 flags, marginIndex, true );
01278 }
01279
01280
01281 void KoTextView::increaseNumberingLevel( const KoStyleCollection* styleCollection )
01282 {
01283
01284 KoParagStyle* style = 0;
01285 int level = 0;
01286 KoParagCounter* counter = m_cursor->parag()->counter();
01287 if ( counter )
01288 level = counter->depth() + 1;
01289 if ( m_cursor->parag()->style()->isOutline() )
01290 {
01291 QValueVector<KoParagStyle *> outlineStyles = styleCollection->outlineStyles();
01292 while ( level < 10 && !style ) {
01293 style = outlineStyles[ level ];
01294 ++level;
01295 }
01296 if ( !style )
01297 style = styleCollection->defaultStyle();
01298 }
01299 else
01300 {
01301
01302 style = styleCollection->numberedStyleForLevel( level );
01303 if ( !style ) {
01304 KoParagCounter c;
01305 if (counter) {
01306 c = *counter;
01307 c.setDepth( level );
01308 c.setDisplayLevels( c.displayLevels() + 1 );
01309 } else {
01310
01311 c.setNumbering(KoParagCounter::NUM_LIST);
01312 c.setStyle(KoParagCounter::STYLE_NUM);
01313 }
01314 KCommand* command = textObject()->setCounterCommand( m_cursor, c );
01315 textObject()->emitNewCommand( command );
01316 }
01317 }
01318 if ( style )
01319 textObject()->applyStyle( m_cursor, style );
01320 }
01321
01322
01323 void KoTextView::decreaseNumberingLevel( const KoStyleCollection* styleCollection )
01324 {
01325
01326 KoParagCounter* counter = m_cursor->parag()->counter();
01327 int level = 9;
01328 if ( counter )
01329 level = counter->depth() - 1;
01330 KoParagStyle* style = 0;
01331 if ( m_cursor->parag()->style()->isOutline() || !counter )
01332 {
01333 if ( level == -1 )
01334 return;
01335 QValueVector<KoParagStyle *> outlineStyles = styleCollection->outlineStyles();
01336 while ( level >= 0 && !style ) {
01337 style = outlineStyles[ level ];
01338 --level;
01339 }
01340 }
01341 else
01342 {
01343 if ( level == -1 )
01344 style = styleCollection->defaultStyle();
01345 else
01346 {
01347 style = styleCollection->numberedStyleForLevel( level );
01348 if ( !style ) {
01349 KoParagCounter c( *counter );
01350 c.setDepth( level );
01351 if ( c.displayLevels() > 1 ) {
01352 c.setDisplayLevels( c.displayLevels() - 1 );
01353 }
01354 KCommand* command = textObject()->setCounterCommand( m_cursor, c );
01355 textObject()->emitNewCommand( command );
01356 }
01357 }
01358 }
01359 if ( style )
01360 textObject()->applyStyle( m_cursor, style );
01361 }
01362
01363 KCommand *KoTextView::setChangeCaseOfTextCommand(KoChangeCaseDia::TypeOfCase _type)
01364 {
01365 QString text;
01366 if ( textObject()->hasSelection() )
01367 text = textObject()->selectedText();
01368 if(!text.isEmpty())
01369 return textObject()->changeCaseOfText(cursor(), _type);
01370 else
01371 return 0L;
01372 }
01373
01374 KCommand *KoTextView::prepareDropMove( KoTextCursor dropCursor )
01375 {
01376 Q_ASSERT( textDocument()->hasSelection( KoTextDocument::Standard ) );
01377
01378 KoTextCursor startSel = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01379 KoTextCursor endSel = textDocument()->selectionEndCursor( KoTextDocument::Standard );
01380 bool inSelection = false;
01381 if ( startSel.parag() == endSel.parag() )
01382 inSelection = dropCursor.parag() == startSel.parag()
01383 && dropCursor.index() >= startSel.index()
01384 && dropCursor.index() <= endSel.index();
01385 else
01386 {
01387
01388 inSelection = dropCursor.parag() == startSel.parag() && dropCursor.index() >= startSel.index();
01389 if ( !inSelection )
01390 {
01391
01392 KoTextParag *p = startSel.parag()->next();
01393 while ( !inSelection && p && p != endSel.parag() )
01394 {
01395 inSelection = ( p == dropCursor.parag() );
01396 p = p->next();
01397 }
01398
01399 if ( !inSelection )
01400 inSelection = dropCursor.parag() == endSel.parag() && dropCursor.index() <= endSel.index();
01401 }
01402 }
01403 if ( inSelection || m_textobj->protectContent() )
01404 {
01405 textDocument()->removeSelection( KoTextDocument::Standard );
01406 textObject()->selectionChangedNotify();
01407 hideCursor();
01408 *cursor() = dropCursor;
01409 showCursor();
01410 ensureCursorVisible();
01411 return 0L;
01412 }
01413 if ( textObject()->protectContent() )
01414 {
01415 textDocument()->removeSelection( KoTextDocument::Standard );
01416 textObject()->selectionChangedNotify();
01417 }
01418
01419
01420
01421 if ( endSel.parag() == dropCursor.parag() )
01422 {
01423
01424 if ( startSel.parag() != dropCursor.parag() || startSel.index() < dropCursor.index() )
01425 {
01426
01427
01428
01429 int dropIndex = dropCursor.index();
01430 dropCursor.setParag( startSel.parag() );
01431
01432 dropCursor.setIndex( dropIndex - QMIN( endSel.index(), dropIndex ) + startSel.index() );
01433 }
01434 kdDebug(32500) << "dropCursor: parag=" << dropCursor.parag()->paragId() << " index=" << dropCursor.index() << endl;
01435 }
01436 KCommand* cmd = textObject()->removeSelectedTextCommand( cursor(), KoTextDocument::Standard );
01437
01438 hideCursor();
01439 *cursor() = dropCursor;
01440 showCursor();
01441
01442 return cmd;
01443 }
01444
01445
01446 void KoTextView::copyTextOfComment()
01447 {
01448 KoNoteVariable *var = dynamic_cast<KoNoteVariable *>( variable() );
01449 if( var )
01450 {
01451 KURL::List lst;
01452 lst.append( var->note() );
01453 QApplication::clipboard()->setSelectionMode(true);
01454 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01455 QApplication::clipboard()->setSelectionMode(false);
01456 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01457 }
01458 }
01459
01460 void KoTextView::removeComment()
01461 {
01462 KoNoteVariable *var = dynamic_cast<KoNoteVariable *>( variable() );
01463 if( var )
01464 {
01465 m_cursor->setIndex( m_variablePosition );
01466 textDocument()->setSelectionStart( KoTextDocument::Temp, m_cursor );
01467 m_cursor->setIndex( m_variablePosition + 1 );
01468 textDocument()->setSelectionEnd( KoTextDocument::Temp, m_cursor );
01469 textObject()->removeSelectedText( m_cursor, KoTextDocument::Temp, i18n("Remove Comment") );
01470 }
01471 }
01472
01473 KoParagStyle * KoTextView::createStyleFromSelection(const QString & name)
01474 {
01475 KoTextCursor cursor = *m_cursor;
01476 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
01477 cursor = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01478 KoParagStyle * style = new KoParagStyle (name);
01479 KoParagLayout layout(cursor.parag()->paragLayout());
01480 layout.style = style;
01481 style->setFollowingStyle( style );
01482 style->format() = *(cursor.parag()->at(cursor.index())->format());
01483
01484 style->paragLayout() = layout;
01485
01486 cursor.parag()->setParagLayout( style->paragLayout() );
01487 return style;
01488 }
01489
01490 void KoTextView::updateStyleFromSelection( KoParagStyle* style )
01491 {
01492 KoTextCursor cursor = *m_cursor;
01493 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
01494 cursor = textDocument()->selectionStartCursor( KoTextDocument::Standard );
01495
01496 style->paragLayout() = cursor.parag()->paragLayout();
01497 style->paragLayout().style = style;
01498 style->format() = *(cursor.parag()->at(cursor.index())->format());
01499 }
01500
01501 void KoTextView::addBookmarks(const QString &url)
01502 {
01503 QString filename = locateLocal( "data", QString::fromLatin1("konqueror/bookmarks.xml") );
01504 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename,false );
01505 KBookmarkGroup group = bookManager->root();
01506 group.addBookmark( bookManager, url, KURL( url));
01507 bookManager->save();
01508
01509 }
01510
01511 void KoTextView::copyLink()
01512 {
01513 KoLinkVariable * var=linkVariable();
01514 if(var)
01515 {
01516 KURL::List lst;
01517 lst.append( var->url() );
01518 QApplication::clipboard()->setSelectionMode(true);
01519 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01520 QApplication::clipboard()->setSelectionMode(false);
01521 QApplication::clipboard()->setData( new KURLDrag(lst, 0, 0) );
01522 }
01523 }
01524
01525 void KoTextView::removeLink()
01526 {
01527 KoLinkVariable * var=linkVariable();
01528 if(var)
01529 {
01530 KoTextCursor c1 = *m_cursor;
01531 KoTextCursor c2 = *m_cursor;
01532 c1.setIndex(var->index());
01533 c2.setIndex(var->index()+1);
01534 textDocument()->setSelectionStart( KoTextDocument::Temp, &c1 );
01535 textDocument()->setSelectionEnd( KoTextDocument::Temp, &c2 );
01536 KCommand *cmd=textObject()->replaceSelectionCommand( &c1, var->value(),
01537 i18n("Remove Link"), KoTextDocument::Temp );
01538 if ( cmd )
01539 textObject()->emitNewCommand( cmd );
01540 }
01541 }
01542
01543 void KoTextView::setBackSpeller( KoBgSpellCheck* backSpeller )
01544 {
01545 d->m_backSpeller = backSpeller;
01546 }
01547
01548 #include "KoTextView.moc"
01549 class KoBgSpellCheck;