Qt 4.8
qlinecontrol_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QLINECONTROL_P_H
43 #define QLINECONTROL_P_H
44 
45 //
46 // W A R N I N G
47 // -------------
48 //
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 #include "QtCore/qglobal.h"
57 
58 #ifndef QT_NO_LINEEDIT
59 #include "private/qwidget_p.h"
60 #include "QtGui/qlineedit.h"
61 #include "QtGui/qtextlayout.h"
62 #include "QtGui/qstyleoption.h"
63 #include "QtCore/qpointer.h"
64 #include "QtGui/qclipboard.h"
65 #include "QtCore/qpoint.h"
66 #include "QtGui/qcompleter.h"
67 #include "QtGui/qaccessible.h"
68 
69 #include "qplatformdefs.h"
70 
72 
74 
75 QT_MODULE(Gui)
76 
78 {
79  Q_OBJECT
80 
81 public:
82  QLineControl(const QString &txt = QString())
83  : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
84  m_hideCursor(false), m_separator(0), m_readOnly(0),
85  m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
86  m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
87  m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
88  m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
89  m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
90 #ifdef QT_GUI_PASSWORD_ECHO_DELAY
91  , m_passwordEchoTimer(0)
92 #endif
93  {
94  init(txt);
95  }
96 
98  {
99  delete [] m_maskData;
100  }
101 
102  int nextMaskBlank(int pos)
103  {
104  int c = findInMask(pos, true, false);
105  m_separator |= (c != pos);
106  return (c != -1 ? c : m_maxLength);
107  }
108 
109  int prevMaskBlank(int pos)
110  {
111  int c = findInMask(pos, false, false);
112  m_separator |= (c != pos);
113  return (c != -1 ? c : 0);
114  }
115 
116  bool isUndoAvailable() const;
117  bool isRedoAvailable() const;
118  void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
119 
120  bool isModified() const { return m_modifiedState != m_undoState; }
121  void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
122 
123  bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
124  bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
125 
126  int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
127  int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; }
128  int ascent() const { return m_ascent; }
129  qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); }
130 
131  void setSelection(int start, int length);
132 
133  inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
134  QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
135  QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
136 
137  int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
138  int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
139  bool inSelection(int x) const
140  {
141  if (m_selstart >= m_selend)
142  return false;
143  int pos = xToPos(x, QTextLine::CursorOnCharacter);
144  return pos >= m_selstart && pos < m_selend;
145  }
146 
148  {
149  int priorState = m_undoState;
150  removeSelectedText();
151  finishChange(priorState);
152  }
153 
154  int start() const { return 0; }
155  int end() const { return m_text.length(); }
156 
157 #ifndef QT_NO_CLIPBOARD
158  void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
159  void paste(QClipboard::Mode mode = QClipboard::Clipboard);
160 #endif
161 
162  int cursor() const{ return m_cursor; }
163  int preeditCursor() const { return m_preeditCursor; }
164 
165  int cursorWidth() const { return m_cursorWidth; }
166  void setCursorWidth(int value) { m_cursorWidth = value; }
167 
168  Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
169  void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
170 
171  void moveCursor(int pos, bool mark = false);
172  void cursorForward(bool mark, int steps)
173  {
174  int c = m_cursor;
175  if (steps > 0) {
176  while (steps--)
177  c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
178  : m_textLayout.nextCursorPosition(c);
179  } else if (steps < 0) {
180  while (steps++)
181  c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
182  : m_textLayout.previousCursorPosition(c);
183  }
184  moveCursor(c, mark);
185  }
186 
187  void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
188  void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
189 
190  void home(bool mark) { moveCursor(0, mark); }
191  void end(bool mark) { moveCursor(text().length(), mark); }
192 
194  QRect cursorRect() const;
195 
196  qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
197  qreal cursorToX() const
198  {
199  int cursor = m_cursor;
200  if (m_preeditCursor != -1)
201  cursor += m_preeditCursor;
202  return cursorToX(cursor);
203  }
204 
205  bool isReadOnly() const { return m_readOnly; }
206  void setReadOnly(bool enable) { m_readOnly = enable; }
207 
208  QString text() const
209  {
210  QString res = m_maskData ? stripString(m_text) : m_text;
211  return (res.isNull() ? QString::fromLatin1("") : res);
212  }
213  void setText(const QString &txt) { internalSetText(txt, -1, false); }
214  QString displayText() const { return m_textLayout.text(); }
215 
216  void backspace();
217  void del();
218  void deselect() { internalDeselect(); finishChange(); }
219  void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
220 
221  void insert(const QString &);
222  void clear();
223  void undo() { internalUndo(); finishChange(-1, true); }
224  void redo() { internalRedo(); finishChange(); }
225  void selectWordAtPos(int);
226 
227  uint echoMode() const { return m_echoMode; }
228  void setEchoMode(uint mode)
229  {
230  cancelPasswordEchoTimer();
231  m_echoMode = mode;
232  m_passwordEchoEditing = false;
233  updateDisplayText();
234  }
235 
236  int maxLength() const { return m_maxLength; }
237  void setMaxLength(int maxLength)
238  {
239  if (m_maskData)
240  return;
241  m_maxLength = maxLength;
242  setText(m_text);
243  }
244 
245 #ifndef QT_NO_VALIDATOR
246  const QValidator *validator() const { return m_validator; }
247  void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); }
248 #endif
249 
250 #ifndef QT_NO_COMPLETER
251  QCompleter *completer() const { return m_completer; }
252  /* Note that you must set the widget for the completer separately */
253  void setCompleter(const QCompleter *c) { m_completer = const_cast<QCompleter*>(c); }
254  void complete(int key);
255 #endif
256 
257  int cursorPosition() const { return m_cursor; }
258  void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
259 
260  bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
261  bool fixup();
262 
263  QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
264  void setInputMask(const QString &mask)
265  {
266  parseInputMask(mask);
267  if (m_maskData)
268  moveCursor(nextMaskBlank(0));
269  }
270 
271  // input methods
272 #ifndef QT_NO_IM
273  bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
274  void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
275 #endif
276 
277  QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
278 
279  void updatePasswordEchoEditing(bool editing);
280  bool passwordEchoEditing() const {
281 #ifdef QT_GUI_PASSWORD_ECHO_DELAY
282  if (m_passwordEchoTimer != 0)
283  return true;
284 #endif
285  return m_passwordEchoEditing ;
286  }
287 
288  QChar passwordCharacter() const { return m_passwordCharacter; }
289  void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
290 
292  if (m_layoutDirection == Qt::LayoutDirectionAuto) {
293  if (m_text.isEmpty())
295  return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
296  }
297  return m_layoutDirection;
298  }
300  {
301  if (direction != m_layoutDirection) {
302  m_layoutDirection = direction;
303  updateDisplayText();
304  }
305  }
306 
307  void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
308 
309  void processInputMethodEvent(QInputMethodEvent *event);
310  void processMouseEvent(QMouseEvent* ev);
311  void processKeyEvent(QKeyEvent* ev);
312 
313  int cursorBlinkPeriod() const { return m_blinkPeriod; }
314  void setCursorBlinkPeriod(int msec);
315  void resetCursorBlinkTimer();
316 
317  QString cancelText() const { return m_cancelText; }
318  void setCancelText(const QString &text) { m_cancelText = text; }
319 
320  const QPalette &palette() const { return m_palette; }
321  void setPalette(const QPalette &p) { m_palette = p; }
322 
323  enum DrawFlags {
324  DrawText = 0x01,
325  DrawSelections = 0x02,
326  DrawCursor = 0x04,
327  DrawAll = DrawText | DrawSelections | DrawCursor
328  };
329  void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
330 
331  bool processEvent(QEvent *ev);
332 
333 private:
334  void init(const QString &txt);
335  void removeSelectedText();
336  void internalSetText(const QString &txt, int pos = -1, bool edited = true);
337  void updateDisplayText(bool forceUpdate = false);
338 
339  void internalInsert(const QString &s);
340  void internalDelete(bool wasBackspace = false);
341  void internalRemove(int pos);
342 
343  inline void internalDeselect()
344  {
345  m_selDirty |= (m_selend > m_selstart);
346  m_selstart = m_selend = 0;
347  }
348 
349  void internalUndo(int until = -1);
350  void internalRedo();
351 
354  int m_cursor;
358  uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
367  int m_blinkPeriod; // 0 for non-blinking cursor
370  int m_ascent;
377 
378  void emitCursorPositionChanged();
379 
380  bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
381 
382 #ifndef QT_NO_VALIDATOR
384 #endif
386 #ifndef QT_NO_COMPLETER
387  bool advanceToEnabledItem(int dir);
388 #endif
389 
390  struct MaskInputData {
391  enum Casemode { NoCaseMode, Upper, Lower };
392  QChar maskChar; // either the separator char or the inputmask
393  bool separator;
395  };
399 
400  // undo/redo handling
401  enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
402  struct Command {
403  inline Command() {}
404  inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
405  uint type : 4;
407  int pos, selStart, selEnd;
408  };
412  void addCommand(const Command& cmd);
413 
414  inline void separate() { m_separator = true; }
415 
416  // selection
418  int m_selend;
419 
420  // masking
421  void parseInputMask(const QString &maskFields);
422  bool isValidInput(QChar key, QChar mask) const;
423  bool hasAcceptableInput(const QString &text) const;
424  QString maskString(uint pos, const QString &str, bool clear = false) const;
425  QString clearString(uint pos, uint len) const;
426  QString stripString(const QString &str) const;
427  int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
428 
429  // complex text layout
431 
434 #ifdef QT_GUI_PASSWORD_ECHO_DELAY
435  int m_passwordEchoTimer;
436 #endif
438  {
439 #ifdef QT_GUI_PASSWORD_ECHO_DELAY
440  if (m_passwordEchoTimer != 0) {
441  killTimer(m_passwordEchoTimer);
442  m_passwordEchoTimer = 0;
443  }
444 #endif
445  }
446 
447 Q_SIGNALS:
448  void cursorPositionChanged(int, int);
449  void selectionChanged();
450 
451  void displayTextChanged(const QString &);
452  void textChanged(const QString &);
453  void textEdited(const QString &);
454 
455  void resetInputContext();
456  void updateMicroFocus();
457 
458  void accepted();
459  void editingFinished();
460  void updateNeeded(const QRect &);
461 
462 #ifdef QT_KEYPAD_NAVIGATION
463  void editFocusChange(bool);
464 #endif
465 protected:
466  virtual void timerEvent(QTimerEvent *event);
467 
468 private Q_SLOTS:
469  void _q_clipboardChanged();
470  void _q_deleteSelected();
471 
472 };
473 
475 
477 
478 #endif // QT_NO_LINEEDIT
479 
480 #endif // QLINECONTROL_P_H
Mode
This enum type is used to control which part of the system clipboard is used by QClipboard::mimeData(...
Definition: qclipboard.h:71
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
QChar m_passwordCharacter
The QKeyEvent class describes a key event.
Definition: qevent.h:224
QString cancelText() const
int type
Definition: qmetatype.cpp:239
double qreal
Definition: qglobal.h:1193
Qt::CursorMoveStyle cursorMoveStyle() const
int selectionStart() const
int cursor() const
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QString textAfterSelection() const
EventRef event
#define QT_MODULE(x)
Definition: qglobal.h:2783
void cursorWordForward(bool mark)
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
void cancelPasswordEchoTimer()
Qt::LayoutDirection m_layoutDirection
void home(bool mark)
void setEchoMode(uint mode)
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
void setText(const QString &txt)
QString text() const
QCompleter * completer() const
static void clear(QVariant::Private *d)
Definition: qvariant.cpp:197
The QCompleter class provides completions based on an item model.
Definition: qcompleter.h:64
void setModified(bool modified)
QVector< Command > m_history
int height() const
QPoint m_tripleClick
QString m_inputMask
#define Q_SLOTS
Definition: qobjectdefs.h:71
The QString class provides a Unicode character string.
Definition: qstring.h:83
QString m_cancelText
void setCursorMoveStyle(Qt::CursorMoveStyle style)
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
int width() const
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_SIGNALS
Definition: qobjectdefs.h:72
const QValidator * validator() const
int preeditCursor() const
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
void setPreeditArea(int cursor, const QString &text)
bool composeMode() const
QString preeditAreaText() const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void setValidator(const QValidator *v)
static QCursor * moveCursor
Definition: qdnd_x11.cpp:254
int cursorPosition() const
QString textBeforeSelection() const
QChar passwordCharacter() const
void setCursorPosition(int pos)
uint echoMode() const
bool hasAcceptableInput() const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QValidator class provides validation of input text.
Definition: qvalidator.h:60
bool passwordEchoEditing() const
int ascent() const
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
int start() const
static bool init
QList< int > m_transactions
LayoutDirection
Definition: qnamespace.h:1580
const QPalette & palette() const
QLineControl(const QString &txt=QString())
unsigned int uint
Definition: qglobal.h:996
qreal cursorToX(int cursor) const
void setCancelText(const QString &text)
int cursorWidth() const
bool isModified() const
int nextMaskBlank(int pos)
QPointer< QCompleter > m_completer
#define Q_OBJECT
Definition: qobjectdefs.h:157
void removeSelection()
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
QString inputMask() const
The QInputMethodEvent class provides parameters for input method events.
Definition: qevent.h:431
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
void setCompleter(const QCompleter *c)
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
QPointer< QValidator > m_validator
QString displayText() const
void cursorWordBackward(bool mark)
bool isReadOnly() const
The QTextLayout class is used to lay out and render text.
Definition: qtextlayout.h:105
QString selectedText() const
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
void internalDeselect()
CursorMoveStyle
This enum describes the movement style available to text cursors.
Definition: qnamespace.h:1790
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
void end(bool mark)
QPalette m_palette
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
void setMaxLength(int maxLength)
int prevMaskBlank(int pos)
MaskInputData * m_maskData
void setFont(const QFont &font)
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
Qt::LayoutDirection layoutDirection() const
void setPasswordCharacter(const QChar &character)
qreal naturalTextWidth() const
void setPalette(const QPalette &p)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
Definition: qnamespace.h:54
Command(CommandType t, int p, QChar c, int ss, int se)
void cursorForward(bool mark, int steps)
void setLayoutDirection(Qt::LayoutDirection direction)
void setCursorWidth(int value)
QTextLayout m_textLayout
void setInputMask(const QString &mask)
void setReadOnly(bool enable)
bool hasSelectedText() const
static Qt::LayoutDirection keyboardInputDirection()
Returns the current keyboard input direction.
int cursorBlinkPeriod() const
#define class
qreal cursorToX() const
int selectionEnd() const
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
bool allSelected() const
int end() const
#define QT_END_HEADER
Definition: qglobal.h:137
bool inSelection(int x) const
bool m_passwordEchoEditing
int maxLength() const
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
#define text
Definition: qobjectdefs.h:80
Qt::LayoutDirection direction
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61