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

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 17.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 return cursorToX(m_cursor);
553}
554
555inline bool QLineControl::isReadOnly() const
556{
557 return m_readOnly;
558}
559
560inline void QLineControl::setReadOnly(bool enable)
561{
562 m_readOnly = enable;
563}
564
565inline QString QLineControl::text() const
566{
567 QString res = m_maskData ? stripString(m_text) : m_text;
568 return (res.isNull() ? QString::fromLatin1("") : res);
569}
570
571inline void QLineControl::setText(const QString &txt)
572{
573 internalSetText(txt, -1, false);
574}
575
576inline QString QLineControl::displayText() const
577{
578 return m_textLayout.text();
579}
580
581inline void QLineControl::deselect()
582{
583 internalDeselect();
584 finishChange();
585}
586
587inline void QLineControl::selectAll()
588{
589 m_selstart = m_selend = m_cursor = 0;
590 moveCursor(m_text.length(), true);
591}
592
593inline void QLineControl::undo()
594{
595 internalUndo();
596 finishChange(-1, true);
597}
598
599inline void QLineControl::redo()
600{
601 internalRedo();
602 finishChange();
603}
604
605inline uint QLineControl::echoMode() const
606{
607 return m_echoMode;
608}
609
610inline void QLineControl::setEchoMode(uint mode)
611{
612 m_echoMode = mode;
613 m_passwordEchoEditing = false;
614 updateDisplayText();
615}
616
617inline void QLineControl::setMaxLength(int maxLength)
618{
619 if (m_maskData)
620 return;
621 m_maxLength = maxLength;
622 setText(m_text);
623}
624
625inline int QLineControl::maxLength() const
626{
627 return m_maxLength;
628}
629
630#ifndef QT_NO_VALIDATOR
631inline const QValidator *QLineControl::validator() const
632{
633 return m_validator;
634}
635
636inline void QLineControl::setValidator(const QValidator *v)
637{
638 m_validator = const_cast<QValidator*>(v);
639}
640#endif
641
642#ifndef QT_NO_COMPLETER
643inline QCompleter *QLineControl::completer() const
644{
645 return m_completer;
646}
647
648/* Note that you must set the widget for the completer seperately */
649inline void QLineControl::setCompleter(const QCompleter* c)
650{
651 m_completer = const_cast<QCompleter*>(c);
652}
653#endif
654
655inline void QLineControl::setCursorPosition(int pos)
656{
657 if (pos < 0)
658 pos = 0;
659 if (pos <= m_text.length())
660 moveCursor(pos);
661}
662
663inline int QLineControl::cursorPosition() const
664{
665 return m_cursor;
666}
667
668inline bool QLineControl::hasAcceptableInput() const
669{
670 return hasAcceptableInput(m_text);
671}
672
673inline QString QLineControl::inputMask() const
674{
675 return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString();
676}
677
678inline void QLineControl::setInputMask(const QString &mask)
679{
680 parseInputMask(mask);
681 if (m_maskData)
682 moveCursor(nextMaskBlank(0));
683}
684
685// input methods
686#ifndef QT_NO_IM
687inline bool QLineControl::composeMode() const
688{
689 return !m_textLayout.preeditAreaText().isEmpty();
690}
691
692inline void QLineControl::setPreeditArea(int cursor, const QString &text)
693{
694 m_textLayout.setPreeditArea(cursor, text);
695}
696#endif
697
698inline QString QLineControl::preeditAreaText() const
699{
700 return m_textLayout.preeditAreaText();
701}
702
703inline bool QLineControl::passwordEchoEditing() const
704{
705 return m_passwordEchoEditing;
706}
707
708inline QChar QLineControl::passwordCharacter() const
709{
710 return m_passwordCharacter;
711}
712
713inline void QLineControl::setPasswordCharacter(const QChar &character)
714{
715 m_passwordCharacter = character;
716 updateDisplayText();
717}
718
719inline Qt::LayoutDirection QLineControl::layoutDirection() const
720{
721 return m_layoutDirection;
722}
723
724inline void QLineControl::setLayoutDirection(Qt::LayoutDirection direction)
725{
726 if (direction != m_layoutDirection) {
727 m_layoutDirection = direction;
728 updateDisplayText();
729 }
730}
731
732inline void QLineControl::setFont(const QFont &font)
733{
734 m_textLayout.setFont(font);
735 updateDisplayText();
736}
737
738inline int QLineControl::cursorBlinkPeriod() const
739{
740 return m_blinkPeriod;
741}
742
743inline QString QLineControl::cancelText() const
744{
745 return m_cancelText;
746}
747
748inline void QLineControl::setCancelText(const QString &text)
749{
750 m_cancelText = text;
751}
752
753inline const QPalette & QLineControl::palette() const
754{
755 return m_palette;
756}
757
758inline void QLineControl::setPalette(const QPalette &p)
759{
760 m_palette = p;
761}
762
763QT_END_NAMESPACE
764
765QT_END_HEADER
766
767#endif // QT_NO_LINEEDIT
768
769#endif // QLINECONTROL_P_H
Note: See TracBrowser for help on using the repository browser.