source: trunk/src/gui/widgets/qlineedit.cpp@ 22

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 106.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qlineedit.h"
43#include "qlineedit_p.h"
44
45#ifndef QT_NO_LINEEDIT
46#include "qaction.h"
47#include "qapplication.h"
48#include "qclipboard.h"
49#include "qdrag.h"
50#include "qdrawutil.h"
51#include "qevent.h"
52#include "qfontmetrics.h"
53#include "qmenu.h"
54#include "qpainter.h"
55#include "qpixmap.h"
56#include "qpointer.h"
57#include "qstringlist.h"
58#include "qstyle.h"
59#include "qstyleoption.h"
60#include "qtimer.h"
61#include "qvalidator.h"
62#include "qvariant.h"
63#include "qvector.h"
64#include "qwhatsthis.h"
65#include "qdebug.h"
66#include "qtextedit.h"
67#include <private/qtextedit_p.h>
68#ifndef QT_NO_ACCESSIBILITY
69#include "qaccessible.h"
70#endif
71#ifndef QT_NO_IM
72#include "qinputcontext.h"
73#include "qlist.h"
74#endif
75#include "qabstractitemview.h"
76#include "private/qstylesheetstyle_p.h"
77
78#ifndef QT_NO_SHORTCUT
79#include "private/qapplication_p.h"
80#include "private/qshortcutmap_p.h"
81#include "qkeysequence.h"
82#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString())
83#else
84#define ACCEL_KEY(k) QString()
85#endif
86
87#include <limits.h>
88
89#define verticalMargin 1
90#define horizontalMargin 2
91
92QT_BEGIN_NAMESPACE
93
94#ifdef Q_WS_MAC
95extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
96#endif
97
98static inline bool shouldEnableInputMethod(QLineEdit *lineedit)
99{
100 const QLineEdit::EchoMode mode = lineedit->echoMode();
101 return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit);
102}
103
104/*!
105 Initialize \a option with the values from this QLineEdit. This method
106 is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want
107 to fill in all the information themselves. This function will check the version
108 of the QStyleOptionFrame and fill in the additional values for a
109 QStyleOptionFrameV2.
110
111 \sa QStyleOption::initFrom()
112*/
113void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
114{
115 if (!option)
116 return;
117
118 Q_D(const QLineEdit);
119 option->initFrom(this);
120 option->rect = contentsRect();
121 option->lineWidth = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this)
122 : 0;
123 option->midLineWidth = 0;
124 option->state |= QStyle::State_Sunken;
125 if (d->readOnly)
126 option->state |= QStyle::State_ReadOnly;
127#ifdef QT_KEYPAD_NAVIGATION
128 if (hasEditFocus())
129 option->state |= QStyle::State_HasEditFocus;
130#endif
131 if (QStyleOptionFrameV2 *optionV2 = qstyleoption_cast<QStyleOptionFrameV2 *>(option))
132 optionV2->features = QStyleOptionFrameV2::None;
133}
134
135/*!
136 \class QLineEdit
137 \brief The QLineEdit widget is a one-line text editor.
138
139 \ingroup basicwidgets
140 \mainclass
141
142 A line edit allows the user to enter and edit a single line of
143 plain text with a useful collection of editing functions,
144 including undo and redo, cut and paste, and drag and drop.
145
146 By changing the echoMode() of a line edit, it can also be used as
147 a "write-only" field, for inputs such as passwords.
148
149 The length of the text can be constrained to maxLength(). The text
150 can be arbitrarily constrained using a validator() or an
151 inputMask(), or both.
152
153 A related class is QTextEdit which allows multi-line, rich text
154 editing.
155
156 You can change the text with setText() or insert(). The text is
157 retrieved with text(); the displayed text (which may be different,
158 see \l{EchoMode}) is retrieved with displayText(). Text can be
159 selected with setSelection() or selectAll(), and the selection can
160 be cut(), copy()ied and paste()d. The text can be aligned with
161 setAlignment().
162
163 When the text changes the textChanged() signal is emitted; when
164 the text changes other than by calling setText() the textEdited()
165 signal is emitted; when the cursor is moved the
166 cursorPositionChanged() signal is emitted; and when the Return or
167 Enter key is pressed the returnPressed() signal is emitted.
168
169 When editing is finished, either because the line edit lost focus
170 or Return/Enter is pressed the editingFinished() signal is
171 emitted.
172
173 Note that if there is a validator set on the line edit, the
174 returnPressed()/editingFinished() signals will only be emitted if
175 the validator returns QValidator::Acceptable.
176
177 By default, QLineEdits have a frame as specified by the Windows
178 and Motif style guides; you can turn it off by calling
179 setFrame(false).
180
181 The default key bindings are described below. The line edit also
182 provides a context menu (usually invoked by a right mouse click)
183 that presents some of these editing options.
184 \target desc
185 \table
186 \header \i Keypress \i Action
187 \row \i Left Arrow \i Moves the cursor one character to the left.
188 \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
189 \row \i Right Arrow \i Moves the cursor one character to the right.
190 \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
191 \row \i Home \i Moves the cursor to the beginning of the line.
192 \row \i End \i Moves the cursor to the end of the line.
193 \row \i Backspace \i Deletes the character to the left of the cursor.
194 \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
195 \row \i Delete \i Deletes the character to the right of the cursor.
196 \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
197 \row \i Ctrl+A \i Select all.
198 \row \i Ctrl+C \i Copies the selected text to the clipboard.
199 \row \i Ctrl+Insert \i Copies the selected text to the clipboard.
200 \row \i Ctrl+K \i Deletes to the end of the line.
201 \row \i Ctrl+V \i Pastes the clipboard text into line edit.
202 \row \i Shift+Insert \i Pastes the clipboard text into line edit.
203 \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
204 \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
205 \row \i Ctrl+Z \i Undoes the last operation.
206 \row \i Ctrl+Y \i Redoes the last undone operation.
207 \endtable
208
209 Any other key sequence that represents a valid character, will
210 cause the character to be inserted into the line edit.
211
212 \table 100%
213 \row \o \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit
214 \o A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
215 \row \o \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit
216 \o A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
217 \row \o \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit
218 \o A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
219 \endtable
220
221 \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
222*/
223
224
225/*!
226 \fn void QLineEdit::textChanged(const QString &text)
227
228 This signal is emitted whenever the text changes. The \a text
229 argument is the new text.
230
231 Unlike textEdited(), this signal is also emitted when the text is
232 changed programmatically, for example, by calling setText().
233*/
234
235/*!
236 \fn void QLineEdit::textEdited(const QString &text)
237
238 This signal is emitted whenever the text is edited. The \a text
239 argument is the next text.
240
241 Unlike textChanged(), this signal is not emitted when the text is
242 changed programmatically, for example, by calling setText().
243*/
244
245/*!
246 \fn void QLineEdit::cursorPositionChanged(int old, int new)
247
248 This signal is emitted whenever the cursor moves. The previous
249 position is given by \a old, and the new position by \a new.
250
251 \sa setCursorPosition(), cursorPosition()
252*/
253
254/*!
255 \fn void QLineEdit::selectionChanged()
256
257 This signal is emitted whenever the selection changes.
258
259 \sa hasSelectedText(), selectedText()
260*/
261
262/*!
263 Constructs a line edit with no text.
264
265 The maximum text length is set to 32767 characters.
266
267 The \a parent argument is sent to the QWidget constructor.
268
269 \sa setText(), setMaxLength()
270*/
271QLineEdit::QLineEdit(QWidget* parent)
272 : QWidget(*new QLineEditPrivate, parent,0)
273{
274 Q_D(QLineEdit);
275 d->init(QString());
276}
277
278/*!
279 Constructs a line edit containing the text \a contents.
280
281 The cursor position is set to the end of the line and the maximum
282 text length to 32767 characters.
283
284 The \a parent and argument is sent to the QWidget
285 constructor.
286
287 \sa text(), setMaxLength()
288*/
289QLineEdit::QLineEdit(const QString& contents, QWidget* parent)
290 : QWidget(*new QLineEditPrivate, parent, 0)
291{
292 Q_D(QLineEdit);
293 d->init(contents);
294}
295
296
297#ifdef QT3_SUPPORT
298/*!
299 Constructs a line edit with no text.
300
301 The maximum text length is set to 32767 characters.
302
303 The \a parent and \a name arguments are sent to the QWidget constructor.
304
305 \sa setText(), setMaxLength()
306*/
307QLineEdit::QLineEdit(QWidget* parent, const char* name)
308 : QWidget(*new QLineEditPrivate, parent,0)
309{
310 Q_D(QLineEdit);
311 setObjectName(QString::fromAscii(name));
312 d->init(QString());
313}
314
315/*!
316 Constructs a line edit containing the text \a contents.
317
318 The cursor position is set to the end of the line and the maximum
319 text length to 32767 characters.
320
321 The \a parent and \a name arguments are sent to the QWidget
322 constructor.
323
324 \sa text(), setMaxLength()
325*/
326
327QLineEdit::QLineEdit(const QString& contents, QWidget* parent, const char* name)
328 : QWidget(*new QLineEditPrivate, parent, 0)
329{
330 Q_D(QLineEdit);
331 setObjectName(QString::fromAscii(name));
332 d->init(contents);
333}
334
335/*!
336 Constructs a line edit with an input \a inputMask and the text \a
337 contents.
338
339 The cursor position is set to the end of the line and the maximum
340 text length is set to the length of the mask (the number of mask
341 characters and separators).
342
343 The \a parent and \a name arguments are sent to the QWidget
344 constructor.
345
346 \sa setMask() text()
347*/
348QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget* parent, const char* name)
349 : QWidget(*new QLineEditPrivate, parent, 0)
350{
351 Q_D(QLineEdit);
352 setObjectName(QString::fromAscii(name));
353 d->parseInputMask(inputMask);
354 if (d->maskData) {
355 QString ms = d->maskString(0, contents);
356 d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length()));
357 d->cursor = d->nextMaskBlank(ms.length());
358 } else {
359 d->init(contents);
360 }
361}
362#endif
363
364/*!
365 Destroys the line edit.
366*/
367
368QLineEdit::~QLineEdit()
369{
370}
371
372
373/*!
374 \property QLineEdit::text
375 \brief the line edit's text
376
377 Setting this property clears the selection, clears the undo/redo
378 history, moves the cursor to the end of the line and resets the
379 \l modified property to false. The text is not validated when
380 inserted with setText().
381
382 The text is truncated to maxLength() length.
383
384 By default, this property contains an empty string.
385
386 \sa insert(), clear()
387*/
388QString QLineEdit::text() const
389{
390 Q_D(const QLineEdit);
391 QString res = d->text;
392 if (d->maskData)
393 res = d->stripString(d->text);
394 return (res.isNull() ? QString::fromLatin1("") : res);
395}
396
397void QLineEdit::setText(const QString& text)
398{
399 Q_D(QLineEdit);
400 d->setText(text, -1, false);
401#ifdef QT_KEYPAD_NAVIGATION
402 d->origText = d->text;
403#endif
404}
405
406
407/*!
408 \property QLineEdit::displayText
409 \brief the displayed text
410
411 If \l echoMode is \l Normal this returns the same as text(); if
412 \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of asterisks
413 text().length() characters long, e.g. "******"; if \l EchoMode is
414 \l NoEcho returns an empty string, "".
415
416 By default, this property contains an empty string.
417
418 \sa setEchoMode() text() EchoMode
419*/
420
421QString QLineEdit::displayText() const
422{
423 Q_D(const QLineEdit);
424 if (d->echoMode == NoEcho)
425 return QString::fromLatin1("");
426 QString res = d->text;
427
428 if (d->echoMode == Password || (d->echoMode == PasswordEchoOnEdit
429 && !d->passwordEchoEditing)) {
430 QStyleOptionFrameV2 opt;
431 initStyleOption(&opt);
432 res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
433 }
434 return (res.isNull() ? QString::fromLatin1("") : res);
435}
436
437
438/*!
439 \property QLineEdit::maxLength
440 \brief the maximum permitted length of the text
441
442 If the text is too long, it is truncated at the limit.
443
444 If truncation occurs any selected text will be unselected, the
445 cursor position is set to 0 and the first part of the string is
446 shown.
447
448 If the line edit has an input mask, the mask defines the maximum
449 string length.
450
451 By default, this property contains a value of 32767.
452
453 \sa inputMask
454*/
455
456int QLineEdit::maxLength() const
457{
458 Q_D(const QLineEdit);
459 return d->maxLength;
460}
461
462void QLineEdit::setMaxLength(int maxLength)
463{
464 Q_D(QLineEdit);
465 if (d->maskData)
466 return;
467 d->maxLength = maxLength;
468 setText(d->text);
469}
470
471
472
473/*!
474 \property QLineEdit::frame
475 \brief whether the line edit draws itself with a frame
476
477 If enabled (the default) the line edit draws itself inside a
478 frame, otherwise the line edit draws itself without any frame.
479*/
480bool QLineEdit::hasFrame() const
481{
482 Q_D(const QLineEdit);
483 return d->frame;
484}
485
486
487void QLineEdit::setFrame(bool enable)
488{
489 Q_D(QLineEdit);
490 d->frame = enable;
491 update();
492 updateGeometry();
493}
494
495
496/*!
497 \enum QLineEdit::EchoMode
498
499 This enum type describes how a line edit should display its
500 contents.
501
502 \value Normal Display characters as they are entered. This is the
503 default.
504 \value NoEcho Do not display anything. This may be appropriate
505 for passwords where even the length of the
506 password should be kept secret.
507 \value Password Display asterisks instead of the characters
508 actually entered.
509 \value PasswordEchoOnEdit Display characters as they are entered
510 while editing otherwise display asterisks.
511
512 \sa setEchoMode() echoMode()
513*/
514
515
516/*!
517 \property QLineEdit::echoMode
518 \brief the line edit's echo mode
519
520 The echo mode determines how the text entered in the line edit is
521 displayed (or echoed) to the user.
522
523 The most common setting is \l Normal, in which the text entered by the
524 user is displayed verbatim, but QLineEdit also supports modes that allow
525 the entered text to be suppressed or obscured: these include \l NoEcho,
526 \l Password and \l PasswordEchoOnEdit.
527
528 The widget's display and the ability to copy or drag the text is
529 affected by this setting.
530
531 By default, this property is set to \l Normal.
532
533 \sa EchoMode displayText()
534*/
535
536QLineEdit::EchoMode QLineEdit::echoMode() const
537{
538 Q_D(const QLineEdit);
539 return (EchoMode) d->echoMode;
540}
541
542void QLineEdit::setEchoMode(EchoMode mode)
543{
544 Q_D(QLineEdit);
545 if (mode == (EchoMode)d->echoMode)
546 return;
547 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
548 d->echoMode = mode;
549 d->passwordEchoEditing = false;
550 d->updateTextLayout();
551 update();
552#ifdef Q_WS_MAC
553 if (hasFocus())
554 qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho);
555#endif
556}
557
558
559#ifndef QT_NO_VALIDATOR
560/*!
561 Returns a pointer to the current input validator, or 0 if no
562 validator has been set.
563
564 \sa setValidator()
565*/
566
567const QValidator * QLineEdit::validator() const
568{
569 Q_D(const QLineEdit);
570 return d->validator;
571}
572
573/*!
574 Sets this line edit to only accept input that the validator, \a v,
575 will accept. This allows you to place any arbitrary constraints on
576 the text which may be entered.
577
578 If \a v == 0, setValidator() removes the current input validator.
579 The initial setting is to have no input validator (i.e. any input
580 is accepted up to maxLength()).
581
582 \sa validator() QIntValidator QDoubleValidator QRegExpValidator
583*/
584
585void QLineEdit::setValidator(const QValidator *v)
586{
587 Q_D(QLineEdit);
588 d->validator = const_cast<QValidator*>(v);
589}
590#endif // QT_NO_VALIDATOR
591
592#ifndef QT_NO_COMPLETER
593/*!
594 \since 4.2
595
596 Sets this line edit to provide auto completions from the completer, \a c.
597 The completion mode is set using QCompleter::setCompletionMode().
598
599 To use a QCompleter with a QValidator or QLineEdit::inputMask, you need to
600 ensure that the model provided to QCompleter contains valid entries. You can
601 use the QSortFilterProxyModel to ensure that the QCompleter's model contains
602 only valid entries.
603
604 If \a c == 0, setCompleter() removes the current completer, effectively
605 disabling auto completion.
606
607 \sa QCompleter
608*/
609void QLineEdit::setCompleter(QCompleter *c)
610{
611 Q_D(QLineEdit);
612 if (c == d->completer)
613 return;
614 if (d->completer) {
615 disconnect(d->completer, 0, this, 0);
616 d->completer->setWidget(0);
617 if (d->completer->parent() == this)
618 delete d->completer;
619 }
620 d->completer = c;
621 if (!c)
622 return;
623 if (c->widget() == 0)
624 c->setWidget(this);
625 if (hasFocus()) {
626 QObject::connect(d->completer, SIGNAL(activated(QString)),
627 this, SLOT(setText(QString)));
628 QObject::connect(d->completer, SIGNAL(highlighted(QString)),
629 this, SLOT(_q_completionHighlighted(QString)));
630 }
631}
632
633/*!
634 \since 4.2
635
636 Returns the current QCompleter that provides completions.
637*/
638QCompleter *QLineEdit::completer() const
639{
640 Q_D(const QLineEdit);
641 return d->completer;
642}
643
644// looks for an enabled item iterating forward(dir=1)/backward(dir=-1) from the
645// current row based. dir=0 indicates a new completion prefix was set.
646bool QLineEditPrivate::advanceToEnabledItem(int dir)
647{
648 int start = completer->currentRow();
649 if (start == -1)
650 return false;
651 int i = start + dir;
652 if (dir == 0) dir = 1;
653 do {
654 if (!completer->setCurrentRow(i)) {
655 if (!completer->wrapAround())
656 break;
657 i = i > 0 ? 0 : completer->completionCount() - 1;
658 } else {
659 QModelIndex currentIndex = completer->currentIndex();
660 if (completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
661 return true;
662 i += dir;
663 }
664 } while (i != start);
665
666 completer->setCurrentRow(start); // restore
667 return false;
668}
669
670void QLineEditPrivate::complete(int key)
671{
672 if (!completer || readOnly || echoMode != QLineEdit::Normal)
673 return;
674
675 if (completer->completionMode() == QCompleter::InlineCompletion) {
676 if (key == Qt::Key_Backspace)
677 return;
678 int n = 0;
679 if (key == Qt::Key_Up || key == Qt::Key_Down) {
680 if (selend != 0 && selend != text.length())
681 return;
682 QString prefix = hasSelectedText() ? text.left(selstart) : text;
683 if (text.compare(completer->currentCompletion(), completer->caseSensitivity()) != 0
684 || prefix.compare(completer->completionPrefix(), completer->caseSensitivity()) != 0) {
685 completer->setCompletionPrefix(prefix);
686 } else {
687 n = (key == Qt::Key_Up) ? -1 : +1;
688 }
689 } else {
690 completer->setCompletionPrefix(text);
691 }
692 if (!advanceToEnabledItem(n))
693 return;
694 } else {
695#ifndef QT_KEYPAD_NAVIGATION
696 if (text.isEmpty()) {
697 completer->popup()->hide();
698 return;
699 }
700#endif
701 completer->setCompletionPrefix(text);
702 }
703
704 completer->complete();
705}
706
707void QLineEditPrivate::_q_completionHighlighted(QString newText)
708{
709 Q_Q(QLineEdit);
710 if (completer->completionMode() != QCompleter::InlineCompletion)
711 q->setText(newText);
712 else {
713 int c = cursor;
714 q->setText(text.left(c) + newText.mid(c));
715 q->setSelection(text.length(), c - newText.length());
716 }
717}
718#endif // QT_NO_COMPLETER
719
720/*!
721 Returns a recommended size for the widget.
722
723 The width returned, in pixels, is usually enough for about 15 to
724 20 characters.
725*/
726
727QSize QLineEdit::sizeHint() const
728{
729 Q_D(const QLineEdit);
730 ensurePolished();
731 QFontMetrics fm(font());
732 int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin
733 + d->topTextMargin + d->bottomTextMargin
734 + d->topmargin + d->bottommargin;
735 int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin
736 + d->leftTextMargin + d->rightTextMargin
737 + d->leftmargin + d->rightmargin; // "some"
738 QStyleOptionFrameV2 opt;
739 initStyleOption(&opt);
740 return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
741 expandedTo(QApplication::globalStrut()), this));
742}
743
744
745/*!
746 Returns a minimum size for the line edit.
747
748 The width returned is enough for at least one character.
749*/
750
751QSize QLineEdit::minimumSizeHint() const
752{
753 Q_D(const QLineEdit);
754 ensurePolished();
755 QFontMetrics fm = fontMetrics();
756 int h = fm.height() + qMax(2*verticalMargin, fm.leading())
757 + d->topmargin + d->bottommargin;
758 int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
759 QStyleOptionFrameV2 opt;
760 initStyleOption(&opt);
761 return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
762 expandedTo(QApplication::globalStrut()), this));
763}
764
765
766/*!
767 \property QLineEdit::cursorPosition
768 \brief the current cursor position for this line edit
769
770 Setting the cursor position causes a repaint when appropriate.
771
772 By default, this property contains a value of 0.
773*/
774
775int QLineEdit::cursorPosition() const
776{
777 Q_D(const QLineEdit);
778 return d->cursor;
779}
780
781void QLineEdit::setCursorPosition(int pos)
782{
783 Q_D(QLineEdit);
784 if (pos < 0)
785 pos = 0;
786
787 if (pos <= d->text.length())
788 d->moveCursor(pos);
789}
790
791/*!
792 Returns the cursor position under the point \a pos.
793*/
794// ### What should this do if the point is outside of contentsRect? Currently returns 0.
795int QLineEdit::cursorPositionAt(const QPoint &pos)
796{
797 Q_D(QLineEdit);
798 return d->xToPos(pos.x());
799}
800
801
802#ifdef QT3_SUPPORT
803/*! \obsolete
804
805 Use setText(), setCursorPosition() and setSelection() instead.
806*/
807bool QLineEdit::validateAndSet(const QString &newText, int newPos,
808 int newMarkAnchor, int newMarkDrag)
809{
810 Q_D(QLineEdit);
811 int priorState = d->undoState;
812 d->selstart = 0;
813 d->selend = d->text.length();
814 d->removeSelectedText();
815 d->insert(newText);
816 d->finishChange(priorState);
817 if (d->undoState > priorState) {
818 d->cursor = newPos;
819 d->selstart = qMin(newMarkAnchor, newMarkDrag);
820 d->selend = qMax(newMarkAnchor, newMarkDrag);
821 update();
822 d->emitCursorPositionChanged();
823 return true;
824 }
825 return false;
826}
827#endif //QT3_SUPPORT
828
829/*!
830 \property QLineEdit::alignment
831 \brief the alignment of the line edit
832
833 Both horizontal and vertical alignment is allowed here, Qt::AlignJustify
834 will map to Qt::AlignLeft.
835
836 By default, this property contains a combination of Qt::AlignLeft and Qt::AlignVCenter.
837
838 \sa Qt::Alignment
839*/
840
841Qt::Alignment QLineEdit::alignment() const
842{
843 Q_D(const QLineEdit);
844 return QFlag(d->alignment);
845}
846
847void QLineEdit::setAlignment(Qt::Alignment alignment)
848{
849 Q_D(QLineEdit);
850 d->alignment = alignment;
851 update();
852}
853
854
855/*!
856 Moves the cursor forward \a steps characters. If \a mark is true
857 each character moved over is added to the selection; if \a mark is
858 false the selection is cleared.
859
860 \sa cursorBackward()
861*/
862
863void QLineEdit::cursorForward(bool mark, int steps)
864{
865 Q_D(QLineEdit);
866 int cursor = d->cursor;
867 if (steps > 0) {
868 while(steps--)
869 cursor = d->textLayout.nextCursorPosition(cursor);
870 } else if (steps < 0) {
871 while (steps++)
872 cursor = d->textLayout.previousCursorPosition(cursor);
873 }
874 d->moveCursor(cursor, mark);
875}
876
877
878/*!
879 Moves the cursor back \a steps characters. If \a mark is true each
880 character moved over is added to the selection; if \a mark is
881 false the selection is cleared.
882
883 \sa cursorForward()
884*/
885void QLineEdit::cursorBackward(bool mark, int steps)
886{
887 cursorForward(mark, -steps);
888}
889
890/*!
891 Moves the cursor one word forward. If \a mark is true, the word is
892 also selected.
893
894 \sa cursorWordBackward()
895*/
896void QLineEdit::cursorWordForward(bool mark)
897{
898 Q_D(QLineEdit);
899 d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
900}
901
902/*!
903 Moves the cursor one word backward. If \a mark is true, the word
904 is also selected.
905
906 \sa cursorWordForward()
907*/
908
909void QLineEdit::cursorWordBackward(bool mark)
910{
911 Q_D(QLineEdit);
912 d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
913}
914
915
916/*!
917 If no text is selected, deletes the character to the left of the
918 text cursor and moves the cursor one position to the left. If any
919 text is selected, the cursor is moved to the beginning of the
920 selected text and the selected text is deleted.
921
922 \sa del()
923*/
924void QLineEdit::backspace()
925{
926 Q_D(QLineEdit);
927 int priorState = d->undoState;
928 if (d->hasSelectedText()) {
929 d->removeSelectedText();
930 } else if (d->cursor) {
931 --d->cursor;
932 if (d->maskData)
933 d->cursor = d->prevMaskBlank(d->cursor);
934 QChar uc = d->text.at(d->cursor);
935 if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
936 // second half of a surrogate, check if we have the first half as well,
937 // if yes delete both at once
938 uc = d->text.at(d->cursor - 1);
939 if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
940 d->del(true);
941 --d->cursor;
942 }
943 }
944 d->del(true);
945 }
946 d->finishChange(priorState);
947}
948
949/*!
950 If no text is selected, deletes the character to the right of the
951 text cursor. If any text is selected, the cursor is moved to the
952 beginning of the selected text and the selected text is deleted.
953
954 \sa backspace()
955*/
956
957void QLineEdit::del()
958{
959 Q_D(QLineEdit);
960 int priorState = d->undoState;
961 if (d->hasSelectedText()) {
962 d->removeSelectedText();
963 } else {
964 int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor;
965 while (n--)
966 d->del();
967 }
968 d->finishChange(priorState);
969}
970
971/*!
972 Moves the text cursor to the beginning of the line unless it is
973 already there. If \a mark is true, text is selected towards the
974 first position; otherwise, any selected text is unselected if the
975 cursor is moved.
976
977 \sa end()
978*/
979
980void QLineEdit::home(bool mark)
981{
982 Q_D(QLineEdit);
983 d->moveCursor(0, mark);
984}
985
986/*!
987 Moves the text cursor to the end of the line unless it is already
988 there. If \a mark is true, text is selected towards the last
989 position; otherwise, any selected text is unselected if the cursor
990 is moved.
991
992 \sa home()
993*/
994
995void QLineEdit::end(bool mark)
996{
997 Q_D(QLineEdit);
998 d->moveCursor(d->text.length(), mark);
999}
1000
1001
1002/*!
1003 \property QLineEdit::modified
1004 \brief whether the line edit's contents has been modified by the user
1005
1006 The modified flag is never read by QLineEdit; it has a default value
1007 of false and is changed to true whenever the user changes the line
1008 edit's contents.
1009
1010 This is useful for things that need to provide a default value but
1011 do not start out knowing what the default should be (perhaps it
1012 depends on other fields on the form). Start the line edit without
1013 the best default, and when the default is known, if modified()
1014 returns false (the user hasn't entered any text), insert the
1015 default value.
1016
1017 Calling setText() resets the modified flag to false.
1018*/
1019
1020bool QLineEdit::isModified() const
1021{
1022 Q_D(const QLineEdit);
1023 return d->modifiedState != d->undoState;
1024}
1025
1026void QLineEdit::setModified(bool modified)
1027{
1028 Q_D(QLineEdit);
1029 if (modified)
1030 d->modifiedState = -1;
1031 else
1032 d->modifiedState = d->undoState;
1033}
1034
1035
1036/*!\fn QLineEdit::clearModified()
1037
1038Use setModified(false) instead.
1039
1040 \sa isModified()
1041*/
1042
1043
1044/*!
1045 \property QLineEdit::hasSelectedText
1046 \brief whether there is any text selected
1047
1048 hasSelectedText() returns true if some or all of the text has been
1049 selected by the user; otherwise returns false.
1050
1051 By default, this property is false.
1052
1053 \sa selectedText()
1054*/
1055
1056
1057bool QLineEdit::hasSelectedText() const
1058{
1059 Q_D(const QLineEdit);
1060 return d->hasSelectedText();
1061}
1062
1063/*!
1064 \property QLineEdit::selectedText
1065 \brief the selected text
1066
1067 If there is no selected text this property's value is
1068 an empty string.
1069
1070 By default, this property contains an empty string.
1071
1072 \sa hasSelectedText()
1073*/
1074
1075QString QLineEdit::selectedText() const
1076{
1077 Q_D(const QLineEdit);
1078 if (d->hasSelectedText())
1079 return d->text.mid(d->selstart, d->selend - d->selstart);
1080 return QString();
1081}
1082
1083/*!
1084 selectionStart() returns the index of the first selected character in the
1085 line edit or -1 if no text is selected.
1086
1087 \sa selectedText()
1088*/
1089
1090int QLineEdit::selectionStart() const
1091{
1092 Q_D(const QLineEdit);
1093 return d->hasSelectedText() ? d->selstart : -1;
1094}
1095
1096
1097#ifdef QT3_SUPPORT
1098
1099/*!
1100 \fn void QLineEdit::lostFocus()
1101
1102 This signal is emitted when the line edit has lost focus.
1103
1104 Use editingFinished() instead
1105 \sa editingFinished(), returnPressed()
1106*/
1107
1108/*!
1109 Use isModified() instead.
1110*/
1111bool QLineEdit::edited() const { return isModified(); }
1112/*!
1113 Use setModified() or setText().
1114*/
1115void QLineEdit::setEdited(bool on) { setModified(on); }
1116
1117/*!
1118 There exists no equivalent functionality in Qt 4.
1119*/
1120int QLineEdit::characterAt(int xpos, QChar *chr) const
1121{
1122 Q_D(const QLineEdit);
1123 int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + horizontalMargin);
1124 if (chr && pos < (int) d->text.length())
1125 *chr = d->text.at(pos);
1126 return pos;
1127
1128}
1129
1130/*!
1131 Use selectedText() and selectionStart() instead.
1132*/
1133bool QLineEdit::getSelection(int *start, int *end)
1134{
1135 Q_D(QLineEdit);
1136 if (d->hasSelectedText() && start && end) {
1137 *start = d->selstart;
1138 *end = d->selend;
1139 return true;
1140 }
1141 return false;
1142}
1143#endif
1144
1145
1146/*!
1147 Selects text from position \a start and for \a length characters.
1148 Negative lengths are allowed.
1149
1150 \sa deselect() selectAll() selectedText()
1151*/
1152
1153void QLineEdit::setSelection(int start, int length)
1154{
1155 Q_D(QLineEdit);
1156 if (start < 0 || start > (int)d->text.length()) {
1157 qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
1158 return;
1159 } else {
1160 if (length > 0) {
1161 d->selstart = start;
1162 d->selend = qMin(start + length, (int)d->text.length());
1163 d->cursor = d->selend;
1164 } else {
1165 d->selstart = qMax(start + length, 0);
1166 d->selend = start;
1167 d->cursor = d->selstart;
1168 }
1169 }
1170
1171 if (d->hasSelectedText()){
1172 QStyleOptionFrameV2 opt;
1173 initStyleOption(&opt);
1174 if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1175 d->setCursorVisible(false);
1176 }
1177
1178 update();
1179 d->emitCursorPositionChanged();
1180}
1181
1182
1183/*!
1184 \property QLineEdit::undoAvailable
1185 \brief whether undo is available
1186
1187 Undo becomes available once the user has modified the text in the line edit.
1188
1189 By default, this property is false.
1190*/
1191
1192bool QLineEdit::isUndoAvailable() const
1193{
1194 Q_D(const QLineEdit);
1195 return d->isUndoAvailable();
1196}
1197
1198/*!
1199 \property QLineEdit::redoAvailable
1200 \brief whether redo is available
1201
1202 Redo becomes available once the user has performed one or more undo operations
1203 on text in the line edit.
1204
1205 By default, this property is false.
1206*/
1207
1208bool QLineEdit::isRedoAvailable() const
1209{
1210 Q_D(const QLineEdit);
1211 return d->isRedoAvailable();
1212}
1213
1214/*!
1215 \property QLineEdit::dragEnabled
1216 \brief whether the lineedit starts a drag if the user presses and
1217 moves the mouse on some selected text
1218
1219 Dragging is disabled by default.
1220*/
1221
1222bool QLineEdit::dragEnabled() const
1223{
1224 Q_D(const QLineEdit);
1225 return d->dragEnabled;
1226}
1227
1228void QLineEdit::setDragEnabled(bool b)
1229{
1230 Q_D(QLineEdit);
1231 d->dragEnabled = b;
1232}
1233
1234
1235/*!
1236 \property QLineEdit::acceptableInput
1237 \brief whether the input satisfies the inputMask and the
1238 validator.
1239
1240 By default, this property is true.
1241
1242 \sa setInputMask(), setValidator()
1243*/
1244bool QLineEdit::hasAcceptableInput() const
1245{
1246 Q_D(const QLineEdit);
1247 return d->hasAcceptableInput(d->text);
1248}
1249
1250/*!
1251 Sets the margins around the text inside the frame to have the
1252 sizes \a left, \a top, \a right, and \a bottom.
1253 \since 4.5
1254
1255 See also getTextMargins().
1256*/
1257void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
1258{
1259 Q_D(QLineEdit);
1260 d->leftTextMargin = left;
1261 d->topTextMargin = top;
1262 d->rightTextMargin = right;
1263 d->bottomTextMargin = bottom;
1264 updateGeometry();
1265 update();
1266}
1267
1268/*!
1269 Returns the widget's text margins for \a left, \a top, \a right, and \a bottom.
1270 \since 4.5
1271
1272 \sa setTextMargins()
1273*/
1274void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) const
1275{
1276 Q_D(const QLineEdit);
1277 if (left)
1278 *left = d->leftTextMargin;
1279 if (top)
1280 *top = d->topTextMargin;
1281 if (right)
1282 *right = d->rightTextMargin;
1283 if (bottom)
1284 *bottom = d->bottomTextMargin;
1285}
1286
1287/*!
1288 \property QLineEdit::inputMask
1289 \brief The validation input mask
1290
1291 If no mask is set, inputMask() returns an empty string.
1292
1293 Sets the QLineEdit's validation mask. Validators can be used
1294 instead of, or in conjunction with masks; see setValidator().
1295
1296 Unset the mask and return to normal QLineEdit operation by passing
1297 an empty string ("") or just calling setInputMask() with no
1298 arguments.
1299
1300 The table below shows the characters that can be used in an input mask.
1301 A space character, the default character for a blank, is needed for cases
1302 where a character is \e{permitted but not required}.
1303
1304 \table
1305 \header \i Character \i Meaning
1306 \row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
1307 \row \i \c a \i ASCII alphabetic character permitted but not required.
1308 \row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
1309 \row \i \c n \i ASCII alphanumeric character permitted but not required.
1310 \row \i \c X \i Any character required.
1311 \row \i \c x \i Any character permitted but not required.
1312 \row \i \c 9 \i ASCII digit required. 0-9.
1313 \row \i \c 0 \i ASCII digit permitted but not required.
1314 \row \i \c D \i ASCII digit required. 1-9.
1315 \row \i \c d \i ASCII digit permitted but not required (1-9).
1316 \row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
1317 \row \i \c H \i Hexadecimal character required. A-F, a-f, 0-9.
1318 \row \i \c h \i Hexadecimal character permitted but not required.
1319 \row \i \c B \i Binary character required. 0-1.
1320 \row \i \c b \i Binary character permitted but not required.
1321 \row \i \c > \i All following alphabetic characters are uppercased.
1322 \row \i \c < \i All following alphabetic characters are lowercased.
1323 \row \i \c ! \i Switch off case conversion.
1324 \row \i \tt{\\} \i Use \tt{\\} to escape the special
1325 characters listed above to use them as
1326 separators.
1327 \endtable
1328
1329 The mask consists of a string of mask characters and separators,
1330 optionally followed by a semicolon and the character used for
1331 blanks. The blank characters are always removed from the text
1332 after editing.
1333
1334 Examples:
1335 \table
1336 \header \i Mask \i Notes
1337 \row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
1338 \row \i \c HH:HH:HH:HH:HH:HH;_ \i MAC address
1339 \row \i \c 0000-00-00 \i ISO Date; blanks are \c space
1340 \row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
1341 blanks are \c - and all (alphabetic) characters are converted to
1342 uppercase.
1343 \endtable
1344
1345 To get range control (e.g., for an IP address) use masks together
1346 with \link setValidator() validators\endlink.
1347
1348 \sa maxLength
1349*/
1350QString QLineEdit::inputMask() const
1351{
1352 Q_D(const QLineEdit);
1353 return (d->maskData ? d->inputMask + QLatin1Char(';') + d->blank : QString());
1354}
1355
1356void QLineEdit::setInputMask(const QString &inputMask)
1357{
1358 Q_D(QLineEdit);
1359 d->parseInputMask(inputMask);
1360 if (d->maskData)
1361 d->moveCursor(d->nextMaskBlank(0));
1362}
1363
1364/*!
1365 Selects all the text (i.e. highlights it) and moves the cursor to
1366 the end. This is useful when a default value has been inserted
1367 because if the user types before clicking on the widget, the
1368 selected text will be deleted.
1369
1370 \sa setSelection() deselect()
1371*/
1372
1373void QLineEdit::selectAll()
1374{
1375 Q_D(QLineEdit);
1376 d->selstart = d->selend = d->cursor = 0;
1377 d->moveCursor(d->text.length(), true);
1378}
1379
1380/*!
1381 Deselects any selected text.
1382
1383 \sa setSelection() selectAll()
1384*/
1385
1386void QLineEdit::deselect()
1387{
1388 Q_D(QLineEdit);
1389 d->deselect();
1390 d->finishChange();
1391}
1392
1393
1394/*!
1395 Deletes any selected text, inserts \a newText, and validates the
1396 result. If it is valid, it sets it as the new contents of the line
1397 edit.
1398
1399 \sa setText(), clear()
1400*/
1401void QLineEdit::insert(const QString &newText)
1402{
1403// q->resetInputContext(); //#### FIX ME IN QT
1404 Q_D(QLineEdit);
1405 int priorState = d->undoState;
1406 d->removeSelectedText();
1407 d->insert(newText);
1408 d->finishChange(priorState);
1409}
1410
1411/*!
1412 Clears the contents of the line edit.
1413
1414 \sa setText(), insert()
1415*/
1416void QLineEdit::clear()
1417{
1418 Q_D(QLineEdit);
1419 int priorState = d->undoState;
1420 resetInputContext();
1421 d->selstart = 0;
1422 d->selend = d->text.length();
1423 d->removeSelectedText();
1424 d->separate();
1425 d->finishChange(priorState, /*update*/false, /*edited*/false);
1426}
1427
1428/*!
1429 Undoes the last operation if undo is \link
1430 QLineEdit::undoAvailable available\endlink. Deselects any current
1431 selection, and updates the selection start to the current cursor
1432 position.
1433*/
1434void QLineEdit::undo()
1435{
1436 Q_D(QLineEdit);
1437 resetInputContext();
1438 d->undo();
1439 d->finishChange(-1, true);
1440}
1441
1442/*!
1443 Redoes the last operation if redo is \link
1444 QLineEdit::redoAvailable available\endlink.
1445*/
1446void QLineEdit::redo()
1447{
1448 Q_D(QLineEdit);
1449 resetInputContext();
1450 d->redo();
1451 d->finishChange();
1452}
1453
1454
1455/*!
1456 \property QLineEdit::readOnly
1457 \brief whether the line edit is read only.
1458
1459 In read-only mode, the user can still copy the text to the
1460 clipboard, or drag and drop the text (if echoMode() is \l Normal),
1461 but cannot edit it.
1462
1463 QLineEdit does not show a cursor in read-only mode.
1464
1465 By default, this property is false.
1466
1467 \sa setEnabled()
1468*/
1469
1470bool QLineEdit::isReadOnly() const
1471{
1472 Q_D(const QLineEdit);
1473 return d->readOnly;
1474}
1475
1476void QLineEdit::setReadOnly(bool enable)
1477{
1478 Q_D(QLineEdit);
1479 if (d->readOnly != enable) {
1480 d->readOnly = enable;
1481 setAttribute(Qt::WA_MacShowFocusRect, !d->readOnly);
1482 setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
1483#ifndef QT_NO_CURSOR
1484 setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
1485#endif
1486 update();
1487 }
1488}
1489
1490
1491#ifndef QT_NO_CLIPBOARD
1492/*!
1493 Copies the selected text to the clipboard and deletes it, if there
1494 is any, and if echoMode() is \l Normal.
1495
1496 If the current validator disallows deleting the selected text,
1497 cut() will copy without deleting.
1498
1499 \sa copy() paste() setValidator()
1500*/
1501
1502void QLineEdit::cut()
1503{
1504 if (hasSelectedText()) {
1505 copy();
1506 del();
1507 }
1508}
1509
1510
1511/*!
1512 Copies the selected text to the clipboard, if there is any, and if
1513 echoMode() is \l Normal.
1514
1515 \sa cut() paste()
1516*/
1517
1518void QLineEdit::copy() const
1519{
1520 Q_D(const QLineEdit);
1521 d->copy();
1522}
1523
1524/*!
1525 Inserts the clipboard's text at the cursor position, deleting any
1526 selected text, providing the line edit is not \link
1527 QLineEdit::readOnly read-only\endlink.
1528
1529 If the end result would not be acceptable to the current
1530 \link setValidator() validator\endlink, nothing happens.
1531
1532 \sa copy() cut()
1533*/
1534
1535void QLineEdit::paste()
1536{
1537 Q_D(QLineEdit);
1538 if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
1539 // Clear the edit and reset to normal echo mode when pasting; the echo
1540 // mode switches back when the edit loses focus. ### changes a public
1541 // property, resets current content
1542 d->updatePasswordEchoEditing(true);
1543 clear();
1544 }
1545 insert(QApplication::clipboard()->text(QClipboard::Clipboard));
1546}
1547
1548void QLineEditPrivate::copy(bool clipboard) const
1549{
1550 Q_Q(const QLineEdit);
1551 QString t = q->selectedText();
1552 if (!t.isEmpty() && echoMode == QLineEdit::Normal) {
1553 q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
1554 QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
1555 q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
1556 q, SLOT(_q_clipboardChanged()));
1557 }
1558}
1559
1560#endif // !QT_NO_CLIPBOARD
1561
1562/*! \reimp
1563*/
1564bool QLineEdit::event(QEvent * e)
1565{
1566 Q_D(QLineEdit);
1567#ifndef QT_NO_SHORTCUT
1568 if (e->type() == QEvent::ShortcutOverride && !d->readOnly) {
1569 QKeyEvent* ke = (QKeyEvent*) e;
1570 if (ke == QKeySequence::Copy
1571 || ke == QKeySequence::Paste
1572 || ke == QKeySequence::Cut
1573 || ke == QKeySequence::Redo
1574 || ke == QKeySequence::Undo
1575 || ke == QKeySequence::MoveToNextWord
1576 || ke == QKeySequence::MoveToPreviousWord
1577 || ke == QKeySequence::MoveToStartOfDocument
1578 || ke == QKeySequence::MoveToEndOfDocument
1579 || ke == QKeySequence::SelectNextWord
1580 || ke == QKeySequence::SelectPreviousWord
1581 || ke == QKeySequence::SelectStartOfLine
1582 || ke == QKeySequence::SelectEndOfLine
1583 || ke == QKeySequence::SelectStartOfBlock
1584 || ke == QKeySequence::SelectEndOfBlock
1585 || ke == QKeySequence::SelectStartOfDocument
1586 || ke == QKeySequence::SelectAll
1587 || ke == QKeySequence::SelectEndOfDocument) {
1588 ke->accept();
1589 } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
1590 || ke->modifiers() == Qt::KeypadModifier) {
1591 if (ke->key() < Qt::Key_Escape) {
1592 ke->accept();
1593 } else {
1594 switch (ke->key()) {
1595 case Qt::Key_Delete:
1596 case Qt::Key_Home:
1597 case Qt::Key_End:
1598 case Qt::Key_Backspace:
1599 case Qt::Key_Left:
1600 case Qt::Key_Right:
1601 ke->accept();
1602 default:
1603 break;
1604 }
1605 }
1606 }
1607 } else
1608#endif
1609 if (e->type() == QEvent::Timer) {
1610 // should be timerEvent, is here for binary compatibility
1611 int timerId = ((QTimerEvent*)e)->timerId();
1612 if (timerId == d->cursorTimer) {
1613 QStyleOptionFrameV2 opt;
1614 initStyleOption(&opt);
1615 if(!hasSelectedText()
1616 || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
1617 d->setCursorVisible(!d->cursorVisible);
1618#ifndef QT_NO_DRAGANDDROP
1619 } else if (timerId == d->dndTimer.timerId()) {
1620 d->drag();
1621#endif
1622 }
1623 else if (timerId == d->tripleClickTimer.timerId())
1624 d->tripleClickTimer.stop();
1625#ifdef QT_KEYPAD_NAVIGATION
1626 else if (timerId == d->deleteAllTimer.timerId()) {
1627 d->deleteAllTimer.stop();
1628 clear();
1629 }
1630#endif
1631 } else if (e->type() == QEvent::ContextMenu) {
1632#ifndef QT_NO_IM
1633 if (d->composeMode())
1634 return true;
1635#endif
1636 d->separate();
1637 } else if (e->type() == QEvent::WindowActivate) {
1638 QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
1639 }
1640#ifdef QT_KEYPAD_NAVIGATION
1641 if (QApplication::keypadNavigationEnabled()) {
1642 if ((e->type() == QEvent::KeyPress) || (e->type() == QEvent::KeyRelease)) {
1643 QKeyEvent *ke = (QKeyEvent *)e;
1644 if (ke->key() == Qt::Key_Back) {
1645 if (ke->isAutoRepeat()) {
1646 // Swallow it. We don't want back keys running amok.
1647 ke->accept();
1648 return true;
1649 }
1650 if ((e->type() == QEvent::KeyRelease)
1651 && !isReadOnly()
1652 && d->deleteAllTimer.isActive()) {
1653 d->deleteAllTimer.stop();
1654 backspace();
1655 ke->accept();
1656 return true;
1657 }
1658 }
1659 } else if (e->type() == QEvent::EnterEditFocus) {
1660 end(false);
1661 if (!d->cursorTimer) {
1662 int cft = QApplication::cursorFlashTime();
1663 d->cursorTimer = cft ? startTimer(cft/2) : -1;
1664 }
1665 } else if (e->type() == QEvent::LeaveEditFocus) {
1666 d->setCursorVisible(false);
1667 if (d->cursorTimer > 0)
1668 killTimer(d->cursorTimer);
1669 d->cursorTimer = 0;
1670
1671 if (!d->emitingEditingFinished) {
1672 if (hasAcceptableInput() || d->fixup()) {
1673 d->emitingEditingFinished = true;
1674 emit editingFinished();
1675 d->emitingEditingFinished = false;
1676 }
1677 }
1678 }
1679 }
1680#endif
1681 return QWidget::event(e);
1682}
1683
1684/*! \reimp
1685*/
1686void QLineEdit::mousePressEvent(QMouseEvent* e)
1687{
1688 Q_D(QLineEdit);
1689 if (d->sendMouseEventToInputContext(e))
1690 return;
1691 if (e->button() == Qt::RightButton)
1692 return;
1693#ifdef QT_KEYPAD_NAVIGATION
1694 if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
1695 setEditFocus(true);
1696 // Get the completion list to pop up.
1697 if (d->completer)
1698 d->completer->complete();
1699 }
1700#endif
1701 if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
1702 QApplication::startDragDistance()) {
1703 selectAll();
1704 return;
1705 }
1706 bool mark = e->modifiers() & Qt::ShiftModifier;
1707 int cursor = d->xToPos(e->pos().x());
1708#ifndef QT_NO_DRAGANDDROP
1709 if (!mark && d->dragEnabled && d->echoMode == Normal &&
1710 e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) {
1711 d->cursor = cursor;
1712 update();
1713 d->dndPos = e->pos();
1714 if (!d->dndTimer.isActive())
1715 d->dndTimer.start(QApplication::startDragTime(), this);
1716 d->emitCursorPositionChanged();
1717 } else
1718#endif
1719 {
1720 d->moveCursor(cursor, mark);
1721 }
1722}
1723
1724/*! \reimp
1725*/
1726void QLineEdit::mouseMoveEvent(QMouseEvent * e)
1727{
1728 Q_D(QLineEdit);
1729 if (d->sendMouseEventToInputContext(e))
1730 return;
1731
1732 if (e->buttons() & Qt::LeftButton) {
1733#ifndef QT_NO_DRAGANDDROP
1734 if (d->dndTimer.isActive()) {
1735 if ((d->dndPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
1736 d->drag();
1737 } else
1738#endif
1739 {
1740 d->moveCursor(d->xToPos(e->pos().x()), true);
1741 }
1742 }
1743}
1744
1745/*! \reimp
1746*/
1747void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
1748{
1749 Q_D(QLineEdit);
1750 if (d->sendMouseEventToInputContext(e))
1751 return;
1752#ifndef QT_NO_DRAGANDDROP
1753 if (e->button() == Qt::LeftButton) {
1754 if (d->dndTimer.isActive()) {
1755 d->dndTimer.stop();
1756 deselect();
1757 return;
1758 }
1759 }
1760#endif
1761#ifndef QT_NO_CLIPBOARD
1762 if (QApplication::clipboard()->supportsSelection()) {
1763 if (e->button() == Qt::LeftButton) {
1764 d->copy(false);
1765 } else if (!d->readOnly && e->button() == Qt::MidButton) {
1766 d->deselect();
1767 insert(QApplication::clipboard()->text(QClipboard::Selection));
1768 }
1769 }
1770#endif
1771}
1772
1773/*! \reimp
1774*/
1775void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
1776{
1777 Q_D(QLineEdit);
1778 if (d->sendMouseEventToInputContext(e))
1779 return;
1780 if (e->button() == Qt::LeftButton) {
1781 deselect();
1782 d->cursor = d->xToPos(e->pos().x());
1783 d->cursor = d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords);
1784 // ## text layout should support end of words.
1785 int end = d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords);
1786 while (end > d->cursor && d->text[end-1].isSpace())
1787 --end;
1788 d->moveCursor(end, true);
1789 d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
1790 d->tripleClick = e->pos();
1791 }
1792}
1793
1794/*!
1795 \fn void QLineEdit::returnPressed()
1796
1797 This signal is emitted when the Return or Enter key is pressed.
1798 Note that if there is a validator() or inputMask() set on the line
1799 edit, the returnPressed() signal will only be emitted if the input
1800 follows the inputMask() and the validator() returns
1801 QValidator::Acceptable.
1802*/
1803
1804/*!
1805 \fn void QLineEdit::editingFinished()
1806
1807 This signal is emitted when the Return or Enter key is pressed or
1808 the line edit loses focus. Note that if there is a validator() or
1809 inputMask() set on the line edit and enter/return is pressed, the
1810 editingFinished() signal will only be emitted if the input follows
1811 the inputMask() and the validator() returns QValidator::Acceptable.
1812*/
1813
1814/*!
1815 Converts the given key press \a event into a line edit action.
1816
1817 If Return or Enter is pressed and the current text is valid (or
1818 can be \link QValidator::fixup() made valid\endlink by the
1819 validator), the signal returnPressed() is emitted.
1820
1821 The default key bindings are listed in the class's detailed
1822 description.
1823*/
1824
1825void QLineEdit::keyPressEvent(QKeyEvent *event)
1826{
1827 Q_D(QLineEdit);
1828
1829 bool inlineCompletionAccepted = false;
1830
1831#ifndef QT_NO_COMPLETER
1832 if (d->completer) {
1833 QCompleter::CompletionMode completionMode = d->completer->completionMode();
1834 if ((completionMode == QCompleter::PopupCompletion
1835 || completionMode == QCompleter::UnfilteredPopupCompletion)
1836 &&d->completer->popup()
1837 && d->completer->popup()->isVisible()) {
1838 // The following keys are forwarded by the completer to the widget
1839 // Ignoring the events lets the completer provide suitable default behavior
1840 switch (event->key()) {
1841 case Qt::Key_Escape:
1842 event->ignore();
1843 return;
1844 case Qt::Key_Enter:
1845 case Qt::Key_Return:
1846 case Qt::Key_F4:
1847#ifdef QT_KEYPAD_NAVIGATION
1848 case Qt::Key_Select:
1849 if (!QApplication::keypadNavigationEnabled())
1850 break;
1851#endif
1852 d->completer->popup()->hide(); // just hide. will end up propagating to parent
1853 default:
1854 break; // normal key processing
1855 }
1856 } else if (completionMode == QCompleter::InlineCompletion) {
1857 switch (event->key()) {
1858 case Qt::Key_Enter:
1859 case Qt::Key_Return:
1860 case Qt::Key_F4:
1861#ifdef QT_KEYPAD_NAVIGATION
1862 case Qt::Key_Select:
1863 if (!QApplication::keypadNavigationEnabled())
1864 break;
1865#endif
1866 if (!d->completer->currentCompletion().isEmpty() && d->selend > d->selstart
1867 && d->selend == d->text.length()) {
1868 setText(d->completer->currentCompletion());
1869 inlineCompletionAccepted = true;
1870 }
1871 default:
1872 break; // normal key processing
1873 }
1874 }
1875 }
1876#endif // QT_NO_COMPLETER
1877
1878#ifdef QT_KEYPAD_NAVIGATION
1879 bool select = false;
1880 switch (event->key()) {
1881 case Qt::Key_Select:
1882 if (QApplication::keypadNavigationEnabled()) {
1883 if (hasEditFocus()) {
1884 setEditFocus(false);
1885 if (d->completer && d->completer->popup()->isVisible())
1886 d->completer->popup()->hide();
1887 select = true;
1888 }
1889 }
1890 break;
1891 case Qt::Key_Back:
1892 case Qt::Key_No:
1893 if (!QApplication::keypadNavigationEnabled() || !hasEditFocus()) {
1894 event->ignore();
1895 return;
1896 }
1897 break;
1898 default:
1899 if (QApplication::keypadNavigationEnabled()) {
1900 if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) {
1901 if (!event->text().isEmpty() && event->text().at(0).isPrint()
1902 && !isReadOnly())
1903 {
1904 setEditFocus(true);
1905 clear();
1906 } else {
1907 event->ignore();
1908 return;
1909 }
1910 }
1911 }
1912 }
1913
1914
1915
1916 if (QApplication::keypadNavigationEnabled() && !select && !hasEditFocus()) {
1917 setEditFocus(true);
1918 if (event->key() == Qt::Key_Select)
1919 return; // Just start. No action.
1920 }
1921#endif
1922
1923 if (echoMode() == PasswordEchoOnEdit
1924 && !d->passwordEchoEditing
1925 && !isReadOnly()
1926 && !event->text().isEmpty()
1927#ifdef QT_KEYPAD_NAVIGATION
1928 && event->key() != Qt::Key_Select
1929 && event->key() != Qt::Key_Up
1930 && event->key() != Qt::Key_Down
1931 && event->key() != Qt::Key_Back
1932#endif
1933 && !(event->modifiers() & Qt::ControlModifier)) {
1934 // Clear the edit and reset to normal echo mode while editing; the
1935 // echo mode switches back when the edit loses focus. ### changes a
1936 // public property, resets current content. dubious code; you can
1937 // navigate with keys up, down, back, and select(?), but if you press
1938 // "left" or "right" it clears?
1939 d->updatePasswordEchoEditing(true);
1940 clear();
1941 }
1942
1943 d->setCursorVisible(true);
1944 if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
1945 if (hasAcceptableInput() || d->fixup()) {
1946 emit returnPressed();
1947 d->emitingEditingFinished = true;
1948 emit editingFinished();
1949 d->emitingEditingFinished = false;
1950 }
1951 if (inlineCompletionAccepted)
1952 event->accept();
1953 else
1954 event->ignore();
1955 return;
1956 }
1957 bool unknown = false;
1958
1959 if (false) {
1960 }
1961#ifndef QT_NO_SHORTCUT
1962 else if (event == QKeySequence::Undo) {
1963 if (!d->readOnly)
1964 undo();
1965 }
1966 else if (event == QKeySequence::Redo) {
1967 if (!d->readOnly)
1968 redo();
1969 }
1970 else if (event == QKeySequence::SelectAll) {
1971 selectAll();
1972 }
1973#ifndef QT_NO_CLIPBOARD
1974 else if (event == QKeySequence::Copy) {
1975 copy();
1976 }
1977 else if (event == QKeySequence::Paste) {
1978 if (!d->readOnly)
1979 paste();
1980 }
1981 else if (event == QKeySequence::Cut) {
1982 if (!d->readOnly) {
1983 cut();
1984 }
1985 }
1986 else if (event == QKeySequence::DeleteEndOfLine) {
1987 if (!d->readOnly) {
1988 setSelection(d->cursor, d->text.size());
1989 copy();
1990 del();
1991 }
1992 }
1993#endif //QT_NO_CLIPBOARD
1994 else if (event == QKeySequence::MoveToStartOfLine) {
1995 home(0);
1996 }
1997 else if (event == QKeySequence::MoveToEndOfLine) {
1998 end(0);
1999 }
2000 else if (event == QKeySequence::SelectStartOfLine) {
2001 home(1);
2002 }
2003 else if (event == QKeySequence::SelectEndOfLine) {
2004 end(1);
2005 }
2006 else if (event == QKeySequence::MoveToNextChar) {
2007#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
2008 if (d->hasSelectedText()) {
2009#else
2010 if (d->hasSelectedText() && d->completer
2011 && d->completer->completionMode() == QCompleter::InlineCompletion) {
2012#endif
2013 d->moveCursor(d->selend, false);
2014 } else {
2015 cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
2016 }
2017 }
2018 else if (event == QKeySequence::SelectNextChar) {
2019 cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
2020 }
2021 else if (event == QKeySequence::MoveToPreviousChar) {
2022#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
2023 if (d->hasSelectedText()) {
2024#else
2025 if (d->hasSelectedText() && d->completer
2026 && d->completer->completionMode() == QCompleter::InlineCompletion) {
2027#endif
2028 d->moveCursor(d->selstart, false);
2029 } else {
2030 cursorBackward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
2031 }
2032 }
2033 else if (event == QKeySequence::SelectPreviousChar) {
2034 cursorBackward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
2035 }
2036 else if (event == QKeySequence::MoveToNextWord) {
2037 if (echoMode() == Normal)
2038 layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
2039 else
2040 layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
2041 }
2042 else if (event == QKeySequence::MoveToPreviousWord) {
2043 if (echoMode() == Normal)
2044 layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
2045 else if (!d->readOnly) {
2046 layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
2047 }
2048 }
2049 else if (event == QKeySequence::SelectNextWord) {
2050 if (echoMode() == Normal)
2051 layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
2052 else
2053 layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
2054 }
2055 else if (event == QKeySequence::SelectPreviousWord) {
2056 if (echoMode() == Normal)
2057 layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
2058 else
2059 layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
2060 }
2061 else if (event == QKeySequence::Delete) {
2062 if (!d->readOnly)
2063 del();
2064 }
2065 else if (event == QKeySequence::DeleteEndOfWord) {
2066 if (!d->readOnly) {
2067 cursorWordForward(true);
2068 del();
2069 }
2070 }
2071 else if (event == QKeySequence::DeleteStartOfWord) {
2072 if (!d->readOnly) {
2073 cursorWordBackward(true);
2074 del();
2075 }
2076 }
2077#endif // QT_NO_SHORTCUT
2078 else {
2079#ifdef Q_WS_MAC
2080 if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
2081 Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
2082 if (myModifiers & Qt::ShiftModifier) {
2083 if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
2084 || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
2085 || myModifiers == Qt::ShiftModifier) {
2086
2087 event->key() == Qt::Key_Up ? home(1) : end(1);
2088 }
2089 } else {
2090 if ((myModifiers == Qt::ControlModifier
2091 || myModifiers == Qt::AltModifier
2092 || myModifiers == Qt::NoModifier)) {
2093 event->key() == Qt::Key_Up ? home(0) : end(0);
2094 }
2095 }
2096 }
2097#endif
2098 if (event->modifiers() & Qt::ControlModifier) {
2099 switch (event->key()) {
2100 case Qt::Key_Backspace:
2101 if (!d->readOnly) {
2102 cursorWordBackward(true);
2103 del();
2104 }
2105 break;
2106#ifndef QT_NO_COMPLETER
2107 case Qt::Key_Up:
2108 case Qt::Key_Down:
2109 d->complete(event->key());
2110 break;
2111#endif
2112#if defined(Q_WS_X11)
2113 case Qt::Key_E:
2114 end(0);
2115 break;
2116
2117 case Qt::Key_U:
2118 if (!d->readOnly) {
2119 setSelection(0, d->text.size());
2120#ifndef QT_NO_CLIPBOARD
2121 copy();
2122#endif
2123 del();
2124 }
2125 break;
2126#endif
2127 default:
2128 unknown = true;
2129 }
2130 } else { // ### check for *no* modifier
2131 switch (event->key()) {
2132 case Qt::Key_Backspace:
2133 if (!d->readOnly) {
2134 backspace();
2135#ifndef QT_NO_COMPLETER
2136 d->complete(Qt::Key_Backspace);
2137#endif
2138 }
2139 break;
2140#ifdef QT_KEYPAD_NAVIGATION
2141 case Qt::Key_Back:
2142 if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
2143 && !isReadOnly()) {
2144 if (text().length() == 0) {
2145 setText(d->origText);
2146
2147 if (d->passwordEchoEditing)
2148 d->updatePasswordEchoEditing(false);
2149
2150 setEditFocus(false);
2151 } else if (!d->deleteAllTimer.isActive()) {
2152 d->deleteAllTimer.start(750, this);
2153 }
2154 } else {
2155 unknown = true;
2156 }
2157 break;
2158#endif
2159
2160 default:
2161 unknown = true;
2162 }
2163 }
2164 }
2165
2166 if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
2167 setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
2168 d->updateTextLayout();
2169 update();
2170 unknown = false;
2171 }
2172
2173 if (unknown && !d->readOnly) {
2174 QString t = event->text();
2175 if (!t.isEmpty() && t.at(0).isPrint()) {
2176 insert(t);
2177#ifndef QT_NO_COMPLETER
2178 d->complete(event->key());
2179#endif
2180 event->accept();
2181 return;
2182 }
2183 }
2184
2185 if (unknown)
2186 event->ignore();
2187 else
2188 event->accept();
2189}
2190
2191/*!
2192 \since 4.4
2193
2194 Returns a rectangle that includes the lineedit cursor.
2195*/
2196QRect QLineEdit::cursorRect() const
2197{
2198 Q_D(const QLineEdit);
2199 return d->cursorRect();
2200}
2201
2202/*!
2203 This function is not intended as polymorphic usage. Just a shared code
2204 fragment that calls QInputContext::mouseHandler for this
2205 class.
2206*/
2207bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
2208{
2209#if !defined QT_NO_IM
2210 Q_Q(QLineEdit);
2211 if ( composeMode() ) {
2212 int tmp_cursor = xToPos(e->pos().x());
2213 int mousePos = tmp_cursor - cursor;
2214 if ( mousePos < 0 || mousePos > textLayout.preeditAreaText().length() ) {
2215 mousePos = -1;
2216 // don't send move events outside the preedit area
2217 if ( e->type() == QEvent::MouseMove )
2218 return true;
2219 }
2220
2221 QInputContext *qic = q->inputContext();
2222 if ( qic )
2223 // may be causing reset() in some input methods
2224 qic->mouseHandler(mousePos, e);
2225 if (!textLayout.preeditAreaText().isEmpty())
2226 return true;
2227 }
2228#else
2229 Q_UNUSED(e);
2230#endif
2231
2232 return false;
2233}
2234
2235/*! \reimp
2236 */
2237void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
2238{
2239 Q_D(QLineEdit);
2240 if (d->readOnly) {
2241 e->ignore();
2242 return;
2243 }
2244
2245 if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
2246 // Clear the edit and reset to normal echo mode while entering input
2247 // method data; the echo mode switches back when the edit loses focus.
2248 // ### changes a public property, resets current content.
2249 d->updatePasswordEchoEditing(true);
2250 clear();
2251 }
2252
2253#ifdef QT_KEYPAD_NAVIGATION
2254 // Focus in if currently in navigation focus on the widget
2255 // Only focus in on preedits, to allow input methods to
2256 // commit text as they focus out without interfering with focus
2257 if (QApplication::keypadNavigationEnabled()
2258 && hasFocus() && !hasEditFocus()
2259 && !e->preeditString().isEmpty()) {
2260 setEditFocus(true);
2261 selectAll(); // so text is replaced rather than appended to
2262 }
2263#endif
2264
2265 int priorState = d->undoState;
2266 d->removeSelectedText();
2267
2268 int c = d->cursor; // cursor position after insertion of commit string
2269 if (e->replacementStart() <= 0)
2270 c += e->commitString().length() + qMin(-e->replacementStart(), e->replacementLength());
2271
2272 d->cursor += e->replacementStart();
2273
2274 // insert commit string
2275 if (e->replacementLength()) {
2276 d->selstart = d->cursor;
2277 d->selend = d->selstart + e->replacementLength();
2278 d->removeSelectedText();
2279 }
2280 if (!e->commitString().isEmpty())
2281 d->insert(e->commitString());
2282
2283 d->cursor = qMin(c, d->text.length());
2284
2285 d->textLayout.setPreeditArea(d->cursor, e->preeditString());
2286 d->preeditCursor = e->preeditString().length();
2287 d->hideCursor = false;
2288 QList<QTextLayout::FormatRange> formats;
2289 for (int i = 0; i < e->attributes().size(); ++i) {
2290 const QInputMethodEvent::Attribute &a = e->attributes().at(i);
2291 if (a.type == QInputMethodEvent::Cursor) {
2292 d->preeditCursor = a.start;
2293 d->hideCursor = !a.length;
2294 } else if (a.type == QInputMethodEvent::TextFormat) {
2295 QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
2296 if (f.isValid()) {
2297 QTextLayout::FormatRange o;
2298 o.start = a.start + d->cursor;
2299 o.length = a.length;
2300 o.format = f;
2301 formats.append(o);
2302 }
2303 }
2304 }
2305 d->textLayout.setAdditionalFormats(formats);
2306 d->updateTextLayout();
2307 update();
2308 if (!e->commitString().isEmpty())
2309 d->emitCursorPositionChanged();
2310 d->finishChange(priorState);
2311#ifndef QT_NO_COMPLETER
2312 if (!e->commitString().isEmpty())
2313 d->complete(Qt::Key_unknown);
2314#endif
2315}
2316
2317/*!\reimp
2318*/
2319QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
2320{
2321 Q_D(const QLineEdit);
2322 switch(property) {
2323 case Qt::ImMicroFocus:
2324 return d->cursorRect();
2325 case Qt::ImFont:
2326 return font();
2327 case Qt::ImCursorPosition:
2328 return QVariant((d->selend - d->selstart == 0) ? d->cursor : d->selend);
2329 case Qt::ImSurroundingText:
2330 return QVariant(d->text);
2331 case Qt::ImCurrentSelection:
2332 return QVariant(selectedText());
2333 default:
2334 return QVariant();
2335 }
2336}
2337
2338/*!\reimp
2339*/
2340
2341void QLineEdit::focusInEvent(QFocusEvent *e)
2342{
2343 Q_D(QLineEdit);
2344 if (e->reason() == Qt::TabFocusReason ||
2345 e->reason() == Qt::BacktabFocusReason ||
2346 e->reason() == Qt::ShortcutFocusReason) {
2347 if (d->maskData)
2348 d->moveCursor(d->nextMaskBlank(0));
2349 else if (!d->hasSelectedText())
2350 selectAll();
2351 }
2352#ifdef QT_KEYPAD_NAVIGATION
2353 if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason))
2354#endif
2355 if (!d->cursorTimer) {
2356 int cft = QApplication::cursorFlashTime();
2357 d->cursorTimer = cft ? startTimer(cft/2) : -1;
2358 }
2359 QStyleOptionFrameV2 opt;
2360 initStyleOption(&opt);
2361 if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty())
2362 || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
2363 d->setCursorVisible(true);
2364#ifdef Q_WS_MAC
2365 if (d->echoMode == Password || d->echoMode == NoEcho)
2366 qt_mac_secure_keyboard(true);
2367#endif
2368#ifdef QT_KEYPAD_NAVIGATION
2369 d->origText = d->text;
2370#endif
2371#ifndef QT_NO_COMPLETER
2372 if (d->completer) {
2373 d->completer->setWidget(this);
2374 QObject::connect(d->completer, SIGNAL(activated(QString)),
2375 this, SLOT(setText(QString)));
2376 QObject::connect(d->completer, SIGNAL(highlighted(QString)),
2377 this, SLOT(_q_completionHighlighted(QString)));
2378 }
2379#endif
2380 update();
2381}
2382
2383/*!\reimp
2384*/
2385
2386void QLineEdit::focusOutEvent(QFocusEvent *e)
2387{
2388 Q_D(QLineEdit);
2389 if (d->passwordEchoEditing) {
2390 // Reset the echomode back to PasswordEchoOnEdit when the widget loses
2391 // focus.
2392 d->updatePasswordEchoEditing(false);
2393 }
2394
2395 Qt::FocusReason reason = e->reason();
2396 if (reason != Qt::ActiveWindowFocusReason &&
2397 reason != Qt::PopupFocusReason)
2398 deselect();
2399
2400 d->setCursorVisible(false);
2401 if (d->cursorTimer > 0)
2402 killTimer(d->cursorTimer);
2403 d->cursorTimer = 0;
2404
2405#ifdef QT_KEYPAD_NAVIGATION
2406 // editingFinished() is already emitted on LeaveEditFocus
2407 if (!QApplication::keypadNavigationEnabled())
2408#endif
2409 if (reason != Qt::PopupFocusReason
2410 || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
2411 if (!d->emitingEditingFinished) {
2412 if (hasAcceptableInput() || d->fixup()) {
2413 d->emitingEditingFinished = true;
2414 emit editingFinished();
2415 d->emitingEditingFinished = false;
2416 }
2417 }
2418#ifdef QT3_SUPPORT
2419 emit lostFocus();
2420#endif
2421 }
2422#ifdef Q_WS_MAC
2423 if (d->echoMode == Password || d->echoMode == NoEcho)
2424 qt_mac_secure_keyboard(false);
2425#endif
2426#ifdef QT_KEYPAD_NAVIGATION
2427 d->origText = QString();
2428#endif
2429#ifndef QT_NO_COMPLETER
2430 if (d->completer) {
2431 QObject::disconnect(d->completer, 0, this, 0);
2432 }
2433#endif
2434 update();
2435}
2436
2437/*!\reimp
2438*/
2439void QLineEdit::paintEvent(QPaintEvent *)
2440{
2441 Q_D(QLineEdit);
2442 QPainter p(this);
2443
2444 QRect r = rect();
2445 QPalette pal = palette();
2446
2447 QStyleOptionFrameV2 panel;
2448 initStyleOption(&panel);
2449 style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
2450 r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
2451 r.setX(r.x() + d->leftTextMargin);
2452 r.setY(r.y() + d->topTextMargin);
2453 r.setRight(r.right() - d->rightTextMargin);
2454 r.setBottom(r.bottom() - d->bottomTextMargin);
2455 p.setClipRect(r);
2456
2457 QFontMetrics fm = fontMetrics();
2458 Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment));
2459 switch (va & Qt::AlignVertical_Mask) {
2460 case Qt::AlignBottom:
2461 d->vscroll = r.y() + r.height() - fm.height() - verticalMargin;
2462 break;
2463 case Qt::AlignTop:
2464 d->vscroll = r.y() + verticalMargin;
2465 break;
2466 default:
2467 //center
2468 d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
2469 break;
2470 }
2471 QRect lineRect(r.x() + horizontalMargin, d->vscroll, r.width() - 2*horizontalMargin, fm.height());
2472 QTextLine line = d->textLayout.lineAt(0);
2473
2474 int cursor = d->cursor;
2475 if (d->preeditCursor != -1)
2476 cursor += d->preeditCursor;
2477 // locate cursor position
2478 int cix = qRound(line.cursorToX(cursor));
2479
2480 // horizontal scrolling. d->hscroll is the left indent from the beginning
2481 // of the text line to the left edge of lineRect. we update this value
2482 // depending on the delta from the last paint event; in effect this means
2483 // the below code handles all scrolling based on the textline (widthUsed,
2484 // minLB, minRB), the line edit rect (lineRect) and the cursor position
2485 // (cix).
2486 int minLB = qMax(0, -fm.minLeftBearing());
2487 int minRB = qMax(0, -fm.minRightBearing());
2488 int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
2489 if ((minLB + widthUsed) <= lineRect.width()) {
2490 // text fits in lineRect; use hscroll for alignment
2491 switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
2492 case Qt::AlignRight:
2493 d->hscroll = widthUsed - lineRect.width() + 1;
2494 break;
2495 case Qt::AlignHCenter:
2496 d->hscroll = (widthUsed - lineRect.width()) / 2;
2497 break;
2498 default:
2499 // Left
2500 d->hscroll = 0;
2501 break;
2502 }
2503 d->hscroll -= minLB;
2504 } else if (cix - d->hscroll >= lineRect.width()) {
2505 // text doesn't fit, cursor is to the right of lineRect (scroll right)
2506 d->hscroll = cix - lineRect.width() + 1;
2507 } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
2508 // text doesn't fit, cursor is to the left of lineRect (scroll left)
2509 d->hscroll = cix;
2510 } else if (widthUsed - d->hscroll < lineRect.width()) {
2511 // text doesn't fit, text document is to the left of lineRect; align
2512 // right
2513 d->hscroll = widthUsed - lineRect.width() + 1;
2514 }
2515 // the y offset is there to keep the baseline constant in case we have script changes in the text.
2516 QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent - fm.ascent());
2517
2518 // draw text, selections and cursors
2519#ifndef QT_NO_STYLE_STYLESHEET
2520 if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
2521 cssStyle->focusPalette(this, &panel, &pal);
2522 }
2523#endif
2524 p.setPen(pal.text().color());
2525
2526 QVector<QTextLayout::FormatRange> selections;
2527#ifdef QT_KEYPAD_NAVIGATION
2528 if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
2529#endif
2530 if (d->selstart < d->selend || (d->cursorVisible && d->maskData && !d->readOnly)) {
2531 QTextLayout::FormatRange o;
2532 if (d->selstart < d->selend) {
2533 o.start = d->selstart;
2534 o.length = d->selend - d->selstart;
2535 o.format.setBackground(pal.brush(QPalette::Highlight));
2536 o.format.setForeground(pal.brush(QPalette::HighlightedText));
2537 } else {
2538 // mask selection
2539 o.start = d->cursor;
2540 o.length = 1;
2541 o.format.setBackground(pal.brush(QPalette::Text));
2542 o.format.setForeground(pal.brush(QPalette::Window));
2543 }
2544 selections.append(o);
2545 }
2546
2547 // Asian users see an IM selection text as cursor on candidate
2548 // selection phase of input method, so the ordinary cursor should be
2549 // invisible if we have a preedit string.
2550 d->textLayout.draw(&p, topLeft, selections, r);
2551 if (d->cursorVisible && !d->readOnly && !d->hideCursor)
2552 d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));
2553}
2554
2555
2556#ifndef QT_NO_DRAGANDDROP
2557/*!\reimp
2558*/
2559void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
2560{
2561 Q_D(QLineEdit);
2562 if (!d->readOnly && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
2563 e->acceptProposedAction();
2564 d->cursor = d->xToPos(e->pos().x());
2565 d->cursorVisible = true;
2566 update();
2567 d->emitCursorPositionChanged();
2568 }
2569}
2570
2571/*!\reimp */
2572void QLineEdit::dragEnterEvent(QDragEnterEvent * e)
2573{
2574 QLineEdit::dragMoveEvent(e);
2575}
2576
2577/*!\reimp */
2578void QLineEdit::dragLeaveEvent(QDragLeaveEvent *)
2579{
2580 Q_D(QLineEdit);
2581 if (d->cursorVisible) {
2582 d->cursorVisible = false;
2583 update();
2584 }
2585}
2586
2587/*!\reimp */
2588void QLineEdit::dropEvent(QDropEvent* e)
2589{
2590 Q_D(QLineEdit);
2591 QString str = e->mimeData()->text();
2592
2593 if (!str.isNull() && !d->readOnly) {
2594 if (e->source() == this && e->dropAction() == Qt::CopyAction)
2595 deselect();
2596 d->cursor =d->xToPos(e->pos().x());
2597 int selStart = d->cursor;
2598 int oldSelStart = d->selstart;
2599 int oldSelEnd = d->selend;
2600 d->cursorVisible = false;
2601 e->acceptProposedAction();
2602 insert(str);
2603 if (e->source() == this) {
2604 if (e->dropAction() == Qt::MoveAction) {
2605 if (selStart > oldSelStart && selStart <= oldSelEnd)
2606 setSelection(oldSelStart, str.length());
2607 else if (selStart > oldSelEnd)
2608 setSelection(selStart - str.length(), str.length());
2609 else
2610 setSelection(selStart, str.length());
2611 } else {
2612 setSelection(selStart, str.length());
2613 }
2614 }
2615 } else {
2616 e->ignore();
2617 update();
2618 }
2619}
2620
2621void QLineEditPrivate::drag()
2622{
2623 Q_Q(QLineEdit);
2624 dndTimer.stop();
2625 QMimeData *data = new QMimeData;
2626 data->setText(q->selectedText());
2627 QDrag *drag = new QDrag(q);
2628 drag->setMimeData(data);
2629 Qt::DropAction action = drag->start();
2630 if (action == Qt::MoveAction && !readOnly && drag->target() != q) {
2631 int priorState = undoState;
2632 removeSelectedText();
2633 finishChange(priorState);
2634 }
2635}
2636
2637#endif // QT_NO_DRAGANDDROP
2638
2639#ifndef QT_NO_CONTEXTMENU
2640/*!
2641 Shows the standard context menu created with
2642 createStandardContextMenu().
2643
2644 If you do not want the line edit to have a context menu, you can set
2645 its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
2646 customize the context menu, reimplement this function. If you want
2647 to extend the standard context menu, reimplement this function, call
2648 createStandardContextMenu() and extend the menu returned.
2649
2650 \snippet doc/src/snippets/code/src_gui_widgets_qlineedit.cpp 0
2651
2652 The \a event parameter is used to obtain the position where
2653 the mouse cursor was when the event was generated.
2654
2655 \sa setContextMenuPolicy()
2656*/
2657void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
2658{
2659 QPointer<QMenu> menu = createStandardContextMenu();
2660 menu->exec(event->globalPos());
2661 delete menu;
2662}
2663
2664#if defined(Q_WS_WIN)
2665 extern bool qt_use_rtl_extensions;
2666#endif
2667
2668/*! This function creates the standard context menu which is shown
2669 when the user clicks on the line edit with the right mouse
2670 button. It is called from the default contextMenuEvent() handler.
2671 The popup menu's ownership is transferred to the caller.
2672*/
2673
2674QMenu *QLineEdit::createStandardContextMenu()
2675{
2676 Q_D(QLineEdit);
2677 QMenu *popup = new QMenu(this);
2678 popup->setObjectName(QLatin1String("qt_edit_menu"));
2679
2680 QAction *action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
2681 action->setEnabled(d->isUndoAvailable());
2682 connect(action, SIGNAL(triggered()), SLOT(undo()));
2683
2684 action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
2685 action->setEnabled(d->isRedoAvailable());
2686 connect(action, SIGNAL(triggered()), SLOT(redo()));
2687
2688 popup->addSeparator();
2689
2690#ifndef QT_NO_CLIPBOARD
2691 action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
2692 action->setEnabled(!d->readOnly && d->hasSelectedText());
2693 connect(action, SIGNAL(triggered()), SLOT(cut()));
2694
2695 action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
2696 action->setEnabled(d->hasSelectedText());
2697 connect(action, SIGNAL(triggered()), SLOT(copy()));
2698
2699 action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
2700 action->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty());
2701 connect(action, SIGNAL(triggered()), SLOT(paste()));
2702#endif
2703
2704 action = popup->addAction(QLineEdit::tr("Delete"));
2705 action->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText());
2706 connect(action, SIGNAL(triggered()), SLOT(_q_deleteSelected()));
2707
2708 popup->addSeparator();
2709
2710 action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
2711 action->setEnabled(!d->text.isEmpty() && !d->allSelected());
2712 d->selectAllAction = action;
2713 connect(action, SIGNAL(triggered()), SLOT(selectAll()));
2714
2715#if !defined(QT_NO_IM)
2716 QInputContext *qic = inputContext();
2717 if (qic) {
2718 QList<QAction *> imActions = qic->actions();
2719 for (int i = 0; i < imActions.size(); ++i)
2720 popup->addAction(imActions.at(i));
2721 }
2722#endif
2723
2724#if defined(Q_WS_WIN)
2725 if (!d->readOnly && qt_use_rtl_extensions) {
2726#else
2727 if (!d->readOnly) {
2728#endif
2729 popup->addSeparator();
2730 QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
2731 popup->addMenu(ctrlCharacterMenu);
2732 }
2733 return popup;
2734}
2735#endif // QT_NO_CONTEXTMENU
2736
2737/*! \reimp */
2738void QLineEdit::changeEvent(QEvent *ev)
2739{
2740 Q_D(QLineEdit);
2741 if(ev->type() == QEvent::ActivationChange) {
2742 if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
2743 update();
2744 } else if (ev->type() == QEvent::FontChange
2745 || ev->type() == QEvent::StyleChange
2746 || ev->type() == QEvent::LayoutDirectionChange) {
2747 d->updateTextLayout();
2748 }
2749 QWidget::changeEvent(ev);
2750}
2751
2752void QLineEditPrivate::_q_clipboardChanged()
2753{
2754}
2755
2756void QLineEditPrivate::_q_handleWindowActivate()
2757{
2758 Q_Q(QLineEdit);
2759 if (!q->hasFocus() && q->hasSelectedText())
2760 q->deselect();
2761}
2762
2763void QLineEditPrivate::_q_deleteSelected()
2764{
2765 Q_Q(QLineEdit);
2766 if (!hasSelectedText())
2767 return;
2768
2769 int priorState = undoState;
2770 q->resetInputContext();
2771 removeSelectedText();
2772 separate();
2773 finishChange(priorState);
2774}
2775
2776void QLineEditPrivate::init(const QString& txt)
2777{
2778 Q_Q(QLineEdit);
2779#ifndef QT_NO_CURSOR
2780 q->setCursor(Qt::IBeamCursor);
2781#endif
2782 q->setFocusPolicy(Qt::StrongFocus);
2783 q->setAttribute(Qt::WA_InputMethodEnabled);
2784 // Specifies that this widget can use more, but is able to survive on
2785 // less, horizontal space; and is fixed vertically.
2786 q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
2787 q->setBackgroundRole(QPalette::Base);
2788 q->setAttribute(Qt::WA_KeyCompression);
2789 q->setMouseTracking(true);
2790 q->setAcceptDrops(true);
2791 text = txt;
2792 updateTextLayout();
2793 cursor = text.length();
2794
2795 q->setAttribute(Qt::WA_MacShowFocusRect);
2796}
2797
2798void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
2799{
2800 Q_Q(QLineEdit);
2801 passwordEchoEditing = editing;
2802 q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q));
2803 updateTextLayout();
2804 q->update();
2805}
2806
2807void QLineEditPrivate::updateTextLayout()
2808{
2809 // replace certain non-printable characters with spaces (to avoid
2810 // drawing boxes when using fonts that don't have glyphs for such
2811 // characters)
2812 Q_Q(QLineEdit);
2813 QString str = q->displayText();
2814 QChar* uc = str.data();
2815 for (int i = 0; i < (int)str.length(); ++i) {
2816 if ((uc[i] < 0x20 && uc[i] != 0x09)
2817 || uc[i] == QChar::LineSeparator
2818 || uc[i] == QChar::ParagraphSeparator
2819 || uc[i] == QChar::ObjectReplacementCharacter)
2820 uc[i] = QChar(0x0020);
2821 }
2822 textLayout.setFont(q->font());
2823 textLayout.setText(str);
2824 QTextOption option;
2825 option.setTextDirection(q->layoutDirection());
2826 option.setFlags(QTextOption::IncludeTrailingSpaces);
2827 textLayout.setTextOption(option);
2828
2829 textLayout.beginLayout();
2830 QTextLine l = textLayout.createLine();
2831 textLayout.endLayout();
2832 ascent = qRound(l.ascent());
2833}
2834
2835int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
2836{
2837 QRect cr = adjustedContentsRect();
2838 x-= cr.x() - hscroll + horizontalMargin;
2839 QTextLine l = textLayout.lineAt(0);
2840 return l.xToCursor(x, betweenOrOn);
2841}
2842
2843QRect QLineEditPrivate::cursorRect() const
2844{
2845 Q_Q(const QLineEdit);
2846 QRect cr = adjustedContentsRect();
2847 int cix = cr.x() - hscroll + horizontalMargin;
2848 QTextLine l = textLayout.lineAt(0);
2849 int c = cursor;
2850 if (preeditCursor != -1)
2851 c += preeditCursor;
2852 cix += qRound(l.cursorToX(c));
2853 int ch = qMin(cr.height(), q->fontMetrics().height() + 1);
2854 int w = q->style()->pixelMetric(QStyle::PM_TextCursorWidth);
2855 return QRect(cix-5, vscroll, w + 9, ch);
2856}
2857
2858QRect QLineEditPrivate::adjustedContentsRect() const
2859{
2860 Q_Q(const QLineEdit);
2861 QStyleOptionFrameV2 opt;
2862 q->initStyleOption(&opt);
2863 QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
2864 r.setX(r.x() + leftTextMargin);
2865 r.setY(r.y() + topTextMargin);
2866 r.setRight(r.right() - rightTextMargin);
2867 r.setBottom(r.bottom() - bottomTextMargin);
2868 return r;
2869}
2870
2871bool QLineEditPrivate::fixup() // this function assumes that validate currently returns != Acceptable
2872{
2873#ifndef QT_NO_VALIDATOR
2874 if (validator) {
2875 QString textCopy = text;
2876 int cursorCopy = cursor;
2877 validator->fixup(textCopy);
2878 if (validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
2879 if (textCopy != text || cursorCopy != cursor)
2880 setText(textCopy, cursorCopy);
2881 return true;
2882 }
2883 }
2884#endif
2885 return false;
2886}
2887
2888void QLineEditPrivate::moveCursor(int pos, bool mark)
2889{
2890 Q_Q(QLineEdit);
2891 if (pos != cursor) {
2892 separate();
2893 if (maskData)
2894 pos = pos > cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
2895 }
2896 bool fullUpdate = mark || hasSelectedText();
2897 if (mark) {
2898 int anchor;
2899 if (selend > selstart && cursor == selstart)
2900 anchor = selend;
2901 else if (selend > selstart && cursor == selend)
2902 anchor = selstart;
2903 else
2904 anchor = cursor;
2905 selstart = qMin(anchor, pos);
2906 selend = qMax(anchor, pos);
2907 updateTextLayout();
2908 } else {
2909 deselect();
2910 }
2911 if (fullUpdate) {
2912 cursor = pos;
2913 q->update();
2914 } else {
2915 setCursorVisible(false);
2916 cursor = pos;
2917 setCursorVisible(true);
2918 if (!adjustedContentsRect().contains(cursorRect()))
2919 q->update();
2920 }
2921 QStyleOptionFrameV2 opt;
2922 q->initStyleOption(&opt);
2923 if (mark && !q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q))
2924 setCursorVisible(false);
2925 if (mark || selDirty) {
2926 selDirty = false;
2927 emit q->selectionChanged();
2928 }
2929 emitCursorPositionChanged();
2930}
2931
2932void QLineEditPrivate::finishChange(int validateFromState, bool update, bool edited)
2933{
2934 Q_Q(QLineEdit);
2935 bool lineDirty = selDirty;
2936 if (textDirty) {
2937 // do validation
2938 bool wasValidInput = validInput;
2939 validInput = true;
2940#ifndef QT_NO_VALIDATOR
2941 if (validator) {
2942 validInput = false;
2943 QString textCopy = text;
2944 int cursorCopy = cursor;
2945 validInput = (validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
2946 if (validInput) {
2947 if (text != textCopy) {
2948 setText(textCopy, cursorCopy);
2949 return;
2950 }
2951 cursor = cursorCopy;
2952 }
2953 }
2954#endif
2955 if (validateFromState >= 0 && wasValidInput && !validInput) {
2956 undo(validateFromState);
2957 history.resize(undoState);
2958 if (modifiedState > undoState)
2959 modifiedState = -1;
2960 validInput = true;
2961 textDirty = false;
2962 }
2963 updateTextLayout();
2964 lineDirty |= textDirty;
2965 if (textDirty) {
2966 textDirty = false;
2967 QString actualText = maskData ? stripString(text) : text;
2968 if (edited)
2969 emit q->textEdited(actualText);
2970 q->updateMicroFocus();
2971#ifndef QT_NO_COMPLETER
2972 if (edited && completer && completer->completionMode() != QCompleter::InlineCompletion)
2973 complete(-1); // update the popup on cut/paste/del
2974#endif
2975 emit q->textChanged(actualText);
2976 }
2977#ifndef QT_NO_ACCESSIBILITY
2978 QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
2979#endif
2980 }
2981 if (selDirty) {
2982 selDirty = false;
2983 emit q->selectionChanged();
2984 }
2985 if (lineDirty || update)
2986 q->update();
2987 emitCursorPositionChanged();
2988}
2989
2990void QLineEditPrivate::emitCursorPositionChanged()
2991{
2992 Q_Q(QLineEdit);
2993 if (cursor != lastCursorPos) {
2994 const int oldLast = lastCursorPos;
2995 lastCursorPos = cursor;
2996 emit q->cursorPositionChanged(oldLast, cursor);
2997 }
2998}
2999
3000void QLineEditPrivate::setText(const QString& txt, int pos, bool edited)
3001{
3002 Q_Q(QLineEdit);
3003 q->resetInputContext();
3004 deselect();
3005 QString oldText = text;
3006 if (maskData) {
3007 text = maskString(0, txt, true);
3008 text += clearString(text.length(), maxLength - text.length());
3009 } else {
3010 text = txt.isEmpty() ? txt : txt.left(maxLength);
3011 }
3012 history.clear();
3013 modifiedState = undoState = 0;
3014 cursor = (pos < 0 || pos > text.length()) ? text.length() : pos;
3015 textDirty = (oldText != text);
3016 finishChange(-1, true, edited);
3017}
3018
3019
3020void QLineEditPrivate::setCursorVisible(bool visible)
3021{
3022 Q_Q(QLineEdit);
3023 if ((bool)cursorVisible == visible)
3024 return;
3025 if (cursorTimer)
3026 cursorVisible = visible;
3027 QRect r = cursorRect();
3028 if (maskData)
3029 q->update();
3030 else
3031 q->update(r);
3032}
3033
3034void QLineEditPrivate::addCommand(const Command& cmd)
3035{
3036 if (separator && undoState && history[undoState-1].type != Separator) {
3037 history.resize(undoState + 2);
3038 history[undoState++] = Command(Separator, cursor, 0, selstart, selend);
3039 } else {
3040 history.resize(undoState + 1);
3041 }
3042 separator = false;
3043 history[undoState++] = cmd;
3044}
3045
3046void QLineEditPrivate::insert(const QString& s)
3047{
3048 if (hasSelectedText())
3049 addCommand(Command(SetSelection, cursor, 0, selstart, selend));
3050 if (maskData) {
3051 QString ms = maskString(cursor, s);
3052 for (int i = 0; i < (int) ms.length(); ++i) {
3053 addCommand (Command(DeleteSelection, cursor+i, text.at(cursor+i), -1, -1));
3054 addCommand(Command(Insert, cursor+i, ms.at(i), -1, -1));
3055 }
3056 text.replace(cursor, ms.length(), ms);
3057 cursor += ms.length();
3058 cursor = nextMaskBlank(cursor);
3059 textDirty = true;
3060 } else {
3061 int remaining = maxLength - text.length();
3062 if (remaining != 0) {
3063 text.insert(cursor, s.left(remaining));
3064 for (int i = 0; i < (int) s.left(remaining).length(); ++i)
3065 addCommand(Command(Insert, cursor++, s.at(i), -1, -1));
3066 textDirty = true;
3067 }
3068 }
3069}
3070
3071void QLineEditPrivate::del(bool wasBackspace)
3072{
3073 if (cursor < (int) text.length()) {
3074 if (hasSelectedText())
3075 addCommand(Command(SetSelection, cursor, 0, selstart, selend));
3076 addCommand (Command((CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor), -1, -1));
3077 if (maskData) {
3078 text.replace(cursor, 1, clearString(cursor, 1));
3079 addCommand(Command(Insert, cursor, text.at(cursor), -1, -1));
3080 } else {
3081 text.remove(cursor, 1);
3082 }
3083 textDirty = true;
3084 }
3085}
3086
3087void QLineEditPrivate::removeSelectedText()
3088{
3089 if (selstart < selend && selend <= (int) text.length()) {
3090 separate();
3091 int i ;
3092 addCommand(Command(SetSelection, cursor, 0, selstart, selend));
3093 if (selstart <= cursor && cursor < selend) {
3094 // cursor is within the selection. Split up the commands
3095 // to be able to restore the correct cursor position
3096 for (i = cursor; i >= selstart; --i)
3097 addCommand (Command(DeleteSelection, i, text.at(i), -1, 1));
3098 for (i = selend - 1; i > cursor; --i)
3099 addCommand (Command(DeleteSelection, i - cursor + selstart - 1, text.at(i), -1, -1));
3100 } else {
3101 for (i = selend-1; i >= selstart; --i)
3102 addCommand (Command(RemoveSelection, i, text.at(i), -1, -1));
3103 }
3104 if (maskData) {
3105 text.replace(selstart, selend - selstart, clearString(selstart, selend - selstart));
3106 for (int i = 0; i < selend - selstart; ++i)
3107 addCommand(Command(Insert, selstart + i, text.at(selstart + i), -1, -1));
3108 } else {
3109 text.remove(selstart, selend - selstart);
3110 }
3111 if (cursor > selstart)
3112 cursor -= qMin(cursor, selend) - selstart;
3113 deselect();
3114 textDirty = true;
3115
3116 // adjust hscroll to avoid gap
3117 const int minRB = qMax(0, -q_func()->fontMetrics().minRightBearing());
3118 updateTextLayout();
3119 const QTextLine line = textLayout.lineAt(0);
3120 const int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
3121 hscroll = qMin(hscroll, widthUsed);
3122 }
3123}
3124
3125void QLineEditPrivate::parseInputMask(const QString &maskFields)
3126{
3127 int delimiter = maskFields.indexOf(QLatin1Char(';'));
3128 if (maskFields.isEmpty() || delimiter == 0) {
3129 if (maskData) {
3130 delete [] maskData;
3131 maskData = 0;
3132 maxLength = 32767;
3133 setText(QString());
3134 }
3135 return;
3136 }
3137
3138 if (delimiter == -1) {
3139 blank = QLatin1Char(' ');
3140 inputMask = maskFields;
3141 } else {
3142 inputMask = maskFields.left(delimiter);
3143 blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
3144 }
3145
3146 // calculate maxLength / maskData length
3147 maxLength = 0;
3148 QChar c = 0;
3149 for (int i=0; i<inputMask.length(); i++) {
3150 c = inputMask.at(i);
3151 if (i > 0 && inputMask.at(i-1) == QLatin1Char('\\')) {
3152 maxLength++;
3153 continue;
3154 }
3155 if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
3156 c != QLatin1Char('<') && c != QLatin1Char('>') &&
3157 c != QLatin1Char('{') && c != QLatin1Char('}') &&
3158 c != QLatin1Char('[') && c != QLatin1Char(']'))
3159 maxLength++;
3160 }
3161
3162 delete [] maskData;
3163 maskData = new MaskInputData[maxLength];
3164
3165 MaskInputData::Casemode m = MaskInputData::NoCaseMode;
3166 c = 0;
3167 bool s;
3168 bool escape = false;
3169 int index = 0;
3170 for (int i = 0; i < inputMask.length(); i++) {
3171 c = inputMask.at(i);
3172 if (escape) {
3173 s = true;
3174 maskData[index].maskChar = c;
3175 maskData[index].separator = s;
3176 maskData[index].caseMode = m;
3177 index++;
3178 escape = false;
3179 } else if (c == QLatin1Char('<')) {
3180 m = MaskInputData::Lower;
3181 } else if (c == QLatin1Char('>')) {
3182 m = MaskInputData::Upper;
3183 } else if (c == QLatin1Char('!')) {
3184 m = MaskInputData::NoCaseMode;
3185 } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
3186 switch (c.unicode()) {
3187 case 'A':
3188 case 'a':
3189 case 'N':
3190 case 'n':
3191 case 'X':
3192 case 'x':
3193 case '9':
3194 case '0':
3195 case 'D':
3196 case 'd':
3197 case '#':
3198 case 'H':
3199 case 'h':
3200 case 'B':
3201 case 'b':
3202 s = false;
3203 break;
3204 case '\\':
3205 escape = true;
3206 default:
3207 s = true;
3208 break;
3209 }
3210
3211 if (!escape) {
3212 maskData[index].maskChar = c;
3213 maskData[index].separator = s;
3214 maskData[index].caseMode = m;
3215 index++;
3216 }
3217 }
3218 }
3219 setText(text);
3220}
3221
3222
3223/* checks if the key is valid compared to the inputMask */
3224bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const
3225{
3226 switch (mask.unicode()) {
3227 case 'A':
3228 if (key.isLetter())
3229 return true;
3230 break;
3231 case 'a':
3232 if (key.isLetter() || key == blank)
3233 return true;
3234 break;
3235 case 'N':
3236 if (key.isLetterOrNumber())
3237 return true;
3238 break;
3239 case 'n':
3240 if (key.isLetterOrNumber() || key == blank)
3241 return true;
3242 break;
3243 case 'X':
3244 if (key.isPrint())
3245 return true;
3246 break;
3247 case 'x':
3248 if (key.isPrint() || key == blank)
3249 return true;
3250 break;
3251 case '9':
3252 if (key.isNumber())
3253 return true;
3254 break;
3255 case '0':
3256 if (key.isNumber() || key == blank)
3257 return true;
3258 break;
3259 case 'D':
3260 if (key.isNumber() && key.digitValue() > 0)
3261 return true;
3262 break;
3263 case 'd':
3264 if ((key.isNumber() && key.digitValue() > 0) || key == blank)
3265 return true;
3266 break;
3267 case '#':
3268 if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == blank)
3269 return true;
3270 break;
3271 case 'B':
3272 if (key == QLatin1Char('0') || key == QLatin1Char('1'))
3273 return true;
3274 break;
3275 case 'b':
3276 if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == blank)
3277 return true;
3278 break;
3279 case 'H':
3280 if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
3281 return true;
3282 break;
3283 case 'h':
3284 if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == blank)
3285 return true;
3286 break;
3287 default:
3288 break;
3289 }
3290 return false;
3291}
3292
3293bool QLineEditPrivate::hasAcceptableInput(const QString &str) const
3294{
3295#ifndef QT_NO_VALIDATOR
3296 QString textCopy = str;
3297 int cursorCopy = cursor;
3298 if (validator && validator->validate(textCopy, cursorCopy)
3299 != QValidator::Acceptable)
3300 return false;
3301#endif
3302
3303 if (!maskData)
3304 return true;
3305
3306 if (str.length() != maxLength)
3307 return false;
3308
3309 for (int i=0; i < maxLength; ++i) {
3310 if (maskData[i].separator) {
3311 if (str.at(i) != maskData[i].maskChar)
3312 return false;
3313 } else {
3314 if (!isValidInput(str.at(i), maskData[i].maskChar))
3315 return false;
3316 }
3317 }
3318 return true;
3319}
3320
3321/*
3322 Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
3323 specifies from where characters should be gotten when a separator is met in \a str - true means
3324 that blanks will be used, false that previous input is used.
3325 Calling this when no inputMask is set is undefined.
3326*/
3327QString QLineEditPrivate::maskString(uint pos, const QString &str, bool clear) const
3328{
3329 if (pos >= (uint)maxLength)
3330 return QString::fromLatin1("");
3331
3332 QString fill;
3333 fill = clear ? clearString(0, maxLength) : text;
3334
3335 int strIndex = 0;
3336 QString s = QString::fromLatin1("");
3337 int i = pos;
3338 while (i < maxLength) {
3339 if (strIndex < str.length()) {
3340 if (maskData[i].separator) {
3341 s += maskData[i].maskChar;
3342 if (str[(int)strIndex] == maskData[i].maskChar)
3343 strIndex++;
3344 ++i;
3345 } else {
3346 if (isValidInput(str[(int)strIndex], maskData[i].maskChar)) {
3347 switch (maskData[i].caseMode) {
3348 case MaskInputData::Upper:
3349 s += str[(int)strIndex].toUpper();
3350 break;
3351 case MaskInputData::Lower:
3352 s += str[(int)strIndex].toLower();
3353 break;
3354 default:
3355 s += str[(int)strIndex];
3356 }
3357 ++i;
3358 } else {
3359 // search for separator first
3360 int n = findInMask(i, true, true, str[(int)strIndex]);
3361 if (n != -1) {
3362 if (str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex]))) {
3363 s += fill.mid(i, n-i+1);
3364 i = n + 1; // update i to find + 1
3365 }
3366 } else {
3367 // search for valid blank if not
3368 n = findInMask(i, true, false, str[(int)strIndex]);
3369 if (n != -1) {
3370 s += fill.mid(i, n-i);
3371 switch (maskData[n].caseMode) {
3372 case MaskInputData::Upper:
3373 s += str[(int)strIndex].toUpper();
3374 break;
3375 case MaskInputData::Lower:
3376 s += str[(int)strIndex].toLower();
3377 break;
3378 default:
3379 s += str[(int)strIndex];
3380 }
3381 i = n + 1; // updates i to find + 1
3382 }
3383 }
3384 }
3385 strIndex++;
3386 }
3387 } else
3388 break;
3389 }
3390
3391 return s;
3392}
3393
3394
3395
3396/*
3397 Returns a "cleared" string with only separators and blank chars.
3398 Calling this when no inputMask is set is undefined.
3399*/
3400QString QLineEditPrivate::clearString(uint pos, uint len) const
3401{
3402 if (pos >= (uint)maxLength)
3403 return QString();
3404
3405 QString s;
3406 int end = qMin((uint)maxLength, pos + len);
3407 for (int i=pos; i<end; i++)
3408 if (maskData[i].separator)
3409 s += maskData[i].maskChar;
3410 else
3411 s += blank;
3412
3413 return s;
3414}
3415
3416/*
3417 Strips blank parts of the input in a QLineEdit when an inputMask is set,
3418 separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
3419*/
3420QString QLineEditPrivate::stripString(const QString &str) const
3421{
3422 if (!maskData)
3423 return str;
3424
3425 QString s;
3426 int end = qMin(maxLength, (int)str.length());
3427 for (int i=0; i < end; i++)
3428 if (maskData[i].separator)
3429 s += maskData[i].maskChar;
3430 else
3431 if (str[i] != blank)
3432 s += str[i];
3433
3434 return s;
3435}
3436
3437/* searches forward/backward in maskData for either a separator or a blank */
3438int QLineEditPrivate::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
3439{
3440 if (pos >= maxLength || pos < 0)
3441 return -1;
3442
3443 int end = forward ? maxLength : -1;
3444 int step = forward ? 1 : -1;
3445 int i = pos;
3446
3447 while (i != end) {
3448 if (findSeparator) {
3449 if (maskData[i].separator && maskData[i].maskChar == searchChar)
3450 return i;
3451 } else {
3452 if (!maskData[i].separator) {
3453 if (searchChar.isNull())
3454 return i;
3455 else if (isValidInput(searchChar, maskData[i].maskChar))
3456 return i;
3457 }
3458 }
3459 i += step;
3460 }
3461 return -1;
3462}
3463
3464void QLineEditPrivate::undo(int until)
3465{
3466 if (!isUndoAvailable())
3467 return;
3468 deselect();
3469 while (undoState && undoState > until) {
3470 Command& cmd = history[--undoState];
3471 switch (cmd.type) {
3472 case Insert:
3473 text.remove(cmd.pos, 1);
3474 cursor = cmd.pos;
3475 break;
3476 case SetSelection:
3477 selstart = cmd.selStart;
3478 selend = cmd.selEnd;
3479 cursor = cmd.pos;
3480 break;
3481 case Remove:
3482 case RemoveSelection:
3483 text.insert(cmd.pos, cmd.uc);
3484 cursor = cmd.pos + 1;
3485 break;
3486 case Delete:
3487 case DeleteSelection:
3488 text.insert(cmd.pos, cmd.uc);
3489 cursor = cmd.pos;
3490 break;
3491 case Separator:
3492 continue;
3493 }
3494 if (until < 0 && undoState) {
3495 Command& next = history[undoState-1];
3496 if (next.type != cmd.type && next.type < RemoveSelection
3497 && (cmd.type < RemoveSelection || next.type == Separator))
3498 break;
3499 }
3500 }
3501 textDirty = true;
3502 emitCursorPositionChanged();
3503}
3504
3505void QLineEditPrivate::redo() {
3506 if (!isRedoAvailable())
3507 return;
3508 deselect();
3509 while (undoState < (int)history.size()) {
3510 Command& cmd = history[undoState++];
3511 switch (cmd.type) {
3512 case Insert:
3513 text.insert(cmd.pos, cmd.uc);
3514 cursor = cmd.pos + 1;
3515 break;
3516 case SetSelection:
3517 selstart = cmd.selStart;
3518 selend = cmd.selEnd;
3519 cursor = cmd.pos;
3520 break;
3521 case Remove:
3522 case Delete:
3523 case RemoveSelection:
3524 case DeleteSelection:
3525 text.remove(cmd.pos, 1);
3526 cursor = cmd.pos;
3527 break;
3528 case Separator:
3529 selstart = cmd.selStart;
3530 selend = cmd.selEnd;
3531 cursor = cmd.pos;
3532 break;
3533 }
3534 if (undoState < (int)history.size()) {
3535 Command& next = history[undoState];
3536 if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
3537 && (next.type < RemoveSelection || cmd.type == Separator))
3538 break;
3539 }
3540 }
3541 textDirty = true;
3542 emitCursorPositionChanged();
3543}
3544
3545/*!
3546 \fn void QLineEdit::repaintArea(int a, int b)
3547
3548 Use update() instead.
3549*/
3550
3551/*!
3552 \fn void QLineEdit::cursorLeft(bool mark, int steps)
3553
3554 Use cursorForward() with a negative number of steps instead. For
3555 example, cursorForward(mark, -steps).
3556*/
3557
3558/*!
3559 \fn void QLineEdit::cursorRight(bool mark, int steps)
3560
3561 Use cursorForward() instead.
3562*/
3563
3564/*!
3565 \fn bool QLineEdit::frame() const
3566
3567 Use hasFrame() instead.
3568*/
3569
3570/*!
3571 \fn void QLineEdit::clearValidator()
3572
3573 Use setValidator(0) instead.
3574*/
3575
3576/*!
3577 \fn bool QLineEdit::hasMarkedText() const
3578
3579 Use hasSelectedText() instead.
3580*/
3581
3582/*!
3583 \fn QString QLineEdit::markedText() const
3584
3585 Use selectedText() instead.
3586*/
3587
3588/*!
3589 \fn void QLineEdit::setFrameRect(QRect)
3590 \internal
3591*/
3592
3593/*!
3594 \fn QRect QLineEdit::frameRect() const
3595 \internal
3596*/
3597/*!
3598 \enum QLineEdit::DummyFrame
3599 \internal
3600
3601 \value Box
3602 \value Sunken
3603 \value Plain
3604 \value Raised
3605 \value MShadow
3606 \value NoFrame
3607 \value Panel
3608 \value StyledPanel
3609 \value HLine
3610 \value VLine
3611 \value GroupBoxPanel
3612 \value WinPanel
3613 \value ToolBarPanel
3614 \value MenuBarPanel
3615 \value PopupPanel
3616 \value LineEditPanel
3617 \value TabWidgetPanel
3618 \value MShape
3619*/
3620
3621/*!
3622 \fn void QLineEdit::setFrameShadow(DummyFrame)
3623 \internal
3624*/
3625
3626/*!
3627 \fn DummyFrame QLineEdit::frameShadow() const
3628 \internal
3629*/
3630
3631/*!
3632 \fn void QLineEdit::setFrameShape(DummyFrame)
3633 \internal
3634*/
3635
3636/*!
3637 \fn DummyFrame QLineEdit::frameShape() const
3638 \internal
3639*/
3640
3641/*!
3642 \fn void QLineEdit::setFrameStyle(int)
3643 \internal
3644*/
3645
3646/*!
3647 \fn int QLineEdit::frameStyle() const
3648 \internal
3649*/
3650
3651/*!
3652 \fn int QLineEdit::frameWidth() const
3653 \internal
3654*/
3655
3656/*!
3657 \fn void QLineEdit::setLineWidth(int)
3658 \internal
3659*/
3660
3661/*!
3662 \fn int QLineEdit::lineWidth() const
3663 \internal
3664*/
3665
3666/*!
3667 \fn void QLineEdit::setMargin(int margin)
3668 Sets the width of the margin around the contents of the widget to \a margin.
3669
3670 Use QWidget::setContentsMargins() instead.
3671 \sa margin(), QWidget::setContentsMargins()
3672*/
3673
3674/*!
3675 \fn int QLineEdit::margin() const
3676 Returns the with of the the margin around the contents of the widget.
3677
3678 Use QWidget::getContentsMargins() instead.
3679 \sa setMargin(), QWidget::getContentsMargins()
3680*/
3681
3682/*!
3683 \fn void QLineEdit::setMidLineWidth(int)
3684 \internal
3685*/
3686
3687/*!
3688 \fn int QLineEdit::midLineWidth() const
3689 \internal
3690*/
3691
3692QT_END_NAMESPACE
3693
3694#include "moc_qlineedit.cpp"
3695
3696#endif // QT_NO_LINEEDIT
Note: See TracBrowser for help on using the repository browser.