1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qlineedit.h"
41 #include "qlineedit_p.h"
42 
43 #include "qaction.h"
44 #include "qapplication.h"
45 #include "qclipboard.h"
46 #if QT_CONFIG(draganddrop)
47 #include <qdrag.h>
48 #endif
49 #include "qdrawutil.h"
50 #include "qevent.h"
51 #include "qfontmetrics.h"
52 #include "qstylehints.h"
53 #if QT_CONFIG(menu)
54 #include "qmenu.h"
55 #endif
56 #include "qpainter.h"
57 #include "qpixmap.h"
58 #include "qpointer.h"
59 #include "qstringlist.h"
60 #include "qstyle.h"
61 #include "qstyleoption.h"
62 #include "qtimer.h"
63 #include "qvalidator.h"
64 #include "qvariant.h"
65 #include "qvector.h"
66 #include "qdebug.h"
67 #if QT_CONFIG(textedit)
68 #include "qtextedit.h"
69 #include <private/qtextedit_p.h>
70 #endif
71 #include <private/qwidgettextcontrol_p.h>
72 
73 #ifndef QT_NO_ACCESSIBILITY
74 #include "qaccessible.h"
75 #endif
76 #if QT_CONFIG(itemviews)
77 #include "qabstractitemview.h"
78 #endif
79 #include "private/qstylesheetstyle_p.h"
80 
81 #ifndef QT_NO_SHORTCUT
82 #include "private/qapplication_p.h"
83 #include "private/qshortcutmap_p.h"
84 #include "qkeysequence.h"
85 #define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus) \
86                         && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \
87                       && !QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(k) ? \
88                       QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
89 #else
90 #define ACCEL_KEY(k) QString()
91 #endif
92 
93 #include <limits.h>
94 #ifdef DrawText
95 #undef DrawText
96 #endif
97 
98 QT_BEGIN_NAMESPACE
99 
100 /*!
101     Initialize \a option with the values from this QLineEdit. This method
102     is useful for subclasses when they need a QStyleOptionFrame, but don't want
103     to fill in all the information themselves.
104 
105     \sa QStyleOption::initFrom()
106 */
initStyleOption(QStyleOptionFrame * option) const107 void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
108 {
109     if (!option)
110         return;
111 
112     Q_D(const QLineEdit);
113     option->initFrom(this);
114     option->rect = contentsRect();
115     option->lineWidth = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this)
116                                  : 0;
117     option->midLineWidth = 0;
118     option->state |= QStyle::State_Sunken;
119     if (d->control->isReadOnly())
120         option->state |= QStyle::State_ReadOnly;
121 #ifdef QT_KEYPAD_NAVIGATION
122     if (hasEditFocus())
123         option->state |= QStyle::State_HasEditFocus;
124 #endif
125     option->features = QStyleOptionFrame::None;
126 }
127 
128 /*!
129     \class QLineEdit
130     \brief The QLineEdit widget is a one-line text editor.
131 
132     \ingroup basicwidgets
133     \inmodule QtWidgets
134 
135     \image windows-lineedit.png
136 
137     A line edit allows the user to enter and edit a single line of
138     plain text with a useful collection of editing functions,
139     including undo and redo, cut and paste, and drag and drop (see
140     \l setDragEnabled()).
141 
142     By changing the echoMode() of a line edit, it can also be used as
143     a "write-only" field, for inputs such as passwords.
144 
145     The length of the text can be constrained to maxLength(). The text
146     can be arbitrarily constrained using a validator() or an
147     inputMask(), or both. When switching between a validator and an input mask
148     on the same line edit, it is best to clear the validator or input mask to
149     prevent undefined behavior.
150 
151     A related class is QTextEdit which allows multi-line, rich text
152     editing.
153 
154     You can change the text with setText() or insert(). The text is
155     retrieved with text(); the displayed text (which may be different,
156     see \l{EchoMode}) is retrieved with displayText(). Text can be
157     selected with setSelection() or selectAll(), and the selection can
158     be cut(), copy()ied and paste()d. The text can be aligned with
159     setAlignment().
160 
161     When the text changes the textChanged() signal is emitted; when
162     the text changes other than by calling setText() the textEdited()
163     signal is emitted; when the cursor is moved the
164     cursorPositionChanged() signal is emitted; and when the Return or
165     Enter key is pressed the returnPressed() signal is emitted.
166 
167     When editing is finished, either because the line edit lost focus
168     or Return/Enter is pressed the editingFinished() signal is
169     emitted.
170 
171     Note that if there is a validator set on the line edit, the
172     returnPressed()/editingFinished() signals will only be emitted if
173     the validator returns QValidator::Acceptable.
174 
175     By default, QLineEdits have a frame as specified by platform
176     style guides; you can turn it off by calling
177     setFrame(false).
178 
179     The default key bindings are described below. The line edit also
180     provides a context menu (usually invoked by a right mouse click)
181     that presents some of these editing options.
182     \target desc
183     \table
184     \header \li Keypress \li Action
185     \row \li Left Arrow \li Moves the cursor one character to the left.
186     \row \li Shift+Left Arrow \li Moves and selects text one character to the left.
187     \row \li Right Arrow \li Moves the cursor one character to the right.
188     \row \li Shift+Right Arrow \li Moves and selects text one character to the right.
189     \row \li Home \li Moves the cursor to the beginning of the line.
190     \row \li End \li Moves the cursor to the end of the line.
191     \row \li Backspace \li Deletes the character to the left of the cursor.
192     \row \li Ctrl+Backspace \li Deletes the word to the left of the cursor.
193     \row \li Delete \li Deletes the character to the right of the cursor.
194     \row \li Ctrl+Delete \li Deletes the word to the right of the cursor.
195     \row \li Ctrl+A \li Select all.
196     \row \li Ctrl+C \li Copies the selected text to the clipboard.
197     \row \li Ctrl+Insert \li Copies the selected text to the clipboard.
198     \row \li Ctrl+K \li Deletes to the end of the line.
199     \row \li Ctrl+V \li Pastes the clipboard text into line edit.
200     \row \li Shift+Insert \li Pastes the clipboard text into line edit.
201     \row \li Ctrl+X \li Deletes the selected text and copies it to the clipboard.
202     \row \li Shift+Delete \li Deletes the selected text and copies it to the clipboard.
203     \row \li Ctrl+Z \li Undoes the last operation.
204     \row \li Ctrl+Y \li Redoes the last undone operation.
205     \endtable
206 
207     Any other key sequence that represents a valid character, will
208     cause the character to be inserted into the line edit.
209 
210     \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
211 */
212 
213 
214 /*!
215     \fn void QLineEdit::textChanged(const QString &text)
216 
217     This signal is emitted whenever the text changes. The \a text
218     argument is the new text.
219 
220     Unlike textEdited(), this signal is also emitted when the text is
221     changed programmatically, for example, by calling setText().
222 */
223 
224 /*!
225     \fn void QLineEdit::textEdited(const QString &text)
226 
227     This signal is emitted whenever the text is edited. The \a text
228     argument is the new text.
229 
230     Unlike textChanged(), this signal is not emitted when the text is
231     changed programmatically, for example, by calling setText().
232 */
233 
234 /*!
235     \fn void QLineEdit::cursorPositionChanged(int oldPos, int newPos)
236 
237     This signal is emitted whenever the cursor moves. The previous
238     position is given by \a oldPos, and the new position by \a newPos.
239 
240     \sa setCursorPosition(), cursorPosition()
241 */
242 
243 /*!
244     \fn void QLineEdit::selectionChanged()
245 
246     This signal is emitted whenever the selection changes.
247 
248     \sa hasSelectedText(), selectedText()
249 */
250 
251 /*!
252     Constructs a line edit with no text.
253 
254     The maximum text length is set to 32767 characters.
255 
256     The \a parent argument is sent to the QWidget constructor.
257 
258     \sa setText(), setMaxLength()
259 */
QLineEdit(QWidget * parent)260 QLineEdit::QLineEdit(QWidget* parent)
261     : QLineEdit(QString(), parent)
262 {
263 }
264 
265 /*!
266     Constructs a line edit containing the text \a contents.
267 
268     The cursor position is set to the end of the line and the maximum
269     text length to 32767 characters.
270 
271     The \a parent and argument is sent to the QWidget
272     constructor.
273 
274     \sa text(), setMaxLength()
275 */
QLineEdit(const QString & contents,QWidget * parent)276 QLineEdit::QLineEdit(const QString& contents, QWidget* parent)
277     : QWidget(*new QLineEditPrivate, parent, { })
278 {
279     Q_D(QLineEdit);
280     d->init(contents);
281 }
282 
283 
284 
285 /*!
286     Destroys the line edit.
287 */
288 
~QLineEdit()289 QLineEdit::~QLineEdit()
290 {
291 }
292 
293 
294 /*!
295     \property QLineEdit::text
296     \brief the line edit's text.
297 
298     Setting this property clears the selection, clears the undo/redo
299     history, moves the cursor to the end of the line and resets the
300     \l modified property to false. The text is not validated when
301     inserted with setText().
302 
303     The text is truncated to maxLength() length.
304 
305     By default, this property contains an empty string.
306 
307     \sa insert(), clear()
308 */
text() const309 QString QLineEdit::text() const
310 {
311     Q_D(const QLineEdit);
312     return d->control->text();
313 }
314 
setText(const QString & text)315 void QLineEdit::setText(const QString& text)
316 {
317     Q_D(QLineEdit);
318     d->setText(text);
319 }
320 
321 /*!
322     \since 4.7
323 
324     \property QLineEdit::placeholderText
325     \brief the line edit's placeholder text.
326 
327     Setting this property makes the line edit display a grayed-out
328     placeholder text as long as the line edit is empty.
329 
330     Normally, an empty line edit shows the placeholder text even
331     when it has focus. However, if the content is horizontally
332     centered, the placeholder text is not displayed under
333     the cursor when the line edit has focus.
334 
335     By default, this property contains an empty string.
336 
337     \sa text()
338 */
placeholderText() const339 QString QLineEdit::placeholderText() const
340 {
341     Q_D(const QLineEdit);
342     return d->placeholderText;
343 }
344 
setPlaceholderText(const QString & placeholderText)345 void QLineEdit::setPlaceholderText(const QString& placeholderText)
346 {
347     Q_D(QLineEdit);
348     if (d->placeholderText != placeholderText) {
349         d->placeholderText = placeholderText;
350         if (d->shouldShowPlaceholderText())
351             update();
352     }
353 }
354 
355 /*!
356     \property QLineEdit::displayText
357     \brief the displayed text.
358 
359     If \l echoMode is \l Normal this returns the same as text(); if
360     \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of
361     platform-dependent password mask characters text().length() in size,
362     e.g. "******"; if \l EchoMode is \l NoEcho returns an empty string, "".
363 
364     By default, this property contains an empty string.
365 
366     \sa setEchoMode(), text(), EchoMode
367 */
368 
displayText() const369 QString QLineEdit::displayText() const
370 {
371     Q_D(const QLineEdit);
372     return d->control->displayText();
373 }
374 
375 
376 /*!
377     \property QLineEdit::maxLength
378     \brief the maximum permitted length of the text.
379 
380     If the text is too long, it is truncated at the limit.
381 
382     If truncation occurs any selected text will be unselected, the
383     cursor position is set to 0 and the first part of the string is
384     shown.
385 
386     If the line edit has an input mask, the mask defines the maximum
387     string length.
388 
389     By default, this property contains a value of 32767.
390 
391     \sa inputMask
392 */
393 
maxLength() const394 int QLineEdit::maxLength() const
395 {
396     Q_D(const QLineEdit);
397     return d->control->maxLength();
398 }
399 
setMaxLength(int maxLength)400 void QLineEdit::setMaxLength(int maxLength)
401 {
402     Q_D(QLineEdit);
403     d->control->setMaxLength(maxLength);
404 }
405 
406 /*!
407     \property QLineEdit::frame
408     \brief whether the line edit draws itself with a frame.
409 
410     If enabled (the default) the line edit draws itself inside a
411     frame, otherwise the line edit draws itself without any frame.
412 */
hasFrame() const413 bool QLineEdit::hasFrame() const
414 {
415     Q_D(const QLineEdit);
416     return d->frame;
417 }
418 
419 /*!
420     \enum QLineEdit::ActionPosition
421 
422     This enum type describes how a line edit should display the action widgets to be
423     added.
424 
425     \value LeadingPosition  The widget is displayed to the left of the text
426                             when using layout direction \c Qt::LeftToRight or to
427                             the right when using \c Qt::RightToLeft, respectively.
428 
429     \value TrailingPosition The widget is displayed to the right of the text
430                             when using layout direction \c Qt::LeftToRight or to
431                             the left when using \c Qt::RightToLeft, respectively.
432 
433     \sa addAction(), removeAction(), QWidget::layoutDirection
434 
435     \since 5.2
436 */
437 
438 #if QT_CONFIG(action)
439 /*!
440     Adds the \a action to the list of actions at the \a position.
441 
442     \since 5.2
443 */
444 
addAction(QAction * action,ActionPosition position)445 void QLineEdit::addAction(QAction *action, ActionPosition position)
446 {
447     Q_D(QLineEdit);
448     QWidget::addAction(action);
449     d->addAction(action, nullptr, position);
450 }
451 
452 /*!
453     \overload
454 
455     Creates a new action with the given \a icon at the \a position.
456 
457     \since 5.2
458 */
459 
addAction(const QIcon & icon,ActionPosition position)460 QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
461 {
462     QAction *result = new QAction(icon, QString(), this);
463     addAction(result, position);
464     return result;
465 }
466 #endif // QT_CONFIG(action)
467 /*!
468     \property QLineEdit::clearButtonEnabled
469     \brief Whether the line edit displays a clear button when it is not empty.
470 
471     If enabled, the line edit displays a trailing \e clear button when it contains
472     some text, otherwise the line edit does not show a clear button (the
473     default).
474 
475     \sa addAction(), removeAction()
476     \since 5.2
477 */
478 
479 static const char clearButtonActionNameC[] = "_q_qlineeditclearaction";
480 
setClearButtonEnabled(bool enable)481 void QLineEdit::setClearButtonEnabled(bool enable)
482 {
483 #if QT_CONFIG(action)
484     Q_D(QLineEdit);
485     if (enable == isClearButtonEnabled())
486         return;
487     if (enable) {
488         QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this);
489         clearAction->setEnabled(!isReadOnly());
490         clearAction->setObjectName(QLatin1String(clearButtonActionNameC));
491 
492         int flags = QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText;
493         auto widgetAction = d->addAction(clearAction, nullptr, QLineEdit::TrailingPosition, flags);
494         widgetAction->setVisible(!text().isEmpty());
495     } else {
496         QAction *clearAction = findChild<QAction *>(QLatin1String(clearButtonActionNameC));
497         Q_ASSERT(clearAction);
498         d->removeAction(clearAction);
499         delete clearAction;
500     }
501 #else
502     Q_UNUSED(enable);
503 #endif // QT_CONFIG(action)
504 }
505 
isClearButtonEnabled() const506 bool QLineEdit::isClearButtonEnabled() const
507 {
508 #if QT_CONFIG(action)
509     return findChild<QAction *>(QLatin1String(clearButtonActionNameC));
510 #else
511     return false;
512 #endif
513 }
514 
setFrame(bool enable)515 void QLineEdit::setFrame(bool enable)
516 {
517     Q_D(QLineEdit);
518     d->frame = enable;
519     update();
520     updateGeometry();
521 }
522 
523 
524 /*!
525     \enum QLineEdit::EchoMode
526 
527     This enum type describes how a line edit should display its
528     contents.
529 
530     \value Normal   Display characters as they are entered. This is the
531                     default.
532     \value NoEcho   Do not display anything. This may be appropriate
533                     for passwords where even the length of the
534                     password should be kept secret.
535     \value Password  Display platform-dependent password mask characters instead
536                     of the characters actually entered.
537     \value PasswordEchoOnEdit Display characters as they are entered
538                     while editing otherwise display characters as with
539                     \c Password.
540 
541     \sa setEchoMode(), echoMode()
542 */
543 
544 
545 /*!
546     \property QLineEdit::echoMode
547     \brief the line edit's echo mode.
548 
549     The echo mode determines how the text entered in the line edit is
550     displayed (or echoed) to the user.
551 
552     The most common setting is \l Normal, in which the text entered by the
553     user is displayed verbatim, but QLineEdit also supports modes that allow
554     the entered text to be suppressed or obscured: these include \l NoEcho,
555     \l Password and \l PasswordEchoOnEdit.
556 
557     The widget's display and the ability to copy or drag the text is
558     affected by this setting.
559 
560     By default, this property is set to \l Normal.
561 
562     \sa EchoMode, displayText()
563 */
564 
echoMode() const565 QLineEdit::EchoMode QLineEdit::echoMode() const
566 {
567     Q_D(const QLineEdit);
568     return (EchoMode) d->control->echoMode();
569 }
570 
setEchoMode(EchoMode mode)571 void QLineEdit::setEchoMode(EchoMode mode)
572 {
573     Q_D(QLineEdit);
574     if (mode == (EchoMode)d->control->echoMode())
575         return;
576     Qt::InputMethodHints imHints = inputMethodHints();
577     imHints.setFlag(Qt::ImhHiddenText, mode == Password || mode == NoEcho);
578     imHints.setFlag(Qt::ImhNoAutoUppercase, mode != Normal);
579     imHints.setFlag(Qt::ImhNoPredictiveText, mode != Normal);
580     imHints.setFlag(Qt::ImhSensitiveData, mode != Normal);
581     setInputMethodHints(imHints);
582     d->control->setEchoMode(mode);
583     update();
584 }
585 
586 
587 #ifndef QT_NO_VALIDATOR
588 /*!
589     Returns a pointer to the current input validator, or \nullptr if no
590     validator has been set.
591 
592     \sa setValidator()
593 */
594 
validator() const595 const QValidator * QLineEdit::validator() const
596 {
597     Q_D(const QLineEdit);
598     return d->control->validator();
599 }
600 
601 /*!
602     Sets the validator for values of line edit to \a v.
603 
604     The line edit's returnPressed() and editingFinished() signals will only
605     be emitted if \a v validates the line edit's content as \l{QValidator::}{Acceptable}.
606     The user may change the content to any \l{QValidator::}{Intermediate}
607     value during editing, but will be prevented from editing the text to a
608     value that \a v validates as \l{QValidator::}{Invalid}.
609 
610     This allows you to constrain the text that shall finally be entered when editing is
611     done, while leaving users with enough freedom to edit the text from one valid state
612     to another.
613 
614     If \a v == 0, setValidator() removes the current input validator.
615     The initial setting is to have no input validator (i.e. any input
616     is accepted up to maxLength()).
617 
618     \sa validator(), hasAcceptableInput(), QIntValidator, QDoubleValidator, QRegExpValidator
619 */
620 
setValidator(const QValidator * v)621 void QLineEdit::setValidator(const QValidator *v)
622 {
623     Q_D(QLineEdit);
624     d->control->setValidator(v);
625 }
626 #endif // QT_NO_VALIDATOR
627 
628 #if QT_CONFIG(completer)
629 /*!
630     \since 4.2
631 
632     Sets this line edit to provide auto completions from the completer, \a c.
633     The completion mode is set using QCompleter::setCompletionMode().
634 
635     To use a QCompleter with a QValidator or QLineEdit::inputMask, you need to
636     ensure that the model provided to QCompleter contains valid entries. You can
637     use the QSortFilterProxyModel to ensure that the QCompleter's model contains
638     only valid entries.
639 
640     If \a c == 0, setCompleter() removes the current completer, effectively
641     disabling auto completion.
642 
643     \sa QCompleter
644 */
setCompleter(QCompleter * c)645 void QLineEdit::setCompleter(QCompleter *c)
646 {
647     Q_D(QLineEdit);
648     if (c == d->control->completer())
649         return;
650     if (d->control->completer()) {
651         disconnect(d->control->completer(), nullptr, this, nullptr);
652         d->control->completer()->setWidget(nullptr);
653         if (d->control->completer()->parent() == this)
654             delete d->control->completer();
655     }
656     d->control->setCompleter(c);
657     if (!c)
658         return;
659     if (c->widget() == nullptr)
660         c->setWidget(this);
661     if (hasFocus()) {
662         QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
663                          this, SLOT(setText(QString)));
664         QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
665                          this, SLOT(_q_completionHighlighted(QString)));
666     }
667 }
668 
669 /*!
670     \since 4.2
671 
672     Returns the current QCompleter that provides completions.
673 */
completer() const674 QCompleter *QLineEdit::completer() const
675 {
676     Q_D(const QLineEdit);
677     return d->control->completer();
678 }
679 
680 #endif // QT_CONFIG(completer)
681 
682 /*!
683     Returns a recommended size for the widget.
684 
685     The width returned, in pixels, is usually enough for about 15 to
686     20 characters.
687 */
688 
sizeHint() const689 QSize QLineEdit::sizeHint() const
690 {
691     Q_D(const QLineEdit);
692     ensurePolished();
693     QFontMetrics fm(font());
694     const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
695     const QMargins tm = d->effectiveTextMargins();
696     int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2 * QLineEditPrivate::verticalMargin
697             + tm.top() + tm.bottom()
698             + d->topmargin + d->bottommargin;
699     int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2 * QLineEditPrivate::horizontalMargin
700             + tm.left() + tm.right()
701             + d->leftmargin + d->rightmargin; // "some"
702     QStyleOptionFrame opt;
703     initStyleOption(&opt);
704     return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
705                                       expandedTo(QApplication::globalStrut()), this));
706 }
707 
708 
709 /*!
710     Returns a minimum size for the line edit.
711 
712     The width returned is usually enough for at least one character.
713 */
714 
minimumSizeHint() const715 QSize QLineEdit::minimumSizeHint() const
716 {
717     Q_D(const QLineEdit);
718     ensurePolished();
719     QFontMetrics fm = fontMetrics();
720     const QMargins tm = d->effectiveTextMargins();
721     int h = fm.height() + qMax(2 * QLineEditPrivate::verticalMargin, fm.leading())
722             + tm.top() + tm.bottom()
723             + d->topmargin + d->bottommargin;
724     int w = fm.maxWidth() + 2 * QLineEditPrivate::horizontalMargin
725             + tm.left() + tm.right()
726             + d->leftmargin + d->rightmargin;
727     QStyleOptionFrame opt;
728     initStyleOption(&opt);
729     return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
730                                       expandedTo(QApplication::globalStrut()), this));
731 }
732 
733 
734 /*!
735     \property QLineEdit::cursorPosition
736     \brief the current cursor position for this line edit.
737 
738     Setting the cursor position causes a repaint when appropriate.
739 
740     By default, this property contains a value of 0.
741 */
742 
cursorPosition() const743 int QLineEdit::cursorPosition() const
744 {
745     Q_D(const QLineEdit);
746     return d->control->cursorPosition();
747 }
748 
setCursorPosition(int pos)749 void QLineEdit::setCursorPosition(int pos)
750 {
751     Q_D(QLineEdit);
752     d->control->setCursorPosition(pos);
753 }
754 
755 // ### What should this do if the point is outside of contentsRect? Currently returns 0.
756 /*!
757     Returns the cursor position under the point \a pos.
758 */
cursorPositionAt(const QPoint & pos)759 int QLineEdit::cursorPositionAt(const QPoint &pos)
760 {
761     Q_D(QLineEdit);
762     return d->xToPos(pos.x());
763 }
764 
765 
766 
767 /*!
768     \property QLineEdit::alignment
769     \brief the alignment of the line edit.
770 
771     Both horizontal and vertical alignment is allowed here, Qt::AlignJustify
772     will map to Qt::AlignLeft.
773 
774     By default, this property contains a combination of Qt::AlignLeft and Qt::AlignVCenter.
775 
776     \sa Qt::Alignment
777 */
778 
alignment() const779 Qt::Alignment QLineEdit::alignment() const
780 {
781     Q_D(const QLineEdit);
782     return QFlag(d->alignment);
783 }
784 
setAlignment(Qt::Alignment alignment)785 void QLineEdit::setAlignment(Qt::Alignment alignment)
786 {
787     Q_D(QLineEdit);
788     d->alignment = alignment;
789     update();
790 }
791 
792 
793 /*!
794     Moves the cursor forward \a steps characters. If \a mark is true
795     each character moved over is added to the selection; if \a mark is
796     false the selection is cleared.
797 
798     \sa cursorBackward()
799 */
800 
cursorForward(bool mark,int steps)801 void QLineEdit::cursorForward(bool mark, int steps)
802 {
803     Q_D(QLineEdit);
804     d->control->cursorForward(mark, steps);
805 }
806 
807 
808 /*!
809     Moves the cursor back \a steps characters. If \a mark is true each
810     character moved over is added to the selection; if \a mark is
811     false the selection is cleared.
812 
813     \sa cursorForward()
814 */
cursorBackward(bool mark,int steps)815 void QLineEdit::cursorBackward(bool mark, int steps)
816 {
817     cursorForward(mark, -steps);
818 }
819 
820 /*!
821     Moves the cursor one word forward. If \a mark is true, the word is
822     also selected.
823 
824     \sa cursorWordBackward()
825 */
cursorWordForward(bool mark)826 void QLineEdit::cursorWordForward(bool mark)
827 {
828     Q_D(QLineEdit);
829     d->control->cursorWordForward(mark);
830 }
831 
832 /*!
833     Moves the cursor one word backward. If \a mark is true, the word
834     is also selected.
835 
836     \sa cursorWordForward()
837 */
838 
cursorWordBackward(bool mark)839 void QLineEdit::cursorWordBackward(bool mark)
840 {
841     Q_D(QLineEdit);
842     d->control->cursorWordBackward(mark);
843 }
844 
845 
846 /*!
847     If no text is selected, deletes the character to the left of the
848     text cursor and moves the cursor one position to the left. If any
849     text is selected, the cursor is moved to the beginning of the
850     selected text and the selected text is deleted.
851 
852     \sa del()
853 */
backspace()854 void QLineEdit::backspace()
855 {
856     Q_D(QLineEdit);
857     d->control->backspace();
858 }
859 
860 /*!
861     If no text is selected, deletes the character to the right of the
862     text cursor. If any text is selected, the cursor is moved to the
863     beginning of the selected text and the selected text is deleted.
864 
865     \sa backspace()
866 */
867 
del()868 void QLineEdit::del()
869 {
870     Q_D(QLineEdit);
871     d->control->del();
872 }
873 
874 /*!
875     Moves the text cursor to the beginning of the line unless it is
876     already there. If \a mark is true, text is selected towards the
877     first position; otherwise, any selected text is unselected if the
878     cursor is moved.
879 
880     \sa end()
881 */
882 
home(bool mark)883 void QLineEdit::home(bool mark)
884 {
885     Q_D(QLineEdit);
886     d->control->home(mark);
887 }
888 
889 /*!
890     Moves the text cursor to the end of the line unless it is already
891     there. If \a mark is true, text is selected towards the last
892     position; otherwise, any selected text is unselected if the cursor
893     is moved.
894 
895     \sa home()
896 */
897 
end(bool mark)898 void QLineEdit::end(bool mark)
899 {
900     Q_D(QLineEdit);
901     d->control->end(mark);
902 }
903 
904 
905 /*!
906     \property QLineEdit::modified
907     \brief whether the line edit's contents has been modified by the user.
908 
909     The modified flag is never read by QLineEdit; it has a default value
910     of false and is changed to true whenever the user changes the line
911     edit's contents.
912 
913     This is useful for things that need to provide a default value but
914     do not start out knowing what the default should be (perhaps it
915     depends on other fields on the form). Start the line edit without
916     the best default, and when the default is known, if modified()
917     returns \c false (the user hasn't entered any text), insert the
918     default value.
919 
920     Calling setText() resets the modified flag to false.
921 */
922 
isModified() const923 bool QLineEdit::isModified() const
924 {
925     Q_D(const QLineEdit);
926     return d->control->isModified();
927 }
928 
setModified(bool modified)929 void QLineEdit::setModified(bool modified)
930 {
931     Q_D(QLineEdit);
932     d->control->setModified(modified);
933 }
934 
935 /*!
936     \property QLineEdit::hasSelectedText
937     \brief whether there is any text selected.
938 
939     hasSelectedText() returns \c true if some or all of the text has been
940     selected by the user; otherwise returns \c false.
941 
942     By default, this property is \c false.
943 
944     \sa selectedText()
945 */
946 
947 
hasSelectedText() const948 bool QLineEdit::hasSelectedText() const
949 {
950     Q_D(const QLineEdit);
951     return d->control->hasSelectedText();
952 }
953 
954 /*!
955     \property QLineEdit::selectedText
956     \brief the selected text.
957 
958     If there is no selected text this property's value is
959     an empty string.
960 
961     By default, this property contains an empty string.
962 
963     \sa hasSelectedText()
964 */
965 
selectedText() const966 QString QLineEdit::selectedText() const
967 {
968     Q_D(const QLineEdit);
969     return d->control->selectedText();
970 }
971 
972 /*!
973     Returns the index of the first selected character in the
974     line edit or -1 if no text is selected.
975 
976     \sa selectedText()
977     \sa selectionEnd()
978     \sa selectionLength()
979 */
980 
selectionStart() const981 int QLineEdit::selectionStart() const
982 {
983     Q_D(const QLineEdit);
984     return d->control->selectionStart();
985 }
986 
987 /*!
988     Returns the index of the character directly after the selection
989     in the line edit or -1 if no text is selected.
990     \since 5.10
991 
992     \sa selectedText()
993     \sa selectionStart()
994     \sa selectionLength()
995 */
selectionEnd() const996 int QLineEdit::selectionEnd() const
997 {
998    Q_D(const QLineEdit);
999    return d->control->selectionEnd();
1000 }
1001 
1002 /*!
1003     Returns the length of the selection.
1004     \since 5.10
1005 
1006     \sa selectedText()
1007     \sa selectionStart()
1008     \sa selectionEnd()
1009 */
selectionLength() const1010 int QLineEdit::selectionLength() const
1011 {
1012    return selectionEnd() - selectionStart();
1013 }
1014 
1015 /*!
1016     Selects text from position \a start and for \a length characters.
1017     Negative lengths are allowed.
1018 
1019     \sa deselect(), selectAll(), selectedText()
1020 */
1021 
setSelection(int start,int length)1022 void QLineEdit::setSelection(int start, int length)
1023 {
1024     Q_D(QLineEdit);
1025     if (Q_UNLIKELY(start < 0 || start > (int)d->control->end())) {
1026         qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
1027         return;
1028     }
1029 
1030     d->control->setSelection(start, length);
1031 
1032     if (d->control->hasSelectedText()){
1033         QStyleOptionFrame opt;
1034         initStyleOption(&opt);
1035         if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1036             d->setCursorVisible(false);
1037     }
1038 }
1039 
1040 
1041 /*!
1042     \property QLineEdit::undoAvailable
1043     \brief whether undo is available.
1044 
1045     Undo becomes available once the user has modified the text in the line edit.
1046 
1047     By default, this property is \c false.
1048 */
1049 
isUndoAvailable() const1050 bool QLineEdit::isUndoAvailable() const
1051 {
1052     Q_D(const QLineEdit);
1053     return d->control->isUndoAvailable();
1054 }
1055 
1056 /*!
1057     \property QLineEdit::redoAvailable
1058     \brief whether redo is available.
1059 
1060     Redo becomes available once the user has performed one or more undo operations
1061     on text in the line edit.
1062 
1063     By default, this property is \c false.
1064 */
1065 
isRedoAvailable() const1066 bool QLineEdit::isRedoAvailable() const
1067 {
1068     Q_D(const QLineEdit);
1069     return d->control->isRedoAvailable();
1070 }
1071 
1072 /*!
1073     \property QLineEdit::dragEnabled
1074     \brief whether the lineedit starts a drag if the user presses and
1075     moves the mouse on some selected text.
1076 
1077     Dragging is disabled by default.
1078 */
1079 
dragEnabled() const1080 bool QLineEdit::dragEnabled() const
1081 {
1082     Q_D(const QLineEdit);
1083     return d->dragEnabled;
1084 }
1085 
setDragEnabled(bool b)1086 void QLineEdit::setDragEnabled(bool b)
1087 {
1088     Q_D(QLineEdit);
1089     d->dragEnabled = b;
1090 }
1091 
1092 /*!
1093   \property QLineEdit::cursorMoveStyle
1094   \brief the movement style of cursor in this line edit.
1095   \since 4.8
1096 
1097   When this property is set to Qt::VisualMoveStyle, the line edit will use visual
1098   movement style. Pressing the left arrow key will always cause the cursor to move
1099   left, regardless of the text's writing direction. The same behavior applies to
1100   right arrow key.
1101 
1102   When the property is Qt::LogicalMoveStyle (the default), within a LTR text block,
1103   increase cursor position when pressing left arrow key, decrease cursor position
1104   when pressing the right arrow key. If the text block is right to left, the opposite
1105   behavior applies.
1106 */
1107 
cursorMoveStyle() const1108 Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const
1109 {
1110     Q_D(const QLineEdit);
1111     return d->control->cursorMoveStyle();
1112 }
1113 
setCursorMoveStyle(Qt::CursorMoveStyle style)1114 void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style)
1115 {
1116     Q_D(QLineEdit);
1117     d->control->setCursorMoveStyle(style);
1118 }
1119 
1120 /*!
1121     \property QLineEdit::acceptableInput
1122     \brief whether the input satisfies the inputMask and the
1123     validator.
1124 
1125     By default, this property is \c true.
1126 
1127     \sa setInputMask(), setValidator()
1128 */
hasAcceptableInput() const1129 bool QLineEdit::hasAcceptableInput() const
1130 {
1131     Q_D(const QLineEdit);
1132     return d->control->hasAcceptableInput();
1133 }
1134 
1135 /*!
1136     Sets the margins around the text inside the frame to have the
1137     sizes \a left, \a top, \a right, and \a bottom.
1138     \since 4.5
1139 
1140     See also textMargins().
1141 */
setTextMargins(int left,int top,int right,int bottom)1142 void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
1143 {
1144     setTextMargins({left, top, right, bottom});
1145 }
1146 
1147 /*!
1148     \since 4.6
1149     Sets the \a margins around the text inside the frame.
1150 
1151     See also textMargins().
1152 */
setTextMargins(const QMargins & margins)1153 void QLineEdit::setTextMargins(const QMargins &margins)
1154 {
1155     Q_D(QLineEdit);
1156     d->textMargins = margins;
1157     updateGeometry();
1158     update();
1159 }
1160 
1161 #if QT_DEPRECATED_SINCE(5, 14)
1162 /*!
1163     \obsolete
1164     Use textMargins()
1165 
1166     Returns the widget's text margins for \a left, \a top, \a right, and \a bottom.
1167     \since 4.5
1168 
1169     \sa setTextMargins()
1170 */
getTextMargins(int * left,int * top,int * right,int * bottom) const1171 void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) const
1172 {
1173     QMargins m = textMargins();
1174     if (left)
1175         *left = m.left();
1176     if (top)
1177         *top = m.top();
1178     if (right)
1179         *right = m.right();
1180     if (bottom)
1181         *bottom = m.bottom();
1182 }
1183 #endif
1184 
1185 /*!
1186     \since 4.6
1187     Returns the widget's text margins.
1188 
1189     \sa setTextMargins()
1190 */
textMargins() const1191 QMargins QLineEdit::textMargins() const
1192 {
1193     Q_D(const QLineEdit);
1194     return d->textMargins;
1195 }
1196 
1197 /*!
1198     \property QLineEdit::inputMask
1199     \brief The validation input mask.
1200 
1201     If no mask is set, inputMask() returns an empty string.
1202 
1203     Sets the QLineEdit's validation mask. Validators can be used
1204     instead of, or in conjunction with masks; see setValidator().
1205 
1206     Unset the mask and return to normal QLineEdit operation by passing
1207     an empty string ("").
1208 
1209     The input mask is an input template string. It can contain the following elements:
1210     \table
1211     \row \li Mask Characters \li Defines the \l {QChar::} {Category} of input characters
1212     that are considered valid in this position
1213     \row \li Meta Characters \li Various special meanings
1214     \row \li Separators \li All other characters are regarded as immutable separators
1215     \endtable
1216 
1217     The following table shows the mask and meta characters that can be used in an input mask.
1218 
1219     \table
1220     \header \li Mask Character \li Meaning
1221     \row \li \c A \li character of the Letter category required, such as A-Z, a-z.
1222     \row \li \c a \li character of the Letter category permitted but not required.
1223     \row \li \c N \li character of the Letter or Number category required, such as
1224                       A-Z, a-z, 0-9.
1225     \row \li \c n \li character of the Letter or Number category permitted but not required.
1226     \row \li \c X \li Any non-blank character required.
1227     \row \li \c x \li Any non-blank character permitted but not required.
1228     \row \li \c 9 \li character of the Number category required, e.g 0-9.
1229     \row \li \c 0 \li character of the Number category permitted but not required.
1230     \row \li \c D \li character of the Number category and larger than zero required,
1231                       such as 1-9
1232     \row \li \c d \li character of the Number category and larger than zero permitted but not
1233                       required, such as 1-9.
1234     \row \li \c # \li character of the Number category, or plus/minus sign permitted but not
1235                       required.
1236     \row \li \c H \li Hexadecimal character required. A-F, a-f, 0-9.
1237     \row \li \c h \li Hexadecimal character permitted but not required.
1238     \row \li \c B \li Binary character required. 0-1.
1239     \row \li \c b \li Binary character permitted but not required.
1240     \header \li Meta Character \li Meaning
1241     \row \li \c > \li All following alphabetic characters are uppercased.
1242     \row \li \c < \li All following alphabetic characters are lowercased.
1243     \row \li \c ! \li Switch off case conversion.
1244     \row \li \c {;c} \li Terminates the input mask and sets the \e{blank} character to \e{c}.
1245     \row \li \c {[ ] { }} \li Reserved.
1246     \row \li \tt{\\} \li Use \tt{\\} to escape the special
1247                            characters listed above to use them as
1248                            separators.
1249     \endtable
1250 
1251     When created or cleared, the line edit will be filled with a copy of the
1252     input mask string where the meta characters have been removed, and the mask
1253     characters have been replaced with the \e{blank} character (by default, a
1254     \c space).
1255 
1256     When an input mask is set, the text() method returns a modified copy of the
1257     line edit content where all the \e{blank} characters have been removed. The
1258     unmodified content can be read using displayText().
1259 
1260     The hasAcceptableInput() method returns false if the current content of the
1261     line edit does not fulfil the requirements of the input mask.
1262 
1263     Examples:
1264     \table
1265     \header \li Mask \li Notes
1266     \row \li \c 000.000.000.000;_ \li IP address; blanks are \c{_}.
1267     \row \li \c HH:HH:HH:HH:HH:HH;_ \li MAC address
1268     \row \li \c 0000-00-00 \li ISO Date; blanks are \c space
1269     \row \li \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \li License number;
1270     blanks are \c{#} and all (alphabetic) characters are converted to
1271     uppercase.
1272     \endtable
1273 
1274     To get range control (e.g., for an IP address) use masks together
1275     with \l{setValidator()}{validators}.
1276 
1277     \sa maxLength, QChar::isLetter(), QChar::isNumber(), QChar::digitValue()
1278 */
inputMask() const1279 QString QLineEdit::inputMask() const
1280 {
1281     Q_D(const QLineEdit);
1282     return d->control->inputMask();
1283 }
1284 
setInputMask(const QString & inputMask)1285 void QLineEdit::setInputMask(const QString &inputMask)
1286 {
1287     Q_D(QLineEdit);
1288     d->control->setInputMask(inputMask);
1289 }
1290 
1291 /*!
1292     Selects all the text (i.e. highlights it) and moves the cursor to
1293     the end. This is useful when a default value has been inserted
1294     because if the user types before clicking on the widget, the
1295     selected text will be deleted.
1296 
1297     \sa setSelection(), deselect()
1298 */
1299 
selectAll()1300 void QLineEdit::selectAll()
1301 {
1302     Q_D(QLineEdit);
1303     d->control->selectAll();
1304 }
1305 
1306 /*!
1307     Deselects any selected text.
1308 
1309     \sa setSelection(), selectAll()
1310 */
1311 
deselect()1312 void QLineEdit::deselect()
1313 {
1314     Q_D(QLineEdit);
1315     d->control->deselect();
1316 }
1317 
1318 
1319 /*!
1320     Deletes any selected text, inserts \a newText, and validates the
1321     result. If it is valid, it sets it as the new contents of the line
1322     edit.
1323 
1324     \sa setText(), clear()
1325 */
insert(const QString & newText)1326 void QLineEdit::insert(const QString &newText)
1327 {
1328 //     q->resetInputContext(); //#### FIX ME IN QT
1329     Q_D(QLineEdit);
1330     d->control->insert(newText);
1331 }
1332 
1333 /*!
1334     Clears the contents of the line edit.
1335 
1336     \sa setText(), insert()
1337 */
clear()1338 void QLineEdit::clear()
1339 {
1340     Q_D(QLineEdit);
1341     d->resetInputMethod();
1342     d->control->clear();
1343 }
1344 
1345 /*!
1346     Undoes the last operation if undo is \l{QLineEdit::undoAvailable}{available}. Deselects any current
1347     selection, and updates the selection start to the current cursor
1348     position.
1349 */
undo()1350 void QLineEdit::undo()
1351 {
1352     Q_D(QLineEdit);
1353     d->resetInputMethod();
1354     d->control->undo();
1355 }
1356 
1357 /*!
1358     Redoes the last operation if redo is \l{QLineEdit::redoAvailable}{available}.
1359 */
redo()1360 void QLineEdit::redo()
1361 {
1362     Q_D(QLineEdit);
1363     d->resetInputMethod();
1364     d->control->redo();
1365 }
1366 
1367 
1368 /*!
1369     \property QLineEdit::readOnly
1370     \brief whether the line edit is read only.
1371 
1372     In read-only mode, the user can still copy the text to the
1373     clipboard, or drag and drop the text (if echoMode() is \l Normal),
1374     but cannot edit it.
1375 
1376     QLineEdit does not show a cursor in read-only mode.
1377 
1378     By default, this property is \c false.
1379 
1380     \sa setEnabled()
1381 */
1382 
isReadOnly() const1383 bool QLineEdit::isReadOnly() const
1384 {
1385     Q_D(const QLineEdit);
1386     return d->control->isReadOnly();
1387 }
1388 
setReadOnly(bool enable)1389 void QLineEdit::setReadOnly(bool enable)
1390 {
1391     Q_D(QLineEdit);
1392     if (d->control->isReadOnly() != enable) {
1393         d->control->setReadOnly(enable);
1394         d->setClearButtonEnabled(!enable);
1395         setAttribute(Qt::WA_MacShowFocusRect, !enable);
1396         setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
1397 #ifndef QT_NO_CURSOR
1398         setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
1399 #endif
1400         QEvent event(QEvent::ReadOnlyChange);
1401         QCoreApplication::sendEvent(this, &event);
1402         update();
1403 #ifndef QT_NO_ACCESSIBILITY
1404         QAccessible::State changedState;
1405         changedState.readOnly = true;
1406         QAccessibleStateChangeEvent ev(this, changedState);
1407         QAccessible::updateAccessibility(&ev);
1408 #endif
1409     }
1410 }
1411 
1412 
1413 #ifndef QT_NO_CLIPBOARD
1414 /*!
1415     Copies the selected text to the clipboard and deletes it, if there
1416     is any, and if echoMode() is \l Normal.
1417 
1418     If the current validator disallows deleting the selected text,
1419     cut() will copy without deleting.
1420 
1421     \sa copy(), paste(), setValidator()
1422 */
1423 
cut()1424 void QLineEdit::cut()
1425 {
1426     if (hasSelectedText()) {
1427         copy();
1428         del();
1429     }
1430 }
1431 
1432 
1433 /*!
1434     Copies the selected text to the clipboard, if there is any, and if
1435     echoMode() is \l Normal.
1436 
1437     \sa cut(), paste()
1438 */
1439 
copy() const1440 void QLineEdit::copy() const
1441 {
1442     Q_D(const QLineEdit);
1443     d->control->copy();
1444 }
1445 
1446 /*!
1447     Inserts the clipboard's text at the cursor position, deleting any
1448     selected text, providing the line edit is not \l{QLineEdit::readOnly}{read-only}.
1449 
1450     If the end result would be invalid to the current
1451     \l{setValidator()}{validator}, nothing happens.
1452 
1453     \sa copy(), cut()
1454 */
1455 
paste()1456 void QLineEdit::paste()
1457 {
1458     Q_D(QLineEdit);
1459     d->control->paste();
1460 }
1461 
1462 #endif // !QT_NO_CLIPBOARD
1463 
1464 /*! \reimp
1465 */
event(QEvent * e)1466 bool QLineEdit::event(QEvent * e)
1467 {
1468     Q_D(QLineEdit);
1469     if (e->type() == QEvent::Timer) {
1470         // ### Qt6: move to timerEvent, is here for binary compatibility
1471         int timerId = ((QTimerEvent*)e)->timerId();
1472         if (false) {
1473 #if QT_CONFIG(draganddrop)
1474         } else if (timerId == d->dndTimer.timerId()) {
1475             d->drag();
1476 #endif
1477         }
1478         else if (timerId == d->tripleClickTimer.timerId())
1479             d->tripleClickTimer.stop();
1480     } else if (e->type() == QEvent::ContextMenu) {
1481 #ifndef QT_NO_IM
1482         if (d->control->composeMode())
1483             return true;
1484 #endif
1485         //d->separate();
1486     } else if (e->type() == QEvent::WindowActivate) {
1487         QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
1488 #ifndef QT_NO_SHORTCUT
1489     } else if (e->type() == QEvent::ShortcutOverride) {
1490         QKeyEvent *ke = static_cast<QKeyEvent*>(e);
1491         d->control->processShortcutOverrideEvent(ke);
1492 #endif
1493     } else if (e->type() == QEvent::KeyRelease) {
1494         d->control->updateCursorBlinking();
1495     } else if (e->type() == QEvent::Show) {
1496         //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
1497         if (hasFocus()) {
1498             d->control->setBlinkingCursorEnabled(true);
1499             QStyleOptionFrame opt;
1500             initStyleOption(&opt);
1501             if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
1502                 || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1503                 d->setCursorVisible(true);
1504         }
1505 #if QT_CONFIG(action)
1506     } else if (e->type() == QEvent::ActionRemoved) {
1507         d->removeAction(static_cast<QActionEvent *>(e)->action());
1508 #endif
1509     } else if (e->type() == QEvent::Resize) {
1510         d->positionSideWidgets();
1511     } else if (e->type() == QEvent::StyleChange) {
1512         d->initMouseYThreshold();
1513     }
1514 #ifdef QT_KEYPAD_NAVIGATION
1515     if (QApplicationPrivate::keypadNavigationEnabled()) {
1516         if (e->type() == QEvent::EnterEditFocus) {
1517             end(false);
1518             d->setCursorVisible(true);
1519             d->control->setCursorBlinkEnabled(true);
1520         } else if (e->type() == QEvent::LeaveEditFocus) {
1521             d->setCursorVisible(false);
1522             d->control->setCursorBlinkEnabled(false);
1523             if (d->edited && (d->control->hasAcceptableInput()
1524                               || d->control->fixup())) {
1525                 emit editingFinished();
1526                 d->edited = false;
1527             }
1528         }
1529     }
1530 #endif
1531     return QWidget::event(e);
1532 }
1533 
1534 /*! \reimp
1535 */
mousePressEvent(QMouseEvent * e)1536 void QLineEdit::mousePressEvent(QMouseEvent* e)
1537 {
1538     Q_D(QLineEdit);
1539 
1540     d->mousePressPos = e->pos();
1541 
1542     if (d->sendMouseEventToInputContext(e))
1543         return;
1544     if (e->button() == Qt::RightButton)
1545         return;
1546 #ifdef QT_KEYPAD_NAVIGATION
1547     if (QApplication::QApplicationPrivate() && !hasEditFocus()) {
1548         setEditFocus(true);
1549         // Get the completion list to pop up.
1550         if (d->control->completer())
1551             d->control->completer()->complete();
1552     }
1553 #endif
1554     if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
1555          QApplication::startDragDistance()) {
1556         selectAll();
1557         return;
1558     }
1559     bool mark = e->modifiers() & Qt::ShiftModifier;
1560 #ifdef Q_OS_ANDROID
1561     mark = mark && (d->imHints & Qt::ImhNoPredictiveText);
1562 #endif // Q_OS_ANDROID
1563     int cursor = d->xToPos(e->pos().x());
1564 #if QT_CONFIG(draganddrop)
1565     if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
1566          e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) {
1567         if (!d->dndTimer.isActive())
1568             d->dndTimer.start(QApplication::startDragTime(), this);
1569     } else
1570 #endif
1571     {
1572         d->control->moveCursor(cursor, mark);
1573     }
1574 }
1575 
1576 /*! \reimp
1577 */
mouseMoveEvent(QMouseEvent * e)1578 void QLineEdit::mouseMoveEvent(QMouseEvent * e)
1579 {
1580     Q_D(QLineEdit);
1581 
1582     if (e->buttons() & Qt::LeftButton) {
1583 #if QT_CONFIG(draganddrop)
1584         if (d->dndTimer.isActive()) {
1585             if ((d->mousePressPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
1586                 d->drag();
1587         } else
1588 #endif
1589         {
1590 #ifndef Q_OS_ANDROID
1591             const bool select = true;
1592 #else
1593             const bool select = (d->imHints & Qt::ImhNoPredictiveText);
1594 #endif
1595 #ifndef QT_NO_IM
1596             if (d->mouseYThreshold > 0 && e->pos().y() > d->mousePressPos.y() + d->mouseYThreshold) {
1597                 if (layoutDirection() == Qt::RightToLeft)
1598                     d->control->home(select);
1599                 else
1600                     d->control->end(select);
1601             } else if (d->mouseYThreshold > 0 && e->pos().y() + d->mouseYThreshold < d->mousePressPos.y()) {
1602                 if (layoutDirection() == Qt::RightToLeft)
1603                     d->control->end(select);
1604                 else
1605                     d->control->home(select);
1606             } else if (d->control->composeMode() && select) {
1607                 int startPos = d->xToPos(d->mousePressPos.x());
1608                 int currentPos = d->xToPos(e->pos().x());
1609                 if (startPos != currentPos)
1610                     d->control->setSelection(startPos, currentPos - startPos);
1611 
1612             } else
1613 #endif
1614             {
1615                 d->control->moveCursor(d->xToPos(e->pos().x()), select);
1616             }
1617         }
1618     }
1619 
1620     d->sendMouseEventToInputContext(e);
1621 }
1622 
1623 /*! \reimp
1624 */
mouseReleaseEvent(QMouseEvent * e)1625 void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
1626 {
1627     Q_D(QLineEdit);
1628     if (d->sendMouseEventToInputContext(e))
1629         return;
1630 #if QT_CONFIG(draganddrop)
1631     if (e->button() == Qt::LeftButton) {
1632         if (d->dndTimer.isActive()) {
1633             d->dndTimer.stop();
1634             deselect();
1635             return;
1636         }
1637     }
1638 #endif
1639 #ifndef QT_NO_CLIPBOARD
1640     if (QGuiApplication::clipboard()->supportsSelection()) {
1641         if (e->button() == Qt::LeftButton) {
1642             d->control->copy(QClipboard::Selection);
1643         } else if (!d->control->isReadOnly() && e->button() == Qt::MiddleButton) {
1644             deselect();
1645             d->control->paste(QClipboard::Selection);
1646         }
1647     }
1648 #endif
1649 
1650     if (!isReadOnly() && rect().contains(e->pos()))
1651         d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
1652     d->clickCausedFocus = 0;
1653 }
1654 
1655 /*! \reimp
1656 */
mouseDoubleClickEvent(QMouseEvent * e)1657 void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
1658 {
1659     Q_D(QLineEdit);
1660 
1661     if (e->button() == Qt::LeftButton) {
1662         int position = d->xToPos(e->pos().x());
1663 
1664         // exit composition mode
1665 #ifndef QT_NO_IM
1666         if (d->control->composeMode()) {
1667             int preeditPos = d->control->cursor();
1668             int posInPreedit = position - d->control->cursor();
1669             int preeditLength = d->control->preeditAreaText().length();
1670             bool positionOnPreedit = false;
1671 
1672             if (posInPreedit >= 0 && posInPreedit <= preeditLength)
1673                 positionOnPreedit = true;
1674 
1675             int textLength = d->control->end();
1676             d->control->commitPreedit();
1677             int sizeChange = d->control->end() - textLength;
1678 
1679             if (positionOnPreedit) {
1680                 if (sizeChange == 0)
1681                     position = -1; // cancel selection, word disappeared
1682                 else
1683                     // ensure not selecting after preedit if event happened there
1684                     position = qBound(preeditPos, position, preeditPos + sizeChange);
1685             } else if (position > preeditPos) {
1686                 // adjust positions after former preedit by how much text changed
1687                 position += (sizeChange - preeditLength);
1688             }
1689         }
1690 #endif
1691 
1692         if (position >= 0)
1693             d->control->selectWordAtPos(position);
1694 
1695         d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
1696         d->tripleClick = e->pos();
1697     } else {
1698         d->sendMouseEventToInputContext(e);
1699     }
1700 }
1701 
1702 /*!
1703     \fn void  QLineEdit::returnPressed()
1704 
1705     This signal is emitted when the Return or Enter key is pressed.
1706     Note that if there is a validator() or inputMask() set on the line
1707     edit, the returnPressed() signal will only be emitted if the input
1708     follows the inputMask() and the validator() returns
1709     QValidator::Acceptable.
1710 */
1711 
1712 /*!
1713     \fn void  QLineEdit::editingFinished()
1714 
1715     This signal is emitted when the Return or Enter key is pressed or
1716     the line edit loses focus. Note that if there is a validator() or
1717     inputMask() set on the line edit and enter/return is pressed, the
1718     editingFinished() signal will only be emitted if the input follows
1719     the inputMask() and the validator() returns QValidator::Acceptable.
1720 */
1721 
1722 /*!
1723     \fn void QLineEdit::inputRejected()
1724     \since 5.12
1725 
1726     This signal is emitted when the user presses a key that is not
1727     considered to be acceptable input. For example, if a key press
1728     results in a validator's validate() call to return Invalid.
1729     Another case is when trying to enter in more characters beyond the
1730     maximum length of the line edit.
1731 
1732     Note: This signal will still be emitted in a case where part of
1733     the text is accepted but not all of it is. For example, if there
1734     is a maximum length set and the clipboard text is longer than the
1735     maximum length when it is pasted.
1736 */
1737 
1738 /*!
1739     Converts the given key press \a event into a line edit action.
1740 
1741     If Return or Enter is pressed and the current text is valid (or
1742     can be \l{QValidator::fixup()}{made valid} by the
1743     validator), the signal returnPressed() is emitted.
1744 
1745     The default key bindings are listed in the class's detailed
1746     description.
1747 */
1748 
keyPressEvent(QKeyEvent * event)1749 void QLineEdit::keyPressEvent(QKeyEvent *event)
1750 {
1751     Q_D(QLineEdit);
1752     #ifdef QT_KEYPAD_NAVIGATION
1753     bool select = false;
1754     switch (event->key()) {
1755         case Qt::Key_Select:
1756             if (QApplicationPrivate::keypadNavigationEnabled()) {
1757                 if (hasEditFocus()) {
1758                     setEditFocus(false);
1759                     if (d->control->completer() && d->control->completer()->popup()->isVisible())
1760                         d->control->completer()->popup()->hide();
1761                     select = true;
1762                 }
1763             }
1764             break;
1765         case Qt::Key_Back:
1766         case Qt::Key_No:
1767             if (!QApplicationPrivate::keypadNavigationEnabled() || !hasEditFocus()) {
1768                 event->ignore();
1769                 return;
1770             }
1771             break;
1772         default:
1773             if (QApplicationPrivate::keypadNavigationEnabled()) {
1774                 if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) {
1775                     if (!event->text().isEmpty() && event->text().at(0).isPrint()
1776                         && !isReadOnly())
1777                         setEditFocus(true);
1778                     else {
1779                         event->ignore();
1780                         return;
1781                     }
1782                 }
1783             }
1784     }
1785 
1786 
1787 
1788     if (QApplicationPrivate::keypadNavigationEnabled() && !select && !hasEditFocus()) {
1789         setEditFocus(true);
1790         if (event->key() == Qt::Key_Select)
1791             return; // Just start. No action.
1792     }
1793 #endif
1794     d->control->processKeyEvent(event);
1795     if (event->isAccepted()) {
1796         if (layoutDirection() != d->control->layoutDirection())
1797             setLayoutDirection(d->control->layoutDirection());
1798         d->control->updateCursorBlinking();
1799     }
1800 }
1801 
1802 /*!
1803   \since 4.4
1804 
1805   Returns a rectangle that includes the lineedit cursor.
1806 */
cursorRect() const1807 QRect QLineEdit::cursorRect() const
1808 {
1809     Q_D(const QLineEdit);
1810     return d->cursorRect();
1811 }
1812 
1813 /*! \reimp
1814  */
inputMethodEvent(QInputMethodEvent * e)1815 void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
1816 {
1817     Q_D(QLineEdit);
1818     if (d->control->isReadOnly()) {
1819         e->ignore();
1820         return;
1821     }
1822 
1823     if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
1824         // Clear the edit and reset to normal echo mode while entering input
1825         // method data; the echo mode switches back when the edit loses focus.
1826         // ### changes a public property, resets current content.
1827         d->updatePasswordEchoEditing(true);
1828         clear();
1829     }
1830 
1831 #ifdef QT_KEYPAD_NAVIGATION
1832     // Focus in if currently in navigation focus on the widget
1833     // Only focus in on preedits, to allow input methods to
1834     // commit text as they focus out without interfering with focus
1835     if (QApplicationPrivate::keypadNavigationEnabled()
1836         && hasFocus() && !hasEditFocus()
1837         && !e->preeditString().isEmpty())
1838         setEditFocus(true);
1839 #endif
1840 
1841     d->control->processInputMethodEvent(e);
1842 
1843 #if QT_CONFIG(completer)
1844     if (!e->commitString().isEmpty())
1845         d->control->complete(Qt::Key_unknown);
1846 #endif
1847 }
1848 
1849 /*!\reimp
1850 */
inputMethodQuery(Qt::InputMethodQuery property) const1851 QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
1852 {
1853     return inputMethodQuery(property, QVariant());
1854 }
1855 
1856 /*!\internal
1857 */
inputMethodQuery(Qt::InputMethodQuery property,QVariant argument) const1858 QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
1859 {
1860     Q_D(const QLineEdit);
1861     switch(property) {
1862     case Qt::ImCursorRectangle:
1863         return d->cursorRect();
1864     case Qt::ImAnchorRectangle:
1865         return d->adjustedControlRect(d->control->anchorRect());
1866     case Qt::ImFont:
1867         return font();
1868     case Qt::ImCursorPosition: {
1869         const QPointF pt = argument.toPointF();
1870         if (!pt.isNull())
1871             return QVariant(d->xToPos(pt.x(), QTextLine::CursorBetweenCharacters));
1872         return QVariant(d->control->cursor()); }
1873     case Qt::ImSurroundingText:
1874         return QVariant(d->control->surroundingText());
1875     case Qt::ImCurrentSelection:
1876         return QVariant(selectedText());
1877     case Qt::ImMaximumTextLength:
1878         return QVariant(maxLength());
1879     case Qt::ImAnchorPosition:
1880         if (d->control->selectionStart() == d->control->selectionEnd())
1881             return QVariant(d->control->cursor());
1882         else if (d->control->selectionStart() == d->control->cursor())
1883             return QVariant(d->control->selectionEnd());
1884         else
1885             return QVariant(d->control->selectionStart());
1886     default:
1887         return QWidget::inputMethodQuery(property);
1888     }
1889 }
1890 
1891 /*!\reimp
1892 */
1893 
focusInEvent(QFocusEvent * e)1894 void QLineEdit::focusInEvent(QFocusEvent *e)
1895 {
1896     Q_D(QLineEdit);
1897     if (e->reason() == Qt::TabFocusReason ||
1898          e->reason() == Qt::BacktabFocusReason  ||
1899          e->reason() == Qt::ShortcutFocusReason) {
1900         if (!d->control->inputMask().isEmpty())
1901             d->control->moveCursor(d->control->nextMaskBlank(0));
1902         else if (!d->control->hasSelectedText())
1903             selectAll();
1904     } else if (e->reason() == Qt::MouseFocusReason) {
1905         d->clickCausedFocus = 1;
1906     }
1907 #ifdef QT_KEYPAD_NAVIGATION
1908     if (!QApplicationPrivate::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) {
1909 #endif
1910     d->control->setBlinkingCursorEnabled(true);
1911     QStyleOptionFrame opt;
1912     initStyleOption(&opt);
1913     if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
1914        || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1915         d->setCursorVisible(true);
1916 #ifdef QT_KEYPAD_NAVIGATION
1917         d->control->setCancelText(d->control->text());
1918     }
1919 #endif
1920 #if QT_CONFIG(completer)
1921     if (d->control->completer()) {
1922         d->control->completer()->setWidget(this);
1923         QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
1924                          this, SLOT(setText(QString)));
1925         QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
1926                          this, SLOT(_q_completionHighlighted(QString)));
1927     }
1928 #endif
1929     update();
1930 }
1931 
1932 /*!\reimp
1933 */
focusOutEvent(QFocusEvent * e)1934 void QLineEdit::focusOutEvent(QFocusEvent *e)
1935 {
1936     Q_D(QLineEdit);
1937     if (d->control->passwordEchoEditing()) {
1938         // Reset the echomode back to PasswordEchoOnEdit when the widget loses
1939         // focus.
1940         d->updatePasswordEchoEditing(false);
1941     }
1942 
1943     Qt::FocusReason reason = e->reason();
1944     if (reason != Qt::ActiveWindowFocusReason &&
1945         reason != Qt::PopupFocusReason)
1946         deselect();
1947 
1948     d->setCursorVisible(false);
1949     d->control->setBlinkingCursorEnabled(false);
1950 #ifdef QT_KEYPAD_NAVIGATION
1951     // editingFinished() is already emitted on LeaveEditFocus
1952     if (!QApplicationPrivate::keypadNavigationEnabled())
1953 #endif
1954     if (reason != Qt::PopupFocusReason
1955         || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
1956             if (d->edited && (hasAcceptableInput() || d->control->fixup())) {
1957                 emit editingFinished();
1958                 d->edited = false;
1959             }
1960     }
1961 #ifdef QT_KEYPAD_NAVIGATION
1962     d->control->setCancelText(QString());
1963 #endif
1964 #if QT_CONFIG(completer)
1965     if (d->control->completer()) {
1966         QObject::disconnect(d->control->completer(), nullptr, this, nullptr);
1967     }
1968 #endif
1969     QWidget::focusOutEvent(e);
1970 }
1971 
1972 /*!\reimp
1973 */
paintEvent(QPaintEvent *)1974 void QLineEdit::paintEvent(QPaintEvent *)
1975 {
1976     Q_D(QLineEdit);
1977     QPainter p(this);
1978     QPalette pal = palette();
1979 
1980     QStyleOptionFrame panel;
1981     initStyleOption(&panel);
1982     style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
1983     QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
1984     r = r.marginsRemoved(d->effectiveTextMargins());
1985     p.setClipRect(r);
1986 
1987     QFontMetrics fm = fontMetrics();
1988     Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment));
1989     switch (va & Qt::AlignVertical_Mask) {
1990      case Qt::AlignBottom:
1991          d->vscroll = r.y() + r.height() - fm.height() - QLineEditPrivate::verticalMargin;
1992          break;
1993      case Qt::AlignTop:
1994          d->vscroll = r.y() + QLineEditPrivate::verticalMargin;
1995          break;
1996      default:
1997          //center
1998          d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
1999          break;
2000     }
2001     QRect lineRect(r.x() + QLineEditPrivate::horizontalMargin, d->vscroll,
2002                    r.width() - 2 * QLineEditPrivate::horizontalMargin, fm.height());
2003 
2004     if (d->shouldShowPlaceholderText()) {
2005         if (!d->placeholderText.isEmpty()) {
2006             const Qt::LayoutDirection layoutDir = d->placeholderText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
2007             const Qt::Alignment alignPhText = QStyle::visualAlignment(layoutDir, QFlag(d->alignment));
2008             const QColor col = pal.placeholderText().color();
2009             QPen oldpen = p.pen();
2010             p.setPen(col);
2011             Qt::LayoutDirection oldLayoutDir = p.layoutDirection();
2012             p.setLayoutDirection(layoutDir);
2013 
2014             const QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, lineRect.width());
2015             p.drawText(lineRect, alignPhText, elidedText);
2016             p.setPen(oldpen);
2017             p.setLayoutDirection(oldLayoutDir);
2018         }
2019     }
2020 
2021     int cix = qRound(d->control->cursorToX());
2022 
2023     // horizontal scrolling. d->hscroll is the left indent from the beginning
2024     // of the text line to the left edge of lineRect. we update this value
2025     // depending on the delta from the last paint event; in effect this means
2026     // the below code handles all scrolling based on the textline (widthUsed),
2027     // the line edit rect (lineRect) and the cursor position (cix).
2028     int widthUsed = qRound(d->control->naturalTextWidth()) + 1;
2029     if (widthUsed <= lineRect.width()) {
2030         // text fits in lineRect; use hscroll for alignment
2031         switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
2032         case Qt::AlignRight:
2033             d->hscroll = widthUsed - lineRect.width() + 1;
2034             break;
2035         case Qt::AlignHCenter:
2036             d->hscroll = (widthUsed - lineRect.width()) / 2;
2037             break;
2038         default:
2039             // Left
2040             d->hscroll = 0;
2041             break;
2042         }
2043     } else if (cix - d->hscroll >= lineRect.width()) {
2044         // text doesn't fit, cursor is to the right of lineRect (scroll right)
2045         d->hscroll = cix - lineRect.width() + 1;
2046     } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
2047         // text doesn't fit, cursor is to the left of lineRect (scroll left)
2048         d->hscroll = cix;
2049     } else if (widthUsed - d->hscroll < lineRect.width()) {
2050         // text doesn't fit, text document is to the left of lineRect; align
2051         // right
2052         d->hscroll = widthUsed - lineRect.width() + 1;
2053     } else {
2054         //in case the text is bigger than the lineedit, the hscroll can never be negative
2055         d->hscroll = qMax(0, d->hscroll);
2056     }
2057 
2058     // the y offset is there to keep the baseline constant in case we have script changes in the text.
2059     // Needs to be kept in sync with QLineEditPrivate::adjustedControlRect
2060     QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
2061 
2062     // draw text, selections and cursors
2063 #ifndef QT_NO_STYLE_STYLESHEET
2064     if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) {
2065         cssStyle->styleSheetPalette(this, &panel, &pal);
2066     }
2067 #endif
2068     p.setPen(pal.text().color());
2069 
2070     int flags = QWidgetLineControl::DrawText;
2071 
2072 #ifdef QT_KEYPAD_NAVIGATION
2073     if (!QApplicationPrivate::keypadNavigationEnabled() || hasEditFocus())
2074 #endif
2075     if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){
2076         flags |= QWidgetLineControl::DrawSelections;
2077         // Palette only used for selections/mask and may not be in sync
2078         if (d->control->palette() != pal
2079            || d->control->palette().currentColorGroup() != pal.currentColorGroup())
2080             d->control->setPalette(pal);
2081     }
2082 
2083     // Asian users see an IM selection text as cursor on candidate
2084     // selection phase of input method, so the ordinary cursor should be
2085     // invisible if we have a preedit string.
2086     if (d->cursorVisible && !d->control->isReadOnly())
2087         flags |= QWidgetLineControl::DrawCursor;
2088 
2089     d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth, &panel));
2090     d->control->draw(&p, topLeft, r, flags);
2091 
2092 }
2093 
2094 
2095 #if QT_CONFIG(draganddrop)
2096 /*!\reimp
2097 */
dragMoveEvent(QDragMoveEvent * e)2098 void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
2099 {
2100     Q_D(QLineEdit);
2101     if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
2102         e->acceptProposedAction();
2103         d->control->moveCursor(d->xToPos(e->pos().x()), false);
2104         d->cursorVisible = true;
2105         update();
2106     }
2107 }
2108 
2109 /*!\reimp */
dragEnterEvent(QDragEnterEvent * e)2110 void QLineEdit::dragEnterEvent(QDragEnterEvent * e)
2111 {
2112     QLineEdit::dragMoveEvent(e);
2113 }
2114 
2115 /*!\reimp */
dragLeaveEvent(QDragLeaveEvent *)2116 void QLineEdit::dragLeaveEvent(QDragLeaveEvent *)
2117 {
2118     Q_D(QLineEdit);
2119     if (d->cursorVisible) {
2120         d->cursorVisible = false;
2121         update();
2122     }
2123 }
2124 
2125 /*!\reimp */
dropEvent(QDropEvent * e)2126 void QLineEdit::dropEvent(QDropEvent* e)
2127 {
2128     Q_D(QLineEdit);
2129     QString str = e->mimeData()->text();
2130 
2131     if (!str.isNull() && !d->control->isReadOnly()) {
2132         if (e->source() == this && e->dropAction() == Qt::CopyAction)
2133             deselect();
2134         int cursorPos = d->xToPos(e->pos().x());
2135         int selStart = cursorPos;
2136         int oldSelStart = d->control->selectionStart();
2137         int oldSelEnd = d->control->selectionEnd();
2138         d->control->moveCursor(cursorPos, false);
2139         d->cursorVisible = false;
2140         e->acceptProposedAction();
2141         insert(str);
2142         if (e->source() == this) {
2143             if (e->dropAction() == Qt::MoveAction) {
2144                 if (selStart > oldSelStart && selStart <= oldSelEnd)
2145                     setSelection(oldSelStart, str.length());
2146                 else if (selStart > oldSelEnd)
2147                     setSelection(selStart - str.length(), str.length());
2148                 else
2149                     setSelection(selStart, str.length());
2150             } else {
2151                 setSelection(selStart, str.length());
2152             }
2153         }
2154     } else {
2155         e->ignore();
2156         update();
2157     }
2158 }
2159 
2160 #endif // QT_CONFIG(draganddrop)
2161 
2162 #ifndef QT_NO_CONTEXTMENU
2163 /*!
2164     Shows the standard context menu created with
2165     createStandardContextMenu().
2166 
2167     If you do not want the line edit to have a context menu, you can set
2168     its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
2169     customize the context menu, reimplement this function. If you want
2170     to extend the standard context menu, reimplement this function, call
2171     createStandardContextMenu() and extend the menu returned.
2172 
2173     \snippet code/src_gui_widgets_qlineedit.cpp 0
2174 
2175     The \a event parameter is used to obtain the position where
2176     the mouse cursor was when the event was generated.
2177 
2178     \sa setContextMenuPolicy()
2179 */
contextMenuEvent(QContextMenuEvent * event)2180 void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
2181 {
2182     if (QMenu *menu = createStandardContextMenu()) {
2183         menu->setAttribute(Qt::WA_DeleteOnClose);
2184         menu->popup(event->globalPos());
2185     }
2186 }
2187 
setActionIcon(QAction * action,const QString & name)2188 static inline void setActionIcon(QAction *action, const QString &name)
2189 {
2190     const QIcon icon = QIcon::fromTheme(name);
2191     if (!icon.isNull())
2192         action->setIcon(icon);
2193 }
2194 
2195 /*!  This function creates the standard context menu which is shown
2196         when the user clicks on the line edit with the right mouse
2197         button. It is called from the default contextMenuEvent() handler.
2198         The popup menu's ownership is transferred to the caller.
2199 */
2200 
createStandardContextMenu()2201 QMenu *QLineEdit::createStandardContextMenu()
2202 {
2203     Q_D(QLineEdit);
2204     QMenu *popup = new QMenu(this);
2205     popup->setObjectName(QLatin1String("qt_edit_menu"));
2206     QAction *action = nullptr;
2207 
2208     if (!isReadOnly()) {
2209         action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
2210         action->setEnabled(d->control->isUndoAvailable());
2211         setActionIcon(action, QStringLiteral("edit-undo"));
2212         connect(action, SIGNAL(triggered()), SLOT(undo()));
2213 
2214         action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
2215         action->setEnabled(d->control->isRedoAvailable());
2216         setActionIcon(action, QStringLiteral("edit-redo"));
2217         connect(action, SIGNAL(triggered()), SLOT(redo()));
2218 
2219         popup->addSeparator();
2220     }
2221 
2222 #ifndef QT_NO_CLIPBOARD
2223     if (!isReadOnly()) {
2224         action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
2225         action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
2226                 && d->control->echoMode() == QLineEdit::Normal);
2227         setActionIcon(action, QStringLiteral("edit-cut"));
2228         connect(action, SIGNAL(triggered()), SLOT(cut()));
2229     }
2230 
2231     action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
2232     action->setEnabled(d->control->hasSelectedText()
2233             && d->control->echoMode() == QLineEdit::Normal);
2234     setActionIcon(action, QStringLiteral("edit-copy"));
2235     connect(action, SIGNAL(triggered()), SLOT(copy()));
2236 
2237     if (!isReadOnly()) {
2238         action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
2239         action->setEnabled(!d->control->isReadOnly() && !QGuiApplication::clipboard()->text().isEmpty());
2240         setActionIcon(action, QStringLiteral("edit-paste"));
2241         connect(action, SIGNAL(triggered()), SLOT(paste()));
2242     }
2243 #endif
2244 
2245     if (!isReadOnly()) {
2246         action = popup->addAction(QLineEdit::tr("Delete"));
2247         action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
2248         setActionIcon(action, QStringLiteral("edit-delete"));
2249         connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
2250     }
2251 
2252     if (!popup->isEmpty())
2253         popup->addSeparator();
2254 
2255     action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
2256     action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
2257     setActionIcon(action, QStringLiteral("edit-select-all"));
2258     d->selectAllAction = action;
2259     connect(action, SIGNAL(triggered()), SLOT(selectAll()));
2260 
2261     if (!d->control->isReadOnly() && QGuiApplication::styleHints()->useRtlExtensions()) {
2262         popup->addSeparator();
2263         QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
2264         popup->addMenu(ctrlCharacterMenu);
2265     }
2266     return popup;
2267 }
2268 #endif // QT_NO_CONTEXTMENU
2269 
2270 /*! \reimp */
changeEvent(QEvent * ev)2271 void QLineEdit::changeEvent(QEvent *ev)
2272 {
2273     Q_D(QLineEdit);
2274     switch(ev->type())
2275     {
2276     case QEvent::ActivationChange:
2277         if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
2278             update();
2279         break;
2280     case QEvent::FontChange:
2281         d->control->setFont(font());
2282         break;
2283     case QEvent::StyleChange:
2284         {
2285             QStyleOptionFrame opt;
2286             initStyleOption(&opt);
2287             d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
2288             d->control->setPasswordMaskDelay(style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, this));
2289         }
2290         update();
2291         break;
2292     case QEvent::LayoutDirectionChange:
2293 #if QT_CONFIG(toolbutton)
2294         for (const auto &e : d->trailingSideWidgets) { // Refresh icon to show arrow in right direction.
2295             if (e.flags & QLineEditPrivate::SideWidgetClearButton)
2296                 static_cast<QLineEditIconButton *>(e.widget)->setIcon(d->clearButtonIcon());
2297         }
2298 #endif
2299         d->positionSideWidgets();
2300         break;
2301     default:
2302         break;
2303     }
2304     QWidget::changeEvent(ev);
2305 }
2306 
2307 QT_END_NAMESPACE
2308 
2309 #include "moc_qlineedit.cpp"
2310