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

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