QGIS API Documentation  2.99.0-Master (ae4d26a)
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  , mNullValue( nullValue )
29 {
30  // need mouse tracking to handle cursor changes
31  setMouseTracking( true );
32 
33  QIcon clearIcon = QgsApplication::getThemeIcon( "/mIconClearText.svg" );
34  mClearIconSize = QSize( 16, 16 );
35  mClearIconPixmap = clearIcon.pixmap( mClearIconSize );
36  QIcon hoverIcon = QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" );
37  mClearHoverPixmap = hoverIcon.pixmap( mClearIconSize );
38 
39  QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
40  mSearchIconSize = QSize( 16, 16 );
41  mSearchIconPixmap = searchIcon.pixmap( mSearchIconSize );
42 
43  connect( this, &QLineEdit::textChanged, this,
44  &QgsFilterLineEdit::onTextChanged );
45 }
46 
48 {
49  bool changed = mClearButtonVisible != visible;
50  mClearButtonVisible = visible;
51  if ( !visible )
52  mClearHover = false;
53 
54  if ( changed )
55  update();
56 }
57 
59 {
60  bool changed = mSearchIconVisible != visible;
61  if ( changed )
62  {
63  mSearchIconVisible = visible;
64  update();
65  }
66 }
67 
68 void QgsFilterLineEdit::mousePressEvent( QMouseEvent *e )
69 {
70  if ( !mFocusInEvent )
71  QLineEdit::mousePressEvent( e );
72  else
73  mFocusInEvent = false;
74 
75  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
76  {
77  clearValue();
78  }
79 }
80 
81 void QgsFilterLineEdit::mouseMoveEvent( QMouseEvent *e )
82 {
83  QLineEdit::mouseMoveEvent( e );
84  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
85  {
86  if ( !mClearHover )
87  {
88  setCursor( Qt::ArrowCursor );
89  mClearHover = true;
90  update();
91  }
92  }
93  else if ( mClearHover )
94  {
95  setCursor( Qt::IBeamCursor );
96  mClearHover = false;
97  update();
98  }
99 }
100 
101 void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
102 {
103  QLineEdit::focusInEvent( e );
104  if ( e->reason() == Qt::MouseFocusReason && isNull() )
105  {
106  mFocusInEvent = true;
107  selectAll();
108  }
109 }
110 
112 {
113  switch ( mClearMode )
114  {
115  case ClearToNull:
116  setText( mNullValue );
117  selectAll();
118  break;
119 
120  case ClearToDefault:
121  setText( mDefaultValue );
122  break;
123  }
124 
125  if ( mClearHover )
126  {
127  setCursor( Qt::IBeamCursor );
128  mClearHover = false;
129  }
130 
131  setModified( true );
132  emit cleared();
133 }
134 
135 void QgsFilterLineEdit::paintEvent( QPaintEvent *e )
136 {
137  QLineEdit::paintEvent( e );
138  if ( shouldShowClear() )
139  {
140  QRect r = clearRect();
141  QPainter p( this );
142  if ( mClearHover )
143  p.drawPixmap( r.left(), r.top(), mClearHoverPixmap );
144  else
145  p.drawPixmap( r.left(), r.top(), mClearIconPixmap );
146  }
147 
148  if ( mSearchIconVisible && !shouldShowClear() )
149  {
150  QRect r = searchRect();
151  QPainter p( this );
152  p.drawPixmap( r.left(), r.top(), mSearchIconPixmap );
153  }
154 }
155 
157 {
158  if ( mClearHover )
159  {
160  mClearHover = false;
161  update();
162  }
163 
164  QLineEdit::leaveEvent( e );
165 }
166 
167 void QgsFilterLineEdit::onTextChanged( const QString &text )
168 {
169  if ( isNull() )
170  {
171  setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
172  emit valueChanged( QString() );
173  }
174  else
175  {
176  setStyleSheet( mStyleSheet );
177  emit valueChanged( text );
178  }
179 
180  if ( mClearHover && !shouldShowClear() )
181  {
182  setCursor( Qt::IBeamCursor );
183  mClearHover = false;
184  }
185 }
186 
187 bool QgsFilterLineEdit::shouldShowClear() const
188 {
189  if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
190  return false;
191 
192  switch ( mClearMode )
193  {
194  case ClearToNull:
195  return !isNull();
196 
197  case ClearToDefault:
198  return value() != mDefaultValue;
199  }
200  return false; //avoid warnings
201 }
202 
203 QRect QgsFilterLineEdit::clearRect() const
204 {
205  int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
206  return QRect( rect().right() - frameWidth * 2 - mClearIconSize.width(),
207  ( rect().bottom() + 1 - mClearIconSize.height() ) / 2,
208  mClearIconSize.width(),
209  mClearIconSize.height() );
210 }
211 
212 QRect QgsFilterLineEdit::searchRect() const
213 {
214  int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
215  return QRect( rect().left() + frameWidth * 2,
216  ( rect().bottom() + 1 - mSearchIconSize.height() ) / 2,
217  mSearchIconSize.width(),
218  mSearchIconSize.height() );
219 }
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.
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.
QgsFilterLineEdit(QWidget *parent=0, const QString &nullValue=QString())
Constructor for QgsFilterLineEdit.
QString value() const
Returns the text of this edit with support for handling null values.