📄 qlineedit.cpp
字号:
/************************************************************************ $Id: qt/src/widgets/qlineedit.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QLineEdit widget class**** Created : 941011**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qlineedit.h"#ifndef QT_NO_LINEEDIT#include "qpainter.h"#include "qdrawutil.h"#include "qfontmetrics.h"#include "qpixmap.h"#include "qclipboard.h"#include "qapplication.h"#include "qvalidator.h"#include "qdragobject.h"#include "qtimer.h"#include "qpopupmenu.h"#include "qstringlist.h"#include "qguardedptr.h"#include <ctype.h>#if defined( _WS_QWS_ ) && !defined( QT_NO_QWS_IM )#include "qwsdisplay_qws.h"#endif#ifndef QT_NO_QWS_IM#include "../kernel/qinputcontext_p.h"#endif#ifdef QT_KEYPAD_MODEextern bool qt_modalEditingEnabled;#endifstruct QLineEditUndoItem{ QLineEditUndoItem(){pos=0;}; QLineEditUndoItem( const QString& s, int p ) : str(s),pos(p){}#if defined(Q_FULL_TEMPLATE_INSTANTIATION) bool operator==( const QLineEditUndoItem& ) const { return FALSE; }#endif QString str; int pos;};enum { IdUndo, IdRedo,#ifndef QT_NO_CLIPBOARD IdCut, IdCopy, IdPaste,#endif IdClear, IdSelectAll};struct QLineEditPrivate { QLineEditPrivate( QLineEdit * l ): frame(TRUE), mode(QLineEdit::Normal), readonly(FALSE), validator( 0 ), pm(0), pmDirty( TRUE ), blinkTimer( l, "QLineEdit blink timer" ), dragTimer( l, "QLineEdit drag timer" ), dndTimer( l, "DnD Timer" ), inDoubleClick( FALSE ), offsetDirty( FALSE ), undo(TRUE), needundo( FALSE ), ignoreUndoWithDel( FALSE ), mousePressed( FALSE ), dnd_primed( FALSE ), passwordChar( '*' )#ifndef QT_NO_QWS_IM ,preeditStart(-1), preeditLength( 0 ), preeditCPos(-1), preeditSelLen(0)#endif#ifdef QT_KEYPAD_MODE ,deleteAllTimerId(-1)#endif#ifdef _WS_QWS_ ,resumePassword( FALSE )#endif {} bool frame; QLineEdit::EchoMode mode; bool readonly; const QValidator * validator; QPixmap * pm; bool pmDirty; QTimer blinkTimer; QTimer dragTimer, dndTimer; QRect cursorRepaintRect; bool inDoubleClick; bool offsetDirty; QValueList<QLineEditUndoItem> undoList; QValueList<QLineEditUndoItem> redoList; bool undo; bool needundo; bool ignoreUndoWithDel; bool mousePressed; QPoint dnd_startpos; bool dnd_primed; QChar passwordChar;#ifndef QT_NO_QWS_IM int preeditStart; int preeditLength; int preeditCPos; int preeditSelLen;#endif#ifdef QT_KEYPAD_MODE QString orgTxt; int deleteAllTimerId;#endif#ifdef _WS_QWS_ bool resumePassword;#endif};static bool inBlinkOn = FALSE;#ifndef QT_NO_QWS_IMextern QBrush *qt_im_compose_background;#endif// REVISED: arnt/*! \class QLineEdit qlineedit.h \brief The QLineEdit widget is a one-line text editor. \ingroup basic A line edit allows the user to enter and edit a single line of plain text, with a useful collection of editing functions, including undo & redo, cut & paste, and drag & drop. By changing the echoMode() of a line edit it can also be used as a "write-only" field, for inputs such as passwords. The length of the field can be constrained to a maxLength(), or the value can be arbitrarily constrained by setting a validator(). A closely related class is QMultiLineEdit which allows multi-line editing. The default QLineEdit object has its own frame as specified by the Windows/Motif style guides, you can turn off the frame by calling setFrame( FALSE ). The default key bindings are described in keyPressEvent(). A right-mouse-button menu presents a number of the editing commands to the user. <img src=qlined-m.png> <img src=qlined-w.png> \sa QMultiLineEdit QLabel QComboBox <a href="guibooks.html#fowler">GUI Design Handbook: Field, Entry,</a> <a href="guibooks.html#fowler">GUI Design Handbook: Field, Required.</a>*//*! \enum QLineEdit::EchoMode This enum type describes how QLineEdit displays its contents. The defined values are: <ul> <li> \c Normal - display characters as they are entered. This is the default. <li> \c NoEcho - do not display anything. This may be appropriate for passwords where even the length of the password should be kept secret. <li> \c Password - display asterisks instead of the characters actually entered. </ul> \sa setEchoMode() echoMode() QMultiLineEdit::EchoMode*//*! \fn void QLineEdit::textChanged( const QString& ) This signal is emitted every time the text changes. The argument is the new text.*/static const int scrollTime = 40; // mark text scroll time/*! Constructs a line edit with no text. The maximum text length is set to 32767 characters. The \e parent and \e name arguments are sent to the QWidget constructor. \sa setText(), setMaxLength()*/QLineEdit::QLineEdit( QWidget *parent, const char *name ) : QWidget( parent, name, WRepaintNoErase ){ init();}/*! Constructs a line edit containing the text \a contents. The cursor position is set to the end of the line and the maximum text length to 32767 characters. The \e parent and \e name arguments are sent to the QWidget constructor. \sa text(), setMaxLength()*/QLineEdit::QLineEdit( const QString & contents, QWidget *parent, const char *name ) : QWidget( parent, name ){ init(); setText( contents );}/*! Destructs the line edit.*/QLineEdit::~QLineEdit(){ if ( d->pm ) delete d->pm; delete d;}/*! Contains initialization common to both constructors. */void QLineEdit::init(){ d = new QLineEditPrivate( this ); connect( &d->blinkTimer, SIGNAL(timeout()), this, SLOT(blinkSlot()) ); connect( &d->dragTimer, SIGNAL(timeout()), this, SLOT(dragScrollSlot()) );#ifndef QT_NO_DRAGANDDROP connect( &d->dndTimer, SIGNAL(timeout()), this, SLOT(doDrag()) );#endif cursorPos = 0; offset = 0; maxLen = 32767; cursorOn = TRUE; markAnchor = 0; markDrag = 0; dragScrolling = FALSE; scrollingLeft = FALSE; tbuf = QString::fromLatin1(""); setFocusPolicy( StrongFocus );#ifndef QT_NO_CURSOR setCursor( ibeamCursor );#endif setBackgroundMode( PaletteBase ); setKeyCompression( TRUE ); alignmentFlag = Qt::AlignLeft; setAcceptDrops( TRUE ); // Specifies that this widget can use more, but is able to survive on // less, horizontal space; and is fixed vertically. setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); ed = FALSE;}/*! Sets the line edit text to \e text, clears the selection and moves the cursor to the end of the line. If necessary the text is truncated to maxLength(). \sa text()*/void QLineEdit::setText( const QString &text ){#ifndef QT_NO_QWS_IM forceIMEnd();#endif QString oldText( tbuf ); tbuf = text; if ( (int)tbuf.length() > maxLen ) tbuf.truncate( maxLen ); offset = 0; cursorPos = 0; markAnchor = 0; markDrag = 0;#ifdef QT_KEYPAD_MODE // In keypad mode, we can show the start (most meaningful) // since we go to the end as modal mode is entered. if ( qt_modalEditingEnabled && !isModalEditing() ) home( FALSE ); else#endif end( FALSE );#ifndef QT_NO_VALIDATOR if ( validator() ) (void)validator()->validate( tbuf, cursorPos );#endif d->pmDirty = TRUE; update(); if ( d->undo ) { d->undoList.clear(); d->redoList.clear(); d->needundo = TRUE; } if ( oldText != tbuf ) emit textChanged( tbuf );}/*! Selects all text (i.e. marks it) and moves the cursor to the end. This is useful when a default value has been inserted, since if the user types before clicking on the widget the selected text will be erased.*/void QLineEdit::selectAll(){ setSelection( 0, tbuf.length() ); end( TRUE );}/*! Deselects all text (i.e. removes marking) and leaves the cursor at the current position.*/void QLineEdit::deselect(){ setSelection( cursorPos, 0 );}/*! Returns the text in the line. \sa setText()*/QString QLineEdit::text() const{ return tbuf;}#if defined (_WS_QWS_)bool qt_lineedit_password_visible_on_focus = FALSE;#endif/*! Returns the text that is displayed. This is normallythe same as text(), but can be e.g. "*****" if EchoMode is Password or"" if it is NoEcho.\sa setEchoMode() text() EchoMode*/QString QLineEdit::displayText() const{ QString res; switch( echoMode() ) { case Normal: res = tbuf; break; case NoEcho: res = QString::fromLatin1(""); break; case Password: res.fill( d->passwordChar, tbuf.length() ); break; } return res;}/*! Returns TRUE if part of the text has been marked by the user (e.g. by clicking and dragging). \sa markedText()*/bool QLineEdit::hasMarkedText() const{ return markAnchor != markDrag;}/*! Returns the text marked by the user (e.g. by clicking and dragging), or a \link QString::operator!() null string\endlink if no text is marked. \sa hasMarkedText()*/QString QLineEdit::markedText() const{ return tbuf.mid( minMark(), maxMark() - minMark() );}/*! Returns the maximum permitted length of the text in the editor. \sa setMaxLength()*/int QLineEdit::maxLength() const{ return maxLen;}/*! Set the maximum length of the text in the editor. If the text is too long, it is chopped off at the limit. Any marked text will be unmarked. The cursor position is set to 0 and the first part of the string is shown. \sa maxLength().*/void QLineEdit::setMaxLength( int m ){ maxLen = m; markAnchor = 0; markDrag = 0; if ( (int)tbuf.length() > maxLen ) { tbuf.truncate( maxLen ); d->pmDirty = TRUE; } setCursorPosition( 0 ); if ( d->pmDirty ) update();}/*! \fn void QLineEdit::returnPressed() This signal is emitted when the return or enter key is pressed.*//*! Converts a key press into a line edit action. If return or enter is pressed and the current text is valid (or can be \link QValidator::fixup() made valid\endlink by the validator), the signal returnPressed is emitted. The default key bindings are: <ul> <li><i> Left Arrow </i> Move the cursor one character leftwards. <li><i> Right Arrow </i> Move the cursor one character rightwards. <li><i> Backspace </i> Delete the character to the left of the cursor. <li><i> Home </i> Move the cursor to the beginning of the line. <li><i> End </i> Move the cursor to the end of the line. <li><i> Delete </i> Delete the character to the right of the cursor. <li><i> Shift - Left Arrow </i> Move and mark text one character leftwards. <li><i> Shift - Right Arrow </i> Move and mark text one character rightwards. <li><i> Control-A </i> Move the cursor to the beginning of the line. <li><i> Control-B </i> Move the cursor one character leftwards. <li><i> Control-C </i> Copy the marked text to the clipboard. <li><i> Control-D </i> Delete the character to the right of the cursor. <li><i> Control-E </i> Move the cursor to the end of the line. <li><i> Control-F </i> Move the cursor one character rightwards. <li><i> Control-H </i> Delete the character to the left of the cursor. <li><i> Control-K </i> Delete to end of line <li><i> Control-V </i> Paste the clipboard text into line edit. <li><i> Control-X </i> Move the marked text to the clipboard. <li><i> Control-Z </i> Undo the last operation. <li><i> Control-Y </i> Redo the last undone operation. </ul> In addition, the following key bindings are used on Windows: <ul> <li><i> Shift - Delete </i> Cut the marked text, copy to clipboard <li><i> Shift - Insert </i> Paste the clipboard text into line edit <li><i> Control - Insert </i> Copy the marked text to the clipboard </ul> All other keys with valid ASCII codes insert themselves into the line.*/void QLineEdit::keyPressEvent( QKeyEvent *e ){#ifdef QT_KEYPAD_MODE bool select = FALSE; switch( e->key() ) { case Key_Select: if( qt_modalEditingEnabled ) { if ( isModalEditing() ) { setModalEditing( FALSE ); select = TRUE; } } break; case Key_Back: case Key_No: if ( !qt_modalEditingEnabled || (qt_modalEditingEnabled && !isModalEditing()) ) { e->ignore(); return; } break; default: if( qt_modalEditingEnabled ) { if ( !isModalEditing() && !(e->state() & ControlButton) ) { if ( e->text()[0].isPrint() ) { setModalEditing( TRUE ); clear(); } else { e->ignore(); return; } } } }#endif#ifdef _WS_QWS_ if ( qt_lineedit_password_visible_on_focus && echoMode() == Password &&#ifdef QT_KEYPAD_MODE e->key() != Key_Select &&#endif e->key() != Key_Up && e->key() != Key_Down && !isReadOnly() ) { clear(); setEchoMode( Normal ); d->resumePassword = TRUE; }#endif#ifdef QT_KEYPAD_MODE if ( qt_modalEditingEnabled && !select && !isModalEditing() ) { setModalEditing( TRUE ); if ( e->key() == Key_Select ) return; // Just start. No action. }#endif#ifdef QT_KEYPAD_MODE select = e->key() == Key_Select;#endif if ( e->key() == Key_Enter || e->key() == Key_Return#ifdef QT_KEYPAD_MODE || select#endif ) {#ifdef QT_NO_VALIDATOR emit returnPressed(); e->ignore();#else const QValidator * v = validator(); if ( !v || v->validate( tbuf, cursorPos ) == QValidator::Acceptable ) { emit returnPressed(); e->ignore(); } else if ( v ) { QString old( tbuf ); v->fixup( tbuf ); if ( old != tbuf ) { d->pmDirty = TRUE; if ( cursorPos > (int)tbuf.length() ) cursorPos = tbuf.length(); update(); } if ( v->validate( tbuf, cursorPos ) == QValidator::Acceptable ) emit returnPressed(); e->ignore(); }#endif return; } if ( !d->readonly ) { QString t = e->text(); if ( !t.isEmpty() && (!e->ascii() || e->ascii()>=32) && e->key() != Key_Delete && e->key() != Key_Backspace ) { insert( t ); return; } } bool needundo = d->needundo; d->needundo = TRUE; bool ignoreUndoWithDel = d->ignoreUndoWithDel; d->ignoreUndoWithDel = FALSE; int unknown = 0; if ( e->state() & ControlButton ) { switch ( e->key() ) { case Key_A: home( e->state() & ShiftButton ); break; case Key_B: cursorLeft( e->state() & ShiftButton ); break;#ifndef QT_NO_CLIPBOARD case Key_C: copy(); break;#endif case Key_D: if ( !d->readonly ) { d->ignoreUndoWithDel = ignoreUndoWithDel; del();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -