QGIS API Documentation  3.0.2-Girona (307d082)
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 #include "qgsanimatedicon.h"
21 
22 #include <QAction>
23 #include <QToolButton>
24 #include <QStyle>
25 #include <QFocusEvent>
26 #include <QPainter>
27 
28 QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue )
29  : QLineEdit( parent )
30  , mNullValue( nullValue )
31 {
32  // icon size is about 2/3 height of text, but minimum size of 16
33  int iconSize = std::floor( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 0.75, 16.0 ) );
34 
35  mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearText.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Normal, QIcon::On );
36  mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Selected, QIcon::On );
37 
38  connect( this, &QLineEdit::textChanged, this,
39  &QgsFilterLineEdit::onTextChanged );
40 }
41 
43 {
44  mClearButtonVisible = visible;
45  updateClearIcon();
46 }
47 
49 {
50  if ( visible && !mSearchAction )
51  {
52  QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
53  mSearchAction = new QAction( searchIcon, QString(), this );
54  mSearchAction->setCheckable( false );
55  addAction( mSearchAction, QLineEdit::LeadingPosition );
56  }
57  else if ( !visible && mSearchAction )
58  {
59  mSearchAction->deleteLater();
60  mSearchAction = nullptr;
61  }
62 }
63 
64 void QgsFilterLineEdit::updateClearIcon()
65 {
66  bool showClear = shouldShowClear();
67  if ( showClear && !mClearAction )
68  {
69  mClearAction = new QAction( mClearIcon, QString(), this );
70  mClearAction->setCheckable( false );
71  addAction( mClearAction, QLineEdit::TrailingPosition );
72  connect( mClearAction, &QAction::triggered, this, &QgsFilterLineEdit::clearValue );
73  }
74  else if ( !showClear && mClearAction )
75  {
76  mClearAction->deleteLater();
77  mClearAction = nullptr;
78  }
79 }
80 
81 void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
82 {
83  QLineEdit::focusInEvent( e );
84  if ( e->reason() == Qt::MouseFocusReason && ( isNull() || mSelectOnFocus ) )
85  {
86  mFocusInEvent = true;
87  selectAll();
88  }
89 }
90 
92 {
93  switch ( mClearMode )
94  {
95  case ClearToNull:
96  setText( mNullValue );
97  selectAll();
98  break;
99 
100  case ClearToDefault:
101  setText( mDefaultValue );
102  break;
103  }
104 
105  setModified( true );
106  emit cleared();
107 }
108 
109 void QgsFilterLineEdit::onTextChanged( const QString &text )
110 {
111  updateClearIcon();
112 
113  if ( isNull() )
114  {
115  setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
116  emit valueChanged( QString() );
117  }
118  else
119  {
120  setStyleSheet( mStyleSheet );
121  emit valueChanged( text );
122  }
123 }
124 
125 void QgsFilterLineEdit::updateBusySpinner()
126 {
127  if ( !mBusySpinnerAction )
128  {
129  mBusySpinnerAction = addAction( mBusySpinnerAnimatedIcon->icon(), QLineEdit::TrailingPosition );
130  }
131  mBusySpinnerAction->setIcon( mBusySpinnerAnimatedIcon->icon() );
132 }
133 
135 {
136  return mSelectOnFocus;
137 }
138 
140 {
141  if ( mSelectOnFocus == selectOnFocus )
142  return;
143 
144  mSelectOnFocus = selectOnFocus;
145  emit selectOnFocusChanged();
146 }
147 
149 {
150  return mShowSpinner;
151 }
152 
154 {
155 
156  if ( showSpinner == mShowSpinner )
157  return;
158 
159  if ( showSpinner )
160  {
161  if ( !mBusySpinnerAnimatedIcon )
162  mBusySpinnerAnimatedIcon = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), this );
163 
164  mBusySpinnerAnimatedIcon->connectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
165  }
166  else
167  {
168  mBusySpinnerAnimatedIcon->disconnectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
169  removeAction( mBusySpinnerAction );
170  mBusySpinnerAction = nullptr;
171  }
172 
173  mShowSpinner = showSpinner;
174  emit showSpinnerChanged();
175 }
176 
177 bool QgsFilterLineEdit::shouldShowClear() const
178 {
179  if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
180  return false;
181 
182  switch ( mClearMode )
183  {
184  case ClearToNull:
185  return !isNull();
186 
187  case ClearToDefault:
188  return value() != mDefaultValue;
189  }
190  return false; //avoid warnings
191 }
192 
194 {
195  if ( event->type() == QEvent::ReadOnlyChange )
196  updateClearIcon();
197 
198  return QLineEdit::event( event );;
199 }
void valueChanged(const QString &value)
Same as textChanged() but with support for null values.
bool disconnectFrameChanged(const typename QtPrivate::FunctionPointer< Func1 >::Object *receiver, Func1 slot)
Convenience function to disconnect the same style that the frame change connection was established...
void setSelectOnFocus(bool selectOnFocus)
Will select all text when this widget receives the focus.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:151
void setShowSpinner(bool showSpinner)
Show a spinner icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
void showSpinnerChanged()
Show a spinner icon.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void selectOnFocusChanged()
Will select all text when this widget receives the focus.
void setShowSearchIcon(bool visible)
Define if a search icon shall be shown on the left of the image when no text is entered.
QgsFilterLineEdit(QWidget *parent=nullptr, const QString &nullValue=QString())
Constructor for QgsFilterLineEdit.
Reset value to default value (see defaultValue() )
virtual void clearValue()
Clears the widget and resets it to the null value.
virtual bool event(QEvent *event) override
Reimplemented to enable/disable the clear action depending on read-only status.
bool selectOnFocus() const
Will select all text when this widget receives the focus.
bool showSpinner() const
Show a spinner icon.
void focusInEvent(QFocusEvent *e) override
void cleared()
Emitted when the widget is cleared.
Animated icon is keeping an animation running if there are listeners connected to frameChanged...
QIcon icon() const
Get the icons representation in the current frame.
bool isNull() const
Determine if the current text represents null.
void setShowClearButton(bool visible)
Sets whether the widget&#39;s clear button is visible.
bool connectFrameChanged(const typename QtPrivate::FunctionPointer< Func1 >::Object *receiver, Func1 slot)
Connect a slot that will be notified repeatedly whenever a frame changes and which should request the...
QString value() const
Returns the text of this edit with support for handling null values.