QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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
20#include "qgis.h"
21#include "qgsanimatedicon.h"
22#include "qgsapplication.h"
23
24#include <QAction>
25#include <QFocusEvent>
26#include <QPainter>
27#include <QString>
28#include <QStyle>
29#include <QToolButton>
30
31#include "moc_qgsfilterlineedit.cpp"
32
33using namespace Qt::StringLiterals;
34
35QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue )
36 : QLineEdit( parent )
37 , mNullValue( nullValue )
38{
39 // icon size is about 2/3 height of text, but minimum size of 16
40 const int iconSize = std::floor( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 0.75, 16.0 ) );
41
42 mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearText.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Normal, QIcon::On );
43 mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Selected, QIcon::On );
44
45 connect( this, &QLineEdit::textChanged, this, &QgsFilterLineEdit::onTextChanged );
46}
47
49{
50 mClearButtonVisible = visible;
51 updateClearIcon();
52}
53
55{
56 if ( visible && !mSearchAction )
57 {
58 const QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
59 mSearchAction = new QAction( searchIcon, QString(), this );
60 mSearchAction->setCheckable( false );
61 addAction( mSearchAction, QLineEdit::LeadingPosition );
62 }
63 else if ( !visible && mSearchAction )
64 {
65 mSearchAction->deleteLater();
66 mSearchAction = nullptr;
67 }
68}
69
71{
72 if ( defaultValue == mDefaultValue )
73 return;
74
75 mDefaultValue = defaultValue;
76 updateClearIcon();
77}
78
79void QgsFilterLineEdit::updateClearIcon()
80{
81 const bool showClear = shouldShowClear();
82 if ( showClear && !mClearAction )
83 {
84 mClearAction = new QAction( mClearIcon, QString(), this );
85 mClearAction->setCheckable( false );
86 addAction( mClearAction, QLineEdit::TrailingPosition );
87 connect( mClearAction, &QAction::triggered, this, &QgsFilterLineEdit::clearValue );
88 }
89 else if ( !showClear && mClearAction )
90 {
91 // pretty freakin weird... seems the deleteLater call on the mClearAction
92 // isn't sufficient to actually remove the action from the line edit, and
93 // a kind of "ghost" action gets left behind... resulting in duplicate
94 // clear actions appearing if later we re-create the action.
95 // in summary: don't remove this "removeAction" call!
96 removeAction( mClearAction );
97 mClearAction->deleteLater();
98 mClearAction = nullptr;
99 }
100}
101
103{
104 QLineEdit::focusInEvent( e );
105 if ( e->reason() == Qt::MouseFocusReason && ( isNull() || mSelectOnFocus ) )
106 {
107 mWaitingForMouseRelease = true;
108 }
109}
110
112{
113 QLineEdit::mouseReleaseEvent( e );
114 if ( mWaitingForMouseRelease )
115 {
116 mWaitingForMouseRelease = false;
117 selectAll();
118 }
119}
120
122{
123 switch ( mClearMode )
124 {
125 case ClearToNull:
126 setText( mNullValue );
127 selectAll();
128 break;
129
130 case ClearToDefault:
131 setText( mDefaultValue );
132 break;
133 }
134
135 setModified( true );
136 emit cleared();
137}
138
139void QgsFilterLineEdit::onTextChanged( const QString &text )
140{
141 updateClearIcon();
142
143 if ( isNull() )
144 {
145 setStyleSheet( u"QLineEdit { font: italic; color: gray; } %1"_s.arg( mStyleSheet ) );
146 emit valueChanged( QString() );
147 }
148 else
149 {
150 setStyleSheet( mStyleSheet );
151 emit valueChanged( text );
152 }
153}
154
155void QgsFilterLineEdit::updateBusySpinner()
156{
157 if ( !mBusySpinnerAction )
158 {
159 mBusySpinnerAction = addAction( mBusySpinnerAnimatedIcon->icon(), QLineEdit::TrailingPosition );
160 }
161 mBusySpinnerAction->setIcon( mBusySpinnerAnimatedIcon->icon() );
162}
163
165{
166 return mSelectOnFocus;
167}
168
170{
171 if ( mSelectOnFocus == selectOnFocus )
172 return;
173
174 mSelectOnFocus = selectOnFocus;
176}
177
179{
180 return mShowSpinner;
181}
182
184{
185 if ( showSpinner == mShowSpinner )
186 return;
187
188 if ( showSpinner )
189 {
190 if ( !mBusySpinnerAnimatedIcon )
191 mBusySpinnerAnimatedIcon = new QgsAnimatedIcon( QgsApplication::iconPath( u"/mIconLoading.gif"_s ), this );
192
193 mBusySpinnerAnimatedIcon->connectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
194 }
195 else
196 {
197 mBusySpinnerAnimatedIcon->disconnectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
198 removeAction( mBusySpinnerAction );
199 mBusySpinnerAction = nullptr;
200 }
201
202 mShowSpinner = showSpinner;
203 emit showSpinnerChanged();
204}
205
206bool QgsFilterLineEdit::shouldShowClear() const
207{
208 if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
209 return false;
210
211 switch ( mClearMode )
212 {
213 case ClearToNull:
214 return !isNull();
215
216 case ClearToDefault:
217 return value() != mDefaultValue;
218 }
219 return false; //avoid warnings
220}
221
223{
224 if ( event->type() == QEvent::ReadOnlyChange || event->type() == QEvent::EnabledChange )
225 updateClearIcon();
226
227 return QLineEdit::event( event );
228}
229
231{
232 mLineEditState.text = text();
233 mLineEditState.selectionStart = selectionStart();
234 mLineEditState.selectionLength = selectedText().length();
235 mLineEditState.cursorPosition = cursorPosition();
236 mLineEditState.hasStateStored = true;
237}
238
240{
241 setText( mLineEditState.text );
242 setCursorPosition( mLineEditState.cursorPosition );
243 if ( mLineEditState.selectionStart > -1 )
244 setSelection( mLineEditState.selectionStart, mLineEditState.selectionLength );
245 mLineEditState.hasStateStored = false;
246}
247
249void QgsSpinBoxLineEdit::focusInEvent( QFocusEvent *e )
250{
252 if ( isNull() )
253 {
254 clear();
255 }
256}
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6499
Animated icon is keeping an animation running if there are listeners connected to frameChanged.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
void focusInEvent(QFocusEvent *e) override
void restoreState()
Restores the current state of the line edit (selection and cursor position).
void storeState()
Stores the current state of the line edit (selection and cursor position).
void selectOnFocusChanged()
Will select all text when this widget receives the focus.
void showSpinnerChanged()
Show a spinner icon.
virtual void clearValue()
Clears the widget and resets it to the null value.
@ ClearToNull
Reset value to null.
@ ClearToDefault
Reset value to default value (see defaultValue() ).
bool isNull() const
Determine if the current text represents null.
bool selectOnFocus() const
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.
void setShowClearButton(bool visible)
Sets whether the widget's clear button is visible.
QgsFilterLineEdit(QWidget *parent=nullptr, const QString &nullValue=QString())
Constructor for QgsFilterLineEdit.
void setSelectOnFocus(bool selectOnFocus)
Will select all text when this widget receives the focus.
void mouseReleaseEvent(QMouseEvent *e) override
void cleared()
Emitted when the widget is cleared.
void setDefaultValue(const QString &defaultValue)
Sets the default value for the widget.
void setShowSpinner(bool showSpinner)
Show a spinner icon.
bool event(QEvent *event) override
Reimplemented to enable/disable the clear action depending on read-only status.
void valueChanged(const QString &value)
Same as textChanged() but with support for null values.