QGIS API Documentation 3.99.0-Master (26c88405ac0)
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 <QStyle>
28#include <QToolButton>
29
30#include "moc_qgsfilterlineedit.cpp"
31
32QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue )
33 : QLineEdit( parent )
34 , mNullValue( nullValue )
35{
36 // icon size is about 2/3 height of text, but minimum size of 16
37 const int iconSize = std::floor( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 0.75, 16.0 ) );
38
39 mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearText.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Normal, QIcon::On );
40 mClearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Selected, QIcon::On );
41
42 connect( this, &QLineEdit::textChanged, this, &QgsFilterLineEdit::onTextChanged );
43}
44
46{
47 mClearButtonVisible = visible;
48 updateClearIcon();
49}
50
52{
53 if ( visible && !mSearchAction )
54 {
55 const QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
56 mSearchAction = new QAction( searchIcon, QString(), this );
57 mSearchAction->setCheckable( false );
58 addAction( mSearchAction, QLineEdit::LeadingPosition );
59 }
60 else if ( !visible && mSearchAction )
61 {
62 mSearchAction->deleteLater();
63 mSearchAction = nullptr;
64 }
65}
66
68{
69 if ( defaultValue == mDefaultValue )
70 return;
71
72 mDefaultValue = defaultValue;
73 updateClearIcon();
74}
75
76void QgsFilterLineEdit::updateClearIcon()
77{
78 const bool showClear = shouldShowClear();
79 if ( showClear && !mClearAction )
80 {
81 mClearAction = new QAction( mClearIcon, QString(), this );
82 mClearAction->setCheckable( false );
83 addAction( mClearAction, QLineEdit::TrailingPosition );
84 connect( mClearAction, &QAction::triggered, this, &QgsFilterLineEdit::clearValue );
85 }
86 else if ( !showClear && mClearAction )
87 {
88 // pretty freakin weird... seems the deleteLater call on the mClearAction
89 // isn't sufficient to actually remove the action from the line edit, and
90 // a kind of "ghost" action gets left behind... resulting in duplicate
91 // clear actions appearing if later we re-create the action.
92 // in summary: don't remove this "removeAction" call!
93 removeAction( mClearAction );
94 mClearAction->deleteLater();
95 mClearAction = nullptr;
96 }
97}
98
99void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
100{
101 QLineEdit::focusInEvent( e );
102 if ( e->reason() == Qt::MouseFocusReason && ( isNull() || mSelectOnFocus ) )
103 {
104 mWaitingForMouseRelease = true;
105 }
106}
107
109{
110 QLineEdit::mouseReleaseEvent( e );
111 if ( mWaitingForMouseRelease )
112 {
113 mWaitingForMouseRelease = false;
114 selectAll();
115 }
116}
117
119{
120 switch ( mClearMode )
121 {
122 case ClearToNull:
123 setText( mNullValue );
124 selectAll();
125 break;
126
127 case ClearToDefault:
128 setText( mDefaultValue );
129 break;
130 }
131
132 setModified( true );
133 emit cleared();
134}
135
136void QgsFilterLineEdit::onTextChanged( const QString &text )
137{
138 updateClearIcon();
139
140 if ( isNull() )
141 {
142 setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
143 emit valueChanged( QString() );
144 }
145 else
146 {
147 setStyleSheet( mStyleSheet );
148 emit valueChanged( text );
149 }
150}
151
152void QgsFilterLineEdit::updateBusySpinner()
153{
154 if ( !mBusySpinnerAction )
155 {
156 mBusySpinnerAction = addAction( mBusySpinnerAnimatedIcon->icon(), QLineEdit::TrailingPosition );
157 }
158 mBusySpinnerAction->setIcon( mBusySpinnerAnimatedIcon->icon() );
159}
160
162{
163 return mSelectOnFocus;
164}
165
167{
168 if ( mSelectOnFocus == selectOnFocus )
169 return;
170
171 mSelectOnFocus = selectOnFocus;
173}
174
176{
177 return mShowSpinner;
178}
179
181{
182 if ( showSpinner == mShowSpinner )
183 return;
184
185 if ( showSpinner )
186 {
187 if ( !mBusySpinnerAnimatedIcon )
188 mBusySpinnerAnimatedIcon = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), this );
189
190 mBusySpinnerAnimatedIcon->connectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
191 }
192 else
193 {
194 mBusySpinnerAnimatedIcon->disconnectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
195 removeAction( mBusySpinnerAction );
196 mBusySpinnerAction = nullptr;
197 }
198
199 mShowSpinner = showSpinner;
200 emit showSpinnerChanged();
201}
202
203bool QgsFilterLineEdit::shouldShowClear() const
204{
205 if ( !isEnabled() || isReadOnly() || !mClearButtonVisible )
206 return false;
207
208 switch ( mClearMode )
209 {
210 case ClearToNull:
211 return !isNull();
212
213 case ClearToDefault:
214 return value() != mDefaultValue;
215 }
216 return false; //avoid warnings
217}
218
220{
221 if ( event->type() == QEvent::ReadOnlyChange || event->type() == QEvent::EnabledChange )
222 updateClearIcon();
223
224 return QLineEdit::event( event );
225}
226
228{
229 mLineEditState.text = text();
230 mLineEditState.selectionStart = selectionStart();
231 mLineEditState.selectionLength = selectedText().length();
232 mLineEditState.cursorPosition = cursorPosition();
233 mLineEditState.hasStateStored = true;
234}
235
237{
238 setText( mLineEditState.text );
239 setCursorPosition( mLineEditState.cursorPosition );
240 if ( mLineEditState.selectionStart > -1 )
241 setSelection( mLineEditState.selectionStart, mLineEditState.selectionLength );
242 mLineEditState.hasStateStored = false;
243}
244
246void QgsSpinBoxLineEdit::focusInEvent( QFocusEvent *e )
247{
249 if ( isNull() )
250 {
251 clear();
252 }
253}
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6222
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.