1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the widgets module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qlineedit.h"
30
#include "qlineedit_p.h"
32
#ifndef QT_NO_LINEEDIT
34
#include "qapplication.h"
35
#include "qclipboard.h"
37
#include "qdrawutil.h"
39
#include "qfontmetrics.h"
44
#include "qstringlist.h"
46
#include "qstyleoption.h"
48
#include "qvalidator.h"
51
#include "qwhatsthis.h"
53
#include <private/qinternal_p.h>
54
#ifndef QT_NO_ACCESSIBILITY
55
#include "qaccessible.h"
57
#if defined(Q_WS_X11) || defined(Q_WS_QWS)
59
#include "qinputcontext.h"
65
#include "qkeysequence.h"
66
#define ACCEL_KEY(k) "\t" + QString(QKeySequence(Qt::CTRL | Qt::Key_ ## k))
68
#define ACCEL_KEY(k) "\t" + QString("Ctrl+" #k)
72
extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
79
QStyleOptionFrame QLineEditPrivate::getStyleOption() const
82
QStyleOptionFrame opt;
84
opt.palette = q->palette();
85
opt.lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
87
opt.state = QStyle::State_None | QStyle::State_Sunken;
93
\brief The QLineEdit widget is a one-line text editor.
98
A line edit allows the user to enter and edit a single line of
99
plain text with a useful collection of editing functions,
100
including undo and redo, cut and paste, and drag and drop.
102
By changing the echoMode() of a line edit, it can also be used as
103
a "write-only" field, for inputs such as passwords.
105
The length of the text can be constrained to maxLength(). The text
106
can be arbitrarily constrained using a validator() or an
107
inputMask(), or both.
109
A related class is QTextEdit which allows multi-line, rich text
112
You can change the text with setText() or insert(). The text is
113
retrieved with text(); the displayed text (which may be different,
114
see \l{EchoMode}) is retrieved with displayText(). Text can be
115
selected with setSelection() or selectAll(), and the selection can
116
be cut(), copy()ied and paste()d. The text can be aligned with
119
When the text changes the textChanged() signal is emitted; when
120
the text changes other than by calling setText() the textEdited()
121
signal is emitted; when the cursor is moved the
122
cursorPositionChanged() signal is emitted; and when the Return or
123
Enter key is pressed the returnPressed() signal is emitted.
125
When editing is finished, either because the line edit lost focus
126
or Return/Enter is pressed the editingFinished() signal is
129
Note that if there is a validator set on the line edit, the
130
returnPressed()/editingFinished() signals will only be emitted if
131
the validator returns \c Acceptable.
133
By default, QLineEdits have a frame as specified by the Windows
134
and Motif style guides; you can turn it off by calling
137
The default key bindings are described below. The line edit also
138
provides a context menu (usually invoked by a right mouse click)
139
that presents some of these editing options.
142
\header \i Keypress \i Action
143
\row \i Left Arrow \i Moves the cursor one character to the left.
144
\row \i Shift+Left Arrow \i Moves and selects text one character to the left.
145
\row \i Right Arrow \i Moves the cursor one character to the right.
146
\row \i Shift+Right Arrow \i Moves and selects text one character to the right.
147
\row \i Home \i Moves the cursor to the beginning of the line.
148
\row \i End \i Moves the cursor to the end of the line.
149
\row \i Backspace \i Deletes the character to the left of the cursor.
150
\row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
151
\row \i Delete \i Deletes the character to the right of the cursor.
152
\row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
153
\row \i Ctrl+A \i Moves the cursor to the beginning of the line.
154
\row \i Ctrl+B \i Moves the cursor one character to the left.
155
\row \i Ctrl+C \i Copies the selected text to the clipboard.
156
\row \i Ctrl+Insert \i Copies the selected text to the clipboard.
157
\row \i Ctrl+D \i Deletes the character to the right of the cursor.
158
\row \i Ctrl+E \i Moves the cursor to the end of the line.
159
\row \i Ctrl+F \i Moves the cursor one character to the right.
160
\row \i Ctrl+H \i Deletes the character to the left of the cursor.
161
\row \i Ctrl+K \i Deletes to the end of the line.
162
\row \i Ctrl+V \i Pastes the clipboard text into line edit.
163
\row \i Shift+Insert \i Pastes the clipboard text into line edit.
164
\row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
165
\row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
166
\row \i Ctrl+Z \i Undoes the last operation.
167
\row \i Ctrl+Y \i Redoes the last undone operation.
170
Any other key sequence that represents a valid character, will
171
cause the character to be inserted into the line edit.
173
\inlineimage macintosh-lineedit.png Screenshot in Macintosh style
174
\inlineimage windows-lineedit.png Screenshot in Windows style
176
\sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}
181
\fn void QLineEdit::textChanged(const QString &text)
183
This signal is emitted whenever the text changes. The \a text
184
argument is the new text.
186
Unlike textEdited(), this signal is also emitted when
187
programmatically setting the text via setText().
191
\fn void QLineEdit::textEdited(const QString &text)
193
This signal is emitted whenever the text is edited. The \a text
194
argument is the next text.
196
Unlike textChanged(), this signal is \e not emitted when
197
programmatically setting the text via setText().
201
\fn void QLineEdit::cursorPositionChanged(int old, int new)
203
This signal is emitted whenever the cursor moves. The previous
204
position is given by \a old, and the new position by \a new.
206
\sa setCursorPosition(), cursorPosition()
210
\fn void QLineEdit::selectionChanged()
212
This signal is emitted whenever the selection changes.
214
\sa hasSelectedText(), selectedText()
218
Constructs a line edit with no text.
220
The maximum text length is set to 32767 characters.
222
The \a parent argument is sent to the QWidget constructor.
224
\sa setText(), setMaxLength()
226
QLineEdit::QLineEdit(QWidget* parent)
227
: QWidget(*new QLineEditPrivate, parent,0)
234
Constructs a line edit containing the text \a contents.
236
The cursor position is set to the end of the line and the maximum
237
text length to 32767 characters.
239
The \a parent and argument is sent to the QWidget
242
\sa text(), setMaxLength()
244
QLineEdit::QLineEdit(const QString& contents, QWidget* parent)
245
: QWidget(*new QLineEditPrivate, parent, 0)
254
Constructs a line edit with no text.
256
The maximum text length is set to 32767 characters.
258
The \a parent and \a name arguments are sent to the QWidget constructor.
260
\sa setText(), setMaxLength()
262
QLineEdit::QLineEdit(QWidget* parent, const char* name)
263
: QWidget(*new QLineEditPrivate, parent,0)
271
Constructs a line edit containing the text \a contents.
273
The cursor position is set to the end of the line and the maximum
274
text length to 32767 characters.
276
The \a parent and \a name arguments are sent to the QWidget
279
\sa text(), setMaxLength()
282
QLineEdit::QLineEdit(const QString& contents, QWidget* parent, const char* name)
283
: QWidget(*new QLineEditPrivate, parent, 0)
291
Constructs a line edit with an input \a inputMask and the text \a
294
The cursor position is set to the end of the line and the maximum
295
text length is set to the length of the mask (the number of mask
296
characters and separators).
298
The \a parent and \a name arguments are sent to the QWidget
303
QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget* parent, const char* name)
304
: QWidget(*new QLineEditPrivate, parent, 0)
308
d->parseInputMask(inputMask);
310
QString ms = d->maskString(0, contents);
311
d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length()));
312
d->cursor = d->nextMaskBlank(ms.length());
320
Destroys the line edit.
323
QLineEdit::~QLineEdit()
329
\property QLineEdit::text
330
\brief the line edit's text
332
Setting this property clears the selection, clears the undo/redo
333
history, moves the cursor to the end of the line and resets the
334
\c modified property to false. The text is not validated when
335
inserted with setText().
337
The text is truncated to maxLength() length.
339
\sa insert(), clear()
341
QString QLineEdit::text() const
343
Q_D(const QLineEdit);
344
QString res = d->text;
346
res = d->stripString(d->text);
347
return (res.isNull() ? QString::fromLatin1("") : res);
350
void QLineEdit::setText(const QString& text)
353
d->setText(text, -1, false);
358
\property QLineEdit::displayText
359
\brief the displayed text
361
If \c EchoMode is \c Normal this returns the same as text(); if
362
\c EchoMode is \c Password it returns a string of asterisks
363
text().length() characters long, e.g. "******"; if \c EchoMode is
364
\c NoEcho returns an empty string, "".
366
\sa setEchoMode() text() EchoMode
369
QString QLineEdit::displayText() const
371
Q_D(const QLineEdit);
372
if (d->echoMode == NoEcho)
373
return QString::fromLatin1("");
374
QString res = d->text;
375
if (d->echoMode == Password) {
376
QStyleOptionFrame opt = d->getStyleOption();
377
res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
379
return (res.isNull() ? QString::fromLatin1("") : res);
384
\property QLineEdit::maxLength
385
\brief the maximum permitted length of the text
387
If the text is too long, it is truncated at the limit.
389
If truncation occurs any selected text will be unselected, the
390
cursor position is set to 0 and the first part of the string is
393
If the line edit has an input mask, the mask defines the maximum
399
int QLineEdit::maxLength() const
401
Q_D(const QLineEdit);
405
void QLineEdit::setMaxLength(int maxLength)
410
d->maxLength = maxLength;
417
\property QLineEdit::frame
418
\brief whether the line edit draws itself with a frame
420
If enabled (the default) the line edit draws itself inside a
421
frame, otherwise the line edit draws itself without any frame.
423
bool QLineEdit::hasFrame() const
425
Q_D(const QLineEdit);
430
void QLineEdit::setFrame(bool enable)
440
\enum QLineEdit::EchoMode
442
This enum type describes how a line edit should display its
445
\value Normal Display characters as they are entered. This is the
447
\value NoEcho Do not display anything. This may be appropriate
448
for passwords where even the length of the
449
password should be kept secret.
450
\value Password Display asterisks instead of the characters
453
\sa setEchoMode() echoMode()
458
\property QLineEdit::echoMode
459
\brief the line edit's echo mode
461
The initial setting is \c Normal, but QLineEdit also supports \c
462
NoEcho and \c Password modes.
464
The widget's display and the ability to copy or drag the text is
465
affected by this setting.
467
\sa EchoMode displayText()
470
QLineEdit::EchoMode QLineEdit::echoMode() const
472
Q_D(const QLineEdit);
473
return (EchoMode) d->echoMode;
476
void QLineEdit::setEchoMode(EchoMode mode)
479
if(mode == (EchoMode)d->echoMode)
482
d->updateTextLayout();
486
qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho);
493
Returns a pointer to the current input validator, or 0 if no
494
validator has been set.
499
const QValidator * QLineEdit::validator() const
501
Q_D(const QLineEdit);
506
Sets this line edit to only accept input that the validator, \a v,
507
will accept. This allows you to place any arbitrary constraints on
508
the text which may be entered.
510
If \a v == 0, setValidator() removes the current input validator.
511
The initial setting is to have no input validator (i.e. any input
512
is accepted up to maxLength()).
514
\sa validator() QIntValidator QDoubleValidator QRegExpValidator
517
void QLineEdit::setValidator(const QValidator *v)
520
d->validator = const_cast<QValidator*>(v);
526
Returns a recommended size for the widget.
528
The width returned, in pixels, is usually enough for about 15 to
532
QSize QLineEdit::sizeHint() const
534
Q_D(const QLineEdit);
536
QFontMetrics fm(font());
537
int h = qMax(fm.lineSpacing(), 14) + 2*innerMargin;
538
int w = fm.width('x') * 17; // "some"
539
int m = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth) : 0;
540
QStyleOptionFrame opt;
542
opt.palette = palette();
543
opt.state = QStyle::State_None;
544
return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w + m, h + m).
545
expandedTo(QApplication::globalStrut()), this));
550
Returns a minimum size for the line edit.
552
The width returned is enough for at least one character.
555
QSize QLineEdit::minimumSizeHint() const
557
Q_D(const QLineEdit);
559
QFontMetrics fm = fontMetrics();
560
int h = fm.height() + qMax(2*innerMargin, fm.leading());
561
int w = fm.maxWidth();
562
int m = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth) : 0;
563
return QSize(w + m, h + m);
568
\property QLineEdit::cursorPosition
569
\brief the current cursor position for this line edit
571
Setting the cursor position causes a repaint when appropriate.
574
int QLineEdit::cursorPosition() const
576
Q_D(const QLineEdit);
580
void QLineEdit::setCursorPosition(int pos)
586
if (pos <= d->text.length())
591
Returns the \c cursorPostion under the point \a pos.
593
// ### What should this do if the point is outside of contentsRect? Currently returns 0.
594
int QLineEdit::cursorPositionAt(const QPoint &pos)
597
return d->xToPos(pos.x());
604
Use setText(), setCursorPosition() and setSelection() instead.
606
bool QLineEdit::validateAndSet(const QString &newText, int newPos,
607
int newMarkAnchor, int newMarkDrag)
610
int priorState = d->undoState;
612
d->selend = d->text.length();
613
d->removeSelectedText();
615
d->finishChange(priorState);
616
if (d->undoState > priorState) {
618
d->selstart = qMin(newMarkAnchor, newMarkDrag);
619
d->selend = qMax(newMarkAnchor, newMarkDrag);
621
d->emitCursorPositionChanged();
629
\property QLineEdit::alignment
630
\brief the alignment of the line edit
632
Only horizontal alignments are allowed in here, Qt::AlignJustify
633
will map to Qt::AlignLeft.
638
Qt::Alignment QLineEdit::alignment() const
640
Q_D(const QLineEdit);
641
return QFlag(d->alignment);
644
void QLineEdit::setAlignment(Qt::Alignment alignment)
647
d->alignment = alignment & Qt::AlignHorizontal_Mask;
653
Moves the cursor forward \a steps characters. If \a mark is true
654
each character moved over is added to the selection; if \a mark is
655
false the selection is cleared.
660
void QLineEdit::cursorForward(bool mark, int steps)
663
int cursor = d->cursor;
666
cursor = d->textLayout.nextCursorPosition(cursor);
667
} else if (steps < 0) {
669
cursor = d->textLayout.previousCursorPosition(cursor);
671
d->moveCursor(cursor, mark);
676
Moves the cursor back \a steps characters. If \a mark is true each
677
character moved over is added to the selection; if \a mark is
678
false the selection is cleared.
682
void QLineEdit::cursorBackward(bool mark, int steps)
684
cursorForward(mark, -steps);
688
Moves the cursor one word forward. If \a mark is true, the word is
691
\sa cursorWordBackward()
693
void QLineEdit::cursorWordForward(bool mark)
696
d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
700
Moves the cursor one word backward. If \a mark is true, the word
703
\sa cursorWordForward()
706
void QLineEdit::cursorWordBackward(bool mark)
709
d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
714
If no text is selected, deletes the character to the left of the
715
text cursor and moves the cursor one position to the left. If any
716
text is selected, the cursor is moved to the beginning of the
717
selected text and the selected text is deleted.
721
void QLineEdit::backspace()
724
int priorState = d->undoState;
725
if (d->hasSelectedText()) {
726
d->removeSelectedText();
727
} else if (d->cursor) {
730
d->cursor = d->prevMaskBlank(d->cursor);
731
QChar uc = d->text.at(d->cursor);
732
if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
733
// second half of a surrogate, check if we have the first half as well,
734
// if yes delete both at once
735
uc = d->text.at(d->cursor - 1);
736
if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
743
d->finishChange(priorState);
747
If no text is selected, deletes the character to the right of the
748
text cursor. If any text is selected, the cursor is moved to the
749
beginning of the selected text and the selected text is deleted.
754
void QLineEdit::del()
757
int priorState = d->undoState;
758
if (d->hasSelectedText()) {
759
d->removeSelectedText();
761
int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor;
765
d->finishChange(priorState);
769
Moves the text cursor to the beginning of the line unless it is
770
already there. If \a mark is true, text is selected towards the
771
first position; otherwise, any selected text is unselected if the
777
void QLineEdit::home(bool mark)
780
d->moveCursor(0, mark);
784
Moves the text cursor to the end of the line unless it is already
785
there. If \a mark is true, text is selected towards the last
786
position; otherwise, any selected text is unselected if the cursor
792
void QLineEdit::end(bool mark)
795
d->moveCursor(d->text.length(), mark);
800
\property QLineEdit::modified
801
\brief whether the line edit's contents has been modified by the user
803
The modified flag is never read by QLineEdit; it has a default value
804
of false and is changed to true whenever the user changes the line
807
This is useful for things that need to provide a default value but
808
do not start out knowing what the default should be (perhaps it
809
depends on other fields on the form). Start the line edit without
810
the best default, and when the default is known, if modified()
811
returns false (the user hasn't entered any text), insert the
814
Calling setText() resets the modified flag to false.
817
bool QLineEdit::isModified() const
819
Q_D(const QLineEdit);
820
return d->modifiedState != d->undoState;
823
void QLineEdit::setModified(bool modified)
827
d->modifiedState = -1;
829
d->modifiedState = d->undoState;
833
/*!\fn QLineEdit::clearModified()
835
Use setModified(false) instead.
842
\property QLineEdit::hasSelectedText
843
\brief whether there is any text selected
845
hasSelectedText() returns true if some or all of the text has been
846
selected by the user; otherwise returns false.
852
bool QLineEdit::hasSelectedText() const
854
Q_D(const QLineEdit);
855
return d->hasSelectedText();
859
\property QLineEdit::selectedText
860
\brief the selected text
862
If there is no selected text this property's value is
865
\sa hasSelectedText()
868
QString QLineEdit::selectedText() const
870
Q_D(const QLineEdit);
871
if (d->hasSelectedText())
872
return d->text.mid(d->selstart, d->selend - d->selstart);
877
selectionStart() returns the index of the first selected character in the
878
line edit or -1 if no text is selected.
883
int QLineEdit::selectionStart() const
885
Q_D(const QLineEdit);
886
return d->hasSelectedText() ? d->selstart : -1;
893
\fn void QLineEdit::lostFocus()
895
This signal is emitted when the line edit has lost focus.
897
Use editingFinished() instead
898
\sa editingFinished(), returnPressed()
902
Use isModified() instead.
904
bool QLineEdit::edited() const { return isModified(); }
906
Use setModified() or setText().
908
void QLineEdit::setEdited(bool on) { setModified(on); }
911
There exists no equivalent functionality in Qt 4.
913
int QLineEdit::characterAt(int xpos, QChar *chr) const
915
Q_D(const QLineEdit);
916
int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + innerMargin);
917
if (chr && pos < (int) d->text.length())
918
*chr = d->text.at(pos);
924
Use selectedText() and selectionStart() instead.
926
bool QLineEdit::getSelection(int *start, int *end)
929
if (d->hasSelectedText() && start && end) {
930
*start = d->selstart;
940
Selects text from position \a start and for \a length characters.
941
Negative lengths are allowed.
943
\sa deselect() selectAll() selectedText()
946
void QLineEdit::setSelection(int start, int length)
949
if (start < 0 || start > (int)d->text.length()) {
950
qWarning("QLineEdit: Invalid start position: %d.", start);
955
d->selend = qMin(start + length, (int)d->text.length());
956
d->cursor = d->selend;
958
d->selstart = qMax(start + length, 0);
960
d->cursor = d->selstart;
964
d->emitCursorPositionChanged();
969
\property QLineEdit::undoAvailable
970
\brief whether undo is available
973
bool QLineEdit::isUndoAvailable() const
975
Q_D(const QLineEdit);
976
return d->isUndoAvailable();
980
\property QLineEdit::redoAvailable
981
\brief whether redo is available
984
bool QLineEdit::isRedoAvailable() const
986
Q_D(const QLineEdit);
987
return d->isRedoAvailable();
991
\property QLineEdit::dragEnabled
992
\brief whether the lineedit starts a drag if the user presses and
993
moves the mouse on some selected text
995
Dragging is disabled by default.
998
bool QLineEdit::dragEnabled() const
1000
Q_D(const QLineEdit);
1001
return d->dragEnabled;
1004
void QLineEdit::setDragEnabled(bool b)
1012
\property QLineEdit::acceptableInput
1013
\brief whether the input satisfies the inputMask and the
1016
\sa setInputMask(), setValidator()
1018
bool QLineEdit::hasAcceptableInput() const
1020
Q_D(const QLineEdit);
1021
return d->hasAcceptableInput(d->text);
1025
\property QLineEdit::inputMask
1026
\brief The validation input mask
1028
If no mask is set, inputMask() returns an empty string.
1030
Sets the QLineEdit's validation mask. Validators can be used
1031
instead of, or in conjunction with masks; see setValidator().
1033
Unset the mask and return to normal QLineEdit operation by passing
1034
an empty string ("") or just calling setInputMask() with no
1037
The mask format understands these mask characters:
1039
\header \i Character \i Meaning
1040
\row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
1041
\row \i \c a \i ASCII alphabetic character permitted but not required.
1042
\row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
1043
\row \i \c n \i ASCII alphanumeric character permitted but not required.
1044
\row \i \c X \i Any character required.
1045
\row \i \c x \i Any character permitted but not required.
1046
\row \i \c 9 \i ASCII digit required. 0-9.
1047
\row \i \c 0 \i ASCII digit permitted but not required.
1048
\row \i \c D \i ASCII digit required. 1-9.
1049
\row \i \c d \i ASCII digit permitted but not required (1-9).
1050
\row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
1051
\row \i \c > \i All following alphabetic characters are uppercased.
1052
\row \i \c < \i All following alphabetic characters are lowercased.
1053
\row \i \c ! \i Switch off case conversion.
1054
\row \i <tt>\\</tt> \i Use <tt>\\</tt> to escape the special
1055
characters listed above to use them as
1059
The mask consists of a string of mask characters and separators,
1060
optionally followed by a semicolon and the character used for
1061
blanks: the blank characters are always removed from the text
1062
after editing. The default blank character is space.
1066
\header \i Mask \i Notes
1067
\row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
1068
\row \i \c 0000-00-00 \i ISO Date; blanks are \c space
1069
\row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
1070
blanks are \c - and all (alphabetic) characters are converted to
1074
To get range control (e.g. for an IP address) use masks together
1075
with \link setValidator() validators\endlink.
1079
QString QLineEdit::inputMask() const
1081
Q_D(const QLineEdit);
1082
return (d->maskData ? d->inputMask + ';' + d->blank : QString());
1085
void QLineEdit::setInputMask(const QString &inputMask)
1088
d->parseInputMask(inputMask);
1090
d->moveCursor(d->nextMaskBlank(0));
1094
Selects all the text (i.e. highlights it) and moves the cursor to
1095
the end. This is useful when a default value has been inserted
1096
because if the user types before clicking on the widget, the
1097
selected text will be deleted.
1099
\sa setSelection() deselect()
1102
void QLineEdit::selectAll()
1105
d->selstart = d->selend = d->cursor = 0;
1106
d->moveCursor(d->text.length(), true);
1110
Deselects any selected text.
1112
\sa setSelection() selectAll()
1115
void QLineEdit::deselect()
1124
Deletes any selected text, inserts \a newText, and validates the
1125
result. If it is valid, it sets it as the new contents of the line
1128
\sa setText(), clear()
1130
void QLineEdit::insert(const QString &newText)
1132
// q->resetInputContext(); //#### FIX ME IN QT
1134
int priorState = d->undoState;
1135
d->removeSelectedText();
1137
d->finishChange(priorState);
1141
Clears the contents of the line edit.
1143
\sa setText(), insert()
1145
void QLineEdit::clear()
1148
int priorState = d->undoState;
1149
resetInputContext();
1151
d->selend = d->text.length();
1152
d->removeSelectedText();
1154
d->finishChange(priorState);
1158
Undoes the last operation if undo is \link
1159
QLineEdit::undoAvailable available\endlink. Deselects any current
1160
selection, and updates the selection start to the current cursor
1163
void QLineEdit::undo()
1166
resetInputContext();
1168
d->finishChange(-1, true);
1172
Redoes the last operation if redo is \link
1173
QLineEdit::redoAvailable available\endlink.
1175
void QLineEdit::redo()
1178
resetInputContext();
1185
\property QLineEdit::readOnly
1186
\brief whether the line edit is read only.
1188
In read-only mode, the user can still copy the text to the
1189
clipboard, or drag and drop the text (if echoMode() is \c Normal),
1192
QLineEdit does not show a cursor in read-only mode.
1197
bool QLineEdit::isReadOnly() const
1199
Q_D(const QLineEdit);
1203
void QLineEdit::setReadOnly(bool enable)
1206
d->readOnly = enable;
1211
#ifndef QT_NO_CLIPBOARD
1213
Copies the selected text to the clipboard and deletes it, if there
1214
is any, and if echoMode() is \c Normal.
1216
If the current validator disallows deleting the selected text,
1217
cut() will copy without deleting.
1219
\sa copy() paste() setValidator()
1222
void QLineEdit::cut()
1224
if (hasSelectedText()) {
1232
Copies the selected text to the clipboard, if there is any, and if
1233
echoMode() is \c Normal.
1238
void QLineEdit::copy() const
1240
Q_D(const QLineEdit);
1245
Inserts the clipboard's text at the cursor position, deleting any
1246
selected text, providing the line edit is not \link
1247
QLineEdit::readOnly read-only\endlink.
1249
If the end result would not be acceptable to the current
1250
\link setValidator() validator\endlink, nothing happens.
1255
void QLineEdit::paste()
1257
insert(QApplication::clipboard()->text(QClipboard::Clipboard));
1260
void QLineEditPrivate::copy(bool clipboard) const
1262
Q_Q(const QLineEdit);
1263
QString t = q->selectedText();
1264
if (!t.isEmpty() && echoMode == QLineEdit::Normal) {
1265
q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
1266
QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
1267
q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
1268
q, SLOT(clipboardChanged()));
1272
#endif // !QT_NO_CLIPBOARD
1276
bool QLineEdit::event(QEvent * e)
1279
if (e->type() == QEvent::ShortcutOverride && !d->readOnly) {
1280
QKeyEvent* ke = (QKeyEvent*) e;
1281
if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
1282
|| ke->modifiers() == Qt::KeypadModifier) {
1283
if (ke->key() < Qt::Key_Escape) {
1285
} else if (ke->modifiers() == Qt::NoModifier
1286
|| ke->modifiers() == Qt::ShiftModifier) {
1287
switch (ke->key()) {
1288
case Qt::Key_Delete:
1291
case Qt::Key_Backspace:
1299
} else if (ke->modifiers() & Qt::ControlModifier) {
1300
switch (ke->key()) {
1301
// Those are too frequently used for application functionality
1317
#if !defined(Q_WS_MAC)
1318
case Qt::Key_Insert:
1319
case Qt::Key_Delete:
1326
} else if (e->type() == QEvent::Timer) {
1327
// should be timerEvent, is here for binary compatibility
1328
int timerId = ((QTimerEvent*)e)->timerId();
1329
if (timerId == d->cursorTimer) {
1330
QStyleOptionFrame opt = d->getStyleOption();
1331
if(!hasSelectedText()
1332
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1333
d->setCursorVisible(!d->cursorVisible);
1334
#ifndef QT_NO_DRAGANDDROP
1335
} else if (timerId == d->dndTimer.timerId()) {
1339
else if (timerId == d->tripleClickTimer.timerId())
1340
d->tripleClickTimer.stop();
1341
} else if (e->type() == QEvent::ContextMenu) {
1343
if (d->composeMode())
1348
return QWidget::event(e);
1353
void QLineEdit::mousePressEvent(QMouseEvent* e)
1356
if (d->sendMouseEventToInputContext(e))
1358
if (e->button() == Qt::RightButton)
1360
if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
1361
QApplication::startDragDistance()) {
1365
bool mark = e->modifiers() & Qt::ShiftModifier;
1366
int cursor = d->xToPos(e->pos().x());
1367
#ifndef QT_NO_DRAGANDDROP
1368
if (!mark && d->dragEnabled && d->echoMode == Normal &&
1369
e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) {
1372
d->dndPos = e->pos();
1373
if (!d->dndTimer.isActive())
1374
d->dndTimer.start(QApplication::startDragTime(), this);
1375
d->emitCursorPositionChanged();
1379
d->moveCursor(cursor, mark);
1385
void QLineEdit::mouseMoveEvent(QMouseEvent * e)
1388
if (d->sendMouseEventToInputContext(e))
1391
if (e->buttons() & Qt::LeftButton) {
1392
#ifndef QT_NO_DRAGANDDROP
1393
if (d->dndTimer.isActive()) {
1394
if ((d->dndPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
1399
d->moveCursor(d->xToPos(e->pos().x()), true);
1406
void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
1409
if (d->sendMouseEventToInputContext(e))
1411
#ifndef QT_NO_DRAGANDDROP
1412
if (e->button() == Qt::LeftButton) {
1413
if (d->dndTimer.isActive()) {
1420
#ifndef QT_NO_CLIPBOARD
1421
if (QApplication::clipboard()->supportsSelection()) {
1422
if (e->button() == Qt::LeftButton) {
1424
} else if (!d->readOnly && e->button() == Qt::MidButton) {
1426
insert(QApplication::clipboard()->text(QClipboard::Selection));
1434
void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
1437
if (d->sendMouseEventToInputContext(e))
1439
if (e->button() == Qt::LeftButton) {
1441
d->cursor = d->xToPos(e->pos().x());
1442
d->cursor = d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords);
1443
// ## text layout should support end of words.
1444
int end = d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords);
1445
while (end > d->cursor && d->text[end-1].isSpace())
1447
d->moveCursor(end, true);
1448
d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
1449
d->tripleClick = e->pos();
1454
\fn void QLineEdit::returnPressed()
1456
This signal is emitted when the Return or Enter key is pressed.
1457
Note that if there is a validator() or inputMask() set on the line
1458
edit, the returnPressed() signal will only be emitted if the input
1459
follows the inputMask() and the validator() returns \c Acceptable.
1463
\fn void QLineEdit::editingFinished()
1465
This signal is emitted when the Return or Enter key is pressed or
1466
the line edit looses focus. Note that if there is a validator() or
1467
inputMask() set on the line edit and enter/return is pressed, the
1468
editingFinished() signal will only be emitted if the input follows
1469
the inputMask() and the validator() returns \c Acceptable.
1473
Converts the given key press \a event into a line edit action.
1475
If Return or Enter is pressed and the current text is valid (or
1476
can be \link QValidator::fixup() made valid\endlink by the
1477
validator), the signal returnPressed() is emitted.
1479
The default key bindings are listed in the class's detailed
1483
void QLineEdit::keyPressEvent(QKeyEvent *event)
1486
d->setCursorVisible(true);
1487
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
1488
const QValidator * v = d->validator;
1489
if (hasAcceptableInput()) {
1490
emit returnPressed();
1491
emit editingFinished();
1493
#ifndef QT_NO_VALIDATOR
1495
QString textCopy = d->text;
1496
int cursorCopy = d->cursor;
1497
if (v && v->validate(textCopy, cursorCopy) != QValidator::Acceptable)
1500
if (d->hasAcceptableInput(textCopy)) {
1501
if (v && (textCopy != d->text || cursorCopy != d->cursor))
1502
d->setText(textCopy, cursorCopy);
1503
emit returnPressed();
1504
emit editingFinished();
1511
bool unknown = false;
1513
if (event->modifiers() & Qt::ControlModifier) {
1514
switch (event->key()) {
1516
#if defined(Q_WS_X11)
1517
home(event->modifiers() & Qt::ShiftModifier);
1523
cursorForward(event->modifiers() & Qt::ShiftModifier, -1);
1525
#ifndef QT_NO_CLIPBOARD
1535
end(event->modifiers() & Qt::ShiftModifier);
1538
cursorForward(event->modifiers() & Qt::ShiftModifier, 1);
1546
int priorState = d->undoState;
1548
while (d->cursor < (int) d->text.length())
1550
d->finishChange(priorState);
1553
#if defined(Q_WS_X11)
1559
#ifndef QT_NO_CLIPBOARD
1565
if (!d->readOnly && d->hasSelectedText() && echoMode() == Normal) {
1570
#if !defined(Q_WS_MAC)
1571
case Qt::Key_Insert:
1576
case Qt::Key_Delete:
1578
cursorWordForward(true);
1582
case Qt::Key_Backspace:
1584
cursorWordBackward(true);
1590
if ((layoutDirection() == Qt::RightToLeft) == (event->key() == Qt::Key_Right)) {
1592
if (echoMode() == Normal)
1593
cursorWordBackward(event->modifiers() & Qt::ShiftModifier);
1596
home(event->modifiers() & Qt::ShiftModifier);
1599
if (echoMode() == Normal)
1600
cursorWordForward(event->modifiers() & Qt::ShiftModifier);
1603
end(event->modifiers() & Qt::ShiftModifier);
1608
if(event->modifiers() & Qt::ShiftModifier)
1621
} else { // ### check for *no* modifier
1622
switch (event->key()) {
1627
case Qt::Key_Right: {
1628
int step = ((layoutDirection() == Qt::RightToLeft) == (event->key() == Qt::Key_Right)) ? -1 : 1;
1630
if (event->modifiers() & Qt::AltModifier) {
1632
cursorWordBackward(event->modifiers() & Qt::ShiftModifier);
1634
cursorWordForward(event->modifiers() & Qt::ShiftModifier);
1635
} else if (event->modifiers() & Qt::MetaModifier) {
1637
home(event->modifiers() & Qt::ShiftModifier);
1639
end(event->modifiers() & Qt::ShiftModifier);
1643
cursorForward(event->modifiers() & Qt::ShiftModifier, step);
1647
case Qt::Key_Backspace:
1653
break; // Home and End do nothing on the mac (but Up and Down do).
1656
home(event->modifiers() & Qt::ShiftModifier);
1663
end(event->modifiers() & Qt::ShiftModifier);
1665
case Qt::Key_Delete:
1667
#if !defined(Q_WS_MAC)
1668
if (event->modifiers() & Qt::ShiftModifier) {
1676
#if !defined(Q_WS_MAC)
1677
case Qt::Key_Insert:
1678
if (!d->readOnly && event->modifiers() & Qt::ShiftModifier)
1684
case Qt::Key_F14: // Undo key on Sun keyboards
1688
#ifndef QT_NO_CLIPBOARD
1689
case Qt::Key_F16: // Copy key on Sun keyboards
1692
case Qt::Key_F18: // Paste key on Sun keyboards
1696
case Qt::Key_F20: // Cut key on Sun keyboards
1697
if (!d->readOnly && hasSelectedText() && echoMode() == Normal) {
1707
if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
1708
setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
1709
d->updateTextLayout();
1714
if (unknown && !d->readOnly) {
1715
QString t = event->text();
1716
if (!t.isEmpty() && t.at(0).isPrint()) {
1730
This function is not intended as polymorphic usage. Just a shared code
1731
fragment that calls QInputContext::mouseHandler for this
1734
bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
1736
// ##### currently X11 only
1737
#if (defined(Q_WS_X11) || defined(Q_WS_QWS)) && !defined QT_NO_IM
1739
if ( composeMode() ) {
1740
int tmp_cursor = xToPosInternal( e->pos().x(), QTextLine::CursorOnCharacter );
1741
int mousePos = tmp_cursor - cursor;
1742
if ( mousePos < 0 || mousePos >= textLayout.preeditAreaText().length() ) {
1744
// don't send move events outside the preedit area
1745
if ( e->type() == QEvent::MouseMove )
1749
QInputContext *qic = q->inputContext();
1751
// may be causing reset() in some input methods
1752
qic->mouseHandler(mousePos, e);
1753
if (!textLayout.preeditAreaText().isEmpty())
1765
void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
1773
d->removeSelectedText();
1775
int c = d->cursor; // cursor position after insertion of commit string
1776
if (e->replacementStart() <= 0)
1777
c += e->commitString().length() + qMin(-e->replacementStart(), e->replacementLength());
1779
d->cursor += e->replacementStart();
1781
// insert commit string
1782
if (e->replacementLength()) {
1783
d->selstart = d->cursor;
1784
d->selend = d->selstart + e->replacementLength();
1785
d->removeSelectedText();
1787
if (!e->commitString().isEmpty())
1788
d->insert(e->commitString());
1792
d->textLayout.setPreeditArea(d->cursor, e->preeditString());
1793
QList<QTextLayout::FormatRange> formats;
1794
for (int i = 0; i < e->attributes().size(); ++i) {
1795
const QInputMethodEvent::Attribute &a = e->attributes().at(i);
1796
if (a.type != QInputMethodEvent::TextFormat)
1798
QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
1800
QTextLayout::FormatRange o;
1801
o.start = a.start + d->cursor;
1802
o.length = a.length;
1807
d->textLayout.setAdditionalFormats(formats);
1808
d->updateTextLayout();
1810
if (!e->commitString().isEmpty())
1811
d->emitCursorPositionChanged();
1816
QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
1818
Q_D(const QLineEdit);
1820
case Qt::ImMicroFocus:
1821
return d->cursorRect();
1824
case Qt::ImCursorPosition:
1825
return QVariant(d->cursor);
1826
case Qt::ImSurroundingText:
1827
return QVariant(d->text);
1828
case Qt::ImCurrentSelection:
1829
return QVariant(selectedText());
1838
void QLineEdit::focusInEvent(QFocusEvent *e)
1841
if (e->reason() == Qt::TabFocusReason ||
1842
e->reason() == Qt::BacktabFocusReason ||
1843
e->reason() == Qt::ShortcutFocusReason)
1844
d->maskData ? d->moveCursor(d->nextMaskBlank(0)) : selectAll();
1845
if (!d->cursorTimer) {
1846
int cft = QApplication::cursorFlashTime();
1847
d->cursorTimer = cft ? startTimer(cft/2) : -1;
1849
QStyleOptionFrame opt = d->getStyleOption();
1850
if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty())
1851
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1852
d->setCursorVisible(true);
1854
if(d->echoMode == Password || d->echoMode == NoEcho)
1855
qt_mac_secure_keyboard(true);
1863
void QLineEdit::focusOutEvent(QFocusEvent *e)
1866
if (e->reason() != Qt::ActiveWindowFocusReason &&
1867
e->reason() != Qt::PopupFocusReason)
1869
d->setCursorVisible(false);
1870
if (d->cursorTimer > 0)
1871
killTimer(d->cursorTimer);
1873
if (e->reason() != Qt::PopupFocusReason) {
1874
emit editingFinished();
1880
if(d->echoMode == Password || d->echoMode == NoEcho)
1881
qt_mac_secure_keyboard(false);
1888
void QLineEdit::paintEvent(QPaintEvent *)
1894
const QPalette &pal = palette();
1897
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
1898
QStyleOptionFrame opt;
1900
opt.lineWidth = frameWidth;
1901
opt.midLineWidth = 0;
1902
opt.state |= QStyle::State_Sunken;
1903
style()->drawPrimitive(QStyle::PE_FrameLineEdit, &opt, &p, this);
1905
r.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth);
1909
QStyleOptionFrame panel = d->getStyleOption();
1910
panel.state |= (isEnabled() ? QStyle::State_Enabled : QStyle::State_None);
1911
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
1913
QFontMetrics fm = fontMetrics();
1914
QRect lineRect(r.x() + innerMargin, r.y() + (r.height() - fm.height() + 1) / 2,
1915
r.width() - 2*innerMargin, fm.height());
1916
QTextLine line = d->textLayout.lineAt(0);
1918
// locate cursor position
1919
int cix = qRound(line.cursorToX(d->cursor));
1921
// horizontal scrolling
1922
int minLB = qMax(0, -fm.minLeftBearing());
1923
int minRB = qMax(0, -fm.minRightBearing());
1926
int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
1927
if ((minLB + widthUsed) <= lineRect.width()) {
1928
Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment));
1929
va &= ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask);
1931
case Qt::AlignRight:
1932
d->hscroll = widthUsed - lineRect.width() + 1;
1934
case Qt::AlignHCenter:
1935
d->hscroll = (widthUsed - lineRect.width()) / 2;
1942
d->hscroll -= minLB;
1943
} else if (cix - d->hscroll >= lineRect.width()) {
1944
d->hscroll = cix - lineRect.width() + 1;
1945
} else if (cix - d->hscroll < 0) {
1947
} else if (widthUsed - d->hscroll < lineRect.width()) {
1948
d->hscroll = widthUsed - lineRect.width() + 1;
1950
// the y offset is there to keep the baseline constant in case we have script changes in the text.
1951
QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent-fm.ascent());
1953
// draw text, selections and cursors
1954
p.setPen(pal.text().color());
1955
bool supressCursor = d->readOnly;
1957
QVector<QTextLayout::FormatRange> selections;
1958
if (d->selstart < d->selend || (d->cursorVisible && d->maskData)) {
1959
QTextLayout::FormatRange o;
1960
const QPalette &pal = palette();
1961
if (d->selstart < d->selend) {
1962
o.start = d->selstart;
1963
o.length = d->selend - d->selstart;
1964
o.format.setBackground(pal.brush(QPalette::Highlight));
1965
o.format.setForeground(pal.brush(QPalette::HighlightedText));
1968
o.start = d->cursor;
1970
o.format.setBackground(pal.brush(QPalette::Text));
1971
o.format.setForeground(pal.brush(QPalette::Background));
1973
selections.append(o);
1976
// Asian users see an IM selection text as cursor on candidate
1977
// selection phase of input method, so the ordinary cursor should be
1978
// invisible if we have a preedit string.
1979
bool showCursor = (d->cursorVisible && !supressCursor && !d->textLayout.preeditAreaText().length());
1980
d->textLayout.draw(&p, topLeft, selections, r);
1981
if (showCursor && d->textLayout.preeditAreaText().isEmpty())
1982
d->textLayout.drawCursor(&p, topLeft, d->cursor);
1987
#ifndef QT_NO_DRAGANDDROP
1990
void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
1993
if (!d->readOnly && e->mimeData()->hasFormat("text/plain")) {
1994
e->acceptProposedAction();
1995
d->cursor = d->xToPos(e->pos().x());
1996
d->cursorVisible = true;
1998
d->emitCursorPositionChanged();
2003
void QLineEdit::dragEnterEvent(QDragEnterEvent * e)
2005
QLineEdit::dragMoveEvent(e);
2009
void QLineEdit::dragLeaveEvent(QDragLeaveEvent *)
2012
if (d->cursorVisible) {
2013
d->cursorVisible = false;
2019
void QLineEdit::dropEvent(QDropEvent* e)
2022
QString str = e->mimeData()->text();
2024
if (!str.isNull() && !d->readOnly) {
2025
if (e->source() == this && e->dropAction() == Qt::CopyAction)
2027
d->cursor =d->xToPos(e->pos().x());
2028
int selStart = d->cursor;
2029
int oldSelStart = d->selstart;
2030
int oldSelEnd = d->selend;
2031
d->cursorVisible = false;
2032
e->acceptProposedAction();
2034
if (e->source() == this) {
2035
if (e->dropAction() == Qt::MoveAction) {
2036
if (selStart > oldSelStart && selStart <= oldSelEnd)
2037
setSelection(oldSelStart, str.length());
2038
else if (selStart > oldSelEnd)
2039
setSelection(selStart - str.length(), str.length());
2041
setSelection(selStart, str.length());
2043
setSelection(selStart, str.length());
2052
void QLineEditPrivate::drag()
2056
QMimeData *data = new QMimeData;
2057
data->setText(q->selectedText());
2058
QDrag *drag = new QDrag(q);
2059
drag->setMimeData(data);
2060
Qt::DropAction action = drag->start();
2061
if (action == Qt::MoveAction && !readOnly && drag->target() != q) {
2062
int priorState = undoState;
2063
removeSelectedText();
2064
finishChange(priorState);
2068
#endif // QT_NO_DRAGANDDROP
2071
Shows the standard context menu created with
2072
createStandardContextMenu().
2074
If you do not want the line edit to have a context menu, you can set
2075
its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
2076
customize the context menu, reimplement this function. If you want
2077
to extend the standard context menu, reimplement this function, call
2078
createStandardContextMenu() and extend the menu returned.
2081
void LineEdit::contextMenuEvent(QContextMenuEvent *event)
2083
QMenu *menu = createStandardContextMenu();
2084
menu->addAction(tr("My Menu Item"));
2086
menu->exec(event->globalPos());
2091
The \a event parameter is used to obtain the position where
2092
the mouse cursor was when the event was generated.
2094
\sa setContextMenuPolicy()
2096
void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
2098
QMenu *menu = createStandardContextMenu();
2099
menu->exec(event->globalPos());
2103
/*! This function creates the standard context menu which is shown
2104
when the user clicks on the line edit with the right mouse
2105
button. It is called from the default contextMenuEvent() handler.
2106
The popup menu's ownership is transferred to the caller.
2109
QMenu *QLineEdit::createStandardContextMenu()
2112
#ifndef QT_NO_POPUPMENU
2113
d->actions[QLineEditPrivate::UndoAct]->setEnabled(d->isUndoAvailable());
2114
d->actions[QLineEditPrivate::RedoAct]->setEnabled(d->isRedoAvailable());
2115
#ifndef QT_NO_CLIPBOARD
2116
d->actions[QLineEditPrivate::CutAct]->setEnabled(!d->readOnly && d->hasSelectedText());
2117
d->actions[QLineEditPrivate::CopyAct]->setEnabled(d->hasSelectedText());
2118
d->actions[QLineEditPrivate::PasteAct]->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty());
2120
d->actions[QLineEditPrivate::CutAct]->setEnabled(false);
2121
d->actions[QLineEditPrivate::CopyAct]->setEnabled(false);
2122
d->actions[QLineEditPrivate::PasteAct]->setEnabled(false);
2124
d->actions[QLineEditPrivate::ClearAct]->setEnabled(!d->readOnly && !d->text.isEmpty());
2125
d->actions[QLineEditPrivate::SelectAllAct]->setEnabled(!d->text.isEmpty() && !d->allSelected());
2127
QMenu *popup = new QMenu(this);
2128
popup->setObjectName("qt_edit_menu");
2129
popup->addAction(d->actions[QLineEditPrivate::UndoAct]);
2130
popup->addAction(d->actions[QLineEditPrivate::RedoAct]);
2131
popup->addSeparator();
2132
popup->addAction(d->actions[QLineEditPrivate::CutAct]);
2133
popup->addAction(d->actions[QLineEditPrivate::CopyAct]);
2134
popup->addAction(d->actions[QLineEditPrivate::PasteAct]);
2135
popup->addAction(d->actions[QLineEditPrivate::ClearAct]);
2136
popup->addSeparator();
2137
popup->addAction(d->actions[QLineEditPrivate::SelectAllAct]);
2138
#if (defined(Q_WS_X11) || defined(Q_WS_QWS)) && !defined(QT_NO_IM)
2139
QInputContext *qic = inputContext();
2141
QList<QAction *> imActions = qic->actions();
2142
for (int i = 0; i < imActions.size(); ++i)
2143
popup->addAction(imActions.at(i));
2153
void QLineEdit::changeEvent(QEvent *ev)
2156
if(ev->type() == QEvent::ActivationChange) {
2157
if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
2159
} else if (ev->type() == QEvent::FontChange) {
2160
d->updateTextLayout();
2162
QWidget::changeEvent(ev);
2165
void QLineEditPrivate::clipboardChanged()
2169
void QLineEditPrivate::init(const QString& txt)
2172
#ifndef QT_NO_CURSOR
2173
q->setCursor(Qt::IBeamCursor);
2175
q->setFocusPolicy(Qt::StrongFocus);
2176
q->setAttribute(Qt::WA_InputMethodEnabled);
2177
// Specifies that this widget can use more, but is able to survive on
2178
// less, horizontal space; and is fixed vertically.
2179
q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
2180
q->setBackgroundRole(QPalette::Base);
2181
q->setAttribute(Qt::WA_KeyCompression);
2182
q->setMouseTracking(true);
2183
q->setAcceptDrops(true);
2186
cursor = text.length();
2188
actions[UndoAct] = new QAction(q->tr("&Undo") + ACCEL_KEY(Z), q);
2189
QObject::connect(actions[UndoAct], SIGNAL(triggered()), q, SLOT(undo()));
2190
actions[RedoAct] = new QAction(q->tr("&Redo") + ACCEL_KEY(Y), q);
2191
QObject::connect(actions[RedoAct], SIGNAL(triggered()), q, SLOT(redo()));
2192
//popup->insertSeparator();
2193
actions[CutAct] = new QAction(q->tr("Cu&t") + ACCEL_KEY(X), q);
2194
QObject::connect(actions[CutAct], SIGNAL(triggered()), q, SLOT(cut()));
2195
actions[CopyAct] = new QAction(q->tr("&Copy") + ACCEL_KEY(C), q);
2196
QObject::connect(actions[CopyAct], SIGNAL(triggered()), q, SLOT(copy()));
2197
actions[PasteAct] = new QAction(q->tr("&Paste") + ACCEL_KEY(V), q);
2198
QObject::connect(actions[PasteAct], SIGNAL(triggered()), q, SLOT(paste()));
2199
actions[ClearAct] = new QAction(q->tr("Clear"), q);
2200
QObject::connect(actions[ClearAct], SIGNAL(triggered()), q, SLOT(clear()));
2201
//popup->insertSeparator();
2202
actions[SelectAllAct] = new QAction(q->tr("Select All")
2207
QObject::connect(actions[SelectAllAct], SIGNAL(triggered()), q, SLOT(selectAll()));
2210
void QLineEditPrivate::updateTextLayout()
2212
// replace all non-printable characters with spaces (to avoid
2213
// drawing boxes when using fonts that don't have glyphs for such
2216
QString str = q->displayText();
2217
QChar* uc = str.data();
2218
for (int i = 0; i < (int)str.length(); ++i) {
2219
if (! uc[i].isPrint())
2220
uc[i] = QChar(0x0020);
2222
textLayout.setFont(q->font());
2223
textLayout.setText(str);
2225
option.setTextDirection(q->layoutDirection());
2226
option.setFlags(QTextOption::IncludeTrailingSpaces);
2227
textLayout.setTextOption(option);
2229
textLayout.beginLayout();
2230
QTextLine l = textLayout.createLine();
2231
textLayout.endLayout();
2232
ascent = qRound(l.ascent());
2235
int QLineEditPrivate::xToPosInternal(int x, QTextLine::CursorPosition betweenOrOn) const
2237
Q_Q(const QLineEdit);
2238
x-= q->contentsRect().x() - hscroll + innerMargin;
2239
QTextLine l = textLayout.lineAt(0);
2240
if (x >= 0 && x < l.naturalTextWidth())
2241
return l.xToCursor(x, betweenOrOn);
2242
return x < 0 ? -1 : text.length();
2246
int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
2248
int pos = xToPosInternal(x, betweenOrOn);
2249
return (pos < 0) ? 0 : pos;
2253
QRect QLineEditPrivate::cursorRect() const
2255
Q_Q(const QLineEdit);
2256
QRect cr = q->contentsRect();
2257
int cix = cr.x() - hscroll + innerMargin;
2258
QTextLine l = textLayout.lineAt(0);
2259
cix += qRound(l.cursorToX(cursor));
2260
int ch = qMin(cr.height(), q->fontMetrics().height() + 1);
2261
return QRect(cix-5, cr.y() + (cr.height() - ch) / 2, 10, ch);
2264
void QLineEditPrivate::moveCursor(int pos, bool mark)
2267
if (pos != cursor) {
2270
pos = pos > cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
2272
bool fullUpdate = mark || hasSelectedText();
2275
if (selend > selstart && cursor == selstart)
2277
else if (selend > selstart && cursor == selend)
2281
selstart = qMin(anchor, pos);
2282
selend = qMax(anchor, pos);
2291
setCursorVisible(false);
2293
setCursorVisible(true);
2295
QStyleOptionFrame opt = getStyleOption();
2296
if (mark && !q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q))
2297
setCursorVisible(false);
2298
if (mark || selDirty) {
2300
emit q->selectionChanged();
2302
emitCursorPositionChanged();
2305
void QLineEditPrivate::finishChange(int validateFromState, bool update, bool edited)
2308
bool lineDirty = selDirty;
2311
bool wasValidInput = validInput;
2313
#ifndef QT_NO_VALIDATOR
2314
if (validator && validateFromState >= 0) {
2315
QString textCopy = text;
2316
int cursorCopy = cursor;
2317
validInput = (validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
2319
if (text != textCopy) {
2320
setText(textCopy, cursorCopy);
2323
cursor = cursorCopy;
2327
if (validateFromState >= 0 && wasValidInput && !validInput) {
2328
undo(validateFromState);
2329
history.resize(undoState);
2330
if (modifiedState > undoState)
2336
lineDirty |= textDirty;
2339
QString actualText = maskData ? stripString(text) : text;
2341
emit q->textEdited(actualText);
2342
emit q->textChanged(actualText);
2344
#ifndef QT_NO_ACCESSIBILITY
2345
QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
2350
emit q->selectionChanged();
2352
if (lineDirty || update)
2354
emitCursorPositionChanged();
2357
void QLineEditPrivate::emitCursorPositionChanged()
2360
if (cursor != lastCursorPos) {
2361
const int oldLast = lastCursorPos;
2362
lastCursorPos = cursor;
2363
emit q->cursorPositionChanged(oldLast, cursor);
2367
void QLineEditPrivate::setText(const QString& txt, int pos, bool edited)
2370
q->resetInputContext();
2372
QString oldText = text;
2374
text = maskString(0, txt, true);
2375
text += clearString(text.length(), maxLength - text.length());
2377
text = txt.isEmpty() ? txt : txt.left(maxLength);
2380
modifiedState = undoState = 0;
2381
cursor = (pos < 0 || pos > text.length()) ? text.length() : pos;
2382
textDirty = (oldText != text);
2383
finishChange(-1, true, edited);
2387
void QLineEditPrivate::setCursorVisible(bool visible)
2390
if ((bool)cursorVisible == visible)
2393
cursorVisible = visible;
2394
QRect r = cursorRect();
2395
if (maskData || !q->contentsRect().contains(r))
2401
void QLineEditPrivate::addCommand(const Command& cmd)
2403
if (separator && undoState && history[undoState-1].type != Separator) {
2404
history.resize(undoState + 2);
2405
history[undoState++] = Command(Separator, 0, 0);
2407
history.resize(undoState + 1);
2410
history[undoState++] = cmd;
2413
void QLineEditPrivate::insert(const QString& s)
2416
QString ms = maskString(cursor, s);
2417
for (int i = 0; i < (int) ms.length(); ++i) {
2418
addCommand (Command(DeleteSelection, cursor+i, text.at(cursor+i)));
2419
addCommand(Command(Insert, cursor+i, ms.at(i)));
2421
text.replace(cursor, ms.length(), ms);
2422
cursor += ms.length();
2423
cursor = nextMaskBlank(cursor);
2425
int remaining = maxLength - text.length();
2426
text.insert(cursor, s.left(remaining));
2427
for (int i = 0; i < (int) s.left(remaining).length(); ++i)
2428
addCommand(Command(Insert, cursor++, s.at(i)));
2433
void QLineEditPrivate::del(bool wasBackspace)
2435
if (cursor < (int) text.length()) {
2436
addCommand (Command((CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor)));
2438
text.replace(cursor, 1, clearString(cursor, 1));
2439
addCommand(Command(Insert, cursor, text.at(cursor)));
2441
text.remove(cursor, 1);
2447
void QLineEditPrivate::removeSelectedText()
2449
if (selstart < selend && selend <= (int) text.length()) {
2452
if (selstart <= cursor && cursor < selend) {
2453
// cursor is within the selection. Split up the commands
2454
// to be able to restore the correct cursor position
2455
for (i = cursor; i >= selstart; --i)
2456
addCommand (Command(DeleteSelection, i, text.at(i)));
2457
for (i = selend - 1; i > cursor; --i)
2458
addCommand (Command(DeleteSelection, i - cursor + selstart - 1, text.at(i)));
2460
for (i = selend-1; i >= selstart; --i)
2461
addCommand (Command(RemoveSelection, i, text.at(i)));
2464
text.replace(selstart, selend - selstart, clearString(selstart, selend - selstart));
2465
for (int i = 0; i < selend - selstart; ++i)
2466
addCommand(Command(Insert, selstart + i, text.at(selstart + i)));
2468
text.remove(selstart, selend - selstart);
2470
if (cursor > selstart)
2471
cursor -= qMin(cursor, selend) - selstart;
2477
void QLineEditPrivate::parseInputMask(const QString &maskFields)
2479
int delimiter = maskFields.indexOf(';');
2480
if (maskFields.isEmpty() || delimiter == 0) {
2490
if (delimiter == -1) {
2492
inputMask = maskFields;
2494
inputMask = maskFields.left(delimiter);
2495
blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QChar(' ');
2498
// calculate maxLength / maskData length
2501
for (int i=0; i<inputMask.length(); i++) {
2502
c = inputMask.at(i);
2503
if (i > 0 && inputMask.at(i-1) == '\\') {
2507
if (c != '\\' && c != '!' &&
2508
c != '<' && c != '>' &&
2509
c != '{' && c != '}' &&
2510
c != '[' && c != ']')
2515
maskData = new MaskInputData[maxLength];
2517
MaskInputData::Casemode m = MaskInputData::NoCaseMode;
2520
bool escape = false;
2522
for (int i = 0; i < inputMask.length(); i++) {
2523
c = inputMask.at(i);
2526
maskData[index].maskChar = c;
2527
maskData[index].separator = s;
2528
maskData[index].caseMode = m;
2531
} else if (c == '<') {
2532
m = MaskInputData::Lower;
2533
} else if (c == '>') {
2534
m = MaskInputData::Upper;
2535
} else if (c == '!') {
2536
m = MaskInputData::NoCaseMode;
2537
} else if (c != '{' && c != '}' && c != '[' && c != ']') {
2538
switch (c.unicode()) {
2560
maskData[index].maskChar = c;
2561
maskData[index].separator = s;
2562
maskData[index].caseMode = m;
2571
/* checks if the key is valid compared to the inputMask */
2572
bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const
2574
switch (mask.unicode()) {
2580
if (key.isLetter() || key == blank)
2584
if (key.isLetterOrNumber())
2588
if (key.isLetterOrNumber() || key == blank)
2596
if (key.isPrint() || key == blank)
2604
if (key.isNumber() || key == blank)
2608
if (key.isNumber() && key.digitValue() > 0)
2612
if ((key.isNumber() && key.digitValue() > 0) || key == blank)
2616
if (key.isNumber() || key == '+' || key == '-' || key == blank)
2625
bool QLineEditPrivate::hasAcceptableInput(const QString &str) const
2627
#ifndef QT_NO_VALIDATOR
2628
QString textCopy = str;
2629
int cursorCopy = cursor;
2630
if (validator && validator->validate(textCopy, cursorCopy)
2631
!= QValidator::Acceptable)
2638
if (str.length() != maxLength)
2641
for (int i=0; i < maxLength; ++i) {
2642
if (maskData[i].separator) {
2643
if (str.at(i) != maskData[i].maskChar)
2646
if (!isValidInput(str.at(i), maskData[i].maskChar))
2654
Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
2655
specifies from where characters should be gotten when a separator is met in \a str - true means
2656
that blanks will be used, false that previous input is used.
2657
Calling this when no inputMask is set is undefined.
2659
QString QLineEditPrivate::maskString(uint pos, const QString &str, bool clear) const
2661
if (pos >= (uint)maxLength)
2662
return QString::fromLatin1("");
2665
fill = clear ? clearString(0, maxLength) : text;
2668
QString s = QString::fromLatin1("");
2670
while (i < maxLength) {
2671
if (strIndex < str.length()) {
2672
if (maskData[i].separator) {
2673
s += maskData[i].maskChar;
2674
if (str[(int)strIndex] == maskData[i].maskChar)
2678
if (isValidInput(str[(int)strIndex], maskData[i].maskChar)) {
2679
switch (maskData[i].caseMode) {
2680
case MaskInputData::Upper:
2681
s += str[(int)strIndex].toUpper();
2683
case MaskInputData::Lower:
2684
s += str[(int)strIndex].toLower();
2687
s += str[(int)strIndex];
2691
// search for separator first
2692
int n = findInMask(i, true, true, str[(int)strIndex]);
2694
if (str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex]))) {
2695
s += fill.mid(i, n-i+1);
2696
i = n + 1; // update i to find + 1
2699
// search for valid blank if not
2700
n = findInMask(i, true, false, str[(int)strIndex]);
2702
s += fill.mid(i, n-i);
2703
switch (maskData[n].caseMode) {
2704
case MaskInputData::Upper:
2705
s += str[(int)strIndex].toUpper();
2707
case MaskInputData::Lower:
2708
s += str[(int)strIndex].toLower();
2711
s += str[(int)strIndex];
2713
i = n + 1; // updates i to find + 1
2729
Returns a "cleared" string with only separators and blank chars.
2730
Calling this when no inputMask is set is undefined.
2732
QString QLineEditPrivate::clearString(uint pos, uint len) const
2734
if (pos >= (uint)maxLength)
2738
int end = qMin((uint)maxLength, pos + len);
2739
for (int i=pos; i<end; i++)
2740
if (maskData[i].separator)
2741
s += maskData[i].maskChar;
2749
Strips blank parts of the input in a QLineEdit when an inputMask is set,
2750
separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
2752
QString QLineEditPrivate::stripString(const QString &str) const
2758
int end = qMin(maxLength, (int)str.length());
2759
for (int i=0; i < end; i++)
2760
if (maskData[i].separator)
2761
s += maskData[i].maskChar;
2763
if (str[i] != blank)
2769
/* searches forward/backward in maskData for either a separator or a blank */
2770
int QLineEditPrivate::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
2772
if (pos >= maxLength || pos < 0)
2775
int end = forward ? maxLength : -1;
2776
int step = forward ? 1 : -1;
2780
if (findSeparator) {
2781
if (maskData[i].separator && maskData[i].maskChar == searchChar)
2784
if (!maskData[i].separator) {
2785
if (searchChar.isNull())
2787
else if (isValidInput(searchChar, maskData[i].maskChar))
2796
void QLineEditPrivate::undo(int until)
2798
if (!isUndoAvailable())
2801
while (undoState && undoState > until) {
2802
Command& cmd = history[--undoState];
2805
text.remove(cmd.pos, 1);
2809
case RemoveSelection:
2810
text.insert(cmd.pos, cmd.uc);
2811
cursor = cmd.pos + 1;
2814
case DeleteSelection:
2815
text.insert(cmd.pos, cmd.uc);
2821
if (until < 0 && undoState) {
2822
Command& next = history[undoState-1];
2823
if (next.type != cmd.type && next.type < RemoveSelection
2824
&& !(cmd.type >= RemoveSelection && next.type != Separator))
2829
emitCursorPositionChanged();
2832
void QLineEditPrivate::redo() {
2833
if (!isRedoAvailable())
2836
while (undoState < (int)history.size()) {
2837
Command& cmd = history[undoState++];
2840
text.insert(cmd.pos, cmd.uc);
2841
cursor = cmd.pos + 1;
2845
case RemoveSelection:
2846
case DeleteSelection:
2847
text.remove(cmd.pos, 1);
2853
if (undoState < (int)history.size()) {
2854
Command& next = history[undoState];
2855
if (next.type != cmd.type && cmd.type < RemoveSelection
2856
&& !(next.type >= RemoveSelection && cmd.type != Separator))
2861
emitCursorPositionChanged();
2865
\fn void QLineEdit::repaintArea(int a, int b)
2867
Use update() instead.
2871
\fn void QLineEdit::cursorLeft(bool mark, int steps)
2873
Use cursorForward() with a negative number of steps instead. For
2874
example, cursorForward(mark, -steps).
2878
\fn void QLineEdit::cursorRight(bool mark, int steps)
2880
Use cursorForward() instead.
2884
\fn bool QLineEdit::frame() const
2886
Use hasFrame() instead.
2890
\fn void QLineEdit::clearValidator()
2892
Use setValidator(0) instead.
2896
\fn bool QLineEdit::hasMarkedText() const
2898
Use hasSelectedText() instead.
2902
\fn QString QLineEdit::markedText() const
2904
Use selectedText() instead.
2908
#include "moc_qlineedit.cpp"
2910
#endif // QT_NO_LINEEDIT