47#if QT_CONFIG(accessibility)
48 ,
public QAccessible::ActivationObserver
52 Q_DECLARE_PUBLIC(QQuickTextInput)
54 typedef QQuickTextInput Public;
64 bool explicitTopPadding : 1;
65 bool explicitLeftPadding : 1;
66 bool explicitRightPadding : 1;
67 bool explicitBottomPadding : 1;
68 bool implicitResize : 1;
70 QLazilyAllocated<ExtraData> extra;
72 QQuickTextInputPrivate()
78 , color(QRgb(0xFF000000))
79 , selectionColor(QRgb(0xFF000080))
80 , selectedTextColor(QRgb(0xFFFFFFFF))
84 , m_undoPreeditState(-1)
86 , m_blinkEnabled(
false)
94 , inputMethodHints(Qt::ImhNone)
96 , hAlign(QQuickTextInput::AlignLeft)
97 , vAlign(QQuickTextInput::AlignTop)
98 , wrapMode(QQuickTextInput::NoWrap)
99 , m_echoMode(QQuickTextInput::Normal)
100 , renderType(QQuickTextUtil::textRenderType<QQuickTextInput>())
101 , updateType(UpdatePaintNode)
102 , mouseSelectionMode(QQuickTextInput::SelectCharacters)
103 , m_layoutDirection(Qt::LayoutDirectionAuto)
104 , m_passwordCharacter(QGuiApplication::styleHints()->passwordMaskCharacter())
105 , m_passwordMaskDelay(QGuiApplication::styleHints()->passwordMaskDelay())
107 , cursorVisible(
false)
108 , cursorPending(
false)
110 , selectByMouse(
true)
112 , canPasteValid(
false)
115 , hAlignImplicit(
true)
116 , selectPressed(
false)
117 , hadSelectionOnMousePress(
false)
118 , textLayoutDirty(
true)
119 , persistentSelection(
false)
129 , m_acceptableInput(1)
131 , m_passwordEchoEditing(
false)
133 , requireImplicitWidth(
false)
134 , overwriteMode(
false)
135 , containsUnscalableGlyphs(
false)
136#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
137 , selectByTouchDrag(
false)
140#if QT_CONFIG(accessibility)
141 QAccessible::installActivationObserver(
this);
146 ~QQuickTextInputPrivate()
151 if (m_echoMode != QQuickTextInput::Normal)
154#if QT_CONFIG(accessibility)
155 QAccessible::removeActivationObserver(
this);
161 void startCreatingCursor();
162 void ensureVisible(
int position,
int preeditCursor = 0,
int preeditLength = 0);
163 void updateHorizontalScroll();
164 void updateVerticalScroll();
165 bool determineHorizontalAlignment();
166 bool setHAlign(QQuickTextInput::HAlignment,
bool forceAlign =
false);
167 void mirrorChange() override;
168#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
169 bool handleContextMenuEvent(QContextMenuEvent *event) override;
171 bool sendMouseEventToInputContext(QMouseEvent *event);
173 Qt::InputMethodHints effectiveInputMethodHints()
const;
175 void handleFocusEvent(QFocusEvent *event);
177 virtual void readOnlyChanged(
bool isReadOnly);
178 void echoModeChanged(QQuickTextInput::EchoMode echoMode);
180#if QT_CONFIG(accessibility)
181 void accessibilityActiveChanged(
bool active) override;
182 QAccessible::Role accessibleRole()
const override;
185 struct MaskInputData {
186 enum Casemode { NoCaseMode, Upper, Lower };
193 enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
196 inline Command(CommandType t,
int p, QChar c,
int ss,
int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
199 int pos, selStart, selEnd;
204 DrawSelections = 0x02,
206 DrawAll = DrawText | DrawSelections | DrawCursor
209 QElapsedTimer tripleClickTimer;
212 QPointF tripleClickStartPoint;
214 QPointer<QQmlComponent> cursorComponent;
215#if QT_CONFIG(validator)
216 QPointer<QValidator> m_validator;
222 QTextLayout m_textLayout;
225 QString m_cancelText;
229 QQuickItem *cursorItem;
230 QSGInternalTextNode *textNode;
231 std::unique_ptr<MaskInputData[]> m_maskData;
232 QInputControl *m_inputControl;
234 QList<
int> m_transactions;
235 QVector<Command> m_history;
238 QColor selectionColor;
239 QColor selectedTextColor;
241 QBasicTimer m_passwordEchoTimer;
242 int lastSelectionStart;
243 int lastSelectionEnd;
247 int m_undoPreeditState;
259 UpdateOnlyPreprocess,
264 Qt::InputMethodHints inputMethodHints;
266 QQuickTextInput::HAlignment hAlign;
267 QQuickTextInput::VAlignment vAlign;
268 QQuickTextInput::WrapMode wrapMode;
269 QQuickTextInput::EchoMode m_echoMode;
270 QQuickTextInput::RenderType renderType;
271 UpdateType updateType;
272 QQuickTextInput::SelectionMode mouseSelectionMode;
273 Qt::LayoutDirection m_layoutDirection;
276 QChar m_passwordCharacter;
277 int m_passwordMaskDelay;
280 bool cursorVisible:1;
281 bool cursorPending:1;
283 bool selectByMouse:1;
285 bool canPasteValid:1;
288 bool hAlignImplicit:1;
289 bool selectPressed:1;
290 bool hadSelectionOnMousePress:1;
291 bool textLayoutDirty:1;
292 bool persistentSelection:1;
294 bool m_separator : 1;
296 bool m_textDirty : 1;
298 bool m_preeditDirty : 1;
301 bool m_validInput : 1;
302 bool m_acceptableInput : 1;
303 bool m_blinkStatus : 1;
304 bool m_passwordEchoEditing : 1;
306 bool requireImplicitWidth:1;
307 bool overwriteMode:1;
308 bool containsUnscalableGlyphs:1;
309#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
310 bool selectByTouchDrag:1;
313 static inline QQuickTextInputPrivate *get(QQuickTextInput *t) {
316 bool hasPendingTripleClick()
const {
317 return !tripleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval());
320 void setNativeCursorEnabled(
bool) {
321 updateCursorBlinking();
324 int nextMaskBlank(
int pos)
326 int c = findInMask(pos,
true,
false);
327 m_separator |= (c != pos);
328 return (c != -1 ? c : m_maxLength);
331 int prevMaskBlank(
int pos)
333 int c = findInMask(pos,
false,
false);
334 m_separator |= (c != pos);
335 return (c != -1 ? c : 0);
338 bool isUndoAvailable()
const {
return !m_readOnly && m_undoState; }
339 bool isRedoAvailable()
const {
return !m_readOnly && m_undoState < (
int)m_history.size(); }
344 m_undoPreeditState = -1;
348 bool allSelected()
const {
return !m_text.isEmpty() && m_selstart == 0 && m_selend == (
int)m_text.size(); }
349 bool hasSelectedText()
const {
return !m_text.isEmpty() && m_selend > m_selstart; }
351 void setSelection(
int start,
int length);
353 inline QString selectedText()
const {
return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
354 QString textBeforeSelection()
const {
return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
355 QString textAfterSelection()
const {
return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
357 int selectionStart()
const {
return hasSelectedText() ? m_selstart : -1; }
358 int selectionEnd()
const {
return hasSelectedText() ? m_selend : -1; }
360 QRectF anchorRectangle()
const;
362 int positionAt(qreal x, qreal y, QTextLine::CursorPosition position)
const;
363 int positionAt(
const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters)
const {
364 return positionAt(point.x(), point.y(), position);
367 void removeSelection()
369 int priorState = m_undoState;
370 removeSelectedText();
371 finishChange(priorState);
374 int start()
const {
return 0; }
375 int end()
const {
return m_text.size(); }
377 QString realText()
const;
379#if QT_CONFIG(clipboard)
380 void copy(QClipboard::Mode mode = QClipboard::Clipboard)
const;
381 void paste(QClipboard::Mode mode = QClipboard::Clipboard);
385 void commitPreedit();
386 void cancelPreedit();
389 Qt::CursorMoveStyle cursorMoveStyle()
const {
return m_textLayout.cursorMoveStyle(); }
390 void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
392 void moveCursor(
int pos,
bool mark =
false);
393 void cursorForward(
bool mark,
int steps)
398 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
399 : m_textLayout.nextCursorPosition(c);
400 }
else if (steps < 0) {
402 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
403 : m_textLayout.previousCursorPosition(c);
408 void cursorWordForward(
bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
409 void cursorWordBackward(
bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
411 void home(
bool mark) { moveCursor(0, mark); }
412 void end(
bool mark) { moveCursor(q_func()->text().size(), mark); }
416 void deselect() { internalDeselect(); finishChange(); }
417 void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(),
true); }
419 void insert(
const QString &);
421 void selectWordAtPos(
int);
423 void setCursorPosition(
int pos) {
if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
427 QString inputMask()
const {
return m_maskData ? m_inputMask + QLatin1Char(
';') + m_blank : QString(); }
428 void setInputMask(
const QString &mask)
430 parseInputMask(mask);
432 moveCursor(nextMaskBlank(0));
437 bool composeMode()
const {
return !m_textLayout.preeditAreaText().isEmpty(); }
439 QString preeditAreaText()
const {
return m_textLayout.preeditAreaText(); }
442 void updatePasswordEchoEditing(
bool editing);
444 void cancelPasswordEchoTimer() {
445 m_passwordEchoTimer.stop();
448 Qt::LayoutDirection textDirection()
const;
449 Qt::LayoutDirection layoutDirection()
const;
450 void setLayoutDirection(Qt::LayoutDirection direction)
452 if (direction != m_layoutDirection) {
453 m_layoutDirection = direction;
459 void processInputMethodEvent(QInputMethodEvent *event);
461 void processKeyEvent(QKeyEvent* ev);
463 void setBlinkingCursorEnabled(
bool enable);
464 void updateCursorBlinking();
467 void updateBaselineOffset();
469 qreal calculateImplicitWidthForText(
const QString &text)
const;
470 qreal getImplicitWidth()
const override;
472 inline qreal padding()
const {
return extra.isAllocated() ? extra->padding : 0.0; }
473 void setTopPadding(qreal value,
bool reset =
false);
474 void setLeftPadding(qreal value,
bool reset =
false);
475 void setRightPadding(qreal value,
bool reset =
false);
476 void setBottomPadding(qreal value,
bool reset =
false);
478 bool isImplicitResizeEnabled()
const;
479 void setImplicitResizeEnabled(
bool enabled);
482 void removeSelectedText();
483 void internalSetText(
const QString &txt,
int pos = -1,
bool edited =
true);
484 void updateDisplayText(
bool forceUpdate =
false);
486 void internalInsert(
const QString &s);
487 void internalDelete(
bool wasBackspace =
false);
488 void internalRemove(
int pos);
490 inline void internalDeselect()
492 m_selDirty |= (m_selend > m_selstart);
493 m_selstart = m_selend = 0;
496 void internalUndo(
int until = -1);
498 void emitUndoRedoChanged();
500 bool emitCursorPositionChanged();
502 bool finishChange(
int validateFromState = -1,
bool update =
false,
bool edited =
true);
504 void addCommand(
const Command& cmd);
506 inline void separate() { m_separator =
true; }
508 bool separateSelection();
509 void deleteStartOfWord();
510 void deleteEndOfWord();
511 void deleteEndOfLine();
513 enum ValidatorState {
514#if QT_CONFIG(validator)
515 InvalidInput = QValidator::Invalid,
516 IntermediateInput = QValidator::Intermediate,
517 AcceptableInput = QValidator::Acceptable
526 void parseInputMask(
const QString &maskFields);
527 bool isValidInput(QChar key, QChar mask)
const;
528 ValidatorState hasAcceptableInput(
const QString &text)
const;
530 QString maskString(uint pos,
const QString &str,
bool clear =
false)
const;
531 QString clearString(uint pos, uint len)
const;
532 QString stripString(
const QString &str)
const;
533 int findInMask(
int pos,
bool forward,
bool findSeparator, QChar searchChar = QChar())
const;