57 QWidgetLineControl(
const QString &txt = QString())
58 : QInputControl(LineEdit)
59 , m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
60 m_hideCursor(
false), m_separator(0), m_readOnly(0),
61 m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
62 m_validInput(1), m_blinkStatus(0), m_blinkEnabled(
false),
63 m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
64 m_maskData(
nullptr), m_modifiedState(0), m_undoState(0),
65 m_selstart(0), m_selend(0), m_passwordEchoEditing(
false)
66 , m_passwordMaskDelay(-1)
67#if defined(QT_BUILD_INTERNAL)
68 , m_passwordMaskDelayOverride(-1)
71 , m_accessibleObject(
nullptr)
81 if (m_echoMode != QLineEdit::Normal)
85 void setAccessibleObject(QObject *object)
88 m_accessibleObject = object;
91 QObject *accessibleObject()
93 if (m_accessibleObject)
94 return m_accessibleObject;
98 int nextMaskBlank(
int pos)
100 int c = findInMask(pos,
true,
false);
101 m_separator |= (c != pos);
102 return (c != -1 ? c : m_maxLength);
105 int prevMaskBlank(
int pos)
107 int c = findInMask(pos,
false,
false);
108 m_separator |= (c != pos);
109 return (c != -1 ? c : 0);
112 bool isUndoAvailable()
const;
113 bool isRedoAvailable()
const;
114 void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
116 bool isModified()
const {
return m_modifiedState != m_undoState; }
117 void setModified(
bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
119 bool allSelected()
const {
return !m_text.isEmpty() && m_selstart == 0 && m_selend == (
int)m_text.size(); }
120 bool hasSelectedText()
const {
return !m_text.isEmpty() && m_selend > m_selstart; }
122 int width()
const {
return qRound(m_textLayout.lineAt(0).width()) + 1; }
123 int height()
const {
return qRound(m_textLayout.lineAt(0).height()) + 1; }
124 int ascent()
const {
return m_ascent; }
125 qreal naturalTextWidth()
const {
return m_textLayout.lineAt(0).naturalTextWidth(); }
127 void setSelection(
int start,
int length);
129 inline QString selectedText()
const {
return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
130 QString textBeforeSelection()
const {
return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
131 QString textAfterSelection()
const {
return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
133 int selectionStart()
const {
return hasSelectedText() ? m_selstart : -1; }
134 int selectionEnd()
const {
return hasSelectedText() ? m_selend : -1; }
135#if defined (Q_OS_ANDROID)
136 bool isSelectableByMouse()
const {
return true; }
138 bool inSelection(
int x)
const
140 if (m_selstart >= m_selend)
142 int pos = xToPos(x, QTextLine::CursorOnCharacter);
143 return pos >= m_selstart && pos < m_selend;
146 void removeSelection()
148 int priorState = m_undoState;
149 removeSelectedText();
150 finishChange(priorState);
153 int start()
const {
return 0; }
154 int end()
const {
return m_text.size(); }
156#ifndef QT_NO_CLIPBOARD
157 void copy(QClipboard::Mode mode = QClipboard::Clipboard)
const;
158 void paste(QClipboard::Mode mode = QClipboard::Clipboard);
161 int cursor()
const{
return m_cursor; }
162 int preeditCursor()
const {
return m_preeditCursor; }
164 int cursorWidth()
const {
return m_cursorWidth; }
165 void setCursorWidth(
int value) { m_cursorWidth = value; }
167 Qt::CursorMoveStyle cursorMoveStyle()
const {
return m_textLayout.cursorMoveStyle(); }
168 void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
170 void moveCursor(
int pos,
bool mark =
false);
171 void cursorForward(
bool mark,
int steps)
176 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
177 : m_textLayout.nextCursorPosition(c);
178 }
else if (steps < 0) {
180 c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
181 : m_textLayout.previousCursorPosition(c);
186 void cursorWordForward(
bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
187 void cursorWordBackward(
bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
189 void home(
bool mark) { moveCursor(0, mark); }
190 void end(
bool mark) { moveCursor(m_text.size(), mark); }
192 int xToPos(
int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters)
const;
193 QRect rectForPos(
int pos)
const;
194 QRect cursorRect()
const;
195 QRect anchorRect()
const;
197 qreal cursorToX(
int cursor)
const {
return m_textLayout.lineAt(0).cursorToX(cursor); }
198 qreal cursorToX()
const
200 int cursor = m_cursor;
201 if (m_preeditCursor != -1)
202 cursor += m_preeditCursor;
203 return cursorToX(cursor);
206 bool isReadOnly()
const {
return m_readOnly; }
207 void setReadOnly(
bool enable);
211 QString content = m_text;
212 QString res = m_maskData ? stripString(content) : content;
213 return (res.isNull() ? QString::fromLatin1(
"") : res);
215 void setText(
const QString &txt)
219 QGuiApplication::inputMethod()->reset();
221 internalSetText(txt, -1,
false);
223 void commitPreedit();
225 QString displayText()
const {
return m_textLayout.text(); }
227 QString surroundingText()
const
229 return m_text.isNull() ? QString::fromLatin1(
"") : m_text;
234 void deselect() { internalDeselect(); finishChange(); }
235 void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(),
true); }
237 void insert(
const QString &);
240 void redo() { internalRedo(); finishChange(); }
241 void selectWordAtPos(
int);
243 uint echoMode()
const {
return m_echoMode; }
244 void setEchoMode(uint mode)
246 cancelPasswordEchoTimer();
248 m_passwordEchoEditing =
false;
253 if (m_echoMode != QLineEdit::Normal)
259 int maxLength()
const {
return m_maxLength; }
260 void setMaxLength(
int maxLength)
264 m_maxLength = maxLength;
268#ifndef QT_NO_VALIDATOR
269 const QValidator *validator()
const {
return m_validator; }
270 void setValidator(
const QValidator *v) { m_validator =
const_cast<QValidator*>(v); }
273#if QT_CONFIG(completer)
274 QCompleter *completer()
const {
return m_completer; }
276 void setCompleter(
const QCompleter *c) { m_completer =
const_cast<QCompleter*>(c); }
277 void complete(
int key);
280 int cursorPosition()
const {
return m_cursor; }
281 void setCursorPosition(
int pos) {
if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
283 bool hasAcceptableInput()
const {
return hasAcceptableInput(m_text); }
286 QString inputMask()
const
291 if (m_blank != u' ') {
298 void setInputMask(
const QString &mask)
300 parseInputMask(mask);
302 moveCursor(nextMaskBlank(0));
307 bool composeMode()
const {
return !m_textLayout.preeditAreaText().isEmpty(); }
308 void setPreeditArea(
int cursor,
const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
311 QString preeditAreaText()
const {
return m_textLayout.preeditAreaText(); }
313 void updatePasswordEchoEditing(
bool editing);
314 bool passwordEchoEditing()
const {
315 if (m_passwordEchoTimer.isActive())
317 return m_passwordEchoEditing ;
320 QChar passwordCharacter()
const {
return m_passwordCharacter; }
321 void setPasswordCharacter(QChar character) { m_passwordCharacter = character; updateDisplayText(); }
323 int passwordMaskDelay()
const {
return m_passwordMaskDelay; }
324 void setPasswordMaskDelay(
int delay) { m_passwordMaskDelay = delay; }
326 Qt::LayoutDirection layoutDirection()
const {
327 if (m_layoutDirection == Qt::LayoutDirectionAuto && !m_text.isEmpty())
328 return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
329 return m_layoutDirection;
331 void setLayoutDirection(Qt::LayoutDirection direction)
333 if (direction != m_layoutDirection) {
334 m_layoutDirection = direction;
339 void setFont(
const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
341 void processInputMethodEvent(QInputMethodEvent *event);
342 void processKeyEvent(QKeyEvent* ev);
344 void setBlinkingCursorEnabled(
bool enable);
345 void updateCursorBlinking();
346 void resetCursorBlinkTimer();
348 bool cursorBlinkStatus()
const {
return m_blinkStatus; }
350 QString cancelText()
const {
return m_cancelText; }
351 void setCancelText(
const QString &text) { m_cancelText = text; }
353 const QPalette &palette()
const {
return m_palette; }
354 void setPalette(
const QPalette &p) { m_palette = p; }
358 DrawSelections = 0x02,
360 DrawAll = DrawText | DrawSelections | DrawCursor
362 void draw(QPainter *,
const QPoint &,
const QRect &,
int flags = DrawAll);
364#ifndef QT_NO_SHORTCUT
365 void processShortcutOverrideEvent(QKeyEvent *ke);
368 QTextLayout *textLayout()
const
370 return &m_textLayout;
374 void init(
const QString &txt);
375 void removeSelectedText();
376 void internalSetText(
const QString &txt,
int pos = -1,
bool edited =
true);
377 void updateDisplayText(
bool forceUpdate =
false);
379 void internalInsert(
const QString &s);
380 void internalDelete(
bool wasBackspace =
false);
381 void internalRemove(
int pos);
383 inline void internalDeselect()
385 m_selDirty |= (m_selend > m_selstart);
386 m_selstart = m_selend = 0;
389 void internalUndo(
int until = -1);
397 Qt::LayoutDirection m_layoutDirection;
398 uint m_hideCursor : 1;
399 uint m_separator : 1;
401 uint m_dragEnabled : 1;
403 uint m_textDirty : 1;
405 uint m_validInput : 1;
406 uint m_blinkStatus : 1;
407 uint m_blinkEnabled : 1;
408 QBasicTimer m_blinkTimer;
409 QBasicTimer m_deleteAllTimer;
413 QList<
int> m_transactions;
414 QPoint m_tripleClick;
415 QBasicTimer m_tripleClickTimer;
416 QString m_cancelText;
418 void emitCursorPositionChanged();
420 bool finishChange(
int validateFromState = -1,
bool update =
false,
bool edited =
true);
422#ifndef QT_NO_VALIDATOR
423 QPointer<QValidator> m_validator;
425 QPointer<QCompleter> m_completer;
426#if QT_CONFIG(completer)
427 bool advanceToEnabledItem(
int dir);
430 struct MaskInputData {
431 enum Casemode { NoCaseMode, Upper, Lower };
438 std::unique_ptr<MaskInputData[]> m_maskData;
441 enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
443 inline Command(CommandType t,
int p, QChar c,
int ss,
int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
446 int pos, selStart, selEnd;
450 std::vector<Command> m_history;
451 void addCommand(
const Command& cmd);
453 inline void separate() { m_separator =
true; }
460 void parseInputMask(
const QString &maskFields);
461 bool isValidInput(QChar key, QChar mask)
const;
462 bool hasAcceptableInput(
const QString &text)
const;
463 QString maskString(
int pos,
const QString &str,
bool clear =
false)
const;
464 QString clearString(
int pos,
int len)
const;
465 QString stripString(
const QString &str)
const;
466 int findInMask(
int pos,
bool forward,
bool findSeparator, QChar searchChar = QChar())
const;
469 mutable QTextLayout m_textLayout;
471 bool m_passwordEchoEditing;
472 QChar m_passwordCharacter;
473 QBasicTimer m_passwordEchoTimer;
474 int m_passwordMaskDelay;
475 void cancelPasswordEchoTimer()
477 m_passwordEchoTimer.stop();
480 int redoTextLayout()
const;
483#if defined(QT_BUILD_INTERNAL)
484 int m_passwordMaskDelayOverride;
488 void cursorPositionChanged(
int,
int);
489 void selectionChanged();
491 void displayTextChanged(
const QString &);
492 void textChanged(
const QString &);
493 void textEdited(
const QString &);
495 void resetInputContext();
496 void updateMicroFocus();
499 void editingFinished();
500 void updateNeeded(
const QRect &);
501 void inputRejected();
503#ifdef QT_KEYPAD_NAVIGATION
504 void editFocusChange(
bool);
507 virtual void timerEvent(QTimerEvent *event) override;
510 void _q_deleteSelected();
513 int m_keyboardScheme;
516 QObject *m_accessibleObject;
518 friend class QLineEdit;