QGIS API Documentation  2.99.0-Master (8ec3eaf)
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  , mClearMode( ClearToNull )
30  , mNullValue( nullValue )
31  , mFocusInEvent( false )
32  , mClearHover( false )
33 {
34  // need mouse tracking to handle cursor changes
35  setMouseTracking( true );
36 
37  QIcon clearIcon = QgsApplication::getThemeIcon( "/mIconClearText.svg" );
38  mClearIconSize = QSize( 16, 16 );
39  mClearIconPixmap = clearIcon.pixmap( mClearIconSize );
40  QIcon hoverIcon = QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" );
41  mClearHoverPixmap = hoverIcon.pixmap( mClearIconSize );
42 
43  connect( this, SIGNAL( textChanged( const QString& ) ), this,
44  SLOT( onTextChanged( const QString& ) ) );
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 
58 void QgsFilterLineEdit::mousePressEvent( QMouseEvent* e )
59 {
60  if ( !mFocusInEvent )
61  QLineEdit::mousePressEvent( e );
62  else
63  mFocusInEvent = false;
64 
65  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
66  {
67  clearValue();
68  }
69 }
70 
71 void QgsFilterLineEdit::mouseMoveEvent( QMouseEvent* e )
72 {
73  QLineEdit::mouseMoveEvent( e );
74  if ( shouldShowClear() && clearRect().contains( e->pos() ) )
75  {
76  if ( !mClearHover )
77  {
78  setCursor( Qt::ArrowCursor );
79  mClearHover = true;
80  update();
81  }
82  }
83  else if ( mClearHover )
84  {
85  setCursor( Qt::IBeamCursor );
86  mClearHover = false;
87  update();
88  }
89 }
90 
91 void QgsFilterLineEdit::focusInEvent( QFocusEvent* e )
92 {
93  QLineEdit::focusInEvent( e );
94  if ( e->reason() == Qt::MouseFocusReason && isNull() )
95  {
96  mFocusInEvent = true;
97  selectAll();
98  }
99 }
100 
102 {
103  switch ( mClearMode )
104  {
105  case ClearToNull:
106  setText( mNullValue );
107  selectAll();
108  break;
109 
110  case ClearToDefault:
111  setText( mDefaultValue );
112  break;
113  }
114 
115  if ( mClearHover )
116  {
117  setCursor( Qt::IBeamCursor );
118  mClearHover = false;
119  }
120 
121  setModified( true );
122  emit cleared();
123 }
124 
125 void QgsFilterLineEdit::paintEvent( QPaintEvent* e )
126 {
127  QLineEdit::paintEvent( e );
128  if ( shouldShowClear() )
129  {
130  QRect r = clearRect();
131  QPainter p( this );
132  if ( mClearHover )
133  p.drawPixmap( r.left() , r.top() , mClearHoverPixmap );
134  else
135  p.drawPixmap( r.left() , r.top() , mClearIconPixmap );
136  }
137 }
138 
140 {
141  if ( mClearHover )
142  {
143  mClearHover = false;
144  update();
145  }
146 
147  QLineEdit::leaveEvent( e );
148 }
149 
150 void QgsFilterLineEdit::onTextChanged( const QString &text )
151 {
152  if ( isNull() )
153  {
154  setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
155  emit valueChanged( QString::null );
156  }
157  else
158  {
159  setStyleSheet( mStyleSheet );
160  emit valueChanged( text );
161  }
162 
163  if ( mClearHover && !shouldShowClear() )
164  {
165  setCursor( Qt::IBeamCursor );
166  mClearHover = false;
167  }
168 }
169 
170 bool QgsFilterLineEdit::shouldShowClear() const
171 {
172  if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
173  return false;
174 
175  switch ( mClearMode )
176  {
177  case ClearToNull:
178  return !isNull();
179 
180  case ClearToDefault:
181  return value() != mDefaultValue;
182  }
183  return false; //avoid warnings
184 }
185 
186 QRect QgsFilterLineEdit::clearRect() const
187 {
188  int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
189  return QRect( rect().right() - frameWidth * 2 - mClearIconSize.width(),
190  ( rect().bottom() + 1 - mClearIconSize.height() ) / 2,
191  mClearIconSize.width(),
192  mClearIconSize.height() );
193 }
void valueChanged(const QString &value)
Same as textChanged() but with support for null values.
void leaveEvent(QEvent *e) override
void mouseMoveEvent(QMouseEvent *e) override
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void paintEvent(QPaintEvent *e) override
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.