QGIS API Documentation 3.29.0-Master (da8bb1db43)
qgssearchwidgettoolbutton.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssearchwidgettoolbutton.cpp
3 -----------------------------
4 Date : May 2016
5 Copyright : (C) 2016 Nyall Dawson
6 Email : nyall dot dawson at gmail.com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgsapplication.h"
18#include <QMenu>
19
21 : QToolButton( parent )
22 , mAvailableFilterFlags( QgsSearchWidgetWrapper::EqualTo | QgsSearchWidgetWrapper::NotEqualTo | QgsSearchWidgetWrapper::CaseInsensitive )
23 , mDefaultFilterFlags( QgsSearchWidgetWrapper::EqualTo )
24 , mFilterFlags( QgsSearchWidgetWrapper::EqualTo )
25
26{
27 setFocusPolicy( Qt::StrongFocus );
28 setPopupMode( QToolButton::InstantPopup );
29
30 mMenu = new QMenu( this );
31 connect( mMenu, &QMenu::aboutToShow, this, &QgsSearchWidgetToolButton::aboutToShowMenu );
32 setMenu( mMenu );
33
34 // sets initial appearance
35 updateState();
36}
37
38void QgsSearchWidgetToolButton::setAvailableFlags( QgsSearchWidgetWrapper::FilterFlags flags )
39{
40 mFilterFlags &= flags;
41 mAvailableFilterFlags = flags;
42 mDefaultFilterFlags = mDefaultFilterFlags & flags;
43 updateState();
44}
45
46void QgsSearchWidgetToolButton::setDefaultFlags( QgsSearchWidgetWrapper::FilterFlags flags )
47{
48 mDefaultFilterFlags = flags & mAvailableFilterFlags;
49}
50
51void QgsSearchWidgetToolButton::setActiveFlags( QgsSearchWidgetWrapper::FilterFlags flags )
52{
53 // sanitize list
54 QgsSearchWidgetWrapper::FilterFlags newFlags;
55
56 // only accept a single exclusive flag
57 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
58 for ( const QgsSearchWidgetWrapper::FilterFlag flag : exclusiveFilterFlags )
59 {
60 if ( !( mAvailableFilterFlags & flag ) )
61 {
62 //unsupported
63 continue;
64 }
65 if ( flags & flag )
66 {
67 newFlags |= flag;
68 break;
69 }
70 }
71 const auto nonExclusiveFilterFlags { QgsSearchWidgetWrapper::nonExclusiveFilterFlags() };
72 for ( const QgsSearchWidgetWrapper::FilterFlag flag : nonExclusiveFilterFlags )
73 {
74 if ( !( mAvailableFilterFlags & flag ) )
75 {
76 //unsupported
77 continue;
78 }
79
80 if ( flags & flag )
81 newFlags |= flag;
82 }
83
84 mFilterFlags = newFlags;
85
86 updateState();
87}
88
90{
91 if ( !( flag & mAvailableFilterFlags ) )
92 return;
93
95 {
96 if ( flag & mFilterFlags )
97 mFilterFlags &= ~flag;
98 else
99 mFilterFlags |= flag;
100 }
101 else
102 {
103 // clear other exclusive flags
104 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
105 for ( const QgsSearchWidgetWrapper::FilterFlag exclusiveFlag : exclusiveFilterFlags )
106 {
107 mFilterFlags &= ~exclusiveFlag;
108 }
109 // and set new exclusive flag
110 mFilterFlags |= flag;
111 }
112
113 updateState();
114}
115
117{
118 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
119 for ( const QgsSearchWidgetWrapper::FilterFlag flag : exclusiveFilterFlags )
120 {
121 if ( mFilterFlags & flag )
122 return true;
123 }
124 return false;
125}
126
127void QgsSearchWidgetToolButton::aboutToShowMenu()
128{
129 mMenu->clear();
130 bool fieldActive = false;
131 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
132 for ( const QgsSearchWidgetWrapper::FilterFlag flag : exclusiveFilterFlags )
133 {
134 if ( !( mAvailableFilterFlags & flag ) )
135 {
136 //unsupported
137 continue;
138 }
139
140 QAction *action = mMenu->addAction( QgsSearchWidgetWrapper::toString( flag ) );
141 connect( action, &QAction::triggered, this, &QgsSearchWidgetToolButton::actionSelected );
142 action->setData( flag );
143 action->setCheckable( true );
144 if ( mFilterFlags & flag )
145 {
146 fieldActive = true;
147 action->setChecked( true );
148 }
149 }
150
151 QAction *clearAction = mMenu->addAction( tr( "Exclude Field" ) );
152 connect( clearAction, &QAction::triggered, this, &QgsSearchWidgetToolButton::setInactive );
153 clearAction->setCheckable( true );
154 clearAction->setChecked( !fieldActive );
155 if ( mMenu->actions().count() > 0 )
156 {
157 mMenu->insertAction( mMenu->actions().at( 0 ), clearAction );
158 mMenu->insertSeparator( mMenu->actions().at( 1 ) );
159 }
160 else
161 mMenu->addAction( clearAction );
162
163 mMenu->addSeparator();
164
165 const auto nonExclusiveFilterFlags { QgsSearchWidgetWrapper::nonExclusiveFilterFlags() };
166 for ( const QgsSearchWidgetWrapper::FilterFlag flag : nonExclusiveFilterFlags )
167 {
168 if ( !( mAvailableFilterFlags & flag ) )
169 {
170 //unsupported
171 continue;
172 }
173
174 QAction *action = mMenu->addAction( QgsSearchWidgetWrapper::toString( flag ) );
175 connect( action, &QAction::triggered, this, &QgsSearchWidgetToolButton::actionSelected );
176 action->setData( flag );
177 action->setCheckable( true );
178 if ( mFilterFlags & flag )
179 action->setChecked( true );
180 }
181}
182
183void QgsSearchWidgetToolButton::actionSelected()
184{
185 const QgsSearchWidgetWrapper::FilterFlag flag = static_cast< QgsSearchWidgetWrapper::FilterFlag >( qobject_cast< QAction * >( sender() )->data().toInt() );
186 toggleFlag( flag );
187}
188
189void QgsSearchWidgetToolButton::searchWidgetValueChanged()
190{
191 setActive();
192}
193
195{
196 if ( !isActive() )
197 return;
198
199 QgsSearchWidgetWrapper::FilterFlags newFlags;
200 const auto nonExclusiveFilterFlags { QgsSearchWidgetWrapper::nonExclusiveFilterFlags() };
201 for ( const QgsSearchWidgetWrapper::FilterFlag flag : nonExclusiveFilterFlags )
202 {
203 if ( !( mAvailableFilterFlags & flag ) || !( mFilterFlags & flag ) )
204 continue;
205 newFlags |= flag;
206 }
207 mFilterFlags = newFlags;
208 updateState();
209}
210
212{
213 if ( isActive() )
214 return;
215
216 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
217 for ( const QgsSearchWidgetWrapper::FilterFlag flag : exclusiveFilterFlags )
218 {
219 if ( mDefaultFilterFlags & flag )
220 {
221 toggleFlag( flag );
222 return;
223 }
224 }
225}
226
227void QgsSearchWidgetToolButton::updateState()
228{
229 bool active = false;
230 QStringList toolTips;
231 const auto exclusiveFilterFlags { QgsSearchWidgetWrapper::exclusiveFilterFlags() };
232 for ( const QgsSearchWidgetWrapper::FilterFlag flag : exclusiveFilterFlags )
233 {
234 if ( mFilterFlags & flag )
235 {
236 toolTips << QgsSearchWidgetWrapper::toString( flag );
237 active = true;
238 }
239 }
240 const auto nonExclusiveFilterFlags { QgsSearchWidgetWrapper::nonExclusiveFilterFlags() };
241 for ( const QgsSearchWidgetWrapper::FilterFlag flag : nonExclusiveFilterFlags )
242 {
243 if ( mFilterFlags & flag )
244 {
245 toolTips << QgsSearchWidgetWrapper::toString( flag ).toLower();
246 }
247 }
248
249 if ( active )
250 {
251 const QString text = toolTips.join( QLatin1String( ", " ) );
252 setText( text );
253 setToolTip( text );
254 }
255 else
256 {
257 setText( tr( "Exclude Field" ) );
258 setToolTip( QString() );
259 }
260
261 emit activeFlagsChanged( mFilterFlags );
262}
void setInactive()
Sets the search widget as inactive, ie do not search the corresponding field.
void setActiveFlags(QgsSearchWidgetWrapper::FilterFlags flags)
Sets the current active filter flags for the widget.
void setDefaultFlags(QgsSearchWidgetWrapper::FilterFlags flags)
Sets the default filter flags to show in the widget.
void activeFlagsChanged(QgsSearchWidgetWrapper::FilterFlags flags)
Emitted when the active flags selected in the widget is changed.
QgsSearchWidgetToolButton(QWidget *parent=nullptr)
Constructor for QgsSearchWidgetToolButton.
void toggleFlag(QgsSearchWidgetWrapper::FilterFlag flag)
Toggles an individual active filter flag for the widget.
void setAvailableFlags(QgsSearchWidgetWrapper::FilterFlags flags)
Sets the available filter flags to show in the widget.
bool isActive() const
Returns true if the widget is set to be included in the search.
void setActive()
Sets the search widget as active by selecting the first available search type.
Shows a search widget on a filter form.
FilterFlag
Flags which indicate what types of filtering and searching is possible using the widget.
static QList< QgsSearchWidgetWrapper::FilterFlag > nonExclusiveFilterFlags()
Returns a list of non-exclusive filter flags, which can be combined with other flags (e....
static QList< QgsSearchWidgetWrapper::FilterFlag > exclusiveFilterFlags()
Returns a list of exclusive filter flags, which cannot be combined with other flags (e....
static QString toString(QgsSearchWidgetWrapper::FilterFlag flag)
Returns a translated string representing a filter flag.