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