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

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