aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/corelib/widgets/mtextedit.cpp61
-rwxr-xr-xsrc/corelib/widgets/mtextedit_p.h16
-rw-r--r--tests/ut_mtextedit/ut_mtextedit.cpp41
3 files changed, 104 insertions, 14 deletions
diff --git a/src/corelib/widgets/mtextedit.cpp b/src/corelib/widgets/mtextedit.cpp
index 1d8e688d..6cfc24bc 100755
--- a/src/corelib/widgets/mtextedit.cpp
+++ b/src/corelib/widgets/mtextedit.cpp
@@ -302,7 +302,9 @@ MTextEditPrivate::MTextEditPrivate()
completer(0),
registeredToolbarId(-1),
editActive(false),
- omitInputMethodEvents(false)
+ omitInputMethodEvents(false),
+ updateMicroFocusDisabled(0),
+ pendingMicroFocusUpdate(false)
{
}
@@ -374,7 +376,7 @@ bool MTextEditPrivate::moveCursor(QTextCursor::MoveOperation moveOp,
result = cursor()->movePosition(moveOp, moveMode, n);
if (result) {
q->model()->updateCursor();
- q->updateMicroFocus();
+ updateMicroFocus();
emit q->cursorPositionChanged();
}
@@ -788,7 +790,7 @@ void MTextEditPrivate::commitPreedit()
}
setMode(MTextEditModel::EditModeBasic);
- q->updateMicroFocus();
+ updateMicroFocus();
if (q->hasFocus()) {
// make sure the committed preedit doesn't get left on the input context
@@ -1212,7 +1214,7 @@ void MTextEditPrivate::_q_confirmCompletion(const QString &completion)
QObject::disconnect(q, SIGNAL(textChanged()), completer, SLOT(complete()));
emit q->textChanged();
QObject::connect(q, SIGNAL(textChanged()), completer, SLOT(complete()));
- q->updateMicroFocus();
+ updateMicroFocus();
}
bool MTextEditPrivate::copy()
@@ -1240,6 +1242,34 @@ QString MTextEditPrivate::replaceLineBreaks(QString text, QChar replacement)
return text;
}
+void MTextEditPrivate::disableUpdateMicroFocus()
+{
+ ++updateMicroFocusDisabled;
+}
+
+void MTextEditPrivate::enableUpdateMicroFocus(bool flush)
+{
+ Q_Q(MTextEdit);
+ Q_ASSERT(updateMicroFocusDisabled);
+ if ((--updateMicroFocusDisabled == 0) && pendingMicroFocusUpdate && flush) {
+ q->updateMicroFocus();
+ }
+ pendingMicroFocusUpdate = false;
+}
+
+void MTextEditPrivate::updateMicroFocus()
+{
+ Q_Q(MTextEdit);
+
+ if (updateMicroFocusDisabled <= 0) {
+ q->updateMicroFocus();
+ pendingMicroFocusUpdate = false;
+ } else {
+ pendingMicroFocusUpdate = true;
+ }
+}
+
+
///////////////////////////////////////////////
// Actual class implementation
@@ -1357,7 +1387,7 @@ void MTextEdit::setSelection(int start, int length, bool useBoundaries)
model()->updateCursor();
- updateMicroFocus();
+ d->updateMicroFocus();
emit selectionChanged();
@@ -1439,6 +1469,7 @@ void MTextEdit::keyPressEvent(QKeyEvent *event)
d->smartMoveCursor(moveDirection, QTextCursor::MoveAnchor, 1);
} else if (event->modifiers() == Qt::ShiftModifier
&& (textInteractionFlags() & Qt::TextSelectableByKeyboard)) {
+ d->disableUpdateMicroFocus();
const bool moved = d->smartMoveCursor(moveDirection, QTextCursor::KeepAnchor, 1);
if (!wasSelecting && d->cursor()->hasSelection()) { // first character was selected
d->setMode(MTextEditModel::EditModeSelect);
@@ -1449,7 +1480,9 @@ void MTextEdit::keyPressEvent(QKeyEvent *event)
}
if (moved) {
emit selectionChanged();
+ d->updateMicroFocus();
}
+ d->enableUpdateMicroFocus(true);
}
event->accept();
return;
@@ -1577,7 +1610,7 @@ void MTextEdit::keyPressEvent(QKeyEvent *event)
}
model()->updateCursor();
- updateMicroFocus();
+ d->updateMicroFocus();
emit textChanged();
emit cursorPositionChanged();
@@ -1700,7 +1733,7 @@ bool MTextEdit::insert(const QString &text)
// either something was inserted or something was deleted, or both
if (insertionSuccess || wasSelecting) {
emit textChanged();
- updateMicroFocus();
+ d->updateMicroFocus();
}
return insertionSuccess;
@@ -1751,7 +1784,7 @@ bool MTextEdit::setText(const QString &text)
// only avoid signaling if empty before and after
if (!((document()->characterCount() == 0) && wasEmpty)) {
- updateMicroFocus();
+ d->updateMicroFocus();
emit textChanged();
}
@@ -1899,7 +1932,7 @@ void MTextEdit::handleMouseRelease(int eventCursorPosition, QGraphicsSceneMouseE
}
if (cursorPosition() != cursorPositionBefore) {
- updateMicroFocus();
+ d->updateMicroFocus();
}
}
@@ -1988,7 +2021,7 @@ void MTextEdit::paste()
if (changed) {
emit textChanged();
emit cursorPositionChanged();
- updateMicroFocus();
+ d->updateMicroFocus();
} else {
mDebug("MTextEdit") << __PRETTY_FUNCTION__ << "paste failed";
emit pasteFailed();
@@ -2021,7 +2054,7 @@ void MTextEdit::cut()
emit selectionChanged();
emit textChanged();
emit cursorPositionChanged();
- updateMicroFocus();
+ d->updateMicroFocus();
}
}
@@ -2121,7 +2154,7 @@ void MTextEdit::inputMethodEvent(QInputMethodEvent *event)
}
if (changed) {
- updateMicroFocus();
+ d->updateMicroFocus();
emit textChanged();
emit cursorPositionChanged();
}
@@ -2406,7 +2439,7 @@ void MTextEdit::deselect()
d->setMode(MTextEditModel::EditModeBasic);
model()->updateCursor();
d->sendCopyAvailable(false);
- updateMicroFocus();
+ d->updateMicroFocus();
emit selectionChanged();
}
}
@@ -2581,7 +2614,7 @@ void MTextEdit::setCompleter(MCompleter *completer)
setInputMethodAutoCapitalizationEnabled(false);
if (hasFocus()) {
- updateMicroFocus();
+ d->updateMicroFocus();
connect(d->completer, SIGNAL(confirmed(QString, QModelIndex)),
this, SLOT(_q_confirmCompletion(QString)));
}
diff --git a/src/corelib/widgets/mtextedit_p.h b/src/corelib/widgets/mtextedit_p.h
index 00ad99b8..9fb65f90 100755
--- a/src/corelib/widgets/mtextedit_p.h
+++ b/src/corelib/widgets/mtextedit_p.h
@@ -105,6 +105,19 @@ public:
QString replaceLineBreaks(QString text, QChar replacement);
void _q_confirmCompletion(const QString &);
+ //! \brief Disable MTextEdit::updateMicroFocus().
+ //!
+ //! Can be called multiple times without calling \a enableUpdateMicroFocus in between. In such a case
+ //! \a enableUpdateMicroFocus must be called equally many times.
+ void disableUpdateMicroFocus();
+ //! \param flush call updateMicroFocus() automatically if true and updateMicroFocus was called
+ //! while being disabled
+ void enableUpdateMicroFocus(bool flush = false);
+ //! \brief updateMicroFocus() wrapper that can be disabled
+ //! \sa disableUpdateMicroFocus
+ //! \sa enableUpdateMicroFocus
+ void updateMicroFocus();
+
bool pendingSoftwareInputPanelRequest;
private:
@@ -118,6 +131,9 @@ private:
// protection from input methods that send something on QInputContext::reset()
bool omitInputMethodEvents;
+
+ int updateMicroFocusDisabled;
+ bool pendingMicroFocusUpdate;
};
#endif
diff --git a/tests/ut_mtextedit/ut_mtextedit.cpp b/tests/ut_mtextedit/ut_mtextedit.cpp
index 2983526b..8521500f 100644
--- a/tests/ut_mtextedit/ut_mtextedit.cpp
+++ b/tests/ut_mtextedit/ut_mtextedit.cpp
@@ -97,6 +97,9 @@ class SimpleInputContext: public QInputContext
public:
SimpleInputContext(QObject *parent = 0)
: QInputContext(parent),
+ updateCallCount(0),
+ selectionAvailableAtLastUpdate(false),
+ edit(0),
m_visible(false)
{}
@@ -143,6 +146,20 @@ public:
return false;
}
+ void update()
+ {
+ ++updateCallCount;
+ if (edit) {
+ selectedTextAtLastUpdate = edit->selectedText();
+ }
+ selectionAvailableAtLastUpdate = !selectedTextAtLastUpdate.isEmpty();
+ }
+
+ int updateCallCount;
+ bool selectionAvailableAtLastUpdate;
+ QString selectedTextAtLastUpdate;
+ MTextEdit *edit;
+
private:
bool m_visible;
};
@@ -258,6 +275,7 @@ void Ut_MTextEdit::init()
{
m_subject.reset(new MTextEdit(MTextEditModel::MultiLine, ""));
qApp->setInputContext(m_sic = new SimpleInputContext);
+ m_sic->edit = m_subject.get();
}
@@ -1946,6 +1964,7 @@ void Ut_MTextEdit::testArrowKeys()
void Ut_MTextEdit::testSelectByArrowKeys()
{
+ setupSipEnv(m_subject.get());
QSignalSpy copyAvailableSpy(m_subject.get(), SIGNAL(copyAvailable(bool)));
QVERIFY(copyAvailableSpy.isValid());
@@ -1982,9 +2001,12 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(copyAvailableSpy.count(), 0);
QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(m_sic->updateCallCount, 0);
+
m_subject->setText(line);
m_subject->setCursorPosition(1);
+ m_sic->updateCallCount = 0;
m_subject->keyPressEvent(&right);
QCOMPARE(m_subject->cursorPosition(), 2);
QCOMPARE(m_subject->selectedText(), QString("2"));
@@ -1994,6 +2016,9 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(selectionChangedSpy.count(), 1);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ QCOMPARE(m_sic->updateCallCount, 1);
+ m_sic->updateCallCount = 0;
+ QVERIFY(m_sic->selectionAvailableAtLastUpdate);
m_subject->keyPressEvent(&left);
QCOMPARE(m_subject->cursorPosition(), 1);
@@ -2004,6 +2029,9 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(selectionChangedSpy.count(), 1);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ QCOMPARE(m_sic->updateCallCount, 1);
+ m_sic->updateCallCount = 0;
+ QVERIFY(!m_sic->selectionAvailableAtLastUpdate);
m_subject->keyPressEvent(&left);
QCOMPARE(m_subject->cursorPosition(), 0);
@@ -2014,11 +2042,14 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(selectionChangedSpy.count(), 1);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ QCOMPARE(m_sic->updateCallCount, 1);
+ QVERIFY(m_sic->selectionAvailableAtLastUpdate);
m_subject->setCursorPosition(0);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ m_sic->updateCallCount = 0;
m_subject->keyPressEvent(&down);
QVERIFY(m_subject->cursorPosition() > 0);
QVERIFY(!m_subject->selectedText().isEmpty());
@@ -2028,6 +2059,9 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(selectionChangedSpy.count(), 1);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ QCOMPARE(m_sic->updateCallCount, 1);
+ m_sic->updateCallCount = 0;
+ QVERIFY(m_sic->selectionAvailableAtLastUpdate);
m_subject->keyPressEvent(&up);
QVERIFY(m_subject->cursorPosition() == 0);
@@ -2038,15 +2072,21 @@ void Ut_MTextEdit::testSelectByArrowKeys()
QCOMPARE(selectionChangedSpy.count(), 1);
copyAvailableSpy.clear();
selectionChangedSpy.clear();
+ QCOMPARE(m_sic->updateCallCount, 1);
+ QVERIFY(!m_sic->selectionAvailableAtLastUpdate);
//disable flag Qt::TextSelectableByKeyboard
m_subject->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextEditable);
+ m_sic->updateCallCount = 0;
m_subject->keyPressEvent(&right);
QCOMPARE(m_subject->cursorPosition(), 0);
QVERIFY(!m_subject->hasSelectedText());
QCOMPARE(copyAvailableSpy.count(), 0);
QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(m_sic->updateCallCount, 0);
+ m_sic->updateCallCount = 0;
+ QVERIFY(!m_sic->selectionAvailableAtLastUpdate);
}
void Ut_MTextEdit::testAutoSipEnabled()
@@ -2419,6 +2459,7 @@ void Ut_MTextEdit::testArrowKeyNavigation()
void Ut_MTextEdit::setupSipEnv(MTextEdit *edit)
{
edit->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
+ m_sic->edit = edit;
}
void Ut_MTextEdit::requestSip(MTextEdit *edit, Qt::FocusReason fr)