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

source code of qtbase/src/widgets/widgets/qlineedit.cpp