Add clearButton-property to QLineEdit.

Based on addAction-API.

Change-Id: Ie6c3d2d728b23a85cdd80428c92ee8208ae0a65c
Done-with: Kevin.Ottens@kdab.com
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
bb10
Friedemann Kleint 2013-07-17 10:38:56 +02:00 committed by The Qt Project
parent bc87acaa1f
commit bff5100177
5 changed files with 98 additions and 1 deletions

View File

@ -475,6 +475,42 @@ QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
return result;
}
/*!
\property QLineEdit::clearButtonEnabled
\brief Whether the line edit displays a clear button when it is not empty.
If enabled, the line edit displays a trailing \e clear button when it contains
some text, otherwise the line edit does not show a clear button (the
default).
\sa addAction(), removeAction()
\since 5.2
*/
static const char clearButtonActionNameC[] = "_q_qlineeditclearaction";
void QLineEdit::setClearButtonEnabled(bool enable)
{
Q_D(QLineEdit);
if (enable == isClearButtonEnabled())
return;
if (enable) {
QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this);
clearAction->setObjectName(QLatin1String(clearButtonActionNameC));
d->addAction(clearAction, 0, QLineEdit::TrailingPosition, QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText);
} else {
QAction *clearAction = findChild<QAction *>(QLatin1String(clearButtonActionNameC));
Q_ASSERT(clearAction);
removeAction(clearAction);
delete clearAction;
}
}
bool QLineEdit::isClearButtonEnabled() const
{
return findChild<QAction *>(QLatin1String(clearButtonActionNameC));
}
void QLineEdit::setFrame(bool enable)
{
Q_D(QLineEdit);
@ -2143,6 +2179,9 @@ void QLineEdit::changeEvent(QEvent *ev)
update();
break;
case QEvent::LayoutDirectionChange:
foreach (const QLineEditPrivate::SideWidgetEntry &e, d->trailingSideWidgets) // Refresh icon to show arrow in right direction.
if (e.flags & QLineEditPrivate::SideWidgetClearButton)
static_cast<QLineEditIconButton *>(e.widget)->setIcon(d->clearButtonIcon());
d->positionSideWidgets();
break;
default:

View File

@ -85,6 +85,7 @@ class Q_WIDGETS_EXPORT QLineEdit : public QWidget
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle)
Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled)
public:
enum ActionPosition {
LeadingPosition,
@ -108,6 +109,9 @@ public:
void setFrame(bool);
bool hasFrame() const;
void setClearButtonEnabled(bool enable);
bool isClearButtonEnabled() const;
enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit };
EchoMode echoMode() const;
void setEchoMode(EchoMode);

View File

@ -368,6 +368,14 @@ QSize QLineEditPrivate::iconSize() const
return m_iconSize;
}
QIcon QLineEditPrivate::clearButtonIcon() const
{
Q_Q(const QLineEdit);
QStyleOptionFrameV2 styleOption;
q->initStyleOption(&styleOption);
return QIcon(q->style()->standardPixmap(QStyle::SP_LineEditClearButton, &styleOption, q));
}
void QLineEditPrivate::positionSideWidgets()
{
Q_Q(QLineEdit);
@ -417,6 +425,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE
QLineEditIconButton *toolButton = new QLineEditIconButton(q);
toolButton->setIcon(newAction->icon());
toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0);
if (flags & SideWidgetClearButton)
QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(clear()));
toolButton->setDefaultAction(newAction);
w = toolButton;
}

View File

@ -101,7 +101,8 @@ class Q_AUTOTEST_EXPORT QLineEditPrivate : public QWidgetPrivate
public:
enum SideWidgetFlag {
SideWidgetFadeInWithText = 0x1,
SideWidgetCreatedByWidgetAction = 0x2
SideWidgetCreatedByWidgetAction = 0x2,
SideWidgetClearButton = 0x4
};
struct SideWidgetEntry {
@ -197,6 +198,7 @@ public:
QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0);
void removeAction(const QActionEvent *e);
QSize iconSize() const;
QIcon clearButtonIcon() const;
void positionSideWidgets();
inline bool hasSideWidgets() const { return !leadingSideWidgets.isEmpty() || !trailingSideWidgets.isEmpty(); }
inline const SideWidgetEntryList &leftSideWidgetList() const

View File

@ -297,6 +297,7 @@ private slots:
void undoRedoAndEchoModes_data();
void undoRedoAndEchoModes();
void clearButton();
void sideWidgets();
protected slots:
@ -4057,6 +4058,47 @@ void tst_QLineEdit::undoRedoAndEchoModes()
QCOMPARE(testWidget->text(), expected.at(2));
}
void tst_QLineEdit::clearButton()
{
// Construct a listview with a stringlist model and filter model.
QWidget testWidget;
QVBoxLayout *l = new QVBoxLayout(&testWidget);
QLineEdit *filterLineEdit = new QLineEdit(&testWidget);
l->addWidget(filterLineEdit);
QListView *listView = new QListView(&testWidget);
QStringListModel *model = new QStringListModel(QStringList() << QStringLiteral("aa") << QStringLiteral("ab") << QStringLiteral("cc"), listView);
QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(listView);
filterModel->setSourceModel(model);
connect(filterLineEdit, SIGNAL(textChanged(QString)), filterModel, SLOT(setFilterFixedString(QString)));
listView->setModel(filterModel);
l->addWidget(listView);
testWidget.move(300, 300);
testWidget.show();
qApp->setActiveWindow(&testWidget);
QVERIFY(QTest::qWaitForWindowActive(&testWidget));
// Flip the clear button on,off, trying to detect crashes.
filterLineEdit->setClearButtonEnabled(true);
QVERIFY(filterLineEdit->isClearButtonEnabled());
filterLineEdit->setClearButtonEnabled(true);
QVERIFY(filterLineEdit->isClearButtonEnabled());
filterLineEdit->setClearButtonEnabled(false);
QVERIFY(!filterLineEdit->isClearButtonEnabled());
filterLineEdit->setClearButtonEnabled(false);
QVERIFY(!filterLineEdit->isClearButtonEnabled());
filterLineEdit->setClearButtonEnabled(true);
QVERIFY(filterLineEdit->isClearButtonEnabled());
// Emulate filtering
QToolButton *clearButton = filterLineEdit->findChild<QToolButton *>();
QVERIFY(clearButton);
QCOMPARE(filterModel->rowCount(), 3);
QTest::keyClick(filterLineEdit, 'a');
QTRY_COMPARE(filterModel->rowCount(), 2); // matches 'aa', 'ab'
QTest::keyClick(filterLineEdit, 'b');
QTRY_COMPARE(filterModel->rowCount(), 1); // matches 'ab'
QTest::mouseClick(clearButton, Qt::LeftButton, 0, QRect(QPoint(0, 0), clearButton->size()).center());
QTRY_COMPARE(filterModel->rowCount(), 3);
}
void tst_QLineEdit::sideWidgets()
{
QWidget testWidget;