Skip to content

Commit

Permalink
Add a persistentSelection property to TextInput.
Browse files Browse the repository at this point in the history
Improves feature parity with TextEdit.

Task-number: QTBUG-16355
Change-Id: I3919c71454a4f4574a1ee35ad38969459beb8363
Reviewed-by: Martin Jones <martin.jones@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Feb 2, 2012
1 parent c30a170 commit 054a1e9
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/quick/items/qquicktextcontrol.cpp
Expand Up @@ -1547,6 +1547,7 @@ void QQuickTextControlPrivate::focusEvent(QFocusEvent *e)
{
Q_Q(QQuickTextControl);
emit q->updateRequest(q->selectionRect());
hasFocus = e->gotFocus();
if (e->gotFocus()) {
setBlinkingCursorEnabled(interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard));
} else {
Expand All @@ -1558,9 +1559,9 @@ void QQuickTextControlPrivate::focusEvent(QFocusEvent *e)
&& e->reason() != Qt::PopupFocusReason
&& cursor.hasSelection()) {
cursor.clearSelection();
emit q->selectionChanged();
}
}
hasFocus = e->gotFocus();
}

QString QQuickTextControlPrivate::anchorForCursor(const QTextCursor &anchorCursor) const
Expand Down
1 change: 1 addition & 0 deletions src/quick/items/qquicktextedit.cpp
Expand Up @@ -1806,6 +1806,7 @@ void QQuickTextEditPrivate::init()
control->setView(q);
control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
control->setAcceptRichText(false);
control->setCursorIsFocusIndicator(true);

// QQuickTextControl follows the default text color
// defined by the platform, declarative text
Expand Down
2 changes: 1 addition & 1 deletion src/quick/items/qquicktextedit_p_p.h
Expand Up @@ -72,7 +72,7 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
QQuickTextEditPrivate()
: color("black"), hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop),
documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
persistentSelection(true), requireImplicitWidth(false), selectByMouse(false), canPaste(false),
persistentSelection(false), requireImplicitWidth(false), selectByMouse(false), canPaste(false),
canPasteValid(false), hAlignImplicit(true), rightToLeftText(false), useImageFallback(false),
textCached(false),
textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0),
Expand Down
25 changes: 24 additions & 1 deletion src/quick/items/qquicktextinput.cpp
Expand Up @@ -2184,6 +2184,28 @@ void QQuickTextInput::setMouseSelectionMode(SelectionMode mode)
}
}

/*!
\qmlproperty bool QtQuick2::TextInput::persistentSelection
Whether the TextInput should keep its selection when it loses active focus to another
item in the scene. By default this is set to false;
*/

bool QQuickTextInput::persistentSelection() const
{
Q_D(const QQuickTextInput);
return d->persistentSelection;
}

void QQuickTextInput::setPersistentSelection(bool on)
{
Q_D(QQuickTextInput);
if (d->persistentSelection == on)
return;
d->persistentSelection = on;
emit persistentSelectionChanged();
}

/*!
\qmlproperty bool QtQuick2::TextInput::canPaste
Expand Down Expand Up @@ -2438,7 +2460,8 @@ void QQuickTextInput::itemChange(ItemChange change, const ItemChangeData &value)

if (!hasFocus) {
d->commitPreedit();
d->deselect();
if (!d->persistentSelection)
d->deselect();
disconnect(qApp->inputPanel(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
this, SLOT(q_updateAlignment()));
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/quick/items/qquicktextinput_p.h
Expand Up @@ -98,6 +98,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
Expand Down Expand Up @@ -233,6 +234,9 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
SelectionMode mouseSelectionMode() const;
void setMouseSelectionMode(SelectionMode mode);

bool persistentSelection() const;
void setPersistentSelection(bool persist);

bool hasAcceptableInput() const;

QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
Expand Down Expand Up @@ -279,6 +283,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
void autoScrollChanged(bool autoScroll);
void selectByMouseChanged(bool selectByMouse);
void mouseSelectionModeChanged(SelectionMode mode);
void persistentSelectionChanged();
void canPasteChanged();
void canUndoChanged();
void canRedoChanged();
Expand Down
2 changes: 2 additions & 0 deletions src/quick/items/qquicktextinput_p_p.h
Expand Up @@ -117,6 +117,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
, hAlignImplicit(true)
, selectPressed(false)
, textLayoutDirty(true)
, persistentSelection(false)
, m_hideCursor(false)
, m_separator(0)
, m_readOnly(0)
Expand Down Expand Up @@ -244,6 +245,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
bool hAlignImplicit:1;
bool selectPressed:1;
bool textLayoutDirty:1;
bool persistentSelection:1;

uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
uint m_separator : 1;
Expand Down
@@ -0,0 +1,8 @@
import QtQuick 2.0

TextEdit {
property string selected: selectedText

text: "Hello World!"
focus: true
}
56 changes: 40 additions & 16 deletions tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
Expand Up @@ -946,23 +946,47 @@ void tst_qquicktextedit::textMargin()

void tst_qquicktextedit::persistentSelection()
{
{
QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: true; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->persistentSelection(), true);
}
QQuickView canvas(testFileUrl("persistentSelection.qml"));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
canvas.requestActivateWindow();

QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
QVERIFY(edit);
QVERIFY(edit->hasActiveFocus());

QSignalSpy spy(edit, SIGNAL(persistentSelectionChanged(bool)));

QCOMPARE(edit->persistentSelection(), false);

edit->setPersistentSelection(false);
QCOMPARE(edit->persistentSelection(), false);
QCOMPARE(spy.count(), 0);

edit->select(1, 4);
QCOMPARE(edit->property("selected").toString(), QLatin1String("ell"));

edit->setFocus(false);
QCOMPARE(edit->property("selected").toString(), QString());

edit->setFocus(true);
QCOMPARE(edit->property("selected").toString(), QString());

edit->setPersistentSelection(true);
QCOMPARE(edit->persistentSelection(), true);
QCOMPARE(spy.count(), 1);

edit->select(1, 4);
QCOMPARE(edit->property("selected").toString(), QLatin1String("ell"));

edit->setFocus(false);
QCOMPARE(edit->property("selected").toString(), QLatin1String("ell"));

edit->setFocus(true);
QCOMPARE(edit->property("selected").toString(), QLatin1String("ell"));

{
QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: false; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->persistentSelection(), false);
}
}

void tst_qquicktextedit::focusOnPress()
Expand Down
@@ -0,0 +1,8 @@
import QtQuick 2.0

TextInput {
property string selected: selectedText

text: "Hello World!"
focus: true
}
45 changes: 45 additions & 0 deletions tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
Expand Up @@ -109,6 +109,7 @@ private slots:
void color();
void wrap();
void selection();
void persistentSelection();
void isRightToLeft_data();
void isRightToLeft();
void moveCursorSelection_data();
Expand Down Expand Up @@ -628,6 +629,50 @@ void tst_qquicktextinput::selection()
delete textinputObject;
}

void tst_qquicktextinput::persistentSelection()
{
QQuickView canvas(testFileUrl("persistentSelection.qml"));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
canvas.requestActivateWindow();

QQuickTextInput *input = qobject_cast<QQuickTextInput *>(canvas.rootObject());
QVERIFY(input);
QVERIFY(input->hasActiveFocus());

QSignalSpy spy(input, SIGNAL(persistentSelectionChanged()));

QCOMPARE(input->persistentSelection(), false);

input->setPersistentSelection(false);
QCOMPARE(input->persistentSelection(), false);
QCOMPARE(spy.count(), 0);

input->select(1, 4);
QCOMPARE(input->property("selected").toString(), QLatin1String("ell"));

input->setFocus(false);
QCOMPARE(input->property("selected").toString(), QString());

input->setFocus(true);
QCOMPARE(input->property("selected").toString(), QString());

input->setPersistentSelection(true);
QCOMPARE(input->persistentSelection(), true);
QCOMPARE(spy.count(), 1);

input->select(1, 4);
QCOMPARE(input->property("selected").toString(), QLatin1String("ell"));

input->setFocus(false);
QCOMPARE(input->property("selected").toString(), QLatin1String("ell"));

input->setFocus(true);
QCOMPARE(input->property("selected").toString(), QLatin1String("ell"));
}

void tst_qquicktextinput::isRightToLeft_data()
{
QTest::addColumn<QString>("text");
Expand Down

0 comments on commit 054a1e9

Please sign in to comment.