QGIS API Documentation  2.99.0-Master (716ff6c)
qgsfilterlineedit.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfilterlineedit.cpp
3  ------------------------
4  begin : October 27, 2012
5  copyright : (C) 2012 by Alexander Bruy
6  email : alexander dot bruy at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsfilterlineedit.h"
19 #include "qgsapplication.h"
20 
21 #include <QToolButton>
22 #include <QStyle>
23 #include <QFocusEvent>
24 #include <QPainter>
25 
26 QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue )
27  : QLineEdit( parent )
28  , mClearButtonVisible( true )
29  , mSearchIconVisible( false )
30  , mClearMode( ClearToNull )
31  , mNullValue( nullValue )
32  , mFocusInEvent( false )
33  , mClearHover( false )
34 {
35  // need mouse tracking to handle cursor changes
36  setMouseTracking( true );
37 
38  QIcon clearIcon = QgsApplication::getThemeIcon( "/mIconClearText.svg" );
39  mClearIconSize = QSize( 16, 16 );
40  mClearIconPixmap = clearIcon.pixmap( mClearIconSize );
41  QIcon hoverIcon = QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" );
42  mClearHoverPixmap = hoverIcon.pixmap( mClearIconSize );
43 
44  QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
45  mSearchIconSize = QSize( 16, 16 );
46  mSearchIconPixmap = searchIcon.pixmap( mSearchIconSize );
47 
48  connect( this, &QLineEdit::textChanged, this,
49  &QgsFilterLineEdit::onTextChanged );
50 }
51 
53 {
54  bool changed = mClearButtonVisible != visible;
55  mClearButtonVisible = visible;
56  if ( !visible )
57  mClearHover = false;
58 
59  if ( changed )
60  update();
61 }
62 
64 {
65  bool changed = mSearchIconVisible != visible;
66  if ( changed )
67  {
68  mSearchIconVisible = visible;
69  update();
70  }
71 }
72 
73 void QgsFilterLineEdit::mousePressEvent( QMouseEvent *e )
74 {
75  if ( !mFocusInEvent )
76  QLineEdit::mousePressEvent( e );
77  else
78  mFocusInEvent = false;
79 
80  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
81  {
82  clearValue();
83  }
84 }
85 
86 void QgsFilterLineEdit::mouseMoveEvent( QMouseEvent *e )
87 {
88  QLineEdit::mouseMoveEvent( e );
89  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
90  {
91  if ( !mClearHover )
92  {
93  setCursor( Qt::ArrowCursor );
94  mClearHover = true;
95  update();
96  }
97  }
98  else if ( mClearHover )
99  {
100  setCursor( Qt::IBeamCursor );
101  mClearHover = false;
102  update();
103  }
104 }
105 
106 void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
107 {
108  QLineEdit::focusInEvent( e );
109  if ( e->reason() == Qt::MouseFocusReason && isNull() )
110  {
111  mFocusInEvent = true;
112  selectAll();
113  }
114 }
115 
117 {
118  switch ( mClearMode )
119  {
120  case ClearToNull:
121  setText( mNullValue );
122  selectAll();
123  break;
124 
125  case ClearToDefault:
126  setText( mDefaultValue );
127  break;
128  }
129 
130  if ( mClearHover )
131  {
132  setCursor( Qt::IBeamCursor );
133  mClearHover = false;
134  }
135 
136  setModified( true );
137  emit cleared();
138 }
139 
140 void QgsFilterLineEdit::paintEvent( QPaintEvent *e )
141 {
142  QLineEdit::paintEvent( e );
143  if ( shouldShowClear() )
144  {
145  QRect r = clearRect();
146  QPainter p( this );
147  if ( mClearHover )
148  p.drawPixmap( r.left(), r.top(), mClearHoverPixmap );
149  else
150  p.drawPixmap( r.left(), r.top(), mClearIconPixmap );
151  }
152 
153  if ( mSearchIconVisible && !shouldShowClear() )
154  {
155  QRect r = searchRect();
156  QPainter p( this );
157  p.drawPixmap( r.left(), r.top(), mSearchIconPixmap );
158  }
159 }
160 
162 {
163  if ( mClearHover )
164  {
165  mClearHover = false;
166  update();
167  }
168 
169  QLineEdit::leaveEvent( e );
170 }
171 
172 void QgsFilterLineEdit::onTextChanged( const QString &text )
173 {
174  if ( isNull() )
175  {
176  setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
177  emit valueChanged( QString::null );
178  }
179  else
180  {
181  setStyleSheet( mStyleSheet );
182  emit valueChanged( text );
183  }
184 
185  if ( mClearHover && !shouldShowClear() )
186  {
187  setCursor( Qt::IBeamCursor );
188  mClearHover = false;
189  }
190 }
191 
192 bool QgsFilterLineEdit::shouldShowClear() const
193 {
194  if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
195  return false;
196 
197  switch ( mClearMode )
198  {
199  case ClearToNull:
200  return !isNull();
201 
202  case ClearToDefault:
203  return value() != mDefaultValue;
204  }
205  return false; //avoid warnings
206 }
207 
208 QRect QgsFilterLineEdit::clearRect() const
209 {
210  int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
211  return QRect( rect().right() - frameWidth * 2 - mClearIconSize.width(),
212  ( rect().bottom() + 1 - mClearIconSize.height() ) / 2,
213  mClearIconSize.width(),
214  mClearIconSize.height() );
215 }
216 
217 QRect QgsFilterLineEdit::searchRect() const
218 {
219  int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
220  return QRect( rect().left() + frameWidth * 2,
221  ( rect().bottom() + 1 - mSearchIconSize.height() ) / 2,
222  mSearchIconSize.width(),
223  mSearchIconSize.height() );
224 }
void valueChanged(const QString &value)
Same as textChanged() but with support for null values.
void leaveEvent(QEvent *e) override
void mouseMoveEvent(QMouseEvent *e) override
void paintEvent(QPaintEvent *e) override
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void setShowSearchIcon(bool visible)
Define if a search icon shall be shown on the left of the image when no text is entered.
void mousePressEvent(QMouseEvent *e) override
Reset value to default value (see defaultValue() )
virtual void clearValue()
Clears the widget and resets it to the null value.
QgsFilterLineEdit(QWidget *parent=nullptr, const QString &nullValue=QString::null)
Constructor for QgsFilterLineEdit.
void focusInEvent(QFocusEvent *e) override
void cleared()
Emitted when the widget is cleared.
bool isNull() const
Determine if the current text represents null.
void setShowClearButton(bool visible)
Sets whether the widget&#39;s clear button is visible.
QString value() const
Returns the text of this edit with support for handling null values.