46 Q_DECLARE_PUBLIC(QQuickTextInput)
48 typedef QQuickTextInput Public;
58 bool explicitTopPadding : 1;
59 bool explicitLeftPadding : 1;
60 bool explicitRightPadding : 1;
61 bool explicitBottomPadding : 1;
62 bool implicitResize : 1;
64 QLazilyAllocated<ExtraData> extra;
66 QQuickTextInputPrivate()
72 , color(QRgb(0xFF000000))
73 , selectionColor(QRgb(0xFF000080))
74 , selectedTextColor(QRgb(0xFFFFFFFF))
78 , m_undoPreeditState(-1)
80 , m_blinkEnabled(
false)
88 , inputMethodHints(Qt::ImhNone)
90 , hAlign(QQuickTextInput::AlignLeft)
91 , vAlign(QQuickTextInput::AlignTop)
92 , wrapMode(QQuickTextInput::NoWrap)
93 , m_echoMode(QQuickTextInput::Normal)
94 , renderType(QQuickTextUtil::textRenderType<QQuickTextInput>())
95 , updateType(UpdatePaintNode)
96 , mouseSelectionMode(QQuickTextInput::SelectCharacters)
97 , m_layoutDirection(Qt::LayoutDirectionAuto)
98 , m_passwordCharacter(QGuiApplication::styleHints()->passwordMaskCharacter())
99 , m_passwordMaskDelay(QGuiApplication::styleHints()->passwordMaskDelay())
101 , cursorVisible(
false)
102 , cursorPending(
false)
104 , selectByMouse(
true)
106 , canPasteValid(
false)
109 , hAlignImplicit(
true)
110 , selectPressed(
false)
111 , hadSelectionOnMousePress(
false)
112 , textLayoutDirty(
true)
113 , persistentSelection(
false)
123 , m_acceptableInput(1)
125 , m_passwordEchoEditing(
false)
127 , requireImplicitWidth(
false)
128 , overwriteMode(
false)
129 , containsUnscalableGlyphs(
false)
130#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
131 , selectByTouchDrag(
false)
136 ~QQuickTextInputPrivate()
141 if (m_echoMode != QQuickTextInput::Normal)
147 void startCreatingCursor();
148 void ensureVisible(
int position,
int preeditCursor = 0,
int preeditLength = 0);
149 void updateHorizontalScroll();
150 void updateVerticalScroll();
151 bool determineHorizontalAlignment();
152 bool setHAlign(QQuickTextInput::HAlignment,
bool forceAlign =
false);
153 void mirrorChange() override;
154#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
155 bool handleContextMenuEvent(QContextMenuEvent *event) override;
157 bool sendMouseEventToInputContext(QMouseEvent *event);
159 Qt::InputMethodHints effectiveInputMethodHints()
const;
161 void handleFocusEvent(QFocusEvent *event);
163 struct MaskInputData {
164 enum Casemode { NoCaseMode, Upper, Lower };
171 enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
174 inline Command(CommandType t,
int p, QChar c,
int ss,
int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
177 int pos, selStart, selEnd;
182 DrawSelections = 0x02,
184 DrawAll = DrawText | DrawSelections | DrawCursor
187 QElapsedTimer tripleClickTimer;
190 QPointF tripleClickStartPoint;
192 QPointer<QQmlComponent> cursorComponent;
193#if QT_CONFIG(validator)
194 QPointer<QValidator> m_validator;
200 QTextLayout m_textLayout;
203 QString m_cancelText;
207 QQuickItem *cursorItem;
208 QSGInternalTextNode *textNode;
209 std::unique_ptr<MaskInputData[]> m_maskData;
210 QInputControl *m_inputControl;
212 QList<
int> m_transactions;
213 QVector<Command> m_history;
216 QColor selectionColor;
217 QColor selectedTextColor;
219 QBasicTimer m_passwordEchoTimer;
220 int lastSelectionStart;
221 int lastSelectionEnd;
225 int m_undoPreeditState;
237 UpdateOnlyPreprocess,
242 Qt::InputMethodHints inputMethodHints;
244 QQuickTextInput::HAlignment hAlign;
245 QQuickTextInput::VAlignment vAlign;
246 QQuickTextInput::WrapMode wrapMode;
247 QQuickTextInput::EchoMode m_echoMode;
248 QQuickTextInput::RenderType renderType;
249 UpdateType updateType;
250 QQuickTextInput::SelectionMode mouseSelectionMode;
251 Qt::LayoutDirection m_layoutDirection;
254 QChar m_passwordCharacter;
255 int m_passwordMaskDelay;
258 bool cursorVisible:1;
259 bool cursorPending:1;
261 bool selectByMouse:1;
263 bool canPasteValid:1;
266 bool hAlignImplicit:1;
267 bool selectPressed:1;
268 bool hadSelectionOnMousePress:1;
269 bool textLayoutDirty:1;
270 bool persistentSelection:1;
272 bool m_separator : 1;
274 bool m_textDirty : 1;
276 bool m_preeditDirty : 1;
279 bool m_validInput : 1;
280 bool m_acceptableInput : 1;
281 bool m_blinkStatus : 1;
282 bool m_passwordEchoEditing : 1;
284 bool requireImplicitWidth:1;
285 bool overwriteMode:1;
286 bool containsUnscalableGlyphs:1;
287#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
288 bool selectByTouchDrag:1;
291 static inline QQuickTextInputPrivate *get(QQuickTextInput *t) {
294 bool hasPendingTripleClick()
const {
295 return !tripleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval());
298 void setNativeCursorEnabled(
bool) {
299 updateCursorBlinking();
302 int nextMaskBlank(
int pos)
304 int c = findInMask(pos,
true,
false);
305 m_separator |= (c != pos);
306 return (c != -1 ? c : m_maxLength);
309 int prevMaskBlank(
int pos)
311 int c = findInMask(pos,
false,
false);
312 m_separator |= (c != pos);
313 return (c != -1 ? c : 0);
316 bool isUndoAvailable()
const {
return !m_readOnly && m_undoState; }
317 bool isRedoAvailable()
const {
return !m_readOnly && m_undoState < (
int)m_history.size(); }
322 m_undoPreeditState = -1;
326 bool allSelected()
const {
return !m_text.isEmpty() && m_selstart == 0 && m_selend == (
int)m_text.size(); }
327 bool hasSelectedText()
const {
return !m_text.isEmpty() && m_selend > m_selstart; }
329 void setSelection(
int start,
int length);
331 inline QString selectedText()
const {
return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
332 QString textBeforeSelection()
const {
return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
333 QString textAfterSelection()
const {
return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
335 int selectionStart()
const {
return hasSelectedText() ? m_selstart : -1; }
336 int selectionEnd()
const {
return hasSelectedText() ? m_selend : -1; }
338 QRectF anchorRectangle()
const;
340 int positionAt(qreal x, qreal y, QTextLine::CursorPosition position)
const;
341 int positionAt(
const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters)
const {
342 return positionAt(point.x(), point.y(), position);
345 void removeSelection()
347 int priorState = m_undoState;
348 removeSelectedText();
349 finishChange(priorState);
352 int start()
const {
return 0; }
353 int end()
const {
return m_text.size(); }
355 QString realText()
const;
357#if QT_CONFIG(clipboard)
358 void copy(QClipboard::Mode mode = QClipboard::Clipboard)
const;
359 void paste(QClipboard::Mode mode = QClipboard::Clipboard);
363 void commitPreedit();
364 void cancelPreedit();
367 Qt::CursorMoveStyle cursorMoveStyle()
const {
return m_textLayout.cursorMoveStyle(); }
368 void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
370 void moveCursor(
int pos,
bool mark =
false);
371 void cursorForward(
bool mark,
int steps)
376 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
377 : m_textLayout.nextCursorPosition(c);
378 }
else if (steps < 0) {
380 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
381 : m_textLayout.previousCursorPosition(c);
386 void cursorWordForward(
bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
387 void cursorWordBackward(
bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
389 void home(
bool mark) { moveCursor(0, mark); }
390 void end(
bool mark) { moveCursor(q_func()->text().size(), mark); }
394 void deselect() { internalDeselect(); finishChange(); }
395 void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(),
true); }
397 void insert(
const QString &);
399 void selectWordAtPos(
int);
401 void setCursorPosition(
int pos) {
if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
405 QString inputMask()
const {
return m_maskData ? m_inputMask + QLatin1Char(
';') + m_blank : QString(); }
406 void setInputMask(
const QString &mask)
408 parseInputMask(mask);
410 moveCursor(nextMaskBlank(0));
415 bool composeMode()
const {
return !m_textLayout.preeditAreaText().isEmpty(); }
417 QString preeditAreaText()
const {
return m_textLayout.preeditAreaText(); }
420 void updatePasswordEchoEditing(
bool editing);
422 void cancelPasswordEchoTimer() {
423 m_passwordEchoTimer.stop();
426 Qt::LayoutDirection textDirection()
const;
427 Qt::LayoutDirection layoutDirection()
const;
428 void setLayoutDirection(Qt::LayoutDirection direction)
430 if (direction != m_layoutDirection) {
431 m_layoutDirection = direction;
437 void processInputMethodEvent(QInputMethodEvent *event);
439 void processKeyEvent(QKeyEvent* ev);
441 void setBlinkingCursorEnabled(
bool enable);
442 void updateCursorBlinking();
445 void updateBaselineOffset();
447 qreal calculateImplicitWidthForText(
const QString &text)
const;
448 qreal getImplicitWidth()
const override;
450 inline qreal padding()
const {
return extra.isAllocated() ? extra->padding : 0.0; }
451 void setTopPadding(qreal value,
bool reset =
false);
452 void setLeftPadding(qreal value,
bool reset =
false);
453 void setRightPadding(qreal value,
bool reset =
false);
454 void setBottomPadding(qreal value,
bool reset =
false);
456 bool isImplicitResizeEnabled()
const;
457 void setImplicitResizeEnabled(
bool enabled);
460 void removeSelectedText();
461 void internalSetText(
const QString &txt,
int pos = -1,
bool edited =
true);
462 void updateDisplayText(
bool forceUpdate =
false);
464 void internalInsert(
const QString &s);
465 void internalDelete(
bool wasBackspace =
false);
466 void internalRemove(
int pos);
468 inline void internalDeselect()
470 m_selDirty |= (m_selend > m_selstart);
471 m_selstart = m_selend = 0;
474 void internalUndo(
int until = -1);
476 void emitUndoRedoChanged();
478 bool emitCursorPositionChanged();
480 bool finishChange(
int validateFromState = -1,
bool update =
false,
bool edited =
true);
482 void addCommand(
const Command& cmd);
484 inline void separate() { m_separator =
true; }
486 bool separateSelection();
487 void deleteStartOfWord();
488 void deleteEndOfWord();
489 void deleteEndOfLine();
491 enum ValidatorState {
492#if QT_CONFIG(validator)
493 InvalidInput = QValidator::Invalid,
494 IntermediateInput = QValidator::Intermediate,
495 AcceptableInput = QValidator::Acceptable
504 void parseInputMask(
const QString &maskFields);
505 bool isValidInput(QChar key, QChar mask)
const;
506 ValidatorState hasAcceptableInput(
const QString &text)
const;
508 QString maskString(uint pos,
const QString &str,
bool clear =
false)
const;
509 QString clearString(uint pos, uint len)
const;
510 QString stripString(
const QString &str)
const;
511 int findInMask(
int pos,
bool forward,
bool findSeparator, QChar searchChar = QChar())
const;