Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquicktextinput_p_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQUICKTEXTINPUT_P_P_H
5#define QQUICKTEXTINPUT_P_P_H
6
7#include "qquicktextinput_p.h"
8#include "qquicktext_p.h"
10#include "qquicktextutil_p.h"
11
12#include <QtQml/qqml.h>
13#include <QtCore/qelapsedtimer.h>
14#include <QtCore/qpointer.h>
15#include <QtCore/qbasictimer.h>
16#include <QtGui/qclipboard.h>
17#include <QtGui/qguiapplication.h>
18#include <QtGui/qpalette.h>
19#include <QtGui/qtextlayout.h>
20#include <QtGui/qstylehints.h>
21#include <private/qlazilyallocated_p.h>
22
23#include "qplatformdefs.h"
24
25#include <memory>
26
27//
28// W A R N I N G
29// -------------
30//
31// This file is not part of the Qt API. It exists purely as an
32// implementation detail. This header file may change from version to
33// version without notice, or even be removed.
34//
35// We mean it.
36
38
40class QInputControl;
41
43{
44public:
45 Q_DECLARE_PUBLIC(QQuickTextInput)
46
48
63 QLazilyAllocated<ExtraData> extra;
64
66 : hscroll(0)
67 , vscroll(0)
68 , cursorItem(nullptr)
69 , textNode(nullptr)
70 , m_maskData(nullptr)
71 , color(QRgb(0xFF000000))
72 , selectionColor(QRgb(0xFF000080))
73 , selectedTextColor(QRgb(0xFFFFFFFF))
74 , m_cursor(0)
75#if QT_CONFIG(im)
76 , m_preeditCursor(0)
77 , m_undoPreeditState(-1)
78#endif
79 , m_blinkEnabled(false)
80 , m_blinkTimer(0)
81 , m_maxLength(32767)
82 , m_lastCursorPos(-1)
83 , m_undoState(0)
84 , m_selstart(0)
85 , m_selend(0)
86#if QT_CONFIG(im)
87 , inputMethodHints(Qt::ImhNone)
88#endif
89 , hAlign(QQuickTextInput::AlignLeft)
90 , vAlign(QQuickTextInput::AlignTop)
91 , wrapMode(QQuickTextInput::NoWrap)
92 , m_echoMode(QQuickTextInput::Normal)
93 , renderType(QQuickTextUtil::textRenderType<QQuickTextInput>())
94 , updateType(UpdatePaintNode)
95 , mouseSelectionMode(QQuickTextInput::SelectCharacters)
96 , m_layoutDirection(Qt::LayoutDirectionAuto)
97 , m_passwordCharacter(QGuiApplication::styleHints()->passwordMaskCharacter())
98 , m_passwordMaskDelay(QGuiApplication::styleHints()->passwordMaskDelay())
99 , focusOnPress(true)
100 , cursorVisible(false)
101 , cursorPending(false)
102 , autoScroll(true)
103 , selectByMouse(true)
104 , canPaste(false)
105 , canPasteValid(false)
106 , canUndo(false)
107 , canRedo(false)
108 , hAlignImplicit(true)
109 , selectPressed(false)
110 , textLayoutDirty(true)
111 , persistentSelection(false)
112 , hasImState(false)
113 , m_separator(0)
114 , m_readOnly(0)
115 , m_textDirty(0)
116#if QT_CONFIG(im)
117 , m_preeditDirty(0)
118#endif
119 , m_selDirty(0)
120 , m_validInput(1)
121 , m_acceptableInput(1)
122 , m_blinkStatus(0)
123 , m_passwordEchoEditing(false)
124 , inLayout(false)
125 , requireImplicitWidth(false)
126 , overwriteMode(false)
128 , selectByTouchDrag(false)
129#endif
130 {
131 }
132
134 {
135 // If this control is used for password input, we don't want the
136 // password data to stay in the process memory, therefore we need
137 // to zero it out
138 if (m_echoMode != QQuickTextInput::Normal)
139 m_text.fill(u'\0');
140 }
141
142 void init();
143 void cancelInput();
145 void ensureVisible(int position, int preeditCursor = 0, int preeditLength = 0);
146 void updateHorizontalScroll();
147 void updateVerticalScroll();
148 bool determineHorizontalAlignment();
149 bool setHAlign(QQuickTextInput::HAlignment, bool forceAlign = false);
150 void mirrorChange() override;
151 bool sendMouseEventToInputContext(QMouseEvent *event);
152#if QT_CONFIG(im)
153 Qt::InputMethodHints effectiveInputMethodHints() const;
154#endif
155 void handleFocusEvent(QFocusEvent *event);
156
158 enum Casemode { NoCaseMode, Upper, Lower };
159 QChar maskChar; // either the separator char or the inputmask
162 };
163
164 // undo/redo handling
165 enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
166 struct Command {
167 inline Command() {}
168 inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
171 int pos, selStart, selEnd;
172 };
173
175 DrawText = 0x01,
176 DrawSelections = 0x02,
177 DrawCursor = 0x04,
178 DrawAll = DrawText | DrawSelections | DrawCursor
179 };
180
185
186 QPointer<QQmlComponent> cursorComponent;
187#if QT_CONFIG(validator)
188 QPointer<QValidator> m_validator;
189#endif
190
193
200
203 std::unique_ptr<MaskInputData[]> m_maskData;
205
206 QList<int> m_transactions;
207 QVector<Command> m_history;
208
212
217#if QT_CONFIG(im)
218 int m_preeditCursor;
219 int m_undoPreeditState;
220#endif
228
234
235#if QT_CONFIG(im)
236 Qt::InputMethodHints inputMethodHints;
237#endif
246
250
256 bool canPaste:1;
258 bool canUndo:1;
259 bool canRedo:1;
264 bool hasImState : 1;
265 bool m_separator : 1;
266 bool m_readOnly : 1;
267 bool m_textDirty : 1;
268#if QT_CONFIG(im)
269 bool m_preeditDirty : 1;
270#endif
271 bool m_selDirty : 1;
272 bool m_validInput : 1;
276 bool inLayout:1;
279#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
280 bool selectByTouchDrag:1;
281#endif
282
284 return t->d_func();
285 }
287 return !tripleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval());
288 }
289
291 updateCursorBlinking();
292 }
293
295 {
296 int c = findInMask(pos, true, false);
297 m_separator |= (c != pos);
298 return (c != -1 ? c : m_maxLength);
299 }
300
302 {
303 int c = findInMask(pos, false, false);
304 m_separator |= (c != pos);
305 return (c != -1 ? c : 0);
306 }
307
308 bool isUndoAvailable() const { return !m_readOnly && m_undoState; }
309 bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); }
310 void clearUndo() {
311 m_history.clear();
312 m_undoState = 0;
313#if QT_CONFIG(im)
314 m_undoPreeditState = -1;
315#endif
316 }
317
318 bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.size(); }
319 bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
320
321 void setSelection(int start, int length);
322
323 inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
324 QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
325 QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
326
327 int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
328 int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
329
330 QRectF anchorRectangle() const;
331
334 return positionAt(point.x(), point.y(), position);
335 }
336
338 {
339 int priorState = m_undoState;
340 removeSelectedText();
341 finishChange(priorState);
342 }
343
344 int start() const { return 0; }
345 int end() const { return m_text.size(); }
346
347 QString realText() const;
348
349#if QT_CONFIG(clipboard)
352#endif
353
354#if QT_CONFIG(im)
355 void commitPreedit();
356 void cancelPreedit();
357#endif
358
359 Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
360 void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
361
362 void moveCursor(int pos, bool mark = false);
363 void cursorForward(bool mark, int steps)
364 {
365 int c = m_cursor;
366 if (steps > 0) {
367 while (steps--)
368 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
369 : m_textLayout.nextCursorPosition(c);
370 } else if (steps < 0) {
371 while (steps++)
372 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
373 : m_textLayout.previousCursorPosition(c);
374 }
375 moveCursor(c, mark);
376 }
377
378 void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
379 void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
380
381 void home(bool mark) { moveCursor(0, mark); }
382 void end(bool mark) { moveCursor(q_func()->text().size(), mark); }
383
384 void backspace();
385 void del();
386 void deselect() { internalDeselect(); finishChange(); }
387 void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(), true); }
388
389 void insert(const QString &);
390 void clear();
391 void selectWordAtPos(int);
392
393 void setCursorPosition(int pos) { if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
394
395 bool fixup();
396
397 QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
399 {
400 parseInputMask(mask);
401 if (m_maskData)
402 moveCursor(nextMaskBlank(0));
403 }
404
405 // input methods
406#if QT_CONFIG(im)
407 bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
408
409 QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
410#endif
411
412 void updatePasswordEchoEditing(bool editing);
413
415 m_passwordEchoTimer.stop();
416 }
417
418 Qt::LayoutDirection textDirection() const;
419 Qt::LayoutDirection layoutDirection() const;
421 {
422 if (direction != m_layoutDirection) {
423 m_layoutDirection = direction;
424 updateDisplayText();
425 }
426 }
427
428#if QT_CONFIG(im)
429 void processInputMethodEvent(QInputMethodEvent *event);
430#endif
431 void processKeyEvent(QKeyEvent* ev);
432
433 void setBlinkingCursorEnabled(bool enable);
434 void updateCursorBlinking();
435
436 void updateLayout();
437 void updateBaselineOffset();
438
439 qreal calculateImplicitWidthForText(const QString &text) const;
440 qreal getImplicitWidth() const override;
441
442 inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
443 void setTopPadding(qreal value, bool reset = false);
444 void setLeftPadding(qreal value, bool reset = false);
445 void setRightPadding(qreal value, bool reset = false);
446 void setBottomPadding(qreal value, bool reset = false);
447
448 bool isImplicitResizeEnabled() const;
449 void setImplicitResizeEnabled(bool enabled);
450
451private:
452 void removeSelectedText();
453 void internalSetText(const QString &txt, int pos = -1, bool edited = true);
454 void updateDisplayText(bool forceUpdate = false);
455
456 void internalInsert(const QString &s);
457 void internalDelete(bool wasBackspace = false);
458 void internalRemove(int pos);
459
460 inline void internalDeselect()
461 {
462 m_selDirty |= (m_selend > m_selstart);
463 m_selstart = m_selend = 0;
464 }
465
466 void internalUndo(int until = -1);
467 void internalRedo();
468 void emitUndoRedoChanged();
469
470 bool emitCursorPositionChanged();
471
472 bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
473
474 void addCommand(const Command& cmd);
475
476 inline void separate() { m_separator = true; }
477
478 bool separateSelection();
479 void deleteStartOfWord();
480 void deleteEndOfWord();
481 void deleteEndOfLine();
482
483 enum ValidatorState {
484#if QT_CONFIG(validator)
485 InvalidInput = QValidator::Invalid,
486 IntermediateInput = QValidator::Intermediate,
487 AcceptableInput = QValidator::Acceptable
488#else
489 InvalidInput,
490 IntermediateInput,
491 AcceptableInput
492#endif
493 };
494
495 // masking
496 void parseInputMask(const QString &maskFields);
497 bool isValidInput(QChar key, QChar mask) const;
498 ValidatorState hasAcceptableInput(const QString &text) const;
499 void checkIsValid();
500 QString maskString(uint pos, const QString &str, bool clear = false) const;
501 QString clearString(uint pos, uint len) const;
502 QString stripString(const QString &str) const;
503 int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
504};
505
507
508#endif // QQUICKTEXTINPUT_P_P_H
\inmodule QtCore
Definition qbasictimer.h:18
void stop()
Stops the timer.
\inmodule QtCore
Mode
\keyword clipboard mode
Definition qclipboard.h:27
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
bool hasExpired(qint64 timeout) const noexcept
Returns true if elapsed() exceeds the given timeout, otherwise false.
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
\reentrant
Definition qfont.h:22
\macro qGuiApp
static QStyleHints * styleHints()
Returns the application's style hints.
The QInputMethodEvent class provides parameters for input method events.
Definition qevent.h:625
The QKeyEvent class describes a key event.
Definition qevent.h:424
\inmodule QtGui
Definition qevent.h:196
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setInputMask(const QString &mask)
QQuickTextInput::SelectionMode mouseSelectionMode
QQuickTextInput::WrapMode wrapMode
QString textBeforeSelection() const
void cursorWordBackward(bool mark)
void setCursorMoveStyle(Qt::CursorMoveStyle style)
void setLayoutDirection(Qt::LayoutDirection direction)
static QQuickTextInputPrivate * get(QQuickTextInput *t)
Qt::CursorMoveStyle cursorMoveStyle() const
QQuickTextInput::VAlignment vAlign
std::unique_ptr< MaskInputData[]> m_maskData
QLazilyAllocated< ExtraData > extra
QQuickTextInput::HAlignment hAlign
QSGInternalTextNode * textNode
QVector< Command > m_history
int positionAt(const QPointF &point, QTextLine::CursorPosition position=QTextLine::CursorBetweenCharacters) const
void cursorForward(bool mark, int steps)
Qt::LayoutDirection m_layoutDirection
QQuickTextInput::RenderType renderType
void cursorWordForward(bool mark)
QPointer< QQmlComponent > cursorComponent
QQuickTextInput::EchoMode m_echoMode
QString textAfterSelection() const
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore
Definition qsize.h:208
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
QString & fill(QChar c, qsizetype size=-1)
Sets every character in the string to character ch.
Definition qstring.cpp:6358
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
\reentrant
Definition qtextlayout.h:70
int rightCursorPosition(int oldPos) const
Returns the cursor position to the right of oldPos, next to it.
int previousCursorPosition(int oldPos, CursorMode mode=SkipCharacters) const
Returns the first valid cursor position before oldPos that respects the given cursor mode.
int nextCursorPosition(int oldPos, CursorMode mode=SkipCharacters) const
Returns the next valid cursor position after oldPos that respects the given cursor mode.
Qt::CursorMoveStyle cursorMoveStyle() const
The cursor movement style of this QTextLayout.
QString preeditAreaText() const
Returns the text that is inserted in the layout before editing occurs.
void setCursorMoveStyle(Qt::CursorMoveStyle style)
Sets the visual cursor movement style to the given style.
int leftCursorPosition(int oldPos) const
Returns the cursor position to the left of oldPos, next to it.
CursorPosition
\value CursorBetweenCharacters \value CursorOnCharacter
@ CursorBetweenCharacters
QString str
[2]
b clear()
QString text
cache insert(employee->id(), employee)
direction
Combined button and popup list for selecting options.
Definition qcompare.h:63
LayoutDirection
CursorMoveStyle
@ VisualMoveStyle
static jboolean copy(JNIEnv *, jobject)
static jboolean paste(JNIEnv *, jobject)
static jboolean setSelection(JNIEnv *, jobject, jint start, jint end)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint color
[2]
GLenum type
GLboolean enable
GLuint start
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint y
struct _cl_event * event
GLdouble s
[6]
Definition qopenglext.h:235
GLboolean reset
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
GLenum GLsizei len
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static qreal positionAt(const QQuickRangeSlider *slider, QQuickItem *handle, const QPointF &point)
void forceUpdate(QQuickItem *item)
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
#define QT_CONFIG(feature)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define QT_VERSION_CHECK(major, minor, patch)
#define QT_VERSION
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
if(qFloatDistance(a, b)<(1<< 7))
[0]
QObject::connect nullptr
Text files * txt
\inmodule QtCore \reentrant
Definition qchar.h:18
Command(CommandType t, int p, QChar c, int ss, int se)