2121#include < QToolButton>
2222#include < QStyle>
2323#include < QFocusEvent>
24+ #include < QPainter>
2425
2526QgsFilterLineEdit::QgsFilterLineEdit ( QWidget* parent, const QString& nullValue )
2627 : QLineEdit( parent )
2728 , mNullValue( nullValue )
2829 , mFocusInEvent( false )
30+ , mClearHover( false )
2931{
30- btnClear = new QToolButton ( this );
31- btnClear-> setIcon ( QgsApplication::getThemeIcon ( " /mIconClear.svg " ) );
32- btnClear-> setCursor ( Qt::ArrowCursor );
33- btnClear-> setFocusPolicy ( Qt::NoFocus );
34- btnClear-> setStyleSheet ( " QToolButton { border: none; padding: 0px; } " );
35- btnClear-> hide ( );
36-
37- connect ( btnClear, SIGNAL ( clicked () ), this , SLOT ( clear () ) );
38- connect ( btnClear, SIGNAL ( clicked () ), this , SIGNAL ( cleared () ) );
32+ // need mouse tracking to handle cursor changes
33+ setMouseTracking ( true );
34+
35+ QIcon clearIcon = QgsApplication::getThemeIcon ( " /mIconClearText.svg " );
36+ mClearIconSize = QSize ( 16 , 16 );
37+ mClearIconPixmap = clearIcon. pixmap ( mClearIconSize );
38+ QIcon hoverIcon = QgsApplication::getThemeIcon ( " /mIconClearTextHover.svg " );
39+ mClearHoverPixmap = hoverIcon. pixmap ( mClearIconSize );
40+
3941 connect ( this , SIGNAL ( textChanged ( const QString& ) ), this ,
4042 SLOT ( onTextChanged ( const QString& ) ) );
4143
4244 int frameWidth = style ()->pixelMetric ( QStyle::PM_DefaultFrameWidth );
43- mStyleSheet = QString ( " QLineEdit { padding-right: %1px; } " )
44- .arg ( btnClear->sizeHint ().width () + frameWidth + 1 );
45-
4645 QSize msz = minimumSizeHint ();
47- setMinimumSize ( qMax ( msz.width (), btnClear-> sizeHint (). height () + frameWidth * 2 + 2 ),
48- qMax ( msz.height (), btnClear-> sizeHint () .height () + frameWidth * 2 + 2 ) );
46+ setMinimumSize ( qMax ( msz.width (), mClearIconSize . width () + frameWidth * 2 + 2 ),
47+ qMax ( msz.height (), mClearIconSize .height () + frameWidth * 2 + 2 ) );
4948}
5049
5150void QgsFilterLineEdit::mousePressEvent ( QMouseEvent* e )
@@ -54,6 +53,32 @@ void QgsFilterLineEdit::mousePressEvent( QMouseEvent* e )
5453 QLineEdit::mousePressEvent ( e );
5554 else
5655 mFocusInEvent = false ;
56+
57+ if ( shouldShowClear () && clearRect ().contains ( e->pos () ) )
58+ {
59+ clear ();
60+ emit cleared ();
61+ }
62+ }
63+
64+ void QgsFilterLineEdit::mouseMoveEvent ( QMouseEvent* e )
65+ {
66+ QLineEdit::mouseMoveEvent ( e );
67+ if ( shouldShowClear () && clearRect ().contains ( e->pos () ) )
68+ {
69+ if ( !mClearHover )
70+ {
71+ setCursor ( Qt::ArrowCursor );
72+ mClearHover = true ;
73+ update ();
74+ }
75+ }
76+ else if ( mClearHover )
77+ {
78+ setCursor ( Qt::IBeamCursor );
79+ mClearHover = false ;
80+ update ();
81+ }
5782}
5883
5984void QgsFilterLineEdit::focusInEvent ( QFocusEvent* e )
@@ -66,37 +91,39 @@ void QgsFilterLineEdit::focusInEvent( QFocusEvent* e )
6691 }
6792}
6893
69- void QgsFilterLineEdit::resizeEvent ( QResizeEvent * )
70- {
71- QSize sz = btnClear->sizeHint ();
72- int frameWidth = style ()->pixelMetric ( QStyle::PM_DefaultFrameWidth );
73- btnClear->move ( rect ().right () - frameWidth - sz.width (),
74- ( rect ().bottom () + 1 - sz.height () ) / 2 );
75- }
76-
7794void QgsFilterLineEdit::clear ()
7895{
7996 setText ( mNullValue );
8097 setModified ( true );
8198}
8299
83- void QgsFilterLineEdit::changeEvent ( QEvent *e )
84- {
85- QLineEdit::changeEvent ( e );
86- btnClear->setVisible ( isEnabled () && !isReadOnly () && !isNull () );
87- }
88-
89100void QgsFilterLineEdit::paintEvent ( QPaintEvent* e )
90101{
91102 QLineEdit::paintEvent ( e );
92- btnClear->setVisible ( isEnabled () && !isReadOnly () && !isNull () );
103+ if ( shouldShowClear () )
104+ {
105+ QRect r = clearRect ();
106+ QPainter p ( this );
107+ if ( mClearHover )
108+ p.drawPixmap ( r.left () , r.top () , mClearHoverPixmap );
109+ else
110+ p.drawPixmap ( r.left () , r.top () , mClearIconPixmap );
111+ }
93112}
94113
114+ void QgsFilterLineEdit::leaveEvent ( QEvent* e )
115+ {
116+ if ( mClearHover )
117+ {
118+ mClearHover = false ;
119+ update ();
120+ }
121+
122+ QLineEdit::leaveEvent ( e );
123+ }
95124
96125void QgsFilterLineEdit::onTextChanged ( const QString &text )
97126{
98- btnClear->setVisible ( isEnabled () && !isReadOnly () && !isNull () );
99-
100127 if ( isNull () )
101128 {
102129 setStyleSheet ( QString ( " QLineEdit { font: italic; color: gray; } %1" ).arg ( mStyleSheet ) );
@@ -108,3 +135,17 @@ void QgsFilterLineEdit::onTextChanged( const QString &text )
108135 emit valueChanged ( text );
109136 }
110137}
138+
139+ bool QgsFilterLineEdit::shouldShowClear () const
140+ {
141+ return isEnabled () && !isReadOnly () && !isNull ();
142+ }
143+
144+ QRect QgsFilterLineEdit::clearRect () const
145+ {
146+ int frameWidth = style ()->pixelMetric ( QStyle::PM_DefaultFrameWidth );
147+ return QRect ( rect ().right () - frameWidth * 2 - mClearIconSize .width (),
148+ ( rect ().bottom () + 1 - mClearIconSize .height () ) / 2 ,
149+ mClearIconSize .width (),
150+ mClearIconSize .height () );
151+ }
0 commit comments