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