1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquicktextfield_p.h"
38#include "qquicktextfield_p_p.h"
39#include "qquickcontrol_p.h"
40#include "qquickcontrol_p_p.h"
41#include "qquickdeferredexecute_p_p.h"
42
43#include <QtQuick/private/qquickitem_p.h>
44#include <QtQuick/private/qquicktextinput_p.h>
45#include <QtQuick/private/qquickclipnode_p.h>
46
47#if QT_CONFIG(accessibility)
48#include <QtQuick/private/qquickaccessibleattached_p.h>
49#endif
50
51QT_BEGIN_NAMESPACE
52
53/*!
54 \qmltype TextField
55 \inherits TextInput
56//! \instantiates QQuickTextField
57 \inqmlmodule QtQuick.Controls
58 \since 5.7
59 \ingroup qtquickcontrols2-input
60 \brief Single-line text input field.
61
62 TextField is a single line text editor. TextField extends TextInput with
63 a \l {placeholderText}{placeholder text} functionality, and adds decoration.
64
65 \table
66 \row \li \image qtquickcontrols2-textfield-normal.png
67 \li A text field in its normal state.
68 \row \li \image qtquickcontrols2-textfield-focused.png
69 \li A text field that has active focus.
70 \row \li \image qtquickcontrols2-textfield-disabled.png
71 \li A text field that is disabled.
72 \endtable
73
74 \code
75 TextField {
76 placeholderText: qsTr("Enter name")
77 }
78 \endcode
79
80 \sa TextArea, {Customizing TextField}, {Input Controls}
81*/
82
83/*!
84 \qmlsignal QtQuick.Controls::TextField::pressAndHold(MouseEvent event)
85
86 This signal is emitted when there is a long press (the delay depends on the platform plugin).
87 The \a event parameter provides information about the press, including the x and y
88 coordinates of the press, and which button is pressed.
89
90 \sa pressed, released
91*/
92
93/*!
94 \qmlsignal QtQuick.Controls::TextField::pressed(MouseEvent event)
95 \since QtQuick.Controls 2.1 (Qt 5.8)
96
97 This signal is emitted when the text field is pressed by the user.
98 The \a event parameter provides information about the press,
99 including the x and y coordinates of the press, and which button
100 is pressed.
101
102 \sa released, pressAndHold
103*/
104
105/*!
106 \qmlsignal QtQuick.Controls::TextField::released(MouseEvent event)
107 \since QtQuick.Controls 2.1 (Qt 5.8)
108
109 This signal is emitted when the text field is released by the user.
110 The \a event parameter provides information about the release,
111 including the x and y coordinates of the press, and which button
112 is pressed.
113
114 \sa pressed, pressAndHold
115*/
116
117QQuickTextFieldPrivate::QQuickTextFieldPrivate()
118{
119#if QT_CONFIG(accessibility)
120 QAccessible::installActivationObserver(this);
121#endif
122}
123
124QQuickTextFieldPrivate::~QQuickTextFieldPrivate()
125{
126#if QT_CONFIG(accessibility)
127 QAccessible::removeActivationObserver(this);
128#endif
129}
130
131void QQuickTextFieldPrivate::setTopInset(qreal value, bool reset)
132{
133 Q_Q(QQuickTextField);
134 const QMarginsF oldInset = getInset();
135 extra.value().topInset = value;
136 extra.value().hasTopInset = !reset;
137 if (!qFuzzyCompare(p1: oldInset.top(), p2: value)) {
138 emit q->topInsetChanged();
139 q->insetChange(newInset: getInset(), oldInset);
140 }
141}
142
143void QQuickTextFieldPrivate::setLeftInset(qreal value, bool reset)
144{
145 Q_Q(QQuickTextField);
146 const QMarginsF oldInset = getInset();
147 extra.value().leftInset = value;
148 extra.value().hasLeftInset = !reset;
149 if (!qFuzzyCompare(p1: oldInset.left(), p2: value)) {
150 emit q->leftInsetChanged();
151 q->insetChange(newInset: getInset(), oldInset);
152 }
153}
154
155void QQuickTextFieldPrivate::setRightInset(qreal value, bool reset)
156{
157 Q_Q(QQuickTextField);
158 const QMarginsF oldInset = getInset();
159 extra.value().rightInset = value;
160 extra.value().hasRightInset = !reset;
161 if (!qFuzzyCompare(p1: oldInset.right(), p2: value)) {
162 emit q->rightInsetChanged();
163 q->insetChange(newInset: getInset(), oldInset);
164 }
165}
166
167void QQuickTextFieldPrivate::setBottomInset(qreal value, bool reset)
168{
169 Q_Q(QQuickTextField);
170 const QMarginsF oldInset = getInset();
171 extra.value().bottomInset = value;
172 extra.value().hasBottomInset = !reset;
173 if (!qFuzzyCompare(p1: oldInset.bottom(), p2: value)) {
174 emit q->bottomInsetChanged();
175 q->insetChange(newInset: getInset(), oldInset);
176 }
177}
178
179void QQuickTextFieldPrivate::resizeBackground()
180{
181 if (!background)
182 return;
183
184 resizingBackground = true;
185
186 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
187 if (((!p->widthValid || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(d: background->x()))
188 || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
189 const bool wasWidthValid = p->widthValid;
190 background->setX(getLeftInset());
191 background->setWidth(width - getLeftInset() - getRightInset());
192 // If the user hadn't previously set the width, that shouldn't change when we set it for them.
193 if (!wasWidthValid)
194 p->widthValid = false;
195 }
196 if (((!p->heightValid || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(d: background->y()))
197 || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
198 const bool wasHeightValid = p->heightValid;
199 background->setY(getTopInset());
200 background->setHeight(height - getTopInset() - getBottomInset());
201 if (!wasHeightValid)
202 p->heightValid = false;
203 }
204
205 resizingBackground = false;
206}
207
208/*!
209 \internal
210
211 Determine which font is implicitly imposed on this control by its ancestors
212 and QGuiApplication::font, resolve this against its own font (attributes from
213 the implicit font are copied over). Then propagate this font to this
214 control's children.
215*/
216void QQuickTextFieldPrivate::resolveFont()
217{
218 Q_Q(QQuickTextField);
219 inheritFont(font: QQuickControlPrivate::parentFont(item: q));
220}
221
222void QQuickTextFieldPrivate::inheritFont(const QFont &font)
223{
224 QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
225 parentFont.resolve(mask: extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve());
226
227 const QFont defaultFont = QQuickTheme::font(scope: QQuickTheme::TextField);
228 QFont resolvedFont = parentFont.resolve(defaultFont);
229 // See comment in QQuickControlPrivate::inheritFont
230 if (defaultFont.families().isEmpty())
231 resolvedFont.setFamilies(QStringList());
232
233 setFont_helper(resolvedFont);
234}
235
236/*!
237 \internal
238
239 Assign \a font to this control, and propagate it to all children.
240*/
241void QQuickTextFieldPrivate::updateFont(const QFont &font)
242{
243 Q_Q(QQuickTextField);
244 QFont oldFont = sourceFont;
245 q->QQuickTextInput::setFont(font);
246
247 QQuickControlPrivate::updateFontRecur(item: q, font);
248
249 if (oldFont != font)
250 emit q->fontChanged();
251}
252
253/*!
254 \internal
255
256 Determine which palette is implicitly imposed on this control by its ancestors
257 and QGuiApplication::palette, resolve this against its own palette (attributes from
258 the implicit palette are copied over). Then propagate this palette to this
259 control's children.
260*/
261void QQuickTextFieldPrivate::resolvePalette()
262{
263 Q_Q(QQuickTextField);
264 inheritPalette(palette: QQuickControlPrivate::parentPalette(item: q));
265}
266
267void QQuickTextFieldPrivate::inheritPalette(const QPalette &palette)
268{
269 QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette;
270 parentPalette.resolve(mask: extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve());
271
272 const QPalette defaultPalette = QQuickTheme::palette(scope: QQuickTheme::TextField);
273 const QPalette resolvedPalette = parentPalette.resolve(defaultPalette);
274
275 setPalette_helper(resolvedPalette);
276}
277
278void QQuickTextFieldPrivate::updatePalette(const QPalette &palette)
279{
280 Q_Q(QQuickTextField);
281 QPalette oldPalette = resolvedPalette;
282 resolvedPalette = palette;
283
284 QQuickControlPrivate::updatePaletteRecur(item: q, palette);
285
286 if (oldPalette != palette)
287 emit q->paletteChanged();
288}
289
290#if QT_CONFIG(quicktemplates2_hover)
291void QQuickTextFieldPrivate::updateHoverEnabled(bool enabled, bool xplicit)
292{
293 Q_Q(QQuickTextField);
294 if (!xplicit && explicitHoverEnabled)
295 return;
296
297 bool wasEnabled = q->isHoverEnabled();
298 explicitHoverEnabled = xplicit;
299 if (wasEnabled != enabled) {
300 q->setAcceptHoverEvents(enabled);
301 QQuickControlPrivate::updateHoverEnabledRecur(item: q, enabled);
302 emit q->hoverEnabledChanged();
303 }
304}
305#endif
306
307qreal QQuickTextFieldPrivate::getImplicitWidth() const
308{
309 return QQuickItemPrivate::getImplicitWidth();
310}
311
312qreal QQuickTextFieldPrivate::getImplicitHeight() const
313{
314 return QQuickItemPrivate::getImplicitHeight();
315}
316
317void QQuickTextFieldPrivate::implicitWidthChanged()
318{
319 Q_Q(QQuickTextField);
320 QQuickItemPrivate::implicitWidthChanged();
321 emit q->implicitWidthChanged3();
322}
323
324void QQuickTextFieldPrivate::implicitHeightChanged()
325{
326 Q_Q(QQuickTextField);
327 QQuickItemPrivate::implicitHeightChanged();
328 emit q->implicitHeightChanged3();
329}
330
331void QQuickTextFieldPrivate::readOnlyChanged(bool isReadOnly)
332{
333 Q_UNUSED(isReadOnly);
334#if QT_CONFIG(accessibility)
335 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: q_func()))
336 accessibleAttached->set_readOnly(isReadOnly);
337#endif
338#if QT_CONFIG(cursor)
339 q_func()->setCursor(isReadOnly ? Qt::ArrowCursor : Qt::IBeamCursor);
340#endif
341}
342
343void QQuickTextFieldPrivate::echoModeChanged(QQuickTextField::EchoMode echoMode)
344{
345#if QT_CONFIG(accessibility)
346 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: q_func()))
347 accessibleAttached->set_passwordEdit((echoMode == QQuickTextField::Password || echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
348#else
349 Q_UNUSED(echoMode)
350#endif
351}
352
353#if QT_CONFIG(accessibility)
354void QQuickTextFieldPrivate::accessibilityActiveChanged(bool active)
355{
356 if (!active)
357 return;
358
359 Q_Q(QQuickTextField);
360 QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(object: qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj: q, create: true));
361 Q_ASSERT(accessibleAttached);
362 accessibleAttached->setRole(accessibleRole());
363 accessibleAttached->set_readOnly(m_readOnly);
364 accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextField::Password || m_echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
365 accessibleAttached->setDescription(placeholder);
366}
367
368QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const
369{
370 return QAccessible::EditableText;
371}
372#endif
373
374static inline QString backgroundName() { return QStringLiteral("background"); }
375
376void QQuickTextFieldPrivate::cancelBackground()
377{
378 Q_Q(QQuickTextField);
379 quickCancelDeferred(object: q, property: backgroundName());
380}
381
382void QQuickTextFieldPrivate::executeBackground(bool complete)
383{
384 Q_Q(QQuickTextField);
385 if (background.wasExecuted())
386 return;
387
388 if (!background || complete)
389 quickBeginDeferred(object: q, property: backgroundName(), delegate&: background);
390 if (complete)
391 quickCompleteDeferred(object: q, property: backgroundName(), delegate&: background);
392}
393
394void QQuickTextFieldPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
395{
396 Q_UNUSED(diff);
397 if (resizingBackground || item != background || !change.sizeChange())
398 return;
399
400 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
401 // QTBUG-71875: only allocate the extra data if we have to.
402 // resizeBackground() relies on the value of extra.isAllocated()
403 // as part of its checks to see whether it should resize the background or not.
404 if (p->widthValid || extra.isAllocated())
405 extra.value().hasBackgroundWidth = p->widthValid;
406 if (p->heightValid || extra.isAllocated())
407 extra.value().hasBackgroundHeight = p->heightValid;
408 resizeBackground();
409}
410
411void QQuickTextFieldPrivate::itemImplicitWidthChanged(QQuickItem *item)
412{
413 Q_Q(QQuickTextField);
414 if (item == background)
415 emit q->implicitBackgroundWidthChanged();
416}
417
418void QQuickTextFieldPrivate::itemImplicitHeightChanged(QQuickItem *item)
419{
420 Q_Q(QQuickTextField);
421 if (item == background)
422 emit q->implicitBackgroundHeightChanged();
423}
424
425void QQuickTextFieldPrivate::itemDestroyed(QQuickItem *item)
426{
427 Q_Q(QQuickTextField);
428 if (item == background) {
429 background = nullptr;
430 emit q->implicitBackgroundWidthChanged();
431 emit q->implicitBackgroundHeightChanged();
432 }
433}
434
435QQuickTextField::QQuickTextField(QQuickItem *parent)
436 : QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
437{
438 Q_D(QQuickTextField);
439 d->pressHandler.control = this;
440 d->setImplicitResizeEnabled(false);
441 setAcceptedMouseButtons(Qt::AllButtons);
442 setActiveFocusOnTab(true);
443#if QT_CONFIG(cursor)
444 setCursor(Qt::IBeamCursor);
445#endif
446 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::readOnlyChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::readOnlyChanged);
447 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::echoModeChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::echoModeChanged);
448}
449
450QQuickTextField::~QQuickTextField()
451{
452 Q_D(QQuickTextField);
453 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
454}
455
456QFont QQuickTextField::font() const
457{
458 return QQuickTextInput::font();
459}
460
461void QQuickTextField::setFont(const QFont &font)
462{
463 Q_D(QQuickTextField);
464 if (d->extra.value().requestedFont.resolve() == font.resolve() && d->extra.value().requestedFont == font)
465 return;
466
467 d->extra.value().requestedFont = font;
468 d->resolveFont();
469}
470
471/*!
472 \qmlproperty Item QtQuick.Controls::TextField::background
473
474 This property holds the background item.
475
476 \input qquickcontrol-background.qdocinc notes
477
478 \sa {Customizing TextField}
479*/
480QQuickItem *QQuickTextField::background() const
481{
482 QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func());
483 if (!d->background)
484 d->executeBackground();
485 return d->background;
486}
487
488void QQuickTextField::setBackground(QQuickItem *background)
489{
490 Q_D(QQuickTextField);
491 if (d->background == background)
492 return;
493
494 if (!d->background.isExecuting())
495 d->cancelBackground();
496
497 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
498 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
499
500 if (d->extra.isAllocated()) {
501 d->extra.value().hasBackgroundWidth = false;
502 d->extra.value().hasBackgroundHeight = false;
503 }
504
505 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
506 QQuickControlPrivate::hideOldItem(item: d->background);
507 d->background = background;
508
509 if (background) {
510 background->setParentItem(this);
511 if (qFuzzyIsNull(d: background->z()))
512 background->setZ(-1);
513 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
514 if (p->widthValid || p->heightValid) {
515 d->extra.value().hasBackgroundWidth = p->widthValid;
516 d->extra.value().hasBackgroundHeight = p->heightValid;
517 }
518 if (isComponentComplete())
519 d->resizeBackground();
520 QQuickControlPrivate::addImplicitSizeListener(item: background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
521 }
522
523 if (!qFuzzyCompare(p1: oldImplicitBackgroundWidth, p2: implicitBackgroundWidth()))
524 emit implicitBackgroundWidthChanged();
525 if (!qFuzzyCompare(p1: oldImplicitBackgroundHeight, p2: implicitBackgroundHeight()))
526 emit implicitBackgroundHeightChanged();
527 if (!d->background.isExecuting())
528 emit backgroundChanged();
529}
530
531/*!
532 \qmlproperty string QtQuick.Controls::TextField::placeholderText
533
534 This property holds the hint that is displayed in the TextField before the user
535 enters text.
536*/
537QString QQuickTextField::placeholderText() const
538{
539 Q_D(const QQuickTextField);
540 return d->placeholder;
541}
542
543void QQuickTextField::setPlaceholderText(const QString &text)
544{
545 Q_D(QQuickTextField);
546 if (d->placeholder == text)
547 return;
548
549 d->placeholder = text;
550#if QT_CONFIG(accessibility)
551 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this))
552 accessibleAttached->setDescription(text);
553#endif
554 emit placeholderTextChanged();
555}
556
557/*!
558 \qmlproperty color QtQuick.Controls::TextField::placeholderTextColor
559 \since QtQuick.Controls 2.5 (Qt 5.12)
560
561 This property holds the color of placeholderText.
562
563 \sa placeholderText
564*/
565QColor QQuickTextField::placeholderTextColor() const
566{
567 Q_D(const QQuickTextField);
568 return d->placeholderColor;
569}
570
571void QQuickTextField::setPlaceholderTextColor(const QColor &color)
572{
573 Q_D(QQuickTextField);
574 if (d->placeholderColor == color)
575 return;
576
577 d->placeholderColor = color;
578 emit placeholderTextColorChanged();
579}
580
581/*!
582 \qmlproperty enumeration QtQuick.Controls::TextField::focusReason
583
584 \include qquickcontrol-focusreason.qdocinc
585*/
586Qt::FocusReason QQuickTextField::focusReason() const
587{
588 Q_D(const QQuickTextField);
589 return d->focusReason;
590}
591
592void QQuickTextField::setFocusReason(Qt::FocusReason reason)
593{
594 Q_D(QQuickTextField);
595 if (d->focusReason == reason)
596 return;
597
598 d->focusReason = reason;
599 emit focusReasonChanged();
600}
601
602/*!
603 \since QtQuick.Controls 2.1 (Qt 5.8)
604 \qmlproperty bool QtQuick.Controls::TextField::hovered
605 \readonly
606
607 This property holds whether the text field is hovered.
608
609 \sa hoverEnabled
610*/
611bool QQuickTextField::isHovered() const
612{
613#if QT_CONFIG(quicktemplates2_hover)
614 Q_D(const QQuickTextField);
615 return d->hovered;
616#else
617 return false;
618#endif
619}
620
621void QQuickTextField::setHovered(bool hovered)
622{
623#if QT_CONFIG(quicktemplates2_hover)
624 Q_D(QQuickTextField);
625 if (hovered == d->hovered)
626 return;
627
628 d->hovered = hovered;
629 emit hoveredChanged();
630#else
631 Q_UNUSED(hovered);
632#endif
633}
634
635/*!
636 \since QtQuick.Controls 2.1 (Qt 5.8)
637 \qmlproperty bool QtQuick.Controls::TextField::hoverEnabled
638
639 This property determines whether the text field accepts hover events. The default value is \c false.
640
641 \sa hovered
642*/
643bool QQuickTextField::isHoverEnabled() const
644{
645#if QT_CONFIG(quicktemplates2_hover)
646 Q_D(const QQuickTextField);
647 return d->hoverEnabled;
648#else
649 return false;
650#endif
651}
652
653void QQuickTextField::setHoverEnabled(bool enabled)
654{
655#if QT_CONFIG(quicktemplates2_hover)
656 Q_D(QQuickTextField);
657 if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
658 return;
659
660 d->updateHoverEnabled(enabled, xplicit: true); // explicit=true
661#else
662 Q_UNUSED(enabled);
663#endif
664}
665
666void QQuickTextField::resetHoverEnabled()
667{
668#if QT_CONFIG(quicktemplates2_hover)
669 Q_D(QQuickTextField);
670 if (!d->explicitHoverEnabled)
671 return;
672
673 d->explicitHoverEnabled = false;
674 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
675#endif
676}
677
678/*!
679 \since QtQuick.Controls 2.3 (Qt 5.10)
680 \qmlproperty palette QtQuick.Controls::TextField::palette
681
682 This property holds the palette currently set for the text field.
683
684 \sa Control::palette
685*/
686QPalette QQuickTextField::palette() const
687{
688 Q_D(const QQuickTextField);
689 QPalette palette = d->resolvedPalette;
690 if (!isEnabled())
691 palette.setCurrentColorGroup(QPalette::Disabled);
692 return palette;
693}
694
695void QQuickTextField::setPalette(const QPalette &palette)
696{
697 Q_D(QQuickTextField);
698 if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette)
699 return;
700
701 d->extra.value().requestedPalette = palette;
702 d->resolvePalette();
703}
704
705void QQuickTextField::resetPalette()
706{
707 setPalette(QPalette());
708}
709
710void QQuickTextField::classBegin()
711{
712 Q_D(QQuickTextField);
713 QQuickTextInput::classBegin();
714 d->resolveFont();
715 d->resolvePalette();
716}
717
718/*!
719 \since QtQuick.Controls 2.5 (Qt 5.12)
720 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundWidth
721 \readonly
722
723 This property holds the implicit background width.
724
725 The value is equal to \c {background ? background.implicitWidth : 0}.
726
727 \sa implicitBackgroundHeight
728*/
729qreal QQuickTextField::implicitBackgroundWidth() const
730{
731 Q_D(const QQuickTextField);
732 if (!d->background)
733 return 0;
734 return d->background->implicitWidth();
735}
736
737/*!
738 \since QtQuick.Controls 2.5 (Qt 5.12)
739 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundHeight
740 \readonly
741
742 This property holds the implicit background height.
743
744 The value is equal to \c {background ? background.implicitHeight : 0}.
745
746 \sa implicitBackgroundWidth
747*/
748qreal QQuickTextField::implicitBackgroundHeight() const
749{
750 Q_D(const QQuickTextField);
751 if (!d->background)
752 return 0;
753 return d->background->implicitHeight();
754}
755
756/*!
757 \since QtQuick.Controls 2.5 (Qt 5.12)
758 \qmlproperty real QtQuick.Controls::TextField::topInset
759
760 This property holds the top inset for the background.
761
762 \sa {Control Layout}, bottomInset
763*/
764qreal QQuickTextField::topInset() const
765{
766 Q_D(const QQuickTextField);
767 return d->getTopInset();
768}
769
770void QQuickTextField::setTopInset(qreal inset)
771{
772 Q_D(QQuickTextField);
773 d->setTopInset(value: inset);
774}
775
776void QQuickTextField::resetTopInset()
777{
778 Q_D(QQuickTextField);
779 d->setTopInset(value: 0, reset: true);
780}
781
782/*!
783 \since QtQuick.Controls 2.5 (Qt 5.12)
784 \qmlproperty real QtQuick.Controls::TextField::leftInset
785
786 This property holds the left inset for the background.
787
788 \sa {Control Layout}, rightInset
789*/
790qreal QQuickTextField::leftInset() const
791{
792 Q_D(const QQuickTextField);
793 return d->getLeftInset();
794}
795
796void QQuickTextField::setLeftInset(qreal inset)
797{
798 Q_D(QQuickTextField);
799 d->setLeftInset(value: inset);
800}
801
802void QQuickTextField::resetLeftInset()
803{
804 Q_D(QQuickTextField);
805 d->setLeftInset(value: 0, reset: true);
806}
807
808/*!
809 \since QtQuick.Controls 2.5 (Qt 5.12)
810 \qmlproperty real QtQuick.Controls::TextField::rightInset
811
812 This property holds the right inset for the background.
813
814 \sa {Control Layout}, leftInset
815*/
816qreal QQuickTextField::rightInset() const
817{
818 Q_D(const QQuickTextField);
819 return d->getRightInset();
820}
821
822void QQuickTextField::setRightInset(qreal inset)
823{
824 Q_D(QQuickTextField);
825 d->setRightInset(value: inset);
826}
827
828void QQuickTextField::resetRightInset()
829{
830 Q_D(QQuickTextField);
831 d->setRightInset(value: 0, reset: true);
832}
833
834/*!
835 \since QtQuick.Controls 2.5 (Qt 5.12)
836 \qmlproperty real QtQuick.Controls::TextField::bottomInset
837
838 This property holds the bottom inset for the background.
839
840 \sa {Control Layout}, topInset
841*/
842qreal QQuickTextField::bottomInset() const
843{
844 Q_D(const QQuickTextField);
845 return d->getBottomInset();
846}
847
848void QQuickTextField::setBottomInset(qreal inset)
849{
850 Q_D(QQuickTextField);
851 d->setBottomInset(value: inset);
852}
853
854void QQuickTextField::resetBottomInset()
855{
856 Q_D(QQuickTextField);
857 d->setBottomInset(value: 0, reset: true);
858}
859
860void QQuickTextField::componentComplete()
861{
862 Q_D(QQuickTextField);
863 d->executeBackground(complete: true);
864 QQuickTextInput::componentComplete();
865 d->resizeBackground();
866#if QT_CONFIG(quicktemplates2_hover)
867 if (!d->explicitHoverEnabled)
868 setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(item: d->parentItem));
869#endif
870#if QT_CONFIG(accessibility)
871 if (QAccessible::isActive())
872 d->accessibilityActiveChanged(active: true);
873#endif
874}
875
876void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
877{
878 Q_D(QQuickTextField);
879 QQuickTextInput::itemChange(change, value);
880 switch (change) {
881 case ItemEnabledHasChanged:
882 emit paletteChanged();
883 break;
884 case ItemSceneChange:
885 case ItemParentHasChanged:
886 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
887 d->resolveFont();
888 d->resolvePalette();
889#if QT_CONFIG(quicktemplates2_hover)
890 if (!d->explicitHoverEnabled)
891 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
892#endif
893 }
894 break;
895 default:
896 break;
897 }
898}
899
900void QQuickTextField::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
901{
902 Q_D(QQuickTextField);
903 QQuickTextInput::geometryChanged(newGeometry, oldGeometry);
904 d->resizeBackground();
905}
906
907void QQuickTextField::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
908{
909 Q_D(QQuickTextField);
910 Q_UNUSED(newInset);
911 Q_UNUSED(oldInset);
912 d->resizeBackground();
913}
914QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
915{
916 QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode);
917 if (!clipNode)
918 clipNode = new QQuickDefaultClipNode(QRectF());
919
920 clipNode->setRect(clipRect().adjusted(xp1: leftPadding(), yp1: topPadding(), xp2: -rightPadding(), yp2: -bottomPadding()));
921 clipNode->update();
922
923 QSGNode *textNode = QQuickTextInput::updatePaintNode(oldNode: clipNode->firstChild(), data);
924 if (!textNode->parent())
925 clipNode->appendChildNode(node: textNode);
926
927 return clipNode;
928}
929
930void QQuickTextField::focusInEvent(QFocusEvent *event)
931{
932 QQuickTextInput::focusInEvent(event);
933 setFocusReason(event->reason());
934}
935
936void QQuickTextField::focusOutEvent(QFocusEvent *event)
937{
938 QQuickTextInput::focusOutEvent(event);
939 setFocusReason(event->reason());
940}
941
942#if QT_CONFIG(quicktemplates2_hover)
943void QQuickTextField::hoverEnterEvent(QHoverEvent *event)
944{
945 Q_D(QQuickTextField);
946 QQuickTextInput::hoverEnterEvent(event);
947 setHovered(d->hoverEnabled);
948 event->setAccepted(d->hoverEnabled);
949}
950
951void QQuickTextField::hoverLeaveEvent(QHoverEvent *event)
952{
953 Q_D(QQuickTextField);
954 QQuickTextInput::hoverLeaveEvent(event);
955 setHovered(false);
956 event->setAccepted(d->hoverEnabled);
957}
958#endif
959
960void QQuickTextField::mousePressEvent(QMouseEvent *event)
961{
962 Q_D(QQuickTextField);
963 d->pressHandler.mousePressEvent(event);
964 if (d->pressHandler.isActive()) {
965 if (d->pressHandler.delayedMousePressEvent) {
966 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent);
967 d->pressHandler.clearDelayedMouseEvent();
968 }
969 if (event->buttons() != Qt::RightButton)
970 QQuickTextInput::mousePressEvent(event);
971 }
972}
973
974void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
975{
976 Q_D(QQuickTextField);
977 d->pressHandler.mouseMoveEvent(event);
978 if (d->pressHandler.isActive()) {
979 if (d->pressHandler.delayedMousePressEvent) {
980 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent);
981 d->pressHandler.clearDelayedMouseEvent();
982 }
983 if (event->buttons() != Qt::RightButton)
984 QQuickTextInput::mouseMoveEvent(event);
985 }
986}
987
988void QQuickTextField::mouseReleaseEvent(QMouseEvent *event)
989{
990 Q_D(QQuickTextField);
991 d->pressHandler.mouseReleaseEvent(event);
992 if (d->pressHandler.isActive()) {
993 if (d->pressHandler.delayedMousePressEvent) {
994 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent);
995 d->pressHandler.clearDelayedMouseEvent();
996 }
997 if (event->buttons() != Qt::RightButton)
998 QQuickTextInput::mouseReleaseEvent(event);
999 }
1000}
1001
1002void QQuickTextField::mouseDoubleClickEvent(QMouseEvent *event)
1003{
1004 Q_D(QQuickTextField);
1005 if (d->pressHandler.delayedMousePressEvent) {
1006 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent);
1007 d->pressHandler.clearDelayedMouseEvent();
1008 }
1009 if (event->buttons() != Qt::RightButton)
1010 QQuickTextInput::mouseDoubleClickEvent(event);
1011}
1012
1013void QQuickTextField::timerEvent(QTimerEvent *event)
1014{
1015 Q_D(QQuickTextField);
1016 if (event->timerId() == d->pressHandler.timer.timerId())
1017 d->pressHandler.timerEvent(event);
1018 else
1019 QQuickTextInput::timerEvent(event);
1020}
1021
1022QT_END_NAMESPACE
1023

source code of qtquickcontrols2/src/quicktemplates2/qquicktextfield.cpp