Widgets: Update micro focus in QLineEdit and friends
QLineEdit, QAbstractSpinBox and QComboBox did not notify micro focus changes to the input context. In particular, the updates were missed during pre-edit stage. This change adds the missing bindings to QWidget::updateMicroFocus(). Change-Id: I9a7fff962f46dbabd8fb02836c206bace115793b Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
07745d7bfb
commit
b07f71a53f
@ -694,6 +694,10 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
|
||||
this, SLOT(_q_editorTextChanged(QString)));
|
||||
connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
|
||||
this, SLOT(_q_editorCursorPositionChanged(int,int)));
|
||||
connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
|
||||
this, SLOT(updateMicroFocus()));
|
||||
connect(d->edit->d_func()->control, SIGNAL(updateMicroFocus()),
|
||||
this, SLOT(updateMicroFocus()));
|
||||
}
|
||||
d->updateEditFieldGeometry();
|
||||
d->edit->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <private/qcombobox_p.h>
|
||||
#include <private/qabstractitemmodel_p.h>
|
||||
#include <private/qabstractscrollarea_p.h>
|
||||
#include <private/qlineedit_p.h>
|
||||
#include <qdebug.h>
|
||||
#if 0 /* Used to be included in Qt4 for Q_WS_MAC */ && !defined(QT_NO_EFFECTS) && QT_CONFIG(style_mac)
|
||||
#include <private/qcore_mac_p.h>
|
||||
@ -1790,6 +1791,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
|
||||
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString)));
|
||||
connect(d->lineEdit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateMicroFocus()));
|
||||
connect(d->lineEdit, SIGNAL(selectionChanged()), this, SLOT(updateMicroFocus()));
|
||||
connect(d->lineEdit->d_func()->control, SIGNAL(updateMicroFocus()), this, SLOT(updateMicroFocus()));
|
||||
d->lineEdit->setFrame(false);
|
||||
d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
d->updateFocusPolicy();
|
||||
|
@ -239,6 +239,7 @@ public:
|
||||
private:
|
||||
friend class QAbstractSpinBox;
|
||||
friend class QAccessibleLineEdit;
|
||||
friend class QComboBox;
|
||||
#ifdef QT_KEYPAD_NAVIGATION
|
||||
friend class QDateTimeEdit;
|
||||
#endif
|
||||
|
@ -196,6 +196,9 @@ void QLineEditPrivate::init(const QString& txt)
|
||||
QObject::connect(control, SIGNAL(textChanged(QString)),
|
||||
q, SLOT(updateMicroFocus()));
|
||||
|
||||
QObject::connect(control, SIGNAL(updateMicroFocus()),
|
||||
q, SLOT(updateMicroFocus()));
|
||||
|
||||
// for now, going completely overboard with updates.
|
||||
QObject::connect(control, SIGNAL(selectionChanged()),
|
||||
q, SLOT(update()));
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
CONFIG += testcase
|
||||
TARGET = tst_qabstractspinbox
|
||||
QT += widgets testlib
|
||||
QT += widgets gui-private core-private testlib
|
||||
SOURCES += tst_qabstractspinbox.cpp
|
||||
|
||||
|
||||
|
@ -35,6 +35,20 @@
|
||||
#include <qlineedit.h>
|
||||
#include <qspinbox.h>
|
||||
|
||||
#include "../../../shared/platforminputcontext.h"
|
||||
#include <private/qinputmethod_p.h>
|
||||
|
||||
static inline void centerOnScreen(QWidget *w, const QSize &size)
|
||||
{
|
||||
const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
|
||||
w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
|
||||
}
|
||||
|
||||
static inline void centerOnScreen(QWidget *w)
|
||||
{
|
||||
centerOnScreen(w, w->geometry().size());
|
||||
}
|
||||
|
||||
class tst_QAbstractSpinBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -44,11 +58,19 @@ public:
|
||||
virtual ~tst_QAbstractSpinBox();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
void getSetCheck();
|
||||
|
||||
// task-specific tests below me:
|
||||
void task183108_clear();
|
||||
void task228728_cssselector();
|
||||
|
||||
void inputMethodUpdate();
|
||||
|
||||
private:
|
||||
PlatformInputContext m_platformInputContext;
|
||||
};
|
||||
|
||||
tst_QAbstractSpinBox::tst_QAbstractSpinBox()
|
||||
@ -67,6 +89,18 @@ public:
|
||||
void setLineEdit(QLineEdit *le) { QAbstractSpinBox::setLineEdit(le); }
|
||||
};
|
||||
|
||||
void tst_QAbstractSpinBox::initTestCase()
|
||||
{
|
||||
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
|
||||
inputMethodPrivate->testContext = &m_platformInputContext;
|
||||
}
|
||||
|
||||
void tst_QAbstractSpinBox::cleanupTestCase()
|
||||
{
|
||||
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
|
||||
inputMethodPrivate->testContext = 0;
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QAbstractSpinBox::getSetCheck()
|
||||
{
|
||||
@ -141,6 +175,60 @@ void tst_QAbstractSpinBox::task228728_cssselector()
|
||||
QSpinBox box;
|
||||
}
|
||||
|
||||
void tst_QAbstractSpinBox::inputMethodUpdate()
|
||||
{
|
||||
QSpinBox box;
|
||||
|
||||
QSpinBox *testWidget = &box;
|
||||
testWidget->setRange(0, 1);
|
||||
|
||||
centerOnScreen(testWidget);
|
||||
testWidget->clear();
|
||||
testWidget->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(testWidget));
|
||||
|
||||
testWidget->activateWindow();
|
||||
testWidget->setFocus();
|
||||
QTRY_VERIFY(testWidget->hasFocus());
|
||||
QTRY_COMPARE(qApp->focusObject(), testWidget);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("1", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
|
||||
QInputMethodEvent event("1", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("", attributes);
|
||||
event.setCommitString("1");
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
QCOMPARE(testWidget->value(), 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
|
||||
QInputMethodEvent event("", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QAbstractSpinBox)
|
||||
#include "tst_qabstractspinbox.moc"
|
||||
|
@ -64,6 +64,9 @@
|
||||
#include <qproxystyle.h>
|
||||
#include <qfont.h>
|
||||
|
||||
#include "../../../shared/platforminputcontext.h"
|
||||
#include <private/qinputmethod_p.h>
|
||||
|
||||
static inline void setFrameless(QWidget *w)
|
||||
{
|
||||
Qt::WindowFlags flags = w->windowFlags();
|
||||
@ -80,6 +83,8 @@ public:
|
||||
tst_QComboBox() {}
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void getSetCheck();
|
||||
void ensureReturnIsIgnored();
|
||||
void setEditable();
|
||||
@ -162,6 +167,10 @@ private slots:
|
||||
void task_QTBUG_39088_inputMethodHints();
|
||||
void task_QTBUG_49831_scrollerNotActivated();
|
||||
void task_QTBUG_56693_itemFontFromModel();
|
||||
void inputMethodUpdate();
|
||||
|
||||
private:
|
||||
PlatformInputContext m_platformInputContext;
|
||||
};
|
||||
|
||||
class MyAbstractItemDelegate : public QAbstractItemDelegate
|
||||
@ -207,6 +216,18 @@ protected:
|
||||
QRegion visualRegionForSelection(const QItemSelection &) const { return QRegion(); }
|
||||
};
|
||||
|
||||
void tst_QComboBox::initTestCase()
|
||||
{
|
||||
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
|
||||
inputMethodPrivate->testContext = &m_platformInputContext;
|
||||
}
|
||||
|
||||
void tst_QComboBox::cleanupTestCase()
|
||||
{
|
||||
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
|
||||
inputMethodPrivate->testContext = 0;
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QComboBox::getSetCheck()
|
||||
{
|
||||
@ -3324,5 +3345,59 @@ void tst_QComboBox::task_QTBUG_56693_itemFontFromModel()
|
||||
box.hidePopup();
|
||||
}
|
||||
|
||||
void tst_QComboBox::inputMethodUpdate()
|
||||
{
|
||||
TestWidget topLevel;
|
||||
topLevel.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
|
||||
QComboBox *testWidget = topLevel.comboBox();
|
||||
// make sure we have no lineedit
|
||||
QVERIFY(!testWidget->lineEdit());
|
||||
// test setEditable(true)
|
||||
testWidget->setEditable(true);
|
||||
QVERIFY(testWidget->lineEdit());
|
||||
|
||||
testWidget->activateWindow();
|
||||
testWidget->setFocus();
|
||||
QTRY_VERIFY(testWidget->hasFocus());
|
||||
QTRY_COMPARE(qApp->focusObject(), testWidget);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("preedit text", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
|
||||
QInputMethodEvent event("preedit text", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("", attributes);
|
||||
event.setCommitString("preedit text");
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
QCOMPARE(testWidget->lineEdit()->text(), QString("preedit text"));
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
|
||||
QInputMethodEvent event("", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QComboBox)
|
||||
#include "tst_qcombobox.moc"
|
||||
|
@ -294,6 +294,8 @@ private slots:
|
||||
void inputMethodQueryImHints_data();
|
||||
void inputMethodQueryImHints();
|
||||
|
||||
void inputMethodUpdate();
|
||||
|
||||
void undoRedoAndEchoModes_data();
|
||||
void undoRedoAndEchoModes();
|
||||
|
||||
@ -4184,6 +4186,57 @@ void tst_QLineEdit::inputMethodQueryImHints()
|
||||
QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints);
|
||||
}
|
||||
|
||||
void tst_QLineEdit::inputMethodUpdate()
|
||||
{
|
||||
QLineEdit *testWidget = ensureTestWidget();
|
||||
|
||||
centerOnScreen(testWidget);
|
||||
testWidget->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(testWidget));
|
||||
|
||||
testWidget->setText("");
|
||||
testWidget->activateWindow();
|
||||
testWidget->setFocus();
|
||||
QTRY_VERIFY(testWidget->hasFocus());
|
||||
QTRY_COMPARE(qApp->focusObject(), testWidget);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("preedit text", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
|
||||
QInputMethodEvent event("preedit text", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
QInputMethodEvent event("", attributes);
|
||||
event.setCommitString("preedit text");
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
QCOMPARE(testWidget->text(), QString("preedit text"));
|
||||
|
||||
m_platformInputContext.m_updateCallCount = 0;
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
|
||||
QInputMethodEvent event("", attributes);
|
||||
QApplication::sendEvent(testWidget, &event);
|
||||
}
|
||||
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
|
||||
}
|
||||
|
||||
void tst_QLineEdit::undoRedoAndEchoModes_data()
|
||||
{
|
||||
QTest::addColumn<int>("echoMode");
|
||||
|
@ -49,6 +49,7 @@ SUBDIRS=\
|
||||
|
||||
# The following tests depend on private API:
|
||||
!qtConfig(private_tests): SUBDIRS -= \
|
||||
qabstractspinbox \
|
||||
qcombobox \
|
||||
qmainwindow \
|
||||
qtextedit \
|
||||
|
Loading…
Reference in New Issue
Block a user