Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qlineedit.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8080#include "private/qshortcutmap_p.h"
    8181#include "qkeysequence.h"
    82 #define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString())
     82#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
    8383#else
    8484#define ACCEL_KEY(k) QString()
     
    8787#include <limits.h>
    8888
    89 #define verticalMargin 1
    90 #define horizontalMargin 2
    91 
    9289QT_BEGIN_NAMESPACE
    9390
     
    9592extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
    9693#endif
    97 
    98 static inline bool shouldEnableInputMethod(QLineEdit *lineedit)
    99 {
    100     const QLineEdit::EchoMode mode = lineedit->echoMode();
    101     return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit);
    102 }
    10394
    10495/*!
     
    123114    option->midLineWidth = 0;
    124115    option->state |= QStyle::State_Sunken;
    125     if (d->readOnly)
     116    if (d->control->isReadOnly())
    126117        option->state |= QStyle::State_ReadOnly;
    127118#ifdef QT_KEYPAD_NAVIGATION
     
    138129
    139130    \ingroup basicwidgets
    140     \mainclass
     131
    141132
    142133    A line edit allows the user to enter and edit a single line of
     
    351342    Q_D(QLineEdit);
    352343    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     }
     344    d->init(contents);
     345    d->control->setInputMask(inputMask);
     346    d->control->moveCursor(d->control->nextMaskBlank(contents.length()));
    361347}
    362348#endif
     
    389375{
    390376    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);
     377    return d->control->text();
    395378}
    396379
     
    398381{
    399382    Q_D(QLineEdit);
    400     d->setText(text, -1, false);
    401 #ifdef QT_KEYPAD_NAVIGATION
    402     d->origText = d->text;
    403 #endif
    404 }
    405 
     383    d->control->setText(text);
     384}
     385
     386// ### Qt 4.7: remove this #if guard
     387#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
     388/*!
     389    \since 4.7
     390
     391    \property QLineEdit::placeholderText
     392    \brief the line edit's placeholder text
     393
     394    Setting this property makes the line edit display a grayed-out
     395    placeholder text as long as the text() is empty and the widget doesn't
     396    have focus.
     397
     398    By default, this property contains an empty string.
     399
     400    \sa text()
     401*/
     402QString QLineEdit::placeholderText() const
     403{
     404    Q_D(const QLineEdit);
     405    return d->placeholderText;
     406}
     407
     408void QLineEdit::setPlaceholderText(const QString& placeholderText)
     409{
     410    Q_D(QLineEdit);
     411    if (d->placeholderText != placeholderText) {
     412        d->placeholderText = placeholderText;
     413        if (!hasFocus())
     414            update();
     415    }
     416}
     417#endif
    406418
    407419/*!
     
    422434{
    423435    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);
     436    return d->control->displayText();
    435437}
    436438
     
    457459{
    458460    Q_D(const QLineEdit);
    459     return d->maxLength;
     461    return d->control->maxLength();
    460462}
    461463
     
    463465{
    464466    Q_D(QLineEdit);
    465     if (d->maskData)
    466         return;
    467     d->maxLength = maxLength;
    468     setText(d->text);
    469 }
    470 
    471 
     467    d->control->setMaxLength(maxLength);
     468}
    472469
    473470/*!
     
    537534{
    538535    Q_D(const QLineEdit);
    539     return (EchoMode) d->echoMode;
     536    return (EchoMode) d->control->echoMode();
    540537}
    541538
     
    543540{
    544541    Q_D(QLineEdit);
    545     if (mode == (EchoMode)d->echoMode)
     542    if (mode == (EchoMode)d->control->echoMode())
    546543        return;
    547     setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
    548     d->echoMode = mode;
    549     d->passwordEchoEditing = false;
    550     d->updateTextLayout();
     544    Qt::InputMethodHints imHints = inputMethodHints();
     545    if (mode == Password) {
     546        imHints |= Qt::ImhHiddenText;
     547    } else {
     548        imHints &= ~Qt::ImhHiddenText;
     549    }
     550    setInputMethodHints(imHints);
     551    d->control->setEchoMode(mode);
    551552    update();
    552553#ifdef Q_WS_MAC
    553554    if (hasFocus())
    554         qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho);
     555        qt_mac_secure_keyboard(mode == Password || mode == NoEcho);
    555556#endif
    556557}
     
    568569{
    569570    Q_D(const QLineEdit);
    570     return d->validator;
     571    return d->control->validator();
    571572}
    572573
     
    586587{
    587588    Q_D(QLineEdit);
    588     d->validator = const_cast<QValidator*>(v);
     589    d->control->setValidator(v);
    589590}
    590591#endif // QT_NO_VALIDATOR
     
    610611{
    611612    Q_D(QLineEdit);
    612     if (c == d->completer)
     613    if (c == d->control->completer())
    613614        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;
     615    if (d->control->completer()) {
     616        disconnect(d->control->completer(), 0, this, 0);
     617        d->control->completer()->setWidget(0);
     618        if (d->control->completer()->parent() == this)
     619            delete d->control->completer();
     620    }
     621    d->control->setCompleter(c);
    621622    if (!c)
    622623        return;
     
    624625        c->setWidget(this);
    625626    if (hasFocus()) {
    626         QObject::connect(d->completer, SIGNAL(activated(QString)),
     627        QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
    627628                         this, SLOT(setText(QString)));
    628         QObject::connect(d->completer, SIGNAL(highlighted(QString)),
     629        QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
    629630                         this, SLOT(_q_completionHighlighted(QString)));
    630631    }
     
    639640{
    640641    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.
    646 bool 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 
    670 void 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 
    707 void 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 }
     642    return d->control->completer();
     643}
     644
    718645#endif // QT_NO_COMPLETER
    719646
     
    730657    ensurePolished();
    731658    QFontMetrics fm(font());
    732     int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin
     659    int h = qMax(fm.height(), 14) + 2*d->verticalMargin
    733660            + d->topTextMargin + d->bottomTextMargin
    734661            + d->topmargin + d->bottommargin;
    735     int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin
     662    int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
    736663            + d->leftTextMargin + d->rightTextMargin
    737664            + d->leftmargin + d->rightmargin; // "some"
     
    754681    ensurePolished();
    755682    QFontMetrics fm = fontMetrics();
    756     int h = fm.height() + qMax(2*verticalMargin, fm.leading())
     683    int h = fm.height() + qMax(2*d->verticalMargin, fm.leading())
    757684            + d->topmargin + d->bottommargin;
    758685    int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
     
    776703{
    777704    Q_D(const QLineEdit);
    778     return d->cursor;
     705    return d->control->cursorPosition();
    779706}
    780707
     
    782709{
    783710    Q_D(QLineEdit);
    784     if (pos < 0)
    785         pos = 0;
    786 
    787     if (pos <= d->text.length())
    788         d->moveCursor(pos);
     711    d->control->setCursorPosition(pos);
    789712}
    790713
     
    808731                                 int newMarkAnchor, int newMarkDrag)
    809732{
    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;
     733    // The suggested functions above in the docs don't seem to validate,
     734    // below code tries to mimic previous behaviour.
     735    QString oldText = text();
     736    setText(newText);
     737    if(!hasAcceptableInput()){
     738        setText(oldText);
     739        return false;
     740    }
     741    setCursorPosition(newPos);
     742    setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag));
     743    return true;
    826744}
    827745#endif //QT3_SUPPORT
     
    864782{
    865783    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);
     784    d->control->cursorForward(mark, steps);
    875785}
    876786
     
    897807{
    898808    Q_D(QLineEdit);
    899     d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
     809    d->control->cursorWordForward(mark);
    900810}
    901811
     
    910820{
    911821    Q_D(QLineEdit);
    912     d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
     822    d->control->cursorWordBackward(mark);
    913823}
    914824
     
    925835{
    926836    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);
     837    d->control->backspace();
    947838}
    948839
     
    958849{
    959850    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);
     851    d->control->del();
    969852}
    970853
     
    981864{
    982865    Q_D(QLineEdit);
    983     d->moveCursor(0, mark);
     866    d->control->home(mark);
    984867}
    985868
     
    996879{
    997880    Q_D(QLineEdit);
    998     d->moveCursor(d->text.length(), mark);
     881    d->control->end(mark);
    999882}
    1000883
     
    1021904{
    1022905    Q_D(const QLineEdit);
    1023     return d->modifiedState != d->undoState;
     906    return d->control->isModified();
    1024907}
    1025908
     
    1027910{
    1028911    Q_D(QLineEdit);
    1029     if (modified)
    1030         d->modifiedState = -1;
    1031     else
    1032         d->modifiedState = d->undoState;
     912    d->control->setModified(modified);
    1033913}
    1034914
     
    1058938{
    1059939    Q_D(const QLineEdit);
    1060     return d->hasSelectedText();
     940    return d->control->hasSelectedText();
    1061941}
    1062942
     
    1076956{
    1077957    Q_D(const QLineEdit);
    1078     if (d->hasSelectedText())
    1079         return d->text.mid(d->selstart, d->selend - d->selstart);
    1080     return QString();
     958    return d->control->selectedText();
    1081959}
    1082960
     
    1091969{
    1092970    Q_D(const QLineEdit);
    1093     return d->hasSelectedText() ? d->selstart : -1;
     971    return d->control->selectionStart();
    1094972}
    1095973
     
    1121999{
    11221000    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);
     1001    int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin);
     1002    QString txt = d->control->text();
     1003    if (chr && pos < (int) txt.length())
     1004        *chr = txt.at(pos);
    11261005    return pos;
    11271006
     
    11341013{
    11351014    Q_D(QLineEdit);
    1136     if (d->hasSelectedText() && start && end) {
    1137         *start = d->selstart;
    1138         *end = d->selend;
     1015    if (d->control->hasSelectedText() && start && end) {
     1016        *start = selectionStart();
     1017        *end = *start + selectedText().length();
    11391018        return true;
    11401019    }
     
    11541033{
    11551034    Q_D(QLineEdit);
    1156     if (start < 0 || start > (int)d->text.length()) {
     1035    if (start < 0 || start > (int)d->control->text().length()) {
    11571036        qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
    11581037        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()){
     1038    }
     1039
     1040    d->control->setSelection(start, length);
     1041
     1042    if (d->control->hasSelectedText()){
    11721043        QStyleOptionFrameV2 opt;
    11731044        initStyleOption(&opt);
     
    11751046            d->setCursorVisible(false);
    11761047    }
    1177 
    1178     update();
    1179     d->emitCursorPositionChanged();
    11801048}
    11811049
     
    11931061{
    11941062    Q_D(const QLineEdit);
    1195     return d->isUndoAvailable();
     1063    return d->control->isUndoAvailable();
    11961064}
    11971065
     
    12091077{
    12101078    Q_D(const QLineEdit);
    1211     return d->isRedoAvailable();
     1079    return d->control->isRedoAvailable();
    12121080}
    12131081
     
    12451113{
    12461114    Q_D(const QLineEdit);
    1247     return d->hasAcceptableInput(d->text);
     1115    return d->control->hasAcceptableInput();
    12481116}
    12491117
     
    12641132    updateGeometry();
    12651133    update();
     1134}
     1135
     1136/*!
     1137    \since 4.6
     1138    Sets the \a margins around the text inside the frame.
     1139
     1140    See also textMargins().
     1141*/
     1142void QLineEdit::setTextMargins(const QMargins &margins)
     1143{
     1144    setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
    12661145}
    12671146
     
    12831162    if (bottom)
    12841163        *bottom = d->bottomTextMargin;
     1164}
     1165
     1166/*!
     1167    \since 4.6
     1168    Returns the widget's text margins.
     1169
     1170    \sa setTextMargins()
     1171*/
     1172QMargins QLineEdit::textMargins() const
     1173{
     1174    Q_D(const QLineEdit);
     1175    return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin);
    12851176}
    12861177
     
    13511242{
    13521243    Q_D(const QLineEdit);
    1353     return (d->maskData ? d->inputMask + QLatin1Char(';') + d->blank : QString());
     1244    return d->control->inputMask();
    13541245}
    13551246
     
    13571248{
    13581249    Q_D(QLineEdit);
    1359     d->parseInputMask(inputMask);
    1360     if (d->maskData)
    1361         d->moveCursor(d->nextMaskBlank(0));
     1250    d->control->setInputMask(inputMask);
    13621251}
    13631252
     
    13741263{
    13751264    Q_D(QLineEdit);
    1376     d->selstart = d->selend = d->cursor = 0;
    1377     d->moveCursor(d->text.length(), true);
     1265    d->control->selectAll();
    13781266}
    13791267
     
    13871275{
    13881276    Q_D(QLineEdit);
    1389     d->deselect();
    1390     d->finishChange();
     1277    d->control->deselect();
    13911278}
    13921279
     
    14031290//     q->resetInputContext(); //#### FIX ME IN QT
    14041291    Q_D(QLineEdit);
    1405     int priorState = d->undoState;
    1406     d->removeSelectedText();
    1407     d->insert(newText);
    1408     d->finishChange(priorState);
     1292    d->control->insert(newText);
    14091293}
    14101294
     
    14171301{
    14181302    Q_D(QLineEdit);
    1419     int priorState = d->undoState;
    14201303    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);
     1304    d->control->clear();
    14261305}
    14271306
     
    14361315    Q_D(QLineEdit);
    14371316    resetInputContext();
    1438     d->undo();
    1439     d->finishChange(-1, true);
     1317    d->control->undo();
    14401318}
    14411319
     
    14481326    Q_D(QLineEdit);
    14491327    resetInputContext();
    1450     d->redo();
    1451     d->finishChange();
     1328    d->control->redo();
    14521329}
    14531330
     
    14711348{
    14721349    Q_D(const QLineEdit);
    1473     return d->readOnly;
     1350    return d->control->isReadOnly();
    14741351}
    14751352
     
    14771354{
    14781355    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));
     1356    if (d->control->isReadOnly() != enable) {
     1357        d->control->setReadOnly(enable);
     1358        setAttribute(Qt::WA_MacShowFocusRect, !enable);
     1359        setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
    14831360#ifndef QT_NO_CURSOR
    14841361        setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
     
    15191396{
    15201397    Q_D(const QLineEdit);
    1521     d->copy();
     1398    d->control->copy();
    15221399}
    15231400
     
    15361413{
    15371414    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 
    1548 void 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     }
     1415    d->control->paste();
    15581416}
    15591417
     
    15651423{
    15661424    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) {
     1425    if (e->type() == QEvent::Timer) {
    16101426        // should be timerEvent, is here for binary compatibility
    16111427        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);
     1428        if (false) {
    16181429#ifndef QT_NO_DRAGANDDROP
    16191430        } else if (timerId == d->dndTimer.timerId()) {
     
    16231434        else if (timerId == d->tripleClickTimer.timerId())
    16241435            d->tripleClickTimer.stop();
    1625 #ifdef QT_KEYPAD_NAVIGATION
    1626         else if (timerId == d->deleteAllTimer.timerId()) {
    1627             d->deleteAllTimer.stop();
    1628             clear();
    1629         }
    1630 #endif
    16311436    } else if (e->type() == QEvent::ContextMenu) {
    16321437#ifndef QT_NO_IM
    1633         if (d->composeMode())
     1438        if (d->control->composeMode())
    16341439            return true;
    16351440#endif
    1636         d->separate();
     1441        //d->separate();
    16371442    } else if (e->type() == QEvent::WindowActivate) {
    16381443        QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
    1639     }
     1444    }else if(e->type() == QEvent::ShortcutOverride){
     1445        d->control->processEvent(e);
     1446    } else if (e->type() == QEvent::KeyRelease) {
     1447        d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
     1448    } else if (e->type() == QEvent::Show) {
     1449        //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
     1450        if (hasFocus()) {
     1451            d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
     1452            QStyleOptionFrameV2 opt;
     1453            initStyleOption(&opt);
     1454            if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
     1455                || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
     1456                d->setCursorVisible(true);
     1457        }
     1458    }
     1459
    16401460#ifdef QT_KEYPAD_NAVIGATION
    16411461    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) {
     1462        if (e->type() == QEvent::EnterEditFocus) {
    16601463            end(false);
    1661             if (!d->cursorTimer) {
    1662                 int cft = QApplication::cursorFlashTime();
    1663                 d->cursorTimer = cft ? startTimer(cft/2) : -1;
    1664             }
     1464            d->setCursorVisible(true);
     1465            d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
    16651466        } else if (e->type() == QEvent::LeaveEditFocus) {
    16661467            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             }
     1468            d->control->setCursorBlinkPeriod(0);
     1469            if (d->control->hasAcceptableInput() || d->control->fixup())
     1470                emit editingFinished();
    16781471        }
    16791472    }
     
    16881481    Q_D(QLineEdit);
    16891482    if (d->sendMouseEventToInputContext(e))
    1690         return;
     1483        return;
    16911484    if (e->button() == Qt::RightButton)
    16921485        return;
     
    16951488        setEditFocus(true);
    16961489        // Get the completion list to pop up.
    1697         if (d->completer)
    1698             d->completer->complete();
     1490        if (d->control->completer())
     1491            d->control->completer()->complete();
    16991492    }
    17001493#endif
     
    17071500    int cursor = d->xToPos(e->pos().x());
    17081501#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();
     1502    if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
     1503         e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
    17131504        d->dndPos = e->pos();
    17141505        if (!d->dndTimer.isActive())
    17151506            d->dndTimer.start(QApplication::startDragTime(), this);
    1716         d->emitCursorPositionChanged();
    17171507    } else
    17181508#endif
    17191509    {
    1720         d->moveCursor(cursor, mark);
     1510        d->control->moveCursor(cursor, mark);
    17211511    }
    17221512}
     
    17281518    Q_D(QLineEdit);
    17291519    if (d->sendMouseEventToInputContext(e))
    1730         return;
     1520        return;
    17311521
    17321522    if (e->buttons() & Qt::LeftButton) {
     
    17381528#endif
    17391529        {
    1740             d->moveCursor(d->xToPos(e->pos().x()), true);
     1530            d->control->moveCursor(d->xToPos(e->pos().x()), true);
    17411531        }
    17421532    }
     
    17491539    Q_D(QLineEdit);
    17501540    if (d->sendMouseEventToInputContext(e))
    1751         return;
     1541        return;
    17521542#ifndef QT_NO_DRAGANDDROP
    17531543    if (e->button() == Qt::LeftButton) {
     
    17621552    if (QApplication::clipboard()->supportsSelection()) {
    17631553        if (e->button() == Qt::LeftButton) {
    1764             d->copy(false);
    1765         } else if (!d->readOnly && e->button() == Qt::MidButton) {
    1766             d->deselect();
     1554            d->control->copy(QClipboard::Selection);
     1555        } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) {
     1556            deselect();
    17671557            insert(QApplication::clipboard()->text(QClipboard::Selection));
    17681558        }
    17691559    }
    17701560#endif
     1561
     1562    if (!isReadOnly() && rect().contains(e->pos()))
     1563        d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
     1564    d->clickCausedFocus = 0;
    17711565}
    17721566
     
    17771571    Q_D(QLineEdit);
    17781572    if (d->sendMouseEventToInputContext(e))
    1779         return;
     1573        return;
    17801574    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);
     1575        d->control->selectWordAtPos(d->xToPos(e->pos().x()));
    17891576        d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
    17901577        d->tripleClick = e->pos();
     
    18261613{
    18271614    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
     1615    #ifdef QT_KEYPAD_NAVIGATION
    18791616    bool select = false;
    18801617    switch (event->key()) {
     
    18831620                if (hasEditFocus()) {
    18841621                    setEditFocus(false);
    1885                     if (d->completer && d->completer->popup()->isVisible())
    1886                         d->completer->popup()->hide();
     1622                    if (d->control->completer() && d->control->completer()->popup()->isVisible())
     1623                        d->control->completer()->popup()->hide();
    18871624                    select = true;
    18881625                }
     
    19031640                    {
    19041641                        setEditFocus(true);
     1642#ifndef Q_OS_SYMBIAN
    19051643                        clear();
     1644#endif
    19061645                    } else {
    19071646                        event->ignore();
     
    19201659    }
    19211660#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();
     1661    d->control->processKeyEvent(event);
     1662    if (event->isAccepted())
     1663        d->control->setCursorBlinkPeriod(0);
    21891664}
    21901665
     
    21981673    Q_D(const QLineEdit);
    21991674    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 */
    2207 bool 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;
    22331675}
    22341676
     
    22381680{
    22391681    Q_D(QLineEdit);
    2240     if (d->readOnly) {
     1682    if (d->control->isReadOnly()) {
    22411683        e->ignore();
    22421684        return;
    22431685    }
    22441686
    2245     if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
     1687    if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
    22461688        // Clear the edit and reset to normal echo mode while entering input
    22471689        // method data; the echo mode switches back when the edit loses focus.
     
    22591701        && !e->preeditString().isEmpty()) {
    22601702        setEditFocus(true);
     1703#ifndef Q_OS_SYMBIAN
    22611704        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);
     1705#endif
     1706    }
     1707#endif
     1708
     1709    d->control->processInputMethodEvent(e);
     1710
    23111711#ifndef QT_NO_COMPLETER
    23121712    if (!e->commitString().isEmpty())
    2313         d->complete(Qt::Key_unknown);
     1713        d->control->complete(Qt::Key_unknown);
    23141714#endif
    23151715}
     
    23261726        return font();
    23271727    case Qt::ImCursorPosition:
    2328         return QVariant((d->selend - d->selstart == 0) ? d->cursor : d->selend);
     1728        return QVariant(d->control->cursor());
    23291729    case Qt::ImSurroundingText:
    2330         return QVariant(d->text);
     1730        return QVariant(text());
    23311731    case Qt::ImCurrentSelection:
    23321732        return QVariant(selectedText());
     1733    case Qt::ImMaximumTextLength:
     1734        return QVariant(maxLength());
     1735    case Qt::ImAnchorPosition:
     1736        if (d->control->selectionStart() == d->control->selectionEnd())
     1737            return QVariant(d->control->cursor());
     1738        else if (d->control->selectionStart() == d->control->cursor())
     1739            return QVariant(d->control->selectionEnd());
     1740        else
     1741            return QVariant(d->control->selectionStart());
    23331742    default:
    23341743        return QVariant();
     
    23451754         e->reason() == Qt::BacktabFocusReason  ||
    23461755         e->reason() == Qt::ShortcutFocusReason) {
    2347         if (d->maskData)
    2348             d->moveCursor(d->nextMaskBlank(0));
    2349         else if (!d->hasSelectedText())
     1756        if (!d->control->inputMask().isEmpty())
     1757            d->control->moveCursor(d->control->nextMaskBlank(0));
     1758        else if (!d->control->hasSelectedText())
    23501759            selectAll();
     1760    } else if (e->reason() == Qt::MouseFocusReason) {
     1761        d->clickCausedFocus = 1;
    23511762    }
    23521763#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     }
     1764    if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
     1765#ifdef Q_OS_SYMBIAN
     1766            || e->reason() == Qt::ActiveWindowFocusReason
     1767#endif
     1768            ))) {
     1769#endif
     1770    d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
    23591771    QStyleOptionFrameV2 opt;
    23601772    initStyleOption(&opt);
    2361     if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty())
     1773    if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
    23621774       || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
    23631775        d->setCursorVisible(true);
    23641776#ifdef Q_WS_MAC
    2365     if (d->echoMode == Password || d->echoMode == NoEcho)
     1777    if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
    23661778        qt_mac_secure_keyboard(true);
    23671779#endif
    23681780#ifdef QT_KEYPAD_NAVIGATION
    2369     d->origText = d->text;
     1781        d->control->setCancelText(d->control->text());
     1782    }
    23701783#endif
    23711784#ifndef QT_NO_COMPLETER
    2372     if (d->completer) {
    2373         d->completer->setWidget(this);
    2374         QObject::connect(d->completer, SIGNAL(activated(QString)),
     1785    if (d->control->completer()) {
     1786        d->control->completer()->setWidget(this);
     1787        QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
    23751788                         this, SLOT(setText(QString)));
    2376         QObject::connect(d->completer, SIGNAL(highlighted(QString)),
     1789        QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
    23771790                         this, SLOT(_q_completionHighlighted(QString)));
    23781791    }
     
    23871800{
    23881801    Q_D(QLineEdit);
    2389     if (d->passwordEchoEditing) {
     1802    if (d->control->passwordEchoEditing()) {
    23901803        // Reset the echomode back to PasswordEchoOnEdit when the widget loses
    23911804        // focus.
     
    23991812
    24001813    d->setCursorVisible(false);
    2401     if (d->cursorTimer > 0)
    2402         killTimer(d->cursorTimer);
    2403     d->cursorTimer = 0;
    2404 
     1814    d->control->setCursorBlinkPeriod(0);
    24051815#ifdef QT_KEYPAD_NAVIGATION
    24061816    // editingFinished() is already emitted on LeaveEditFocus
     
    24091819    if (reason != Qt::PopupFocusReason
    24101820        || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
    2411         if (!d->emitingEditingFinished) {
    2412             if (hasAcceptableInput() || d->fixup()) {
    2413                 d->emitingEditingFinished = true;
     1821            if (hasAcceptableInput() || d->control->fixup())
    24141822                emit editingFinished();
    2415                 d->emitingEditingFinished = false;
    2416             }
    2417         }
    24181823#ifdef QT3_SUPPORT
    24191824        emit lostFocus();
     
    24211826    }
    24221827#ifdef Q_WS_MAC
    2423     if (d->echoMode == Password || d->echoMode == NoEcho)
     1828    if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
    24241829        qt_mac_secure_keyboard(false);
    24251830#endif
    24261831#ifdef QT_KEYPAD_NAVIGATION
    2427     d->origText = QString();
     1832    d->control->setCancelText(QString());
    24281833#endif
    24291834#ifndef QT_NO_COMPLETER
    2430     if (d->completer) {
    2431         QObject::disconnect(d->completer, 0, this, 0);
     1835    if (d->control->completer()) {
     1836        QObject::disconnect(d->control->completer(), 0, this, 0);
    24321837    }
    24331838#endif
     
    24591864    switch (va & Qt::AlignVertical_Mask) {
    24601865     case Qt::AlignBottom:
    2461          d->vscroll = r.y() + r.height() - fm.height() - verticalMargin;
     1866         d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin;
    24621867         break;
    24631868     case Qt::AlignTop:
    2464          d->vscroll = r.y() + verticalMargin;
     1869         d->vscroll = r.y() + d->verticalMargin;
    24651870         break;
    24661871     default:
     
    24691874         break;
    24701875    }
    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));
     1876    QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
     1877
     1878    if (d->control->text().isEmpty()) {
     1879        if (!hasFocus() && !d->placeholderText.isEmpty()) {
     1880            QColor col = pal.text().color();
     1881            col.setAlpha(128);
     1882            QPen oldpen = p.pen();
     1883            p.setPen(col);
     1884            p.drawText(lineRect, va, d->placeholderText);
     1885            p.setPen(oldpen);
     1886            return;
     1887        }
     1888    }
     1889
     1890    int cix = qRound(d->control->cursorToX());
    24791891
    24801892    // horizontal scrolling. d->hscroll is the left indent from the beginning
     
    24861898    int minLB = qMax(0, -fm.minLeftBearing());
    24871899    int minRB = qMax(0, -fm.minRightBearing());
    2488     int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
     1900    int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
    24891901    if ((minLB + widthUsed) <=  lineRect.width()) {
    24901902        // text fits in lineRect; use hscroll for alignment
     
    25141926    }
    25151927    // 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());
     1928    QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
    25171929
    25181930    // draw text, selections and cursors
    25191931#ifndef QT_NO_STYLE_STYLESHEET
    25201932    if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
    2521         cssStyle->focusPalette(this, &panel, &pal);
     1933        cssStyle->styleSheetPalette(this, &panel, &pal);
    25221934    }
    25231935#endif
    25241936    p.setPen(pal.text().color());
    25251937
    2526     QVector<QTextLayout::FormatRange> selections;
     1938    int flags = QLineControl::DrawText;
     1939
    25271940#ifdef QT_KEYPAD_NAVIGATION
    25281941    if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
    25291942#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);
     1943    if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){
     1944        flags |= QLineControl::DrawSelections;
     1945        // Palette only used for selections/mask and may not be in sync
     1946        if(d->control->palette() != pal)
     1947            d->control->setPalette(pal);
    25451948    }
    25461949
     
    25481951    // selection phase of input method, so the ordinary cursor should be
    25491952    // 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));
     1953    if (d->cursorVisible && !d->control->isReadOnly())
     1954        flags |= QLineControl::DrawCursor;
     1955
     1956    d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
     1957    d->control->draw(&p, topLeft, r, flags);
     1958
    25531959}
    25541960
     
    25601966{
    25611967    Q_D(QLineEdit);
    2562     if (!d->readOnly && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
     1968    if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
    25631969        e->acceptProposedAction();
    2564         d->cursor = d->xToPos(e->pos().x());
     1970        d->control->moveCursor(d->xToPos(e->pos().x()), false);
    25651971        d->cursorVisible = true;
    25661972        update();
    2567         d->emitCursorPositionChanged();
    25681973    }
    25691974}
     
    25911996    QString str = e->mimeData()->text();
    25921997
    2593     if (!str.isNull() && !d->readOnly) {
     1998    if (!str.isNull() && !d->control->isReadOnly()) {
    25941999        if (e->source() == this && e->dropAction() == Qt::CopyAction)
    25952000            deselect();
    2596         d->cursor =d->xToPos(e->pos().x());
    2597         int selStart = d->cursor;
    2598         int oldSelStart = d->selstart;
    2599         int oldSelEnd = d->selend;
     2001        int cursorPos = d->xToPos(e->pos().x());
     2002        int selStart = cursorPos;
     2003        int oldSelStart = d->control->selectionStart();
     2004        int oldSelEnd = d->control->selectionEnd();
     2005        d->control->moveCursor(cursorPos, false);
    26002006        d->cursorVisible = false;
    26012007        e->acceptProposedAction();
     
    26192025}
    26202026
    2621 void 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 
    26372027#endif // QT_NO_DRAGANDDROP
    26382028
     
    26772067    QMenu *popup = new QMenu(this);
    26782068    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();
     2069    QAction *action = 0;
     2070
     2071    if (!isReadOnly()) {
     2072        action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
     2073        action->setEnabled(d->control->isUndoAvailable());
     2074        connect(action, SIGNAL(triggered()), SLOT(undo()));
     2075
     2076        action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
     2077        action->setEnabled(d->control->isRedoAvailable());
     2078        connect(action, SIGNAL(triggered()), SLOT(redo()));
     2079
     2080        popup->addSeparator();
     2081    }
    26892082
    26902083#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()));
     2084    if (!isReadOnly()) {
     2085        action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
     2086        action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
     2087                && d->control->echoMode() == QLineEdit::Normal);
     2088        connect(action, SIGNAL(triggered()), SLOT(cut()));
     2089    }
    26942090
    26952091    action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
    2696     action->setEnabled(d->hasSelectedText());
     2092    action->setEnabled(d->control->hasSelectedText()
     2093            && d->control->echoMode() == QLineEdit::Normal);
    26972094    connect(action, SIGNAL(triggered()), SLOT(copy()));
    26982095
    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();
     2096    if (!isReadOnly()) {
     2097        action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
     2098        action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
     2099        connect(action, SIGNAL(triggered()), SLOT(paste()));
     2100    }
     2101#endif
     2102
     2103    if (!isReadOnly()) {
     2104        action = popup->addAction(QLineEdit::tr("Delete"));
     2105        action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
     2106        connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
     2107    }
     2108
     2109    if (!popup->isEmpty())
     2110        popup->addSeparator();
    27092111
    27102112    action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
    2711     action->setEnabled(!d->text.isEmpty() && !d->allSelected());
     2113    action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
    27122114    d->selectAllAction = action;
    27132115    connect(action, SIGNAL(triggered()), SLOT(selectAll()));
     
    27232125
    27242126#if defined(Q_WS_WIN)
    2725     if (!d->readOnly && qt_use_rtl_extensions) {
     2127    if (!d->control->isReadOnly() && qt_use_rtl_extensions) {
    27262128#else
    2727     if (!d->readOnly) {
     2129    if (!d->control->isReadOnly()) {
    27282130#endif
    27292131        popup->addSeparator();
     
    27392141{
    27402142    Q_D(QLineEdit);
    2741     if(ev->type() == QEvent::ActivationChange) {
     2143    switch(ev->type())
     2144    {
     2145    case QEvent::ActivationChange:
    27422146        if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
    27432147            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 
    2752 void QLineEditPrivate::_q_clipboardChanged()
    2753 {
    2754 }
    2755 
    2756 void QLineEditPrivate::_q_handleWindowActivate()
    2757 {
    2758     Q_Q(QLineEdit);
    2759     if (!q->hasFocus() && q->hasSelectedText())
    2760         q->deselect();
    2761 }
    2762 
    2763 void 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 
    2776 void 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 
    2798 void 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 
    2807 void 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 
    2835 int 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 
    2843 QRect 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 
    2858 QRect 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 
    2871 bool 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;
     2148        break;
     2149    case QEvent::FontChange:
     2150        d->control->setFont(font());
     2151        break;
     2152    case QEvent::StyleChange:
     2153        {
     2154            QStyleOptionFrameV2 opt;
     2155            initStyleOption(&opt);
     2156            d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
    28822157        }
    2883     }
    2884 #endif
    2885     return false;
    2886 }
    2887 
    2888 void 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 
    2932 void 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 
    2990 void 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 
    3000 void 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 
    3020 void 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 
    3034 void 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 
    3046 void 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 
    3071 void 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 
    3087 void 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 
    3125 void 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 */
    3224 bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const
    3225 {
    3226     switch (mask.unicode()) {
    3227     case 'A':
    3228         if (key.isLetter())
    3229             return true;
     2158        update();
    32302159        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;
     2160    case QEvent::LayoutDirectionChange:
     2161        d->control->setLayoutDirection(layoutDirection());
    32862162        break;
    32872163    default:
    32882164        break;
    32892165    }
    3290     return false;
    3291 }
    3292 
    3293 bool 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 */
    3327 QString 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 */
    3400 QString 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 */
    3420 QString 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 */
    3438 int 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 
    3464 void 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 
    3505 void 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();
     2166    QWidget::changeEvent(ev);
    35432167}
    35442168
     
    36742298/*!
    36752299    \fn int QLineEdit::margin() const
    3676     Returns the with of the the margin around the contents of the widget.
     2300    Returns the width of the margin around the contents of the widget.
    36772301
    36782302    Use QWidget::getContentsMargins() instead.
Note: See TracChangeset for help on using the changeset viewer.