DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+static const int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY;
+#endif
+
/*!
\qmlclass TextInput QQuickTextInput
\inqmlmodule QtQuick 2
Q_D(QQuickTextInput);
if (echoMode() == echo)
return;
+ d->cancelPasswordEchoTimer();
d->m_echoMode = echo;
d->m_passwordEchoEditing = false;
d->updateInputMethodHints();
bool hasFocus = value.boolValue;
d->focused = hasFocus;
setCursorVisible(hasFocus); // ### refactor: && d->canvas && d->canvas->hasFocus()
- if (echoMode() == QQuickTextInput::PasswordEchoOnEdit && !hasFocus)
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ if (!hasFocus && (d->m_passwordEchoEditing || d->m_passwordEchoTimer.isActive())) {
+#else
+ if (!hasFocus && d->m_passwordEchoEditing) {
+#endif
d->updatePasswordEchoEditing(false);//QQuickTextInputPrivate sets it on key events, but doesn't deal with focus events
+ }
if (!hasFocus)
d->deselect();
}
else
str = m_text;
- if (m_echoMode == QQuickTextInput::Password
- || (m_echoMode == QQuickTextInput::PasswordEchoOnEdit && !m_passwordEchoEditing))
+ if (m_echoMode == QQuickTextInput::Password) {
+ str.fill(m_passwordCharacter);
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ if (m_passwordEchoTimer.isActive() && m_cursor > 0 && m_cursor <= m_text.length()) {
+ int cursor = m_cursor - 1;
+ QChar uc = m_text.at(cursor);
+ str[cursor] = uc;
+ if (cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ // second half of a surrogate, check if we have the first half as well,
+ // if yes restore both at once
+ uc = m_text.at(cursor - 1);
+ if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
+ str[cursor - 1] = uc;
+ }
+ }
+#endif
+ } else if (m_echoMode == QQuickTextInput::PasswordEchoOnEdit && !m_passwordEchoEditing) {
str.fill(m_passwordCharacter);
+ }
// replace certain non-printable characters with spaces (to avoid
// drawing boxes when using fonts that don't have glyphs for such
*/
void QQuickTextInputPrivate::updatePasswordEchoEditing(bool editing)
{
+ cancelPasswordEchoTimer();
m_passwordEchoEditing = editing;
updateDisplayText();
}
*/
void QQuickTextInputPrivate::internalInsert(const QString &s)
{
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ Q_Q(QQuickTextInput);
+ if (m_echoMode == QQuickTextInput::Password)
+ m_passwordEchoTimer.start(qt_passwordEchoDelay, q);
+#endif
if (hasSelectedText())
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
if (m_maskData) {
void QQuickTextInputPrivate::internalDelete(bool wasBackspace)
{
if (m_cursor < (int) m_text.length()) {
+ cancelPasswordEchoTimer();
if (hasSelectedText())
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
void QQuickTextInputPrivate::removeSelectedText()
{
if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ cancelPasswordEchoTimer();
separate();
int i ;
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
{
if (!isUndoAvailable())
return;
+ cancelPasswordEchoTimer();
internalDeselect();
while (m_undoState && m_undoState > until) {
Command& cmd = m_history[--m_undoState];
killTimer(d->m_deleteAllTimer);
d->m_deleteAllTimer = 0;
d->clear();
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ } else if (event->timerId() == d->m_passwordEchoTimer.timerId()) {
+ d->m_passwordEchoTimer.stop();
+ d->updateDisplayText();
+#endif
}
}
#include <QtDeclarative/qdeclarative.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qbasictimer.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qpalette.h>
#include <QtGui/qtextlayout.h>
#include <QtGui/qstylehints.h>
+#include "qplatformdefs.h"
//
// W A R N I N G
int m_blinkPeriod; // 0 for non-blinking cursor
int m_blinkTimer;
int m_deleteAllTimer;
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ QBasicTimer m_passwordEchoTimer;
+#endif
int m_ascent;
int m_maxLength;
int m_lastCursorPos;
void updatePasswordEchoEditing(bool editing);
+ void cancelPasswordEchoTimer() {
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ m_passwordEchoTimer.stop();
+#endif
+ }
+
Qt::LayoutDirection layoutDirection() const {
if (m_layoutDirection == Qt::LayoutDirectionAuto) {
if (m_text.isEmpty())
}
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
-void tst_qdeclarativetextinput::passwordEchoDelay()
+void tst_qquicktextinput::passwordEchoDelay()
{
QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
canvas.show();
- canvas.setFocus();
- QGuiApplication::setActiveWindow(&canvas);
+ canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QChar fillChar = QLatin1Char('*');
- input->setEchoMode(QDeclarativeTextInput::Password);
+ input->setEchoMode(QQuickTextInput::Password);
QCOMPARE(input->displayText(), QString(8, fillChar));
input->setText(QString());
QCOMPARE(input->displayText(), QString());
QInputMethodEvent ev;
ev.setCommitString(QLatin1String("7"));
- QGuiApplication::sendEvent(&canvas, &ev);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev);
QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7'));
+
+ input->setCursorPosition(3);
+ QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7'));
+ QTest::keyPress(&canvas, 'a');
+ QCOMPARE(input->displayText(), QString(3, fillChar) + QLatin1Char('a') + QString(5, fillChar));
+ QTest::keyPress(&canvas, Qt::Key_Backspace);
+ QCOMPARE(input->displayText(), QString(8, fillChar));
}
#endif