00001 #include "ScrollableLineEdit.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "ScrollableLineEdit.h"
00041 #ifndef QT_NO_LINEEDIT
00042 #include "qpainter.h"
00043 #include "qdrawutil.h"
00044 #include "qfontmetrics.h"
00045 #include "qpixmap.h"
00046 #include "qclipboard.h"
00047 #include "qapplication.h"
00048 #include "qvalidator.h"
00049 #include "qdragobject.h"
00050 #include "qtimer.h"
00051 #include "qpopupmenu.h"
00052 #include "qstringlist.h"
00053 #include "qguardedptr.h"
00054 #include <ctype.h>
00055
00056
00057 struct ScrollableLineEditUndoItem
00058 {
00059 ScrollableLineEditUndoItem(){pos=0;};
00060 ScrollableLineEditUndoItem( const QString& s, int p )
00061 : str(s),pos(p){}
00062 #if defined(Q_FULL_TEMPLATE_INSTANTIATION)
00063 bool operator==( const ScrollableLineEditUndoItem& ) const { return FALSE; }
00064 #endif
00065 QString str;
00066 int pos;
00067 };
00068
00069 enum {
00070 IdUndo,
00071 IdRedo,
00072 #ifndef QT_NO_CLIPBOARD
00073 IdCut,
00074 IdCopy,
00075 IdPaste,
00076 #endif
00077 IdClear,
00078 IdSelectAll
00079 };
00080
00081 struct ScrollableLineEditPrivate {
00082 ScrollableLineEditPrivate( ScrollableLineEdit * l ):
00083 frame(TRUE), mode(ScrollableLineEdit::Normal),
00084 readonly(FALSE), validator( 0 ),
00085 pm(0), pmDirty( TRUE ),
00086 blinkTimer( l, "ScrollableLineEdit blink timer" ),
00087 dragTimer( l, "ScrollableLineEdit drag timer" ),
00088 dndTimer( l, "DnD Timer" ),
00089 inDoubleClick( FALSE ), offsetDirty( FALSE ),
00090 undo(TRUE), needundo( FALSE ), ignoreUndoWithDel( FALSE ),
00091 mousePressed( FALSE ), dnd_primed( FALSE ), passwordChar( '*' ) {}
00092
00093 bool frame;
00094 ScrollableLineEdit::EchoMode mode;
00095 bool readonly;
00096 const QValidator * validator;
00097 QPixmap * pm;
00098 bool pmDirty;
00099 QTimer blinkTimer;
00100 QTimer dragTimer, dndTimer;
00101 QRect cursorRepaintRect;
00102 bool inDoubleClick;
00103 bool offsetDirty;
00104 QValueList<ScrollableLineEditUndoItem> undoList;
00105 QValueList<ScrollableLineEditUndoItem> redoList;
00106 bool undo;
00107 bool needundo;
00108 bool ignoreUndoWithDel;
00109 bool mousePressed;
00110 QPoint dnd_startpos;
00111 bool dnd_primed;
00112 QChar passwordChar;
00113 };
00114
00115
00116
00178 static const int scrollTime = 40;
00179
00180
00191 ScrollableLineEdit::ScrollableLineEdit( QWidget *parent, const char *name )
00192 : QWidget( parent, name, WRepaintNoErase )
00193 {
00194 init();
00195 }
00196
00197
00209 ScrollableLineEdit::ScrollableLineEdit( const QString & contents,
00210 QWidget *parent, const char *name )
00211 : QWidget( parent, name )
00212 {
00213 init();
00214 setText( contents );
00215 }
00216
00217
00222 ScrollableLineEdit::~ScrollableLineEdit()
00223 {
00224 if ( d->pm )
00225 delete d->pm;
00226 delete d;
00227 }
00228
00229
00232 void ScrollableLineEdit::init()
00233 {
00234 d = new ScrollableLineEditPrivate( this );
00235 connect( &d->blinkTimer, SIGNAL(timeout()),
00236 this, SLOT(blinkSlot()) );
00237
00238
00239
00240
00241
00242
00243 cursorPos = 0;
00244 offset = 0;
00245 maxLen = 32767;
00246 cursorOn = TRUE;
00247 markAnchor = 0;
00248 markDrag = 0;
00249 dragScrolling = FALSE;
00250 scrollingLeft = FALSE;
00251 tbuf = QString::fromLatin1("");
00252 setFocusPolicy( StrongFocus );
00253 #ifndef QT_NO_CURSOR
00254 setCursor( ibeamCursor );
00255 #endif
00256 setBackgroundMode( PaletteBase );
00257 setKeyCompression( TRUE );
00258 alignmentFlag = Qt::AlignLeft;
00259 setAcceptDrops( TRUE );
00260
00261
00262 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
00263 ed = FALSE;
00264 }
00265
00266
00276 void ScrollableLineEdit::setText( const QString &text )
00277 {
00278 QString oldText( tbuf );
00279 tbuf = text;
00280 if ( (int)tbuf.length() > maxLen )
00281 tbuf.truncate( maxLen );
00282 offset = 0;
00283 cursorPos = 0;
00284 markAnchor = 0;
00285 markDrag = 0;
00286 end( FALSE );
00287 #ifndef QT_NO_VALIDATOR
00288 if ( validator() )
00289 (void)validator()->validate( tbuf, cursorPos );
00290 #endif
00291 d->pmDirty = TRUE;
00292
00293 update();
00294 if ( d->undo ) {
00295 d->undoList.clear();
00296 d->redoList.clear();
00297 d->needundo = TRUE;
00298 }
00299 if ( oldText != tbuf )
00300 emit textChanged( tbuf );
00301 }
00302
00303
00311 void ScrollableLineEdit::selectAll()
00312 {
00313 setSelection( 0, tbuf.length() );
00314 end( TRUE );
00315 }
00316
00317
00318
00324 void ScrollableLineEdit::deselect()
00325 {
00326 setSelection( cursorPos, 0 );
00327 }
00328
00329
00335 QString ScrollableLineEdit::text() const
00336 {
00337 return tbuf;
00338 }
00339
00340
00341
00349 QString ScrollableLineEdit::displayText() const
00350 {
00351 QString res;
00352
00353 switch( echoMode() ) {
00354 case Normal:
00355 res = tbuf;
00356 break;
00357 case NoEcho:
00358 res = QString::fromLatin1("");
00359 break;
00360 case Password:
00361 res.fill( d->passwordChar, tbuf.length() );
00362 break;
00363 }
00364 return res;
00365 }
00366
00367
00368
00376 bool ScrollableLineEdit::hasMarkedText() const
00377 {
00378 return markAnchor != markDrag;
00379 }
00380
00388 QString ScrollableLineEdit::markedText() const
00389 {
00390 return tbuf.mid( minMark(), maxMark() - minMark() );
00391 }
00392
00398 int ScrollableLineEdit::maxLength() const
00399 {
00400 return maxLen;
00401 }
00402
00410 void ScrollableLineEdit::setMaxLength( int m )
00411 {
00412 maxLen = m;
00413 markAnchor = 0;
00414 markDrag = 0;
00415 if ( (int)tbuf.length() > maxLen ) {
00416 tbuf.truncate( maxLen );
00417 d->pmDirty = TRUE;
00418 }
00419 setCursorPosition( 0 );
00420 if ( d->pmDirty )
00421 update();
00422 }
00423
00470 void ScrollableLineEdit::keyPressEvent( QKeyEvent *e )
00471 {
00472 if ( e->key() == Key_Enter || e->key() == Key_Return ) {
00473 #ifdef QT_NO_VALIDATOR
00474 emit returnPressed();
00475 e->ignore();
00476 #else
00477 const QValidator * v = validator();
00478 if ( !v || v->validate( tbuf, cursorPos ) == QValidator::Acceptable ) {
00479 emit returnPressed();
00480 e->ignore();
00481 }
00482 else if ( v ) {
00483 QString old( tbuf );
00484 v->fixup( tbuf );
00485 if ( old != tbuf ) {
00486 d->pmDirty = TRUE;
00487 if ( cursorPos > (int)tbuf.length() )
00488 cursorPos = tbuf.length();
00489 update();
00490 }
00491 if ( v->validate( tbuf, cursorPos ) == QValidator::Acceptable )
00492 emit returnPressed();
00493 e->ignore();
00494 }
00495 #endif
00496 return;
00497 }
00498 if ( !d->readonly ) {
00499 QString t = e->text();
00500 if ( !t.isEmpty() && (!e->ascii() || e->ascii()>=32) &&
00501 e->key() != Key_Delete &&
00502 e->key() != Key_Backspace ) {
00503 insert( t );
00504 return;
00505 }
00506 }
00507 bool needundo = d->needundo;
00508 d->needundo = TRUE;
00509 bool ignoreUndoWithDel = d->ignoreUndoWithDel;
00510 d->ignoreUndoWithDel = FALSE;
00511 int unknown = 0;
00512 if ( e->state() & ControlButton ) {
00513 switch ( e->key() ) {
00514 case Key_A:
00515 home( e->state() & ShiftButton );
00516 break;
00517 case Key_B:
00518 cursorLeft( e->state() & ShiftButton );
00519 break;
00520 #ifndef QT_NO_CLIPBOARD
00521 case Key_C:
00522 copy();
00523 break;
00524 #endif
00525 case Key_D:
00526 if ( !d->readonly ) {
00527 d->ignoreUndoWithDel = ignoreUndoWithDel;
00528 del();
00529 }
00530 break;
00531 case Key_E:
00532 end( e->state() & ShiftButton );
00533 break;
00534 case Key_F:
00535 cursorRight( e->state() & ShiftButton );
00536 break;
00537 case Key_H:
00538 if ( !d->readonly ) {
00539 d->ignoreUndoWithDel = ignoreUndoWithDel;
00540 backspace();
00541 }
00542 break;
00543 case Key_K:
00544 if ( !d->readonly && cursorPos < (int)tbuf.length() ) {
00545 QString t( tbuf );
00546 if ( d->undoList.isEmpty() || d->undoList.last().str != tbuf ) {
00547 d->undoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
00548 d->redoList.clear();
00549 }
00550 t.truncate( cursorPos );
00551 validateAndSet( t, cursorPos, cursorPos, cursorPos );
00552 }
00553 break;
00554 #ifndef QT_NO_CLIPBOARD
00555 case Key_V:
00556 if ( !d->readonly )
00557 insert( QApplication::clipboard()->text() );
00558 break;
00559 case Key_X:
00560 if ( !d->readonly && hasMarkedText() && echoMode() == Normal ) {
00561 copy();
00562 del();
00563 }
00564 break;
00565 #if defined (_WS_WIN_)
00566 case Key_Insert:
00567 copy();
00568 break;
00569 #endif
00570 #endif
00571 case Key_Right:
00572 cursorWordForward( e->state() & ShiftButton );
00573 break;
00574 case Key_Left:
00575 cursorWordBackward( e->state() & ShiftButton );
00576 break;
00577 case Key_Z:
00578 if ( !d->readonly )
00579 undoInternal();
00580 break;
00581 case Key_Y:
00582 if ( !d->readonly )
00583 redoInternal();
00584 break;
00585 default:
00586 unknown++;
00587 }
00588 } else {
00589 switch ( e->key() ) {
00590 case Key_Left:
00591 cursorLeft( e->state() & ShiftButton );
00592 break;
00593 case Key_Right:
00594 cursorRight( e->state() & ShiftButton );
00595 break;
00596 case Key_Backspace:
00597 if ( !d->readonly ) {
00598 d->ignoreUndoWithDel = ignoreUndoWithDel;
00599 backspace();
00600 }
00601 break;
00602 case Key_Home:
00603 home( e->state() & ShiftButton );
00604 break;
00605 case Key_End:
00606 end( e->state() & ShiftButton );
00607 break;
00608 case Key_Delete:
00609 if ( !d->readonly ) {
00610 #if defined (_WS_WIN_)
00611 if ( e->state() & ShiftButton ) {
00612 cut();
00613 break;
00614 }
00615 #endif
00616 d->ignoreUndoWithDel = ignoreUndoWithDel;
00617 del();
00618 }
00619 break;
00620 #if defined (_WS_WIN_)
00621 case Key_Insert:
00622 if ( !d->readonly && e->state() & ShiftButton )
00623 paste();
00624 else
00625 unknown++;
00626 break;
00627 #endif
00628 case Key_F14:
00629 if ( !d->readonly )
00630 undoInternal();
00631 break;
00632 #ifndef QT_NO_CLIPBOARD
00633 case Key_F16:
00634 copy();
00635 break;
00636 case Key_F18:
00637 if ( !d->readonly )
00638 insert( QApplication::clipboard()->text() );
00639 break;
00640 case Key_F20:
00641 if ( !d->readonly && hasMarkedText() && echoMode() == Normal ) {
00642 copy();
00643 del();
00644 }
00645 break;
00646 #endif
00647 default:
00648 unknown++;
00649 }
00650 }
00651
00652 if ( unknown ) {
00653 d->needundo = needundo;
00654 e->ignore();
00655 return;
00656 }
00657 }
00658
00662 void ScrollableLineEdit::focusInEvent( QFocusEvent * e)
00663 {
00664 d->pmDirty = TRUE;
00665 cursorOn = FALSE;
00666 blinkOn();
00667 if ( e->reason() == QFocusEvent::Tab )
00668 selectAll();
00669 d->pmDirty = TRUE;
00670 repaint( FALSE );
00671 }
00672
00673
00677 void ScrollableLineEdit::focusOutEvent( QFocusEvent * e )
00678 {
00679 if ( e->reason() != QFocusEvent::ActiveWindow
00680 && e->reason() != QFocusEvent::Popup )
00681 deselect();
00682 d->dragTimer.stop();
00683 if ( cursorOn )
00684 blinkSlot();
00685 d->pmDirty = TRUE;
00686 repaint( FALSE );
00687 }
00688
00691 void ScrollableLineEdit::leaveEvent( QEvent * )
00692 {
00693 }
00694
00695
00699 void ScrollableLineEdit::paintEvent( QPaintEvent *e )
00700 {
00701 if ( d->offsetDirty )
00702 updateOffset();
00703 if ( !d->pm || d->pmDirty ) {
00704 makePixmap();
00705 if ( d->pm->isNull() ) {
00706 delete d->pm;
00707 d->pm = 0;
00708 return;
00709 }
00710
00711 QPainter p( d->pm, this );
00712
00713 const QColorGroup & g = colorGroup();
00714 QBrush bg = g.brush((isEnabled()) ? QColorGroup::Base :
00715 QColorGroup::Background);
00716 QFontMetrics fm = fontMetrics();
00717 int markBegin = minMark();
00718 int markEnd = maxMark();
00719
00720 p.fillRect( 0, 0, width(), height(), bg );
00721
00722 QString display = displayText();
00723 QString before = display.mid( 0, markBegin );
00724 QString marked = display.mid( markBegin, markEnd - markBegin );
00725 QString after = display.mid( markEnd, display.length() );
00726
00727 int y = (d->pm->height() + fm.height())/2 - fm.descent() - 1 ;
00728
00729 int x = offset + 2;
00730 int w;
00731
00732 w = fm.width( before );
00733 if ( x < d->pm->width() && x + w >= 0 ) {
00734 p.setPen( g.text() );
00735 p.drawText( x, y, before );
00736 }
00737 x += w;
00738
00739 w = fm.width( marked );
00740 if ( x < d->pm->width() && x + w >= 0 ) {
00741 p.fillRect( x, y-fm.ascent()-1, w, fm.height()+2,
00742 g.brush( QColorGroup::Highlight ) );
00743 p.setPen( g.highlightedText() );
00744 p.drawText( x, y, marked );
00745 }
00746 x += w;
00747
00748 w = fm.width( after );
00749 if ( x < d->pm->width() && x + w >= 0 ) {
00750 p.setPen( g.text() );
00751 p.drawText( x, y, after );
00752 }
00753
00754
00755 p.setPen( g.text() );
00756
00757 d->cursorRepaintRect.setTop( y + frameW() - fm.ascent() );
00758 d->cursorRepaintRect.setHeight( fm.height() );
00759 d->pmDirty = FALSE;
00760 }
00761
00762 QPainter p( this );
00763
00764 if ( frame() ) {
00765 style().drawPanel( &p, 0, 0, width(), height(), colorGroup(),
00766 TRUE, style().defaultFrameWidth() );
00767 p.drawPixmap( frameW(), frameW(), *d->pm );
00768 } else {
00769 p.drawPixmap( 0, 0, *d->pm );
00770 }
00771
00772 if ( hasFocus() ) {
00773 d->cursorRepaintRect
00774 = QRect( offset + frameW() +
00775 fontMetrics().width( displayText().left( cursorPos ) ),
00776 d->cursorRepaintRect.top(),
00777 5, d->cursorRepaintRect.height() );
00778
00779 int curYTop = d->cursorRepaintRect.y();
00780 int curYBot = d->cursorRepaintRect.bottom();
00781 int curXPos = d->cursorRepaintRect.x() + 2;
00782 if ( !d->readonly && cursorOn &&
00783 d->cursorRepaintRect.intersects( e->rect() ) ) {
00784 p.setPen( colorGroup().text() );
00785 p.drawLine( curXPos, curYTop, curXPos, curYBot );
00786 if ( style() != WindowsStyle ) {
00787 p.drawLine( curXPos - 2, curYTop, curXPos + 2, curYTop );
00788 p.drawLine( curXPos - 2, curYBot, curXPos + 2, curYBot );
00789 }
00790 }
00791
00792
00793 setMicroFocusHint( curXPos, curYTop, 1, curYBot-curYTop+1 );
00794 } else {
00795 delete d->pm;
00796 d->pm = 0;
00797 }
00798
00799 }
00800
00801
00805 void ScrollableLineEdit::resizeEvent( QResizeEvent * )
00806 {
00807 delete d->pm;
00808 d->pm = 0;
00809 offset = 0;
00810 updateOffset();
00811 }
00812
00813
00816 bool ScrollableLineEdit::event( QEvent * e )
00817 {
00818 if ( e->type() == QEvent::AccelOverride && !d->readonly ) {
00819 QKeyEvent* ke = (QKeyEvent*) e;
00820 if ( ke->state() == NoButton ) {
00821 if ( ke->key() < Key_Escape ) {
00822 ke->accept();
00823 } else {
00824 switch ( ke->key() ) {
00825 case Key_Delete:
00826 case Key_Home:
00827 case Key_End:
00828 case Key_Backspace:
00829 ke->accept();
00830 default:
00831 break;
00832 }
00833 }
00834 } else if ( ke->state() & ControlButton ) {
00835 switch ( ke->key() ) {
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 case Key_C:
00846 case Key_V:
00847 case Key_X:
00848 case Key_Y:
00849 case Key_Z:
00850 case Key_Left:
00851 case Key_Right:
00852 #if defined (_WS_WIN_)
00853 case Key_Insert:
00854 #endif
00855 ke->accept();
00856 default:
00857 break;
00858 }
00859 }
00860 }
00861 return QWidget::event( e );
00862 }
00863
00864
00867 void ScrollableLineEdit::mousePressEvent( QMouseEvent *e )
00868 {
00869 d->dnd_startpos = e->pos();
00870 d->dnd_primed = FALSE;
00871 #ifndef QT_NO_POPUPMENU
00872 if ( e->button() == RightButton ) {
00873 QGuardedPtr<QPopupMenu> popup = new QPopupMenu( this );
00874 int id[ 7 ];
00875 id[ IdUndo ] = popup->insertItem( tr( "Undo" ) );
00876 id[ IdRedo ] = popup->insertItem( tr( "Redo" ) );
00877 popup->insertSeparator();
00878 #ifndef QT_NO_CLIPBOARD
00879 id[ IdCut ] = popup->insertItem( tr( "Cut" ) );
00880 id[ IdCopy ] = popup->insertItem( tr( "Copy" ) );
00881 id[ IdPaste ] = popup->insertItem( tr( "Paste" ) );
00882 #endif
00883 id[ IdClear ] = popup->insertItem( tr( "Clear" ) );
00884 popup->insertSeparator();
00885 id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) );
00886 popup->setItemEnabled( id[ IdUndo ],
00887 !this->d->readonly && !this->d->undoList.isEmpty() );
00888 popup->setItemEnabled( id[ IdRedo ],
00889 !this->d->readonly && !this->d->redoList.isEmpty() );
00890 #ifndef QT_NO_CLIPBOARD
00891 popup->setItemEnabled( id[ IdCut ],
00892 !this->d->readonly && !this->d->readonly && hasMarkedText() );
00893 popup->setItemEnabled( id[ IdCopy ], hasMarkedText() );
00894 popup->setItemEnabled( id[ IdPaste ],
00895 !this->d->readonly
00896 && (bool)QApplication::clipboard()->text().length() );
00897 #endif
00898 popup->setItemEnabled( id[ IdClear ],
00899 !this->d->readonly && (bool)text().length() );
00900 int allSelected = minMark() == 0 && maxMark() == (int)text().length();
00901 popup->setItemEnabled( id[ IdSelectAll ],
00902 (bool)text().length() && !allSelected );
00903
00904 int r = popup->exec( e->globalPos() );
00905 delete (QPopupMenu *) popup;
00906
00907 if ( r == id[ IdUndo ] )
00908 undoInternal();
00909 else if ( r == id[ IdRedo ] )
00910 redoInternal();
00911 #ifndef QT_NO_CLIPBOARD
00912 else if ( r == id[ IdCut ] )
00913 cut();
00914 else if ( r == id[ IdCopy ] )
00915 copy();
00916 else if ( r == id[ IdPaste ] )
00917 paste();
00918 #endif
00919 else if ( r == id[ IdClear ] )
00920 clear();
00921 else if ( r == id[ IdSelectAll ] )
00922 selectAll();
00923 return;
00924 }
00925 #endif //QT_NO_POPUPMENU
00926 d->inDoubleClick = FALSE;
00927 int newCP = xPosToCursorPos( e->pos().x() );
00928 int m1 = minMark();
00929 int m2 = maxMark();
00930 #ifndef QT_NO_DRAGANDDROP
00931 if ( hasMarkedText() && echoMode() == Normal && !( e->state() & ShiftButton ) &&
00932 e->button() == LeftButton && m1 < newCP && m2 > newCP ) {
00933 d->dndTimer.start( QApplication::startDragTime(), TRUE );
00934 d->dnd_primed = TRUE;
00935 return;
00936 }
00937 #endif
00938
00939 m1 = QMIN( m1, cursorPos );
00940 m2 = QMAX( m2, cursorPos );
00941 dragScrolling = FALSE;
00942 if ( e->state() & ShiftButton ) {
00943 newMark( newCP, FALSE );
00944 } else {
00945 markDrag = newCP;
00946 markAnchor = newCP;
00947 newMark( newCP, FALSE );
00948 }
00949 repaintArea( m1, m2 );
00950 d->mousePressed = TRUE;
00951 }
00952
00953 #ifndef QT_NO_DRAGANDDROP
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 #endif // QT_NO_DRAGANDDROP
00967
00970 void ScrollableLineEdit::mouseMoveEvent( QMouseEvent *e )
00971 {
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 if ( !(e->state() & LeftButton) )
00986 return;
00987
00988 int margin = frame() ? frameW()*2 : 2;
00989
00990 if ( e->pos().x() < margin || e->pos().x() > width() - margin ) {
00991 if ( !dragScrolling ) {
00992 dragScrolling = TRUE;
00993 scrollingLeft = e->pos().x() < margin;
00994 if ( scrollingLeft )
00995 newMark( xPosToCursorPos( 0 ), FALSE );
00996 else
00997 newMark( xPosToCursorPos( width() ), FALSE );
00998 d->dragTimer.start( scrollTime );
00999 }
01000 } else {
01001 dragScrolling = FALSE;
01002 int mousePos = xPosToCursorPos( e->pos().x() );
01003 int m1 = markDrag;
01004 newMark( mousePos, FALSE );
01005 repaintArea( m1, mousePos );
01006 }
01007 }
01008
01011 void ScrollableLineEdit::mouseReleaseEvent( QMouseEvent * e )
01012 {
01013 dragScrolling = FALSE;
01014 d->dnd_primed = FALSE;
01015 if ( d->dndTimer.isActive() ) {
01016 d->dndTimer.stop();
01017 int ncp = xPosToCursorPos( e->pos().x() );
01018 setSelection( ncp, 0 );
01019 setCursorPosition( ncp );
01020 return;
01021 }
01022 if ( d->inDoubleClick ) {
01023 d->inDoubleClick = FALSE;
01024 return;
01025 }
01026
01027 if ( !d->mousePressed )
01028 return;
01029 d->mousePressed = FALSE;
01030
01031 #ifndef QT_NO_CLIPBOARD
01032 #if defined(_WS_X11_)
01033 copy();
01034 #endif
01035
01036 if ( !d->readonly && e->button() == MidButton ) {
01037 #if defined(_WS_X11_)
01038 insert( QApplication::clipboard()->text() );
01039 #else
01040 if ( style() == MotifStyle )
01041 insert( QApplication::clipboard()->text() );
01042 #endif
01043 return;
01044 }
01045 #endif
01046
01047 if ( e->button() != LeftButton )
01048 return;
01049
01050 int margin = frame() ? frameW()*2 : 2;
01051 if ( !QRect( margin, margin,
01052 width() - 2*margin,
01053 height() - 2*margin ).contains( e->pos() ) )
01054 return;
01055
01056 int mousePos = xPosToCursorPos( e->pos().x() );
01057 int m1 = markDrag;
01058 newMark( mousePos, FALSE );
01059 repaintArea( m1, mousePos );
01060 }
01061
01062
01065 void ScrollableLineEdit::mouseDoubleClickEvent( QMouseEvent * )
01066 {
01067 d->inDoubleClick = TRUE;
01068 dragScrolling = FALSE;
01069 if ( echoMode() == Password )
01070 selectAll();
01071 else
01072 markWord( cursorPos );
01073 }
01074
01080 void ScrollableLineEdit::cursorLeft( bool mark, int steps )
01081 {
01082 cursorRight( mark, -steps );
01083 }
01084
01090 void ScrollableLineEdit::cursorRight( bool mark, int steps )
01091 {
01092 int cp = cursorPos + steps;
01093 cp = QMAX( cp, 0 );
01094 cp = QMIN( cp, (int)tbuf.length() );
01095 if ( cp == cursorPos ) {
01096 if ( !mark )
01097 deselect();
01098 } else if ( mark ) {
01099 newMark( cp );
01100 blinkOn();
01101 } else {
01102 setCursorPosition( cp );
01103 setSelection( cp, 0 );
01104 }
01105 }
01106
01114 void ScrollableLineEdit::backspace()
01115 {
01116 if ( hasMarkedText() ) {
01117 del();
01118 } else if ( cursorPos > 0 ) {
01119 if ( d->undo && d->needundo && !d->ignoreUndoWithDel ) {
01120 if ( d->undoList.isEmpty() || d->undoList.last().str != tbuf ) {
01121 d->undoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
01122 d->redoList.clear();
01123 }
01124 }
01125 cursorLeft( FALSE );
01126 del();
01127 }
01128 }
01129
01137 void ScrollableLineEdit::del()
01138 {
01139 QString test( tbuf);
01140 d->ignoreUndoWithDel = TRUE;
01141 if ( d->undo && ( (d->needundo && !d->ignoreUndoWithDel) || hasMarkedText() ) ) {
01142 if ( d->undoList.isEmpty() || d->undoList.last().str != tbuf ) {
01143 d->undoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
01144 d->redoList.clear();
01145 }
01146 }
01147
01148 if ( hasMarkedText() ) {
01149 test.remove( minMark(), maxMark() - minMark() );
01150 validateAndSet( test, minMark(), minMark(), minMark() );
01151 } else if ( cursorPos != (int)tbuf.length() ) {
01152 test.remove( cursorPos, 1 );
01153 validateAndSet( test, cursorPos, 0, 0 );
01154 }
01155 }
01156
01163 void ScrollableLineEdit::home( bool mark )
01164 {
01165 cursorRight( mark, -cursorPos );
01166 }
01167
01175 void ScrollableLineEdit::end( bool mark )
01176 {
01177 cursorRight( mark, tbuf.length()-cursorPos );
01178 }
01179
01180
01181 void ScrollableLineEdit::newMark( int pos, bool )
01182 {
01183 if ( markDrag != pos || cursorPos != pos )
01184 d->pmDirty = TRUE;
01185 markDrag = pos;
01186 setCursorPosition( pos );
01187 #ifndef QT_NO_CLIPBOARD
01188 #if defined(_WS_X11_)
01189 if ( c )
01190 copy();
01191 #endif
01192 #endif
01193 }
01194
01195
01196 void ScrollableLineEdit::markWord( int pos )
01197 {
01198 int i = pos - 1;
01199 while ( i >= 0 && tbuf[i].isPrint() && !tbuf[i].isSpace() )
01200 i--;
01201 i++;
01202 int newAnchor = i;
01203
01204 i = pos;
01205 while ( tbuf[i].isPrint() && !tbuf[i].isSpace() )
01206 i++;
01207 if ( style() != MotifStyle ) {
01208 while( tbuf[i].isSpace() )
01209 i++;
01210 setCursorPosition( i );
01211 }
01212 int newDrag = i;
01213 setSelection( newAnchor, newDrag - newAnchor );
01214
01215 #ifndef QT_NO_CLIPBOARD
01216 #if defined(_WS_X11_)
01217 copy();
01218 #endif
01219 #endif
01220 }
01221
01222 #ifndef QT_NO_CLIPBOARD
01223
01230 void ScrollableLineEdit::copy() const
01231 {
01232 QString t = markedText();
01233 if ( !t.isEmpty() && echoMode() == Normal ) {
01234 disconnect( QApplication::clipboard(), SIGNAL(dataChanged()), this, 0);
01235 QApplication::clipboard()->setText( t );
01236 connect( QApplication::clipboard(), SIGNAL(dataChanged()),
01237 this, SLOT(clipboardChanged()) );
01238 }
01239 }
01240
01251 void ScrollableLineEdit::paste()
01252 {
01253 insert( QApplication::clipboard()->text() );
01254 }
01255
01266 void ScrollableLineEdit::cut()
01267 {
01268 QString t = markedText();
01269 if ( !t.isEmpty() ) {
01270 copy();
01271 del();
01272 }
01273 }
01274
01275 #endif
01276
01282 void ScrollableLineEdit::setAlignment( int flag ){
01283 if ( flag == alignmentFlag )
01284 return;
01285 if ( flag == Qt::AlignRight ||
01286 flag == Qt::AlignCenter ||
01287 flag == Qt::AlignHCenter ||
01288 flag == Qt::AlignLeft ) {
01289 alignmentFlag = flag;
01290 updateOffset();
01291 update();
01292 }
01293 }
01294
01302 int ScrollableLineEdit::alignment() const
01303 {
01304 return alignmentFlag;
01305 }
01306
01312 void ScrollableLineEdit::clipboardChanged()
01313 {
01314 #if defined(_WS_X11_)
01315 disconnect( QApplication::clipboard(), SIGNAL(dataChanged()),
01316 this, SLOT(clipboardChanged()) );
01317 deselect();
01318 #endif
01319 }
01320
01321 int ScrollableLineEdit::lastCharVisible() const
01322 {
01323 int tDispWidth = width() - (frameW()*2 + 4);
01324 return xPosToCursorPos( tDispWidth );
01325 }
01326
01327
01328 int ScrollableLineEdit::minMark() const
01329 {
01330 return markAnchor < markDrag ? markAnchor : markDrag;
01331 }
01332
01333
01334 int ScrollableLineEdit::maxMark() const
01335 {
01336 return markAnchor > markDrag ? markAnchor : markDrag;
01337 }
01338
01339
01340
01350 void ScrollableLineEdit::setFrame( bool enable )
01351 {
01352 if ( d->frame == enable )
01353 return;
01354
01355 d->frame = enable;
01356 d->pmDirty = TRUE;
01357 updateOffset();
01358 update();
01359 }
01360
01361
01370 bool ScrollableLineEdit::frame() const
01371 {
01372 return d ? d->frame : TRUE;
01373 }
01374
01375 int ScrollableLineEdit::frameW() const
01376 {
01377 return frame() ? style().defaultFrameWidth() : 0;
01378 }
01379
01399 void ScrollableLineEdit::setEchoMode( EchoMode mode )
01400 {
01401 if ( d->mode == mode )
01402 return;
01403
01404 d->mode = mode;
01405 d->pmDirty = TRUE;
01406 updateOffset();
01407 update();
01408 }
01409
01410
01417 ScrollableLineEdit::EchoMode ScrollableLineEdit::echoMode() const
01418 {
01419 return d->mode;
01420 }
01421
01429 void ScrollableLineEdit::setReadOnly( bool enable )
01430 {
01431 d->readonly = enable;
01432 }
01433
01438 bool ScrollableLineEdit::isReadOnly() const
01439 {
01440 return d->readonly;
01441 }
01442
01443
01444
01450 QSize ScrollableLineEdit::sizeHint() const
01451 {
01452 constPolish();
01453 QFontMetrics fm( font() );
01454 int h = fm.height();
01455 int w = fm.width( 'x' ) * 17;
01456 if ( frame() ) {
01457 h += 4 + frameW()*2;
01458 if ( style() == WindowsStyle && h < 26 )
01459 h = 22;
01460 return QSize( w + 4 + frameW()*2, h ).expandedTo( QApplication::globalStrut() );
01461 } else {
01462 return QSize( w + 4, h + 4 ).expandedTo( QApplication::globalStrut() );
01463 }
01464 }
01465
01466
01467
01474 QSize ScrollableLineEdit::minimumSizeHint() const
01475 {
01476 constPolish();
01477 QFontMetrics fm( font() );
01478 int h = fm.height();
01479 int w = fm.maxWidth();
01480 if ( frame() ) {
01481 h += 4 + frameW()*2;
01482 if ( style() == WindowsStyle && h < 26 )
01483 h = 22;
01484 return QSize( w + 4 + frameW()*2, h );
01485 } else {
01486 return QSize( w + 4, h + 4 );
01487 }
01488 }
01489
01490
01491
01494 QSizePolicy ScrollableLineEdit::sizePolicy() const
01495 {
01496
01497 return QWidget::sizePolicy();
01498 }
01499
01500
01511 void ScrollableLineEdit::setValidator( const QValidator * v )
01512 {
01513 d->validator = v;
01514 }
01515
01523 const QValidator * ScrollableLineEdit::validator() const
01524 {
01525 return d ? d->validator : 0;
01526 }
01527
01528
01531 void ScrollableLineEdit::clearValidator()
01532 {
01533 setValidator( 0 );
01534 }
01535
01536 #ifndef QT_NO_DRAGANDDROP
01537
01540 void ScrollableLineEdit::dragEnterEvent( QDragEnterEvent *e )
01541 {
01542 if ( !d->readonly && QTextDrag::canDecode(e) )
01543 e->accept( rect() );
01544 }
01545
01546
01549 void ScrollableLineEdit::dropEvent( QDropEvent *e )
01550 {
01551 QString str;
01552 QCString plain = "plain";
01553
01554
01555 bool decoded = QTextDrag::decode(e, str, plain);
01556
01557 if (! decoded) decoded = QTextDrag::decode(e, str);
01558
01559 if ( !d->readonly && decoded) {
01560 if ( e->source() == this && hasMarkedText() )
01561 del();
01562 if ( !hasMarkedText() )
01563 setCursorPosition( xPosToCursorPos(e->pos().x()) );
01564 insert( str );
01565 e->accept();
01566 } else {
01567 e->ignore();
01568 }
01569 }
01570
01571 #endif // QT_NO_DRAGANDDROP
01572
01575 void ScrollableLineEdit::blinkSlot()
01576 {
01577 if ( hasFocus() || cursorOn ) {
01578 cursorOn = !cursorOn;
01579 if ( d->pm && !d->pmDirty && d->cursorRepaintRect.isValid() )
01580 repaint( d->cursorRepaintRect, FALSE );
01581 else
01582 repaint( FALSE );
01583 }
01584 if ( hasFocus() )
01585 d->blinkTimer.start( QApplication::cursorFlashTime()/2, TRUE );
01586 else
01587 d->blinkTimer.stop();
01588 }
01589
01590
01593 void ScrollableLineEdit::dragScrollSlot()
01594 {
01595 if ( !hasFocus() || !dragScrolling )
01596 d->dragTimer.stop();
01597 else if ( scrollingLeft )
01598 cursorLeft( TRUE );
01599 else
01600 cursorRight( TRUE );
01601 }
01602
01603
01615 bool ScrollableLineEdit::validateAndSet( const QString &newText, int newPos,
01616 int newMarkAnchor, int newMarkDrag )
01617 {
01618 QString t( newText );
01619 for ( uint i=0; i<t.length(); i++ ) {
01620 if ( t[(int)i] < ' ' )
01621 t[(int)i] = ' ';
01622 }
01623 t.truncate( maxLength() );
01624 #ifndef QT_NO_VALIDATOR
01625 const QValidator * v = validator();
01626
01627 if ( v && v->validate( t, newPos ) == QValidator::Invalid &&
01628 v->validate( tbuf, cursorPos ) != QValidator::Invalid ) {
01629 return FALSE;
01630 }
01631 #endif
01632 bool tc = ( t != tbuf );
01633
01634
01635 if ( newMarkDrag != markDrag ||
01636 newMarkAnchor != markAnchor ||
01637 newPos != cursorPos ||
01638 tc ) {
01639 int minP = QMIN( cursorPos, minMark() );
01640 int maxP = QMAX( cursorPos, maxMark() );
01641
01642 cursorPos = newPos;
01643 markAnchor = newMarkAnchor;
01644 markDrag = newMarkDrag;
01645
01646 minP = QMIN( minP, QMIN( cursorPos, minMark() ) );
01647 int i = 0;
01648 while( i < minP && t[i] == tbuf[i] )
01649 i++;
01650 minP = i;
01651
01652 maxP = QMAX( maxP, QMAX( cursorPos, maxMark() ) );
01653 if ( fontMetrics().width( t ) < fontMetrics().width( tbuf ) )
01654 maxP = t.length();
01655 tbuf = t;
01656
01657 if ( cursorPos < (int)text().length() && maxP < (int)text().length() )
01658 maxP = text().length();
01659
01660 repaintArea( minP, maxP );
01661 }
01662 if ( tc ) {
01663 ed = TRUE;
01664 emit textChanged( tbuf );
01665 }
01666 return TRUE;
01667 }
01668
01669
01676 void ScrollableLineEdit::insert( const QString &newText )
01677 {
01678 QString t( newText );
01679 if ( t.isEmpty() && !hasMarkedText() )
01680 return;
01681
01682 for ( int i=0; i<(int)t.length(); i++ )
01683 if ( t[i] < ' ' )
01684 t[i] = ' ';
01685
01686 QString test( tbuf );
01687 int cp = cursorPos;
01688 if ( d->undo && ( d->needundo || hasMarkedText() ) ) {
01689 if ( d->undoList.isEmpty() || d->undoList.last().str != tbuf ) {
01690 d->undoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
01691 d->redoList.clear();
01692 d->needundo = FALSE;
01693 }
01694 }
01695 if ( hasMarkedText() ) {
01696 test.remove( minMark(), maxMark() - minMark() );
01697 cp = minMark();
01698 }
01699 test.insert( cp, t );
01700 int ncp = QMIN( cp+t.length(), (uint)maxLength() );
01701 blinkOn();
01702 validateAndSet( test, ncp, ncp, ncp );
01703 }
01704
01705
01709 void ScrollableLineEdit::repaintArea( int from, int to )
01710 {
01711 QString buf = displayText();
01712
01713 int a, b;
01714 if ( from < to ) {
01715 a = from;
01716 b = to;
01717 } else {
01718 a = to;
01719 b = from;
01720 }
01721
01722 d->pmDirty = TRUE;
01723 int old = offset;
01724 if ( d->offsetDirty || cursorPos >= a && cursorPos <= b )
01725 updateOffset();
01726 if ( !d->pmDirty ) {
01727 return;
01728 } else if ( old != offset ) {
01729 repaint( FALSE );
01730 return;
01731 }
01732
01733 QFontMetrics fm = fontMetrics();
01734 int x = fm.width( buf.left( a ) ) + offset - 2 + frameW();
01735 QRect r( x, 0, fm.width( buf.mid( a, b-a ) ) + 5, height() );
01736 r = r.intersect( rect() );
01737 if ( !r.isValid() )
01738 return;
01739 if ( b >= (int)buf.length() )
01740 r.setRight( width() );
01741 repaint( r, FALSE );
01742 }
01743
01744
01747 void ScrollableLineEdit::setEnabled( bool e )
01748 {
01749 d->pmDirty = TRUE;
01750 QWidget::setEnabled( e );
01751 }
01752
01753
01756 void ScrollableLineEdit::setFont( const QFont & f )
01757 {
01758 d->pmDirty = TRUE;
01759 d->offsetDirty = TRUE;
01760 QWidget::setFont( f );
01761 }
01762
01763
01768 void ScrollableLineEdit::clear()
01769 {
01770 setText( QString::fromLatin1("") );
01771 }
01772
01773
01777 void ScrollableLineEdit::setSelection( int start, int length )
01778 {
01779 int b, e;
01780 b = QMIN( markAnchor, markDrag );
01781 e = QMAX( markAnchor, markDrag );
01782 b = QMIN( b, start );
01783 e = QMAX( e, start + length );
01784 markAnchor = start;
01785 markDrag = start + length;
01786 repaintArea( b, e );
01787 }
01788
01789
01793 void ScrollableLineEdit::setCursorPosition( int newPos )
01794 {
01795 if ( newPos == cursorPos )
01796 return;
01797 newPos = QMIN( newPos, (int)tbuf.length() );
01798 newPos = QMAX( newPos, 0 );
01799 int b, e;
01800 b = QMIN( newPos, cursorPos );
01801 e = QMAX( newPos, cursorPos );
01802 cursorPos = newPos;
01803 blinkOn();
01804 repaintArea( b, e );
01805 }
01806
01807
01811 int ScrollableLineEdit::cursorPosition() const
01812 {
01813 return cursorPos;
01814 }
01815
01816
01819 void ScrollableLineEdit::setPalette( const QPalette & p )
01820 {
01821 d->pmDirty = TRUE;
01822 QWidget::setPalette( p );
01823 }
01824
01825
01839 void ScrollableLineEdit::setEdited( bool on )
01840 {
01841 ed = on;
01842 }
01843
01844
01854 bool ScrollableLineEdit::edited() const
01855 {
01856 return ed;
01857 }
01858
01864 void ScrollableLineEdit::cursorWordForward( bool mark )
01865 {
01866 int i = cursorPos;
01867 while ( i < (int) tbuf.length() && !tbuf[i].isSpace() )
01868 ++i;
01869 while ( i < (int) tbuf.length() && tbuf[i].isSpace() )
01870 ++i;
01871 cursorRight( mark, i - cursorPos );
01872 }
01873
01874
01880 void ScrollableLineEdit::cursorWordBackward( bool mark )
01881 {
01882 int i = cursorPos;
01883 while ( i > 0 && tbuf[i-1].isSpace() )
01884 --i;
01885 while ( i > 0 && !tbuf[i-1].isSpace() )
01886 --i;
01887 cursorLeft( mark, cursorPos - i );
01888 }
01889
01890
01891 void ScrollableLineEdit::updateOffset()
01892 {
01893 if ( !isVisible() ) {
01894 d->offsetDirty = TRUE;
01895 return;
01896 }
01897 d->offsetDirty = FALSE;
01898 makePixmap();
01899 QFontMetrics fm = fontMetrics();
01900 int textWidth = fm.width( displayText() )+4;
01901 int w = d->pm->width();
01902 int old = offset;
01903
01904 if ( textWidth > w ) {
01905
01906 QString dt = displayText();
01907 dt += QString::fromLatin1( " " );
01908 dt = dt.left( cursorPos + 2 );
01909 if ( cursorPos < 3 )
01910 offset = 0;
01911 else if ( fm.width( dt.left( cursorPos - 2 ) ) + offset < 0 )
01912 offset = -fm.width( dt.left( cursorPos - 2 ) );
01913 else if ( fm.width( dt ) + offset > w )
01914 offset = w - fm.width( dt );
01915 } else {
01916 if ( textWidth < 5 ) {
01917
01918 textWidth = QMIN( 5, w );
01919 }
01920 if ( alignmentFlag == Qt::AlignRight ) {
01921
01922 offset = w - textWidth;
01923 } else if ( alignmentFlag == Qt::AlignCenter || alignmentFlag == Qt::AlignHCenter ) {
01924
01925 offset = (w - textWidth)/2;
01926 } else {
01927
01928 offset = 0;
01929 }
01930 }
01931
01932 if ( old == offset && !d->pmDirty )
01933 return;
01934
01935 d->pmDirty = TRUE;
01936 }
01937
01938
01943 int ScrollableLineEdit::xPosToCursorPos( int goalx ) const
01944 {
01945 int x1, x2;
01946 x1 = offset;
01947 int i = 0;
01948 QFontMetrics fm = fontMetrics();
01949 QString s = displayText();
01950 goalx -= (frameW() + 2);
01951
01952 while( i < (int) s.length() ) {
01953 x2 = x1 + fm.width( s[i] );
01954 if ( QABS( x1 - goalx ) < QABS( x2 - goalx ) )
01955 return i;
01956 i++;
01957 x1 = x2;
01958 }
01959 return i;
01960 }
01961
01962
01965 void ScrollableLineEdit::blinkOn()
01966 {
01967 if ( !hasFocus() )
01968 return;
01969
01970 d->blinkTimer.start( cursorOn?QApplication::cursorFlashTime() / 2 : 0, TRUE );
01971 blinkSlot();
01972 }
01973
01974
01975 void ScrollableLineEdit::makePixmap() const
01976 {
01977 if ( d->pm )
01978 return;
01979
01980 QSize s( width() - frameW()*2, height() - frameW()*2 );
01981 if ( s.width() < 0 )
01982 s.setWidth( 0 );
01983 if ( s.height() < 0 )
01984 s.setHeight( 0 );
01985 d->pm = new QPixmap( s );
01986 d->pmDirty = TRUE;
01987 }
01988
01989
01990 void ScrollableLineEdit::undoInternal()
01991 {
01992 if ( d->undoList.isEmpty() )
01993 return;
01994 d->undo = FALSE;
01995
01996 d->redoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
01997 setText( d->undoList.last().str );
01998 setCursorPosition( d->undoList.last().pos );
01999 markAnchor = cursorPos;
02000 d->undoList.remove( d->undoList.fromLast() );
02001 if ( d->undoList.count() > 10 )
02002 d->undoList.remove( d->undoList.begin() );
02003 d->undo = TRUE;
02004 d->needundo = TRUE;
02005 }
02006
02007 void ScrollableLineEdit::redoInternal()
02008 {
02009 if ( d->redoList.isEmpty() )
02010 return;
02011 d->undo = FALSE;
02012 d->undoList += ScrollableLineEditUndoItem(tbuf, cursorPos );
02013 setText( d->redoList.last().str );
02014 setCursorPosition( d->redoList.last().pos );
02015 markAnchor = cursorPos;
02016 d->redoList.remove( d->redoList.fromLast() );
02017 d->undo = TRUE;
02018 d->needundo = TRUE;
02019 }
02020 #endif
02021
02022
02023 #if defined(Q_INCOMPATIBLE_3_0_ADDONS)
02024 bool ScrollableLineEdit::getSelection( int *start, int *end )
02025 {
02026 if( !hasMarkedText() )
02027 return false;
02028
02029 *start = minMark();
02030 *end = maxMark();
02031 return true;
02032 }
02033
02034 void ScrollableLineEdit::setPasswordChar( QChar c )
02035 {
02036 d->passwordChar = c;
02037 }
02038
02039 QChar ScrollableLineEdit::passwordChar() const
02040 {
02041 return d->passwordChar;
02042 }
02043
02044 #endif
02045
02046
02047 void ScrollableLineEdit::scrollLeft() {
02048 int firstCharPos = xPosToCursorPos( 0 );
02049 setCursorPosition( firstCharPos );
02050 }
02051
02052 void ScrollableLineEdit::scrollRight() {
02053 int lastCharPos = lastCharVisible();
02054 setCursorPosition( lastCharPos );
02055 }
02056
02057 void ScrollableLineEdit::keyReleaseEvent( QKeyEvent *e ) {
02058 if ( e->state() & ControlButton ) {
02059 switch ( e->key() ) {
02060 #ifndef QT_NO_CLIPBOARD
02061 case Key_C:
02062 copy();
02063 break;
02064 case Key_V:
02065 if ( !d->readonly )
02066 insert( QApplication::clipboard()->text() );
02067 break;
02068 case Key_X:
02069 if ( !d->readonly && hasMarkedText() && echoMode() == Normal ) {
02070 copy();
02071 del();
02072 }
02073 break;
02074 #endif
02075 }
02076 }
02077 QWidget::keyReleaseEvent( e );
02078 }