source: trunk/src/gui/widgets/qlinecontrol_p.h@ 698

Last change on this file since 698 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 18.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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/qlineedit.h"
65#include "QtGui/qclipboard.h"
66#include "QtCore/qpoint.h"
67#include "QtGui/qcompleter.h"
68
69QT_BEGIN_HEADER
70
71QT_BEGIN_NAMESPACE
72
73QT_MODULE(Gui)
74
75class Q_GUI_EXPORT QLineControl : public QObject
76{
77 Q_OBJECT
78
79public:
80 QLineControl(const QString &txt = QString())
81 : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LeftToRight),
82 m_hideCursor(false), m_separator(0), m_readOnly(0),
83 m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
84 m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
85 m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
86 m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
87 m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
88 {
89 init(txt);
90 }
91
92 ~QLineControl()
93 {
94 delete [] m_maskData;
95 }
96
97 int nextMaskBlank(int pos);
98 int prevMaskBlank(int pos);
99
100 bool isUndoAvailable() const;
101 bool isRedoAvailable() const;
102 void clearUndo();
103 bool isModified() const;
104 void setModified(bool modified);
105
106 bool allSelected() const;
107 bool hasSelectedText() const;
108
109 int width() const;
110 int height() const;
111 int ascent() const;
112 qreal naturalTextWidth() const;
113
114 void setSelection(int start, int length);
115
116 QString selectedText() const;
117 QString textBeforeSelection() const;
118 QString textAfterSelection() const;
119
120 int selectionStart() const;
121 int selectionEnd() const;
122 bool inSelection(int x) const;
123
124 void removeSelection();
125
126 int start() const;
127 int end() const;
128
129#ifndef QT_NO_CLIPBOARD
130 void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
131 void paste();
132#endif
133
134 int cursor() const;
135 int preeditCursor() const;
136
137 int cursorWidth() const;
138 void setCursorWidth(int value);
139
140 void moveCursor(int pos, bool mark = false);
141 void cursorForward(bool mark, int steps);
142 void cursorWordForward(bool mark);
143 void cursorWordBackward(bool mark);
144 void home(bool mark);
145 void end(bool mark);
146
147 int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
148 QRect cursorRect() const;
149
150 qreal cursorToX(int cursor) const;
151 qreal cursorToX() const;
152
153 bool isReadOnly() const;
154 void setReadOnly(bool enable);
155
156 QString text() const;
157 void setText(const QString &txt);
158
159 QString displayText() const;
160
161 void backspace();
162 void del();
163 void deselect();
164 void selectAll();
165 void insert(const QString &);
166 void clear();
167 void undo();
168 void redo();
169 void selectWordAtPos(int);
170
171 uint echoMode() const;
172 void setEchoMode(uint mode);
173
174 void setMaxLength(int maxLength);
175 int maxLength() const;
176
177#ifndef QT_NO_VALIDATOR
178 const QValidator *validator() const;
179 void setValidator(const QValidator *);
180#endif
181
182#ifndef QT_NO_COMPLETER
183 QCompleter *completer() const;
184 void setCompleter(const QCompleter*);
185 void complete(int key);
186#endif
187
188 void setCursorPosition(int pos);
189 int cursorPosition() const;
190
191 bool hasAcceptableInput() const;
192 bool fixup();
193
194 QString inputMask() const;
195 void setInputMask(const QString &mask);
196
197 // input methods
198#ifndef QT_NO_IM
199 bool composeMode() const;
200 void setPreeditArea(int cursor, const QString &text);
201#endif
202
203 QString preeditAreaText() const;
204
205 void updatePasswordEchoEditing(bool editing);
206 bool passwordEchoEditing() const;
207
208 QChar passwordCharacter() const;
209 void setPasswordCharacter(const QChar &character);
210
211 Qt::LayoutDirection layoutDirection() const;
212 void setLayoutDirection(Qt::LayoutDirection direction);
213 void setFont(const QFont &font);
214
215 void processInputMethodEvent(QInputMethodEvent *event);
216 void processMouseEvent(QMouseEvent* ev);
217 void processKeyEvent(QKeyEvent* ev);
218
219 int cursorBlinkPeriod() const;
220 void setCursorBlinkPeriod(int msec);
221
222 QString cancelText() const;
223 void setCancelText(const QString &text);
224
225 const QPalette &palette() const;
226 void setPalette(const QPalette &);
227
228 enum DrawFlags {
229 DrawText = 0x01,
230 DrawSelections = 0x02,
231 DrawCursor = 0x04,
232 DrawAll = DrawText | DrawSelections | DrawCursor
233 };
234 void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
235
236 bool processEvent(QEvent *ev);
237
238private:
239 void init(const QString &txt);
240 void removeSelectedText();
241 void internalSetText(const QString &txt, int pos = -1, bool edited = true);
242 void updateDisplayText();
243
244 void internalInsert(const QString &s);
245 void internalDelete(bool wasBackspace = false);
246 void internalRemove(int pos);
247
248 inline void internalDeselect()
249 {
250 m_selDirty |= (m_selend > m_selstart);
251 m_selstart = m_selend = 0;
252 }
253
254 void internalUndo(int until = -1);
255 void internalRedo();
256
257 QString m_text;
258 QPalette m_palette;
259 int m_cursor;
260 int m_preeditCursor;
261 int m_cursorWidth;
262 Qt::LayoutDirection m_layoutDirection;
263 uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
264 uint m_separator : 1;
265 uint m_readOnly : 1;
266 uint m_dragEnabled : 1;
267 uint m_echoMode : 2;
268 uint m_textDirty : 1;
269 uint m_selDirty : 1;
270 uint m_validInput : 1;
271 uint m_blinkStatus : 1;
272 int m_blinkPeriod; // 0 for non-blinking cursor
273 int m_blinkTimer;
274 int m_deleteAllTimer;
275 int m_ascent;
276 int m_maxLength;
277 int m_lastCursorPos;
278 QList<int> m_transactions;
279 QPoint m_tripleClick;
280 int m_tripleClickTimer;
281 QString m_cancelText;
282
283 void emitCursorPositionChanged();
284
285 bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
286
287#ifndef QT_NO_VALIDATOR
288 QPointer<QValidator> m_validator;
289#endif
290 QPointer<QCompleter> m_completer;
291#ifndef QT_NO_COMPLETER
292 bool advanceToEnabledItem(int dir);
293#endif
294
295 struct MaskInputData {
296 enum Casemode { NoCaseMode, Upper, Lower };
297 QChar maskChar; // either the separator char or the inputmask
298 bool separator;
299 Casemode caseMode;
300 };
301 QString m_inputMask;
302 QChar m_blank;
303 MaskInputData *m_maskData;
304
305 // undo/redo handling
306 enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
307 struct Command {
308 inline Command() {}
309 inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
310 uint type : 4;
311 QChar uc;
312 int pos, selStart, selEnd;
313 };
314 int m_modifiedState;
315 int m_undoState;
316 QVector<Command> m_history;
317 void addCommand(const Command& cmd);
318
319 inline void separate() { m_separator = true; }
320
321 // selection
322 int m_selstart;
323 int m_selend;
324
325 // masking
326 void parseInputMask(const QString &maskFields);
327 bool isValidInput(QChar key, QChar mask) const;
328 bool hasAcceptableInput(const QString &text) const;
329 QString maskString(uint pos, const QString &str, bool clear = false) const;
330 QString clearString(uint pos, uint len) const;
331 QString stripString(const QString &str) const;
332 int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
333
334 // complex text layout
335 QTextLayout m_textLayout;
336
337 bool m_passwordEchoEditing;
338 QChar m_passwordCharacter;
339
340Q_SIGNALS:
341 void cursorPositionChanged(int, int);
342 void selectionChanged();
343
344 void displayTextChanged(const QString &);
345 void textChanged(const QString &);
346 void textEdited(const QString &);
347
348 void resetInputContext();
349
350 void accepted();
351 void editingFinished();
352 void updateNeeded(const QRect &);
353
354#ifdef QT_KEYPAD_NAVIGATION
355 void editFocusChange(bool);
356#endif
357protected:
358 virtual void timerEvent(QTimerEvent *event);
359
360private Q_SLOTS:
361 void _q_clipboardChanged();
362 void _q_deleteSelected();
363
364};
365
366inline int QLineControl::nextMaskBlank(int pos)
367{
368 int c = findInMask(pos, true, false);
369 m_separator |= (c != pos);
370 return (c != -1 ? c : m_maxLength);
371}
372
373inline int QLineControl::prevMaskBlank(int pos)
374{
375 int c = findInMask(pos, false, false);
376 m_separator |= (c != pos);
377 return (c != -1 ? c : 0);
378}
379
380inline bool QLineControl::isUndoAvailable() const
381{
382 return !m_readOnly && m_undoState;
383}
384
385inline bool QLineControl::isRedoAvailable() const
386{
387 return !m_readOnly && m_undoState < (int)m_history.size();
388}
389
390inline void QLineControl::clearUndo()
391{
392 m_history.clear();
393 m_modifiedState = m_undoState = 0;
394}
395
396inline bool QLineControl::isModified() const
397{
398 return m_modifiedState != m_undoState;
399}
400
401inline void QLineControl::setModified(bool modified)
402{
403 m_modifiedState = modified ? -1 : m_undoState;
404}
405
406inline bool QLineControl::allSelected() const
407{
408 return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length();
409}
410
411inline bool QLineControl::hasSelectedText() const
412{
413 return !m_text.isEmpty() && m_selend > m_selstart;
414}
415
416inline int QLineControl::width() const
417{
418 return qRound(m_textLayout.lineAt(0).width()) + 1;
419}
420
421inline qreal QLineControl::naturalTextWidth() const
422{
423 return m_textLayout.lineAt(0).naturalTextWidth();
424}
425
426inline int QLineControl::height() const
427{
428 return qRound(m_textLayout.lineAt(0).height()) + 1;
429}
430
431inline int QLineControl::ascent() const
432{
433 return m_ascent;
434}
435
436inline QString QLineControl::selectedText() const
437{
438 if (hasSelectedText())
439 return m_text.mid(m_selstart, m_selend - m_selstart);
440 return QString();
441}
442
443inline QString QLineControl::textBeforeSelection() const
444{
445 if (hasSelectedText())
446 return m_text.left(m_selstart);
447 return QString();
448}
449
450inline QString QLineControl::textAfterSelection() const
451{
452 if (hasSelectedText())
453 return m_text.mid(m_selend);
454 return QString();
455}
456
457inline int QLineControl::selectionStart() const
458{
459 return hasSelectedText() ? m_selstart : -1;
460}
461
462inline int QLineControl::selectionEnd() const
463{
464 return hasSelectedText() ? m_selend : -1;
465}
466
467inline int QLineControl::start() const
468{
469 return 0;
470}
471
472inline int QLineControl::end() const
473{
474 return m_text.length();
475}
476
477inline void QLineControl::removeSelection()
478{
479 int priorState = m_undoState;
480 removeSelectedText();
481 finishChange(priorState);
482}
483
484inline bool QLineControl::inSelection(int x) const
485{
486 if (m_selstart >= m_selend)
487 return false;
488 int pos = xToPos(x, QTextLine::CursorOnCharacter);
489 return pos >= m_selstart && pos < m_selend;
490}
491
492inline int QLineControl::cursor() const
493{
494 return m_cursor;
495}
496
497inline int QLineControl::preeditCursor() const
498{
499 return m_preeditCursor;
500}
501
502inline int QLineControl::cursorWidth() const
503{
504 return m_cursorWidth;
505}
506
507inline void QLineControl::setCursorWidth(int value)
508{
509 m_cursorWidth = value;
510}
511
512inline void QLineControl::cursorForward(bool mark, int steps)
513{
514 int c = m_cursor;
515 if (steps > 0) {
516 while (steps--)
517 c = m_textLayout.nextCursorPosition(c);
518 } else if (steps < 0) {
519 while (steps++)
520 c = m_textLayout.previousCursorPosition(c);
521 }
522 moveCursor(c, mark);
523}
524
525inline void QLineControl::cursorWordForward(bool mark)
526{
527 moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark);
528}
529
530inline void QLineControl::home(bool mark)
531{
532 moveCursor(0, mark);
533}
534
535inline void QLineControl::end(bool mark)
536{
537 moveCursor(text().length(), mark);
538}
539
540inline void QLineControl::cursorWordBackward(bool mark)
541{
542 moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark);
543}
544
545inline qreal QLineControl::cursorToX(int cursor) const
546{
547 return m_textLayout.lineAt(0).cursorToX(cursor);
548}
549
550inline qreal QLineControl::cursorToX() const
551{
552 int cursor = m_cursor;
553 if (m_preeditCursor != -1)
554 cursor += m_preeditCursor;
555 return cursorToX(cursor);
556}
557
558inline bool QLineControl::isReadOnly() const
559{
560 return m_readOnly;
561}
562
563inline void QLineControl::setReadOnly(bool enable)
564{
565 m_readOnly = enable;
566}
567
568inline QString QLineControl::text() const
569{
570 QString res = m_maskData ? stripString(m_text) : m_text;
571 return (res.isNull() ? QString::fromLatin1("") : res);
572}
573
574inline void QLineControl::setText(const QString &txt)
575{
576 internalSetText(txt, -1, false);
577}
578
579inline QString QLineControl::displayText() const
580{
581 return m_textLayout.text();
582}
583
584inline void QLineControl::deselect()
585{
586 internalDeselect();
587 finishChange();
588}
589
590inline void QLineControl::selectAll()
591{
592 m_selstart = m_selend = m_cursor = 0;
593 moveCursor(m_text.length(), true);
594}
595
596inline void QLineControl::undo()
597{
598 internalUndo();
599 finishChange(-1, true);
600}
601
602inline void QLineControl::redo()
603{
604 internalRedo();
605 finishChange();
606}
607
608inline uint QLineControl::echoMode() const
609{
610 return m_echoMode;
611}
612
613inline void QLineControl::setEchoMode(uint mode)
614{
615 m_echoMode = mode;
616 m_passwordEchoEditing = false;
617 updateDisplayText();
618}
619
620inline void QLineControl::setMaxLength(int maxLength)
621{
622 if (m_maskData)
623 return;
624 m_maxLength = maxLength;
625 setText(m_text);
626}
627
628inline int QLineControl::maxLength() const
629{
630 return m_maxLength;
631}
632
633#ifndef QT_NO_VALIDATOR
634inline const QValidator *QLineControl::validator() const
635{
636 return m_validator;
637}
638
639inline void QLineControl::setValidator(const QValidator *v)
640{
641 m_validator = const_cast<QValidator*>(v);
642}
643#endif
644
645#ifndef QT_NO_COMPLETER
646inline QCompleter *QLineControl::completer() const
647{
648 return m_completer;
649}
650
651/* Note that you must set the widget for the completer seperately */
652inline void QLineControl::setCompleter(const QCompleter* c)
653{
654 m_completer = const_cast<QCompleter*>(c);
655}
656#endif
657
658inline void QLineControl::setCursorPosition(int pos)
659{
660 if (pos < 0)
661 pos = 0;
662 if (pos <= m_text.length())
663 moveCursor(pos);
664}
665
666inline int QLineControl::cursorPosition() const
667{
668 return m_cursor;
669}
670
671inline bool QLineControl::hasAcceptableInput() const
672{
673 return hasAcceptableInput(m_text);
674}
675
676inline QString QLineControl::inputMask() const
677{
678 return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString();
679}
680
681inline void QLineControl::setInputMask(const QString &mask)
682{
683 parseInputMask(mask);
684 if (m_maskData)
685 moveCursor(nextMaskBlank(0));
686}
687
688// input methods
689#ifndef QT_NO_IM
690inline bool QLineControl::composeMode() const
691{
692 return !m_textLayout.preeditAreaText().isEmpty();
693}
694
695inline void QLineControl::setPreeditArea(int cursor, const QString &text)
696{
697 m_textLayout.setPreeditArea(cursor, text);
698}
699#endif
700
701inline QString QLineControl::preeditAreaText() const
702{
703 return m_textLayout.preeditAreaText();
704}
705
706inline bool QLineControl::passwordEchoEditing() const
707{
708 return m_passwordEchoEditing;
709}
710
711inline QChar QLineControl::passwordCharacter() const
712{
713 return m_passwordCharacter;
714}
715
716inline void QLineControl::setPasswordCharacter(const QChar &character)
717{
718 m_passwordCharacter = character;
719 updateDisplayText();
720}
721
722inline Qt::LayoutDirection QLineControl::layoutDirection() const
723{
724 return m_layoutDirection;
725}
726
727inline void QLineControl::setLayoutDirection(Qt::LayoutDirection direction)
728{
729 if (direction != m_layoutDirection) {
730 m_layoutDirection = direction;
731 updateDisplayText();
732 }
733}
734
735inline void QLineControl::setFont(const QFont &font)
736{
737 m_textLayout.setFont(font);
738 updateDisplayText();
739}
740
741inline int QLineControl::cursorBlinkPeriod() const
742{
743 return m_blinkPeriod;
744}
745
746inline QString QLineControl::cancelText() const
747{
748 return m_cancelText;
749}
750
751inline void QLineControl::setCancelText(const QString &text)
752{
753 m_cancelText = text;
754}
755
756inline const QPalette & QLineControl::palette() const
757{
758 return m_palette;
759}
760
761inline void QLineControl::setPalette(const QPalette &p)
762{
763 m_palette = p;
764}
765
766QT_END_NAMESPACE
767
768QT_END_HEADER
769
770#endif // QT_NO_LINEEDIT
771
772#endif // QLINECONTROL_P_H
Note: See TracBrowser for help on using the repository browser.