Add side widgets to QLineEdit via QAction.
Add QLineEdit::addAction() overloads, allowing for a variable number of icons or user-defined widgets. Change-Id: Id298f18c2f47cc998170357e65cc6098df851aab Done-with: Kevin.Ottens@kdab.com Reviewed-by: Thomas Zander <zander@kde.org> Reviewed-by: Richard J. Moore <rich@kde.org> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>bb10
parent
c207724c9b
commit
9ce12cc8de
|
|
@ -420,6 +420,60 @@ bool QLineEdit::hasFrame() const
|
|||
return d->frame;
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QLineEdit::ActionPosition
|
||||
|
||||
This enum type describes how a line edit should display the action widgets to be
|
||||
added.
|
||||
|
||||
\value LeadingPosition The widget is displayed to the left of the text
|
||||
when using layout direction \c Qt::LeftToRight or to
|
||||
the right when using \c Qt::RightToLeft, respectively.
|
||||
|
||||
\value TrailingPosition The widget is displayed to the right of the text
|
||||
when using layout direction \c Qt::LeftToRight or to
|
||||
the left when using \c Qt::RightToLeft, respectively.
|
||||
|
||||
\sa addAction(), removeAction(), QWidget::layoutDirection
|
||||
|
||||
\since 5.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QLineEdit::addAction(QAction *action)
|
||||
\overload
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\overload
|
||||
|
||||
Adds the \a action to the list of actions at the \a position.
|
||||
|
||||
\since 5.2
|
||||
*/
|
||||
|
||||
void QLineEdit::addAction(QAction *action, ActionPosition position)
|
||||
{
|
||||
Q_D(QLineEdit);
|
||||
QWidget::addAction(action);
|
||||
d->addAction(action, 0, position);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
|
||||
Creates a new action with the given \a icon at the \a position.
|
||||
|
||||
\since 5.2
|
||||
*/
|
||||
|
||||
QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
|
||||
{
|
||||
QAction *result = new QAction(icon, QString(), this);
|
||||
addAction(result, position);
|
||||
return result;
|
||||
}
|
||||
|
||||
void QLineEdit::setFrame(bool enable)
|
||||
{
|
||||
|
|
@ -606,7 +660,7 @@ QSize QLineEdit::sizeHint() const
|
|||
+ d->topTextMargin + d->bottomTextMargin
|
||||
+ d->topmargin + d->bottommargin;
|
||||
int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
|
||||
+ d->leftTextMargin + d->rightTextMargin
|
||||
+ d->effectiveLeftTextMargin() + d->effectiveRightTextMargin()
|
||||
+ d->leftmargin + d->rightmargin; // "some"
|
||||
QStyleOptionFrameV2 opt;
|
||||
initStyleOption(&opt);
|
||||
|
|
@ -967,7 +1021,6 @@ void QLineEdit::setDragEnabled(bool b)
|
|||
d->dragEnabled = b;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\property QLineEdit::cursorMoveStyle
|
||||
\brief the movement style of cursor in this line edit
|
||||
|
|
@ -1350,8 +1403,11 @@ bool QLineEdit::event(QEvent * e)
|
|||
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
|
||||
d->setCursorVisible(true);
|
||||
}
|
||||
} else if (e->type() == QEvent::ActionRemoved) {
|
||||
d->removeAction(static_cast<QActionEvent *>(e));
|
||||
} else if (e->type() == QEvent::Resize) {
|
||||
d->positionSideWidgets();
|
||||
}
|
||||
|
||||
#ifdef QT_KEYPAD_NAVIGATION
|
||||
if (QApplication::keypadNavigationEnabled()) {
|
||||
if (e->type() == QEvent::EnterEditFocus) {
|
||||
|
|
@ -1777,9 +1833,9 @@ void QLineEdit::paintEvent(QPaintEvent *)
|
|||
initStyleOption(&panel);
|
||||
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
|
||||
r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
|
||||
r.setX(r.x() + d->leftTextMargin);
|
||||
r.setX(r.x() + d->effectiveLeftTextMargin());
|
||||
r.setY(r.y() + d->topTextMargin);
|
||||
r.setRight(r.right() - d->rightTextMargin);
|
||||
r.setRight(r.right() - d->effectiveRightTextMargin());
|
||||
r.setBottom(r.bottom() - d->bottomTextMargin);
|
||||
p.setClipRect(r);
|
||||
|
||||
|
|
@ -2083,8 +2139,12 @@ void QLineEdit::changeEvent(QEvent *ev)
|
|||
initStyleOption(&opt);
|
||||
d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
|
||||
}
|
||||
d->m_iconSize = QSize();
|
||||
update();
|
||||
break;
|
||||
case QEvent::LayoutDirectionChange:
|
||||
d->positionSideWidgets();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,12 +59,14 @@ class QCompleter;
|
|||
class QStyleOptionFrame;
|
||||
class QAbstractSpinBox;
|
||||
class QDateTimeEdit;
|
||||
class QIcon;
|
||||
class QToolButton;
|
||||
|
||||
class Q_WIDGETS_EXPORT QLineEdit : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_ENUMS(EchoMode)
|
||||
Q_ENUMS(ActionPosition EchoMode)
|
||||
Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask)
|
||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true)
|
||||
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
|
||||
|
|
@ -83,8 +85,12 @@ 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)
|
||||
|
||||
public:
|
||||
enum ActionPosition {
|
||||
LeadingPosition,
|
||||
TrailingPosition
|
||||
};
|
||||
|
||||
explicit QLineEdit(QWidget* parent=0);
|
||||
explicit QLineEdit(const QString &, QWidget* parent=0);
|
||||
~QLineEdit();
|
||||
|
|
@ -164,6 +170,16 @@ public:
|
|||
void getTextMargins(int *left, int *top, int *right, int *bottom) const;
|
||||
QMargins textMargins() const;
|
||||
|
||||
#ifdef Q_NO_USING_KEYWORD
|
||||
inline void addAction(QAction *action)
|
||||
{ QWidget::addAction(action); }
|
||||
#else
|
||||
using QWidget::addAction;
|
||||
#endif
|
||||
|
||||
void addAction(QAction *action, ActionPosition position);
|
||||
QAction *addAction(const QIcon &icon, ActionPosition position);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setText(const QString &);
|
||||
void clear();
|
||||
|
|
@ -240,6 +256,7 @@ private:
|
|||
#endif
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString &))
|
||||
};
|
||||
|
||||
#endif // QT_NO_LINEEDIT
|
||||
|
|
|
|||
|
|
@ -44,8 +44,10 @@
|
|||
|
||||
#ifndef QT_NO_LINEEDIT
|
||||
|
||||
#include "qvariant.h"
|
||||
#include "qabstractitemview.h"
|
||||
#include "qdrag.h"
|
||||
#include "qwidgetaction.h"
|
||||
#include "qclipboard.h"
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
#include "qaccessible.h"
|
||||
|
|
@ -53,6 +55,7 @@
|
|||
#ifndef QT_NO_IM
|
||||
#include "qinputmethod.h"
|
||||
#include "qlist.h"
|
||||
#include <qpropertyanimation.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -219,9 +222,9 @@ QRect QLineEditPrivate::adjustedContentsRect() const
|
|||
QStyleOptionFrameV2 opt;
|
||||
q->initStyleOption(&opt);
|
||||
QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
|
||||
r.setX(r.x() + leftTextMargin);
|
||||
r.setX(r.x() + effectiveLeftTextMargin());
|
||||
r.setY(r.y() + topTextMargin);
|
||||
r.setRight(r.right() - rightTextMargin);
|
||||
r.setRight(r.right() - effectiveRightTextMargin());
|
||||
r.setBottom(r.bottom() - bottomTextMargin);
|
||||
return r;
|
||||
}
|
||||
|
|
@ -297,6 +300,160 @@ void QLineEditPrivate::drag()
|
|||
|
||||
#endif // QT_NO_DRAGANDDROP
|
||||
|
||||
QLineEditIconButton::QLineEditIconButton(QWidget *parent)
|
||||
: QToolButton(parent)
|
||||
, m_opacity(0)
|
||||
{
|
||||
#ifndef QT_NO_CURSOR
|
||||
setCursor(Qt::ArrowCursor);
|
||||
#endif
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
void QLineEditIconButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
// Note isDown should really use the active state but in most styles
|
||||
// this has no proper feedback
|
||||
QIcon::Mode state = QIcon::Disabled;
|
||||
if (isEnabled())
|
||||
state = isDown() ? QIcon::Selected : QIcon::Normal;
|
||||
const QPixmap iconPixmap = icon().pixmap(QSize(IconButtonSize, IconButtonSize),
|
||||
state, QIcon::Off);
|
||||
QRect pixmapRect = QRect(0, 0, iconPixmap.width(), iconPixmap.height());
|
||||
pixmapRect.moveCenter(rect().center());
|
||||
painter.setOpacity(m_opacity);
|
||||
painter.drawPixmap(pixmapRect, iconPixmap);
|
||||
}
|
||||
|
||||
void QLineEditIconButton::setOpacity(qreal value)
|
||||
{
|
||||
if (!qFuzzyCompare(m_opacity, value)) {
|
||||
m_opacity = value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void QLineEditIconButton::startOpacityAnimation(qreal endValue)
|
||||
{
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"));
|
||||
animation->setDuration(160);
|
||||
animation->setEndValue(endValue);
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
|
||||
void QLineEditPrivate::_q_textChanged(const QString &text)
|
||||
{
|
||||
if (hasSideWidgets()) {
|
||||
const int newTextSize = text.size();
|
||||
if (!newTextSize || !lastTextSize) {
|
||||
lastTextSize = newTextSize;
|
||||
const bool fadeIn = newTextSize > 0;
|
||||
foreach (const SideWidgetEntry &e, leadingSideWidgets) {
|
||||
if (e.flags & SideWidgetFadeInWithText)
|
||||
static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
|
||||
}
|
||||
foreach (const SideWidgetEntry &e, trailingSideWidgets) {
|
||||
if (e.flags & SideWidgetFadeInWithText)
|
||||
static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSize QLineEditPrivate::iconSize() const
|
||||
{
|
||||
if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric).
|
||||
m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2);
|
||||
return m_iconSize;
|
||||
}
|
||||
|
||||
void QLineEditPrivate::positionSideWidgets()
|
||||
{
|
||||
Q_Q(QLineEdit);
|
||||
if (hasSideWidgets()) {
|
||||
const QRect contentRect = q->rect();
|
||||
const QSize iconSize = QLineEditPrivate::iconSize();
|
||||
const int delta = QLineEditIconButton::IconMargin + iconSize.width();
|
||||
QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize);
|
||||
foreach (const SideWidgetEntry &e, leftSideWidgetList()) {
|
||||
e.widget->setGeometry(widgetGeometry);
|
||||
widgetGeometry.moveLeft(widgetGeometry.left() + delta);
|
||||
}
|
||||
widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin);
|
||||
foreach (const SideWidgetEntry &e, rightSideWidgetList()) {
|
||||
e.widget->setGeometry(widgetGeometry);
|
||||
widgetGeometry.moveLeft(widgetGeometry.left() - delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QLineEditPrivate::PositionIndexPair QLineEditPrivate::findSideWidget(const QAction *a) const
|
||||
{
|
||||
for (int i = 0; i < leadingSideWidgets.size(); ++i) {
|
||||
if (a == leadingSideWidgets.at(i).action)
|
||||
return PositionIndexPair(QLineEdit::LeadingPosition, i);
|
||||
}
|
||||
for (int i = 0; i < trailingSideWidgets.size(); ++i) {
|
||||
if (a == trailingSideWidgets.at(i).action)
|
||||
return PositionIndexPair(QLineEdit::TrailingPosition, i);
|
||||
}
|
||||
return PositionIndexPair(QLineEdit::LeadingPosition, -1);
|
||||
}
|
||||
|
||||
QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition position, int flags)
|
||||
{
|
||||
Q_Q(QLineEdit);
|
||||
if (!newAction)
|
||||
return 0;
|
||||
QWidget *w = 0;
|
||||
// Store flags about QWidgetAction here since removeAction() may be called from ~QAction,
|
||||
// in which a qobject_cast<> no longer works.
|
||||
if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(newAction)) {
|
||||
if ((w = widgetAction->requestWidget(q)))
|
||||
flags |= SideWidgetCreatedByWidgetAction;
|
||||
}
|
||||
if (!w) {
|
||||
QLineEditIconButton *toolButton = new QLineEditIconButton(q);
|
||||
toolButton->setIcon(newAction->icon());
|
||||
toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0);
|
||||
toolButton->setDefaultAction(newAction);
|
||||
w = toolButton;
|
||||
}
|
||||
if (!hasSideWidgets()) { // initial setup.
|
||||
QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
|
||||
lastTextSize = q->text().size();
|
||||
}
|
||||
// If there is a 'before' action, it takes preference
|
||||
PositionIndexPair positionIndex = before ? findSideWidget(before) : PositionIndexPair(position, -1);
|
||||
SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
|
||||
if (positionIndex.second < 0)
|
||||
positionIndex.second = list.size();
|
||||
list.insert(positionIndex.second, SideWidgetEntry(w, newAction, flags));
|
||||
positionSideWidgets();
|
||||
w->show();
|
||||
return w;
|
||||
}
|
||||
|
||||
void QLineEditPrivate::removeAction(const QActionEvent *e)
|
||||
{
|
||||
Q_Q(QLineEdit);
|
||||
QAction *action = e->action();
|
||||
const PositionIndexPair positionIndex = findSideWidget(action);
|
||||
if (positionIndex.second == -1)
|
||||
return;
|
||||
SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
|
||||
SideWidgetEntry entry = list.takeAt(positionIndex.second);
|
||||
if (entry.flags & SideWidgetCreatedByWidgetAction)
|
||||
static_cast<QWidgetAction *>(entry.action)->releaseWidget(entry.widget);
|
||||
else
|
||||
delete entry.widget;
|
||||
positionSideWidgets();
|
||||
if (!hasSideWidgets()) // Last widget, remove connection
|
||||
QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
|
||||
q->update();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@
|
|||
#ifndef QT_NO_LINEEDIT
|
||||
#include "private/qwidget_p.h"
|
||||
#include "QtWidgets/qlineedit.h"
|
||||
#include "QtWidgets/qtoolbutton.h"
|
||||
#include "QtGui/qtextlayout.h"
|
||||
#include "QtGui/qicon.h"
|
||||
#include "QtWidgets/qstyleoption.h"
|
||||
#include "QtCore/qbasictimer.h"
|
||||
#include "QtWidgets/qcompleter.h"
|
||||
|
|
@ -69,16 +71,54 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text
|
||||
|
||||
class QLineEditIconButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
|
||||
public:
|
||||
enum { IconMargin = 4, IconButtonSize = 16 };
|
||||
|
||||
explicit QLineEditIconButton(QWidget *parent = 0);
|
||||
|
||||
qreal opacity() const { return m_opacity; }
|
||||
void setOpacity(qreal value);
|
||||
void animateShow(bool visible) { startOpacityAnimation(visible ? 1.0 : 0.0); }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
void startOpacityAnimation(qreal endValue);
|
||||
|
||||
qreal m_opacity;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QLineEditPrivate : public QWidgetPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QLineEdit)
|
||||
public:
|
||||
enum SideWidgetFlag {
|
||||
SideWidgetFadeInWithText = 0x1,
|
||||
SideWidgetCreatedByWidgetAction = 0x2
|
||||
};
|
||||
|
||||
struct SideWidgetEntry {
|
||||
SideWidgetEntry(QWidget *w = 0, QAction *a = 0, int _flags = 0) : widget(w), action(a), flags(_flags) {}
|
||||
|
||||
QWidget *widget;
|
||||
QAction *action;
|
||||
int flags;
|
||||
};
|
||||
typedef QList<SideWidgetEntry> SideWidgetEntryList;
|
||||
|
||||
QLineEditPrivate()
|
||||
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
|
||||
dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
|
||||
alignment(Qt::AlignLeading | Qt::AlignVCenter),
|
||||
leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
|
||||
leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0),
|
||||
lastTextSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -145,15 +185,49 @@ public:
|
|||
QBasicTimer dndTimer;
|
||||
void drag();
|
||||
#endif
|
||||
void _q_textChanged(const QString &);
|
||||
|
||||
int leftTextMargin;
|
||||
int leftTextMargin; // use effectiveLeftTextMargin() in case of icon.
|
||||
int topTextMargin;
|
||||
int rightTextMargin;
|
||||
int rightTextMargin; // use effectiveRightTextMargin() in case of icon.
|
||||
int bottomTextMargin;
|
||||
|
||||
QString placeholderText;
|
||||
|
||||
QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0);
|
||||
void removeAction(const QActionEvent *e);
|
||||
QSize iconSize() const;
|
||||
void positionSideWidgets();
|
||||
inline bool hasSideWidgets() const { return !leadingSideWidgets.isEmpty() || !trailingSideWidgets.isEmpty(); }
|
||||
inline const SideWidgetEntryList &leftSideWidgetList() const
|
||||
{ return q_func()->layoutDirection() == Qt::LeftToRight ? leadingSideWidgets : trailingSideWidgets; }
|
||||
inline const SideWidgetEntryList &rightSideWidgetList() const
|
||||
{ return q_func()->layoutDirection() == Qt::LeftToRight ? trailingSideWidgets : leadingSideWidgets; }
|
||||
|
||||
int effectiveLeftTextMargin() const;
|
||||
int effectiveRightTextMargin() const;
|
||||
|
||||
private:
|
||||
typedef QPair<QLineEdit::ActionPosition, int> PositionIndexPair;
|
||||
|
||||
PositionIndexPair findSideWidget(const QAction *a) const;
|
||||
|
||||
SideWidgetEntryList leadingSideWidgets;
|
||||
SideWidgetEntryList trailingSideWidgets;
|
||||
int lastTextSize;
|
||||
mutable QSize m_iconSize;
|
||||
};
|
||||
|
||||
inline int QLineEditPrivate::effectiveLeftTextMargin() const
|
||||
{
|
||||
return leftTextMargin + leftSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
|
||||
}
|
||||
|
||||
inline int QLineEditPrivate::effectiveRightTextMargin() const
|
||||
{
|
||||
return rightTextMargin + rightSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
|
||||
}
|
||||
|
||||
#endif // QT_NO_LINEEDIT
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@
|
|||
#include "qstringlist.h"
|
||||
#include "qstyle.h"
|
||||
#include "qvalidator.h"
|
||||
#include "qwidgetaction.h"
|
||||
#include "qimage.h"
|
||||
#include "qicon.h"
|
||||
#include "qcompleter.h"
|
||||
#include "qstandarditemmodel.h"
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
|
@ -61,8 +64,12 @@
|
|||
#include <private/qlineedit_p.h>
|
||||
#include <private/qwidgetlinecontrol_p.h>
|
||||
#include <qmenu.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlayout.h>
|
||||
#include <qspinbox.h>
|
||||
#include <qlistview.h>
|
||||
#include <qstringlistmodel.h>
|
||||
#include <qsortfilterproxymodel.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
#include "qcommonstyle.h"
|
||||
|
|
@ -290,6 +297,8 @@ private slots:
|
|||
void undoRedoAndEchoModes_data();
|
||||
void undoRedoAndEchoModes();
|
||||
|
||||
void sideWidgets();
|
||||
|
||||
protected slots:
|
||||
void editingFinished();
|
||||
|
||||
|
|
@ -4048,5 +4057,39 @@ void tst_QLineEdit::undoRedoAndEchoModes()
|
|||
QCOMPARE(testWidget->text(), expected.at(2));
|
||||
}
|
||||
|
||||
void tst_QLineEdit::sideWidgets()
|
||||
{
|
||||
QWidget testWidget;
|
||||
QVBoxLayout *l = new QVBoxLayout(&testWidget);
|
||||
QLineEdit *lineEdit = new QLineEdit(&testWidget);
|
||||
l->addWidget(lineEdit);
|
||||
l->addSpacerItem(new QSpacerItem(0, 50, QSizePolicy::Ignored, QSizePolicy::Fixed));
|
||||
QImage image(QSize(20, 20), QImage::Format_ARGB32);
|
||||
image.fill(Qt::yellow);
|
||||
QAction *iconAction = new QAction(QIcon(QPixmap::fromImage(image)), QString(), lineEdit);
|
||||
QWidgetAction *label1Action = new QWidgetAction(lineEdit);
|
||||
label1Action->setDefaultWidget(new QLabel(QStringLiteral("l1")));
|
||||
QWidgetAction *label2Action = new QWidgetAction(lineEdit);
|
||||
label2Action->setDefaultWidget(new QLabel(QStringLiteral("l2")));
|
||||
QWidgetAction *label3Action = new QWidgetAction(lineEdit);
|
||||
label3Action->setDefaultWidget(new QLabel(QStringLiteral("l3")));
|
||||
lineEdit->addAction(iconAction, QLineEdit::LeadingPosition);
|
||||
lineEdit->addAction(label2Action, QLineEdit::LeadingPosition);
|
||||
lineEdit->addAction(label1Action, QLineEdit::TrailingPosition);
|
||||
lineEdit->addAction(label3Action, QLineEdit::TrailingPosition);
|
||||
testWidget.move(300, 300);
|
||||
testWidget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
|
||||
// Arbitrarily add/remove actions, trying to detect crashes. Add QTRY_VERIFY(false) to view the result.
|
||||
delete label3Action;
|
||||
lineEdit->removeAction(label2Action);
|
||||
lineEdit->removeAction(iconAction);
|
||||
lineEdit->removeAction(label1Action);
|
||||
lineEdit->removeAction(iconAction);
|
||||
lineEdit->removeAction(label1Action);
|
||||
lineEdit->addAction(iconAction);
|
||||
lineEdit->addAction(iconAction);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QLineEdit)
|
||||
#include "tst_qlineedit.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue